mirror of
https://github.com/rwengine/openrw.git
synced 2024-09-03 09:09:47 +02:00
Improve Menu system implementation
This commit is contained in:
parent
6a7802de87
commit
613d386488
@ -19,6 +19,9 @@ set(RWGAME_SOURCES
|
||||
StateManager.cpp
|
||||
State.cpp
|
||||
|
||||
MenuSystem.hpp
|
||||
MenuSystem.cpp
|
||||
|
||||
states/LoadingState.hpp
|
||||
states/LoadingState.cpp
|
||||
states/IngameState.hpp
|
||||
|
0
rwgame/MenuSystem.cpp
Normal file
0
rwgame/MenuSystem.cpp
Normal file
@ -21,27 +21,35 @@ constexpr const char* kOptionsId = "FET_OPT";
|
||||
constexpr const char* kQuitGameId = "FET_QG";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Implements user navigable menus
|
||||
*
|
||||
* This is a temporary implementation
|
||||
*/
|
||||
class Menu {
|
||||
int font;
|
||||
|
||||
public:
|
||||
Menu(int font = MenuDefaults::kFont) : font(font), activeEntry(-1) {
|
||||
}
|
||||
|
||||
struct MenuEntry {
|
||||
/**
|
||||
* @brief Handles rendering and dispatch of menu items
|
||||
*/
|
||||
class MenuEntry {
|
||||
GameString text;
|
||||
float _size;
|
||||
float size;
|
||||
std::function<void(void)> callback;
|
||||
|
||||
MenuEntry(const GameString& n, float size = 30.f)
|
||||
: text(n), _size(size) {
|
||||
public:
|
||||
MenuEntry(const std::string& n, std::function<void(void)> cb)
|
||||
: text(GameStringUtil::fromString(n)), size(30.f), callback(cb) {
|
||||
}
|
||||
MenuEntry(const GameString& n, std::function<void(void)> cb,
|
||||
float size = 30.f)
|
||||
: text(n), size(size), callback(cb) {
|
||||
}
|
||||
|
||||
float getHeight() {
|
||||
return _size;
|
||||
float getHeight() const {
|
||||
return size;
|
||||
}
|
||||
|
||||
virtual void draw(int font, bool active, GameRenderer* r,
|
||||
glm::vec2& basis) {
|
||||
void draw(int font, bool active, GameRenderer* r, glm::vec2& basis) {
|
||||
TextRenderer::TextInfo ti;
|
||||
ti.font = font;
|
||||
ti.screenPosition = basis;
|
||||
@ -56,16 +64,6 @@ public:
|
||||
basis.y += getHeight();
|
||||
}
|
||||
|
||||
virtual void activate(float clickX, float clickY) = 0;
|
||||
};
|
||||
|
||||
struct Entry : public MenuEntry {
|
||||
std::function<void(void)> callback;
|
||||
|
||||
Entry(const GameString& title, std::function<void(void)> cb, float size)
|
||||
: MenuEntry(title, size), callback(cb) {
|
||||
}
|
||||
|
||||
void activate(float clickX, float clickY) {
|
||||
RW_UNUSED(clickX);
|
||||
RW_UNUSED(clickY);
|
||||
@ -73,19 +71,28 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static std::shared_ptr<MenuEntry> lambda(const GameString& n,
|
||||
std::function<void(void)> callback,
|
||||
float size = 30.f) {
|
||||
return std::shared_ptr<MenuEntry>(new Entry(n, callback, size));
|
||||
Menu(std::vector<MenuEntry> initial, int font = MenuDefaults::kFont)
|
||||
: activeEntry(-1), font(font), entries(std::move(initial)) {
|
||||
}
|
||||
|
||||
static std::shared_ptr<MenuEntry> lambda(const std::string& n,
|
||||
std::function<void(void)> callback,
|
||||
float size = 30.f) {
|
||||
return lambda(GameStringUtil::fromString(n), callback, size);
|
||||
/**
|
||||
* @brief creates a menu from the given menu items
|
||||
* @return a shared pointer to the menu with the items
|
||||
*/
|
||||
static std::shared_ptr<Menu> create(std::vector<MenuEntry> items,
|
||||
int font = MenuDefaults::kFont) {
|
||||
return std::make_shared<Menu>(std::move(items), font);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<MenuEntry>> entries;
|
||||
Menu& lambda(const GameString& n, std::function<void()> callback) {
|
||||
entries.emplace_back(n, callback, 30.f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Menu& lambda(const std::string& n, std::function<void(void)> callback) {
|
||||
entries.emplace_back(GameStringUtil::fromString(n), callback, 30.f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Active Entry index
|
||||
@ -94,10 +101,6 @@ public:
|
||||
|
||||
glm::vec2 offset;
|
||||
|
||||
void addEntry(std::shared_ptr<MenuEntry> entry) {
|
||||
entries.push_back(entry);
|
||||
}
|
||||
|
||||
void draw(GameRenderer* r) {
|
||||
glm::vec2 basis(offset);
|
||||
for (size_t i = 0; i < entries.size(); ++i) {
|
||||
@ -105,18 +108,18 @@ public:
|
||||
if (activeEntry >= 0 && i == (unsigned)activeEntry) {
|
||||
active = true;
|
||||
}
|
||||
entries[i]->draw(font, active, r, basis);
|
||||
entries[i].draw(font, active, r, basis);
|
||||
}
|
||||
}
|
||||
|
||||
void hover(const float x, const float y) {
|
||||
glm::vec2 c(x - offset.x, y - offset.y);
|
||||
for (size_t i = 0; i < entries.size(); ++i) {
|
||||
if (c.y > 0.f && c.y < entries[i]->getHeight()) {
|
||||
if (c.y > 0.f && c.y < entries[i].getHeight()) {
|
||||
activeEntry = i;
|
||||
return;
|
||||
} else {
|
||||
c.y -= entries[i]->getHeight();
|
||||
c.y -= entries[i].getHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,11 +127,11 @@ public:
|
||||
void click(const float x, const float y) {
|
||||
glm::vec2 c(x - offset.x, y - offset.y);
|
||||
for (auto it = entries.begin(); it != entries.end(); ++it) {
|
||||
if (c.y > 0.f && c.y < (*it)->getHeight()) {
|
||||
(*it)->activate(c.x, c.y);
|
||||
if (c.y > 0.f && c.y < (*it).getHeight()) {
|
||||
(*it).activate(c.x, c.y);
|
||||
return;
|
||||
} else {
|
||||
c.y -= (*it)->getHeight();
|
||||
c.y -= (*it).getHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -136,7 +139,7 @@ public:
|
||||
// Activates the menu entry at the current active index.
|
||||
void activate() {
|
||||
if (activeEntry >= 0 && (unsigned)activeEntry < entries.size()) {
|
||||
entries[activeEntry]->activate(0.f, 0.f);
|
||||
entries[activeEntry].activate(0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,6 +151,14 @@ public:
|
||||
activeEntry = entries.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<MenuEntry>& getEntries() const {
|
||||
return entries;
|
||||
}
|
||||
|
||||
private:
|
||||
int font;
|
||||
std::vector<MenuEntry> entries;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -12,13 +12,12 @@ class StateManager;
|
||||
|
||||
class State {
|
||||
public:
|
||||
// Helper for global menu behaviour
|
||||
Menu* currentMenu;
|
||||
Menu* nextMenu;
|
||||
std::shared_ptr<Menu> menu;
|
||||
std::shared_ptr<Menu> nextMenu;
|
||||
|
||||
RWGame* game;
|
||||
|
||||
State(RWGame* game) : currentMenu(nullptr), nextMenu(nullptr), game(game) {
|
||||
State(RWGame* game) : game(game) {
|
||||
}
|
||||
|
||||
virtual void enter() = 0;
|
||||
@ -33,24 +32,18 @@ public:
|
||||
}
|
||||
|
||||
virtual ~State() {
|
||||
if (getCurrentMenu()) {
|
||||
delete getCurrentMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void enterMenu(Menu* menu) {
|
||||
void enterMenu(const std::shared_ptr<Menu>& menu) {
|
||||
nextMenu = menu;
|
||||
}
|
||||
|
||||
Menu* getCurrentMenu() {
|
||||
if (nextMenu) {
|
||||
if (currentMenu) {
|
||||
delete currentMenu;
|
||||
}
|
||||
currentMenu = nextMenu;
|
||||
menu = nextMenu;
|
||||
nextMenu = nullptr;
|
||||
}
|
||||
return currentMenu;
|
||||
return menu.get();
|
||||
}
|
||||
|
||||
virtual void handleEvent(const SDL_Event& e);
|
||||
@ -72,8 +65,11 @@ public:
|
||||
|
||||
private:
|
||||
bool hasexited_ = false;
|
||||
|
||||
protected:
|
||||
void done() { hasexited_ = true; }
|
||||
void done() {
|
||||
hasexited_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "RWGame.hpp"
|
||||
|
||||
constexpr float kDebugEntryHeight = 14.f;
|
||||
constexpr int kDebugFont = 2;
|
||||
const glm::vec2 kDebugMenuOffset = glm::vec2(10.f, 50.f);
|
||||
|
||||
static void jumpCharacter(RWGame* game, CharacterObject* player,
|
||||
@ -29,195 +30,119 @@ static void jumpCharacter(RWGame* game, CharacterObject* player,
|
||||
}
|
||||
}
|
||||
|
||||
Menu* DebugState::createDebugMenu() {
|
||||
std::shared_ptr<Menu> DebugState::createDebugMenu() {
|
||||
CharacterObject* player = nullptr;
|
||||
if (game->getPlayer()) {
|
||||
player = game->getPlayer()->getCharacter();
|
||||
}
|
||||
|
||||
Menu* m = new Menu(2);
|
||||
m->offset = kDebugMenuOffset;
|
||||
#if 0
|
||||
m->addEntry(Menu::lambda("Random Vehicle", [this] {
|
||||
auto it = getWorld()->vehicleTypes.begin();
|
||||
std::uniform_int_distribution<int> uniform(0, 3);
|
||||
for(size_t i = 0, n = uniform(getWorld()->randomEngine); i != n; i++) {
|
||||
it++;
|
||||
}
|
||||
spawnVehicle(it->first);
|
||||
}, entryHeight));
|
||||
m->addEntry(Menu::lambda("Open All Doors/Flaps", [=] {
|
||||
auto pc = getWorld()->state->player->getCharacter();
|
||||
auto pv = pc->getCurrentVehicle();
|
||||
if( pv ) {
|
||||
for(auto& it : pv->_hingedObjects) {
|
||||
pv->setHingeLocked(it.first, false);
|
||||
}
|
||||
}
|
||||
}, entryHeight));
|
||||
auto menu = Menu::create(
|
||||
{{"Jump to Debug Camera",
|
||||
[=] {
|
||||
jumpCharacter(game, player,
|
||||
_debugCam.position +
|
||||
_debugCam.rotation * glm::vec3(3.f, 0.f, 0.f),
|
||||
false);
|
||||
}},
|
||||
{"-Map", [=] { this->enterMenu(createMapMenu()); }},
|
||||
{"-Vehicles", [=] { this->enterMenu(createVehicleMenu()); }},
|
||||
{"-AI", [=] { this->enterMenu(createAIMenu()); }},
|
||||
{"-Weapons", [=] { this->enterMenu(createWeaponMenu()); }},
|
||||
{"Set Super Jump", [=] { player->setJumpSpeed(20.f); }},
|
||||
{"Set Normal Jump",
|
||||
[=] { player->setJumpSpeed(CharacterObject::DefaultJumpSpeed); }},
|
||||
{"Full Health", [=] { player->getCurrentState().health = 100.f; }},
|
||||
{"Full Armour", [=] { player->getCurrentState().armour = 100.f; }},
|
||||
{"Cull Here",
|
||||
[=] { game->getRenderer().setCullOverride(true, _debugCam); }}},
|
||||
kDebugFont);
|
||||
|
||||
m->addEntry(Menu::lambda("Spawn Pedestrians", [=] {
|
||||
glm::vec3 hit, normal;
|
||||
if(game->hitWorldRay(hit, normal)) {
|
||||
glm::vec3 spawnPos = hit + glm::vec3(-5, 0.f, 0.0) + normal;
|
||||
size_t k = 1;
|
||||
// Spawn every pedestrian.
|
||||
for(auto it = getWorld()->pedestrianTypes.begin();
|
||||
it != getWorld()->pedestrianTypes.end(); ++it) {
|
||||
getWorld()->createPedestrian(it->first, spawnPos);
|
||||
spawnPos += glm::vec3(2.5, 0, 0);
|
||||
if((k++ % 6) == 0) { spawnPos += glm::vec3(-15, -2.5, 0); }
|
||||
}
|
||||
}
|
||||
}, entryHeight));
|
||||
|
||||
int vehiclesMax = 16, i = 0;
|
||||
for( auto& v : getWorld()->vehicleTypes ) {
|
||||
if( (i++) > vehiclesMax ) break;
|
||||
m->addEntry(Menu::lambda(v.second->handlingID, [=] {
|
||||
spawnVehicle(v.first);
|
||||
}, entryHeight));
|
||||
}
|
||||
#endif
|
||||
m->addEntry(Menu::lambda("Jump to Debug Camera",
|
||||
[=] {
|
||||
jumpCharacter(game, player,
|
||||
_debugCam.position +
|
||||
_debugCam.rotation *
|
||||
glm::vec3(3.f, 0.f, 0.f),
|
||||
false);
|
||||
},
|
||||
kDebugEntryHeight));
|
||||
|
||||
m->addEntry(Menu::lambda("-Map", [=] { this->enterMenu(createMapMenu()); },
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda("-Vehicles",
|
||||
[=] { this->enterMenu(createVehicleMenu()); },
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda("-AI", [=] { this->enterMenu(createAIMenu()); },
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda("-Weapons",
|
||||
[=] { this->enterMenu(createWeaponMenu()); },
|
||||
kDebugEntryHeight));
|
||||
|
||||
m->addEntry(Menu::lambda("Set Super Jump",
|
||||
[=] { player->setJumpSpeed(20.f); },
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda(
|
||||
"Set Normal Jump",
|
||||
[=] { player->setJumpSpeed(CharacterObject::DefaultJumpSpeed); },
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda("Full Health",
|
||||
[=] { player->getCurrentState().health = 100.f; },
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda("Full Armour",
|
||||
[=] { player->getCurrentState().armour = 100.f; },
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda(
|
||||
"Cull Here",
|
||||
[=] { game->getRenderer().setCullOverride(true, _debugCam); },
|
||||
kDebugEntryHeight));
|
||||
menu->offset = kDebugMenuOffset;
|
||||
|
||||
// Optional block if the player is in a vehicle
|
||||
auto cv = player->getCurrentVehicle();
|
||||
if (cv) {
|
||||
m->addEntry(Menu::lambda(
|
||||
"Flip vehicle",
|
||||
[=] {
|
||||
cv->setRotation(
|
||||
cv->getRotation() *
|
||||
glm::quat(glm::vec3(0.f, glm::pi<float>(), 0.f)));
|
||||
},
|
||||
kDebugEntryHeight));
|
||||
menu->lambda("Flip vehicle", [=] {
|
||||
cv->setRotation(cv->getRotation() *
|
||||
glm::quat(glm::vec3(0.f, glm::pi<float>(), 0.f)));
|
||||
});
|
||||
}
|
||||
|
||||
return m;
|
||||
return menu;
|
||||
}
|
||||
|
||||
Menu* DebugState::createMapMenu() {
|
||||
std::shared_ptr<Menu> DebugState::createMapMenu() {
|
||||
CharacterObject* player = nullptr;
|
||||
if (game->getPlayer()) {
|
||||
player = game->getPlayer()->getCharacter();
|
||||
}
|
||||
|
||||
Menu* m = new Menu(2);
|
||||
m->offset = kDebugMenuOffset;
|
||||
auto menu = Menu::create(
|
||||
{{"Back", [=] { enterMenu(createDebugMenu()); }},
|
||||
{"Jump to Docks",
|
||||
[=] {
|
||||
jumpCharacter(game, player, glm::vec3(1390.f, -837.f, 100.f));
|
||||
}},
|
||||
{"Jump to Garage",
|
||||
[=] { jumpCharacter(game, player, glm::vec3(270.f, -605.f, 40.f)); }},
|
||||
{"Jump to Airport",
|
||||
[=] {
|
||||
jumpCharacter(game, player, glm::vec3(-950.f, -980.f, 12.f));
|
||||
}},
|
||||
{"Jump to Hideout",
|
||||
[=] {
|
||||
jumpCharacter(game, player, glm::vec3(875.0, -309.0, 100.0));
|
||||
}},
|
||||
{"Jump to Luigi's",
|
||||
[=] {
|
||||
jumpCharacter(game, player, glm::vec3(902.75, -425.56, 100.0));
|
||||
}},
|
||||
{"Jump to Hospital",
|
||||
[=] {
|
||||
jumpCharacter(game, player, glm::vec3(1123.77, -569.15, 100.0));
|
||||
}},
|
||||
{"Unsolid garage doors",
|
||||
[=] {
|
||||
|
||||
m->addEntry(Menu::lambda("Back",
|
||||
[=] { this->enterMenu(createDebugMenu()); },
|
||||
kDebugEntryHeight));
|
||||
std::vector<std::string> garageDoorModels{
|
||||
"8ballsuburbandoor", "amcogaragedoor",
|
||||
"bankjobdoor", "bombdoor",
|
||||
"crushercrush", "crushertop",
|
||||
"door2_garage", "door3_garage",
|
||||
"door4_garage", "door_bombshop",
|
||||
"door_col_compnd_01", "door_col_compnd_02",
|
||||
"door_col_compnd_03", "door_col_compnd_04",
|
||||
"door_col_compnd_05", "door_jmsgrage",
|
||||
"door_sfehousegrge", "double_garage_dr",
|
||||
"impex_door", "impexpsubgrgdoor",
|
||||
"ind_plyrwoor", "ind_slidedoor",
|
||||
"jamesgrge_kb", "leveldoor2",
|
||||
"oddjgaragdoor", "plysve_gragedoor",
|
||||
"SalvGarage", "shedgaragedoor",
|
||||
"Sub_sprayshopdoor", "towergaragedoor1",
|
||||
"towergaragedoor2", "towergaragedoor3",
|
||||
"vheistlocdoor"};
|
||||
|
||||
m->addEntry(Menu::lambda(
|
||||
"Jump to Docks",
|
||||
[=] { jumpCharacter(game, player, glm::vec3(1390.f, -837.f, 100.f)); },
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda(
|
||||
"Jump to Garage",
|
||||
[=] { jumpCharacter(game, player, glm::vec3(270.f, -605.f, 40.f)); },
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda(
|
||||
"Jump to Airport",
|
||||
[=] { jumpCharacter(game, player, glm::vec3(-950.f, -980.f, 12.f)); },
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda(
|
||||
"Jump to Hideout",
|
||||
[=] { jumpCharacter(game, player, glm::vec3(875.0, -309.0, 100.0)); },
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda(
|
||||
"Jump to Luigi's",
|
||||
[=] { jumpCharacter(game, player, glm::vec3(902.75, -425.56, 100.0)); },
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda(
|
||||
"Jump to Hospital",
|
||||
[=] {
|
||||
jumpCharacter(game, player, glm::vec3(1123.77, -569.15, 100.0));
|
||||
},
|
||||
kDebugEntryHeight));
|
||||
m->addEntry(Menu::lambda(
|
||||
"Unsolid garage doors",
|
||||
[=] {
|
||||
auto gw = game->getWorld();
|
||||
for (auto& i : gw->instancePool.objects) {
|
||||
auto obj = static_cast<InstanceObject*>(i.second);
|
||||
if (std::find(garageDoorModels.begin(),
|
||||
garageDoorModels.end(),
|
||||
obj->getModelInfo<BaseModelInfo>()->name) !=
|
||||
garageDoorModels.end()) {
|
||||
obj->setSolid(false);
|
||||
}
|
||||
}
|
||||
}}},
|
||||
kDebugFont);
|
||||
|
||||
std::vector<std::string> garageDoorModels{
|
||||
"8ballsuburbandoor", "amcogaragedoor",
|
||||
"bankjobdoor", "bombdoor",
|
||||
"crushercrush", "crushertop",
|
||||
"door2_garage", "door3_garage",
|
||||
"door4_garage", "door_bombshop",
|
||||
"door_col_compnd_01", "door_col_compnd_02",
|
||||
"door_col_compnd_03", "door_col_compnd_04",
|
||||
"door_col_compnd_05", "door_jmsgrage",
|
||||
"door_sfehousegrge", "double_garage_dr",
|
||||
"impex_door", "impexpsubgrgdoor",
|
||||
"ind_plyrwoor", "ind_slidedoor",
|
||||
"jamesgrge_kb", "leveldoor2",
|
||||
"oddjgaragdoor", "plysve_gragedoor",
|
||||
"SalvGarage", "shedgaragedoor",
|
||||
"Sub_sprayshopdoor", "towergaragedoor1",
|
||||
"towergaragedoor2", "towergaragedoor3",
|
||||
"vheistlocdoor"};
|
||||
|
||||
auto gw = game->getWorld();
|
||||
for (auto& i : gw->instancePool.objects) {
|
||||
auto obj = static_cast<InstanceObject*>(i.second);
|
||||
if (std::find(garageDoorModels.begin(), garageDoorModels.end(),
|
||||
obj->getModelInfo<BaseModelInfo>()->name) !=
|
||||
garageDoorModels.end()) {
|
||||
obj->setSolid(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
kDebugEntryHeight));
|
||||
|
||||
return m;
|
||||
menu->offset = kDebugMenuOffset;
|
||||
return menu;
|
||||
}
|
||||
|
||||
Menu* DebugState::createVehicleMenu() {
|
||||
Menu* m = new Menu(2);
|
||||
m->offset = kDebugMenuOffset;
|
||||
|
||||
m->addEntry(Menu::lambda("Back",
|
||||
[=] { this->enterMenu(createDebugMenu()); },
|
||||
kDebugEntryHeight));
|
||||
std::shared_ptr<Menu> DebugState::createVehicleMenu() {
|
||||
auto menu = Menu::create({{"Back", [=] { enterMenu(createDebugMenu()); }}},
|
||||
kDebugFont);
|
||||
|
||||
const std::map<std::string, int> kVehicleTypes = {
|
||||
{"Landstalker", 90}, {"Taxi", 110}, {"Firetruck", 97},
|
||||
@ -228,20 +153,16 @@ Menu* DebugState::createVehicleMenu() {
|
||||
};
|
||||
|
||||
for (auto& e : kVehicleTypes) {
|
||||
m->addEntry(Menu::lambda(e.first, [=] { spawnVehicle(e.second); },
|
||||
kDebugEntryHeight));
|
||||
menu->lambda(e.first, [=] { spawnVehicle(e.second); });
|
||||
}
|
||||
|
||||
return m;
|
||||
menu->offset = kDebugMenuOffset;
|
||||
return menu;
|
||||
}
|
||||
|
||||
Menu* DebugState::createAIMenu() {
|
||||
Menu* m = new Menu(2);
|
||||
m->offset = kDebugMenuOffset;
|
||||
|
||||
m->addEntry(Menu::lambda("Back",
|
||||
[=] { this->enterMenu(createDebugMenu()); },
|
||||
kDebugEntryHeight));
|
||||
std::shared_ptr<Menu> DebugState::createAIMenu() {
|
||||
auto menu = Menu::create(
|
||||
{{"Back", [=] { this->enterMenu(createDebugMenu()); }}}, kDebugFont);
|
||||
|
||||
const std::map<std::string, int> kPedTypes = {
|
||||
{"Triad", 12}, {"Cop", 1}, {"SWAT", 2},
|
||||
@ -249,42 +170,35 @@ Menu* DebugState::createAIMenu() {
|
||||
};
|
||||
|
||||
for (auto& e : kPedTypes) {
|
||||
m->addEntry(Menu::lambda(e.first + " Follower",
|
||||
[=] { spawnFollower(e.second); },
|
||||
kDebugEntryHeight));
|
||||
menu->lambda(e.first + " Follower", [=] { spawnFollower(e.second); });
|
||||
}
|
||||
|
||||
m->addEntry(Menu::lambda(
|
||||
"Kill All Peds",
|
||||
[=] {
|
||||
for (auto& p : game->getWorld()->pedestrianPool.objects) {
|
||||
if (p.second->getLifetime() == GameObject::PlayerLifetime) {
|
||||
continue;
|
||||
}
|
||||
p.second->takeDamage({p.second->getPosition(),
|
||||
p.second->getPosition(), 100.f,
|
||||
GameObject::DamageInfo::Explosion, 0.f});
|
||||
menu->lambda("Kill All Peds", [=] {
|
||||
for (auto& p : game->getWorld()->pedestrianPool.objects) {
|
||||
if (p.second->getLifetime() == GameObject::PlayerLifetime) {
|
||||
continue;
|
||||
}
|
||||
},
|
||||
kDebugEntryHeight));
|
||||
return m;
|
||||
p.second->takeDamage({p.second->getPosition(),
|
||||
p.second->getPosition(), 100.f,
|
||||
GameObject::DamageInfo::Explosion, 0.f});
|
||||
}
|
||||
});
|
||||
|
||||
menu->offset = kDebugMenuOffset;
|
||||
return menu;
|
||||
}
|
||||
|
||||
Menu* DebugState::createWeaponMenu() {
|
||||
Menu* m = new Menu(2);
|
||||
m->offset = kDebugMenuOffset;
|
||||
|
||||
m->addEntry(Menu::lambda("Back",
|
||||
[=] { this->enterMenu(createDebugMenu()); },
|
||||
kDebugEntryHeight));
|
||||
std::shared_ptr<Menu> DebugState::createWeaponMenu() {
|
||||
auto menu = Menu::create(
|
||||
{{"Back", [=] { this->enterMenu(createDebugMenu()); }}}, kDebugFont);
|
||||
|
||||
for (int i = 1; i < kMaxInventorySlots; ++i) {
|
||||
auto& name = getWorld()->data->weaponData[i]->name;
|
||||
m->addEntry(
|
||||
Menu::lambda(name, [=] { giveItem(i); }, kDebugEntryHeight));
|
||||
menu->lambda(name, [=] { giveItem(i); });
|
||||
}
|
||||
|
||||
return m;
|
||||
menu->offset = kDebugMenuOffset;
|
||||
return menu;
|
||||
}
|
||||
|
||||
DebugState::DebugState(RWGame* game, const glm::vec3& vp, const glm::quat& vd)
|
||||
|
@ -11,11 +11,11 @@ class DebugState : public State {
|
||||
bool _sonicMode = false;
|
||||
bool _invertedY;
|
||||
|
||||
Menu* createDebugMenu();
|
||||
Menu* createMapMenu();
|
||||
Menu* createVehicleMenu();
|
||||
Menu* createAIMenu();
|
||||
Menu* createWeaponMenu();
|
||||
std::shared_ptr<Menu> createDebugMenu();
|
||||
std::shared_ptr<Menu> createMapMenu();
|
||||
std::shared_ptr<Menu> createVehicleMenu();
|
||||
std::shared_ptr<Menu> createAIMenu();
|
||||
std::shared_ptr<Menu> createWeaponMenu();
|
||||
|
||||
public:
|
||||
DebugState(RWGame* game, const glm::vec3& vp = {},
|
||||
|
@ -13,27 +13,24 @@ MenuState::MenuState(RWGame* game) : State(game) {
|
||||
void MenuState::enterMainMenu() {
|
||||
auto& t = game->getGameData().texts;
|
||||
|
||||
Menu* m = new Menu;
|
||||
m->offset = glm::vec2(200.f, 200.f);
|
||||
m->addEntry(Menu::lambda(t.text(MenuDefaults::kStartGameId), [=] {
|
||||
StateManager::get().enter<IngameState>(game);
|
||||
}));
|
||||
m->addEntry(Menu::lambda(t.text(MenuDefaults::kLoadGameId),
|
||||
[=] { enterLoadMenu(); }));
|
||||
m->addEntry(Menu::lambda(t.text(MenuDefaults::kDebugId), [=] {
|
||||
StateManager::get().enter<IngameState>(game, true, "test");
|
||||
}));
|
||||
m->addEntry(Menu::lambda(t.text(MenuDefaults::kOptionsId),
|
||||
[] { RW_UNIMPLEMENTED("Options Menu"); }));
|
||||
m->addEntry(Menu::lambda(t.text(MenuDefaults::kQuitGameId),
|
||||
[] { StateManager::get().clear(); }));
|
||||
this->enterMenu(m);
|
||||
auto menu = Menu::create(
|
||||
{{t.text(MenuDefaults::kStartGameId),
|
||||
[=] { StateManager::get().enter<IngameState>(game); }},
|
||||
{t.text(MenuDefaults::kLoadGameId), [=] { enterLoadMenu(); }},
|
||||
{t.text(MenuDefaults::kDebugId),
|
||||
[=] { StateManager::get().enter<IngameState>(game, true, "test"); }},
|
||||
{t.text(MenuDefaults::kOptionsId),
|
||||
[] { RW_UNIMPLEMENTED("Options Menu"); }},
|
||||
{t.text(MenuDefaults::kQuitGameId),
|
||||
[] { StateManager::get().clear(); }}});
|
||||
menu->offset = glm::vec2(200.f, 200.f);
|
||||
|
||||
enterMenu(menu);
|
||||
}
|
||||
|
||||
void MenuState::enterLoadMenu() {
|
||||
Menu* m = new Menu;
|
||||
m->offset = glm::vec2(20.f, 30.f);
|
||||
m->addEntry(Menu::lambda("BACK", [=] { enterMainMenu(); }));
|
||||
auto menu = Menu::create({{"BACK", [=] { enterMainMenu(); }}});
|
||||
|
||||
auto saves = SaveGame::getAllSaveGameInfo();
|
||||
for (SaveGameInfo& save : saves) {
|
||||
if (save.valid) {
|
||||
@ -49,12 +46,14 @@ void MenuState::enterLoadMenu() {
|
||||
StateManager::get().enter<IngameState>(game, false);
|
||||
game->loadGame(save.savePath);
|
||||
};
|
||||
m->addEntry(Menu::lambda(name, loadsave, 20.f));
|
||||
menu->lambda(name, loadsave);
|
||||
} else {
|
||||
m->addEntry(Menu::lambda("CORRUPT", [=] {}));
|
||||
menu->lambda("CORRUPT", [=] {});
|
||||
}
|
||||
}
|
||||
this->enterMenu(m);
|
||||
menu->offset = glm::vec2(20.f, 30.f);
|
||||
|
||||
enterMenu(menu);
|
||||
}
|
||||
|
||||
void MenuState::enter() {
|
||||
|
@ -4,15 +4,14 @@
|
||||
PauseState::PauseState(RWGame* game) : State(game) {
|
||||
auto& t = game->getGameData().texts;
|
||||
|
||||
Menu* m = new Menu;
|
||||
m->offset = glm::vec2(200.f, 200.f);
|
||||
m->addEntry(Menu::lambda(t.text(MenuDefaults::kResumeGameId),
|
||||
[&] { done(); }));
|
||||
m->addEntry(Menu::lambda(t.text(MenuDefaults::kOptionsId),
|
||||
[] { std::cout << "Options" << std::endl; }));
|
||||
m->addEntry(Menu::lambda(t.text(MenuDefaults::kQuitGameId),
|
||||
[] { StateManager::get().clear(); }));
|
||||
this->enterMenu(m);
|
||||
auto menu = Menu::create(
|
||||
{{t.text(MenuDefaults::kResumeGameId), [&] { done(); }},
|
||||
{t.text(MenuDefaults::kOptionsId),
|
||||
[] { std::cout << "Options" << std::endl; }},
|
||||
{t.text(MenuDefaults::kQuitGameId),
|
||||
[] { StateManager::get().clear(); }}});
|
||||
menu->offset = glm::vec2(200.f, 200.f);
|
||||
enterMenu(menu);
|
||||
}
|
||||
|
||||
void PauseState::enter() {
|
||||
|
@ -6,8 +6,7 @@ BOOST_AUTO_TEST_SUITE(MenuUnitTests)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(menu_test_click) {
|
||||
bool clickered = false;
|
||||
Menu test(0);
|
||||
test.addEntry(Menu::lambda("Test", [&] { clickered = true; }));
|
||||
Menu test({{"Test", [&] { clickered = true; }}});
|
||||
|
||||
BOOST_CHECK(!clickered);
|
||||
|
||||
@ -16,7 +15,7 @@ BOOST_AUTO_TEST_CASE(menu_test_click) {
|
||||
|
||||
BOOST_CHECK(!clickered);
|
||||
|
||||
float h = test.entries.at(0)->getHeight();
|
||||
float h = test.getEntries().at(0).getHeight();
|
||||
|
||||
test.click(0.f, h + 1.f);
|
||||
|
||||
@ -29,9 +28,8 @@ BOOST_AUTO_TEST_CASE(menu_test_click) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(menu_test_click_offset) {
|
||||
bool clickered = false;
|
||||
Menu test(0);
|
||||
Menu test({{"Test", [&] { clickered = true; }}});
|
||||
test.offset = glm::vec2(200.f, 200.f);
|
||||
test.addEntry(Menu::lambda("Test", [&] { clickered = true; }));
|
||||
|
||||
BOOST_CHECK(!clickered);
|
||||
|
||||
@ -40,7 +38,7 @@ BOOST_AUTO_TEST_CASE(menu_test_click_offset) {
|
||||
|
||||
BOOST_CHECK(!clickered);
|
||||
|
||||
float h = test.entries.at(0)->getHeight();
|
||||
float h = test.getEntries().at(0).getHeight();
|
||||
|
||||
test.click(201.f, 200.f + h + 1.f);
|
||||
|
||||
@ -53,9 +51,8 @@ BOOST_AUTO_TEST_CASE(menu_test_click_offset) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(menu_test_active_index) {
|
||||
int clickindex = -1;
|
||||
Menu test(0);
|
||||
test.addEntry(Menu::lambda("Test1", [&] { clickindex = 0; }));
|
||||
test.addEntry(Menu::lambda("Test2", [&] { clickindex = 1; }));
|
||||
Menu test({{"Test1", [&] { clickindex = 0; }},
|
||||
{"Test2", [&] { clickindex = 1; }}});
|
||||
|
||||
test.activate();
|
||||
|
||||
@ -79,14 +76,13 @@ BOOST_AUTO_TEST_CASE(menu_test_active_index) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(menu_test_hover_index) {
|
||||
int clickindex = -1;
|
||||
Menu test(0);
|
||||
test.addEntry(Menu::lambda("Test1", [&] { clickindex = 0; }));
|
||||
test.addEntry(Menu::lambda("Test2", [&] { clickindex = 1; }));
|
||||
Menu test({{"Test1", [&] { clickindex = 0; }},
|
||||
{"Test2", [&] { clickindex = 1; }}});
|
||||
|
||||
test.hover(0.f, test.entries[0]->getHeight() - 0.1f);
|
||||
test.hover(0.f, test.getEntries()[0].getHeight() - 0.1f);
|
||||
BOOST_CHECK(test.activeEntry == 0);
|
||||
|
||||
test.hover(0.f, test.entries[0]->getHeight() + 0.1f);
|
||||
test.hover(0.f, test.getEntries()[0].getHeight() + 0.1f);
|
||||
BOOST_CHECK(test.activeEntry == 1);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user