From 522a43d16e812e10ff69747ee916918b4bd29f2f Mon Sep 17 00:00:00 2001 From: jacopograndi Date: Sun, 5 Sep 2021 23:00:42 +0200 Subject: invariant added as 'inv' --- game/ground.cpp | 14 +++---- game/ground.h | 5 ++- game/gst.cpp | 99 +++++++++++++++++++++++++++----------------------- game/gst.h | 15 ++++---- game/load.cpp | 14 +++---- game/load.h | 2 +- game/playercontrol.cpp | 52 +++++++++++++------------- game/view.cpp | 2 +- 8 files changed, 103 insertions(+), 100 deletions(-) (limited to 'game') diff --git a/game/ground.cpp b/game/ground.cpp index 1cadd9b..5f58717 100644 --- a/game/ground.cpp +++ b/game/ground.cpp @@ -4,16 +4,12 @@ #include #include -Ground::Ground (int sx, int sy) { +void Ground::build (int sx, int sy) { sizex = sx; sizey = sy; tiles = new int[sx*sy]; for (int i=0; i Ground::move_area (Gst &gst, Entity &ent) { std::vector frontier { step { at(ent.x, ent.y), move_num } }; int maxcost = 99; - if (gst.info_has_ability(ent.info, "Scout")) maxcost = 2; + if (gst.inv->info_has_ability(ent.info, "Scout")) maxcost = 2; int iter=0; for (; iter<10000; iter++) { @@ -66,7 +62,7 @@ std::vector Ground::move_area (Gst &gst, Entity &ent) { for (int t : forward_star) { if (!(std::find(visited.begin(), visited.end(), t) != visited.end()) && !(std::find(frontier.begin(), frontier.end(), t) != frontier.end())) { - int movecost = gst.tiles[gst.ground.tiles[t]].move_cost; + int movecost = gst.inv->tiles[tiles[t]].move_cost; if (movecost > maxcost) movecost = maxcost; int walkedm = maxf.m - movecost; bool obstructed = false; @@ -93,8 +89,8 @@ std::vector Ground::move_area (Gst &gst, Entity &ent) { std::vector Ground::attack_targets (Gst &gst, Entity &ent) { std::vector attacks; int range = gst.get_range(ent); - bool builds = !gst.info_has_ability(ent.info, "Units Only"); - bool units = !gst.info_has_ability(ent.info, "Buildings Only"); + bool builds = !gst.inv->info_has_ability(ent.info, "Units Only"); + bool units = !gst.inv->info_has_ability(ent.info, "Buildings Only"); for (Entity &e : gst.entities) { if (!units && e.info->unit == 1) continue; if (!builds && e.info->unit == 0) continue; diff --git a/game/ground.h b/game/ground.h index ab8f0e8..d1a4f34 100644 --- a/game/ground.h +++ b/game/ground.h @@ -16,13 +16,14 @@ class Resource { class Ground { public: - Ground (int sx, int sy); - ~Ground (); + Ground () {} int *tiles; std::vector resources; + void build (int sx, int sy); + int sizex; int sizey; int at (int x, int y); diff --git a/game/gst.cpp b/game/gst.cpp index 886dcc7..52dfe81 100644 --- a/game/gst.cpp +++ b/game/gst.cpp @@ -4,37 +4,39 @@ #include -Player& Gst::get_player (int id) { - for (auto &player : players) { - if (id == player.id) return player; - } -} - -Tech* Gst::get_tech (int id) { +Tech* Inv::get_tech (int id) { for (auto &tech : techs) { if (id == tech.id) return &tech; } } -EntityInfo* Gst::get_info (std::string name) { +EntityInfo* Inv::get_info (std::string name) { for (EntityInfo &info : infos) { if (name == info.name) return &info; } } -EntityInfo* Gst::get_info (int id) { +EntityInfo* Inv::get_info (int id) { for (EntityInfo &info : infos) { if (id == info.id) return &info; } } -bool Gst::info_has_ability (EntityInfo* info, std::string name) { +bool Inv::info_has_ability (EntityInfo* info, std::string name) { for (int ab : info->abilities) { if (abilities[ab].name == name) return true; } return false; } + + +Player& Gst::get_player (int id) { + for (auto &player : players) { + if (id == player.id) return player; + } +} + Entity& Gst::get_at (int x, int y) { for (Entity &e : entities) { if (e.x ==x && e.y == y) return e; @@ -86,6 +88,8 @@ float Gst::get_type_bonus (Entity &atk, Entity &def) { int Gst::get_vet_level (Entity &ent) { return std::min(3, ent.fights/3); } std::vector Gst::get_bonuses (Entity &atk, Entity &def) { + auto &tiles = inv->tiles; + auto &ground = inv->ground; std::vector bs; if (tiles[ground.tiles[ground.at(atk.x, atk.y)]].attack_bonus != 0) { @@ -116,35 +120,35 @@ std::vector Gst::get_bonuses (Entity &atk, Entity &def) { bs.emplace_back(get_type_bonus(def, atk), Bonus::Id::type, false); }*/ - if (info_has_ability(atk.info, "Causes Fear")) + if (inv->info_has_ability(atk.info, "Causes Fear")) bs.emplace_back(-1.0f/3, Bonus::Id::ability, false); - if (info_has_ability(def.info, "Causes Fear")) + if (inv->info_has_ability(def.info, "Causes Fear")) bs.emplace_back(-1.0f/3, Bonus::Id::ability, true); - if (info_has_ability(atk.info, "Anti-Cavalry")) + if (inv->info_has_ability(atk.info, "Anti-Cavalry")) bs.emplace_back(4.0f/3, Bonus::Id::ability, true); - if (info_has_ability(def.info, "Anti-Cavalry")) + if (inv->info_has_ability(def.info, "Anti-Cavalry")) bs.emplace_back(4.0f/3, Bonus::Id::ability, false); - if (info_has_ability(atk.info, "Desert Charge") - && !info_has_ability(def.info, "Desert Charge") + if (inv->info_has_ability(atk.info, "Desert Charge") + && !inv->info_has_ability(def.info, "Desert Charge") && tiles[ground.tiles[ground.at(def.x, def.y)]].name == "Desert") bs.emplace_back(1.0f/3, Bonus::Id::ability, true); - if (info_has_ability(atk.info, "Plains Charge") - && !info_has_ability(def.info, "Plains Charge") + if (inv->info_has_ability(atk.info, "Plains Charge") + && !inv->info_has_ability(def.info, "Plains Charge") && tiles[ground.tiles[ground.at(def.x, def.y)]].name == "Plains") bs.emplace_back(1.0f/3, Bonus::Id::ability, true); - if (info_has_ability(atk.info, "Woodsman") - && !info_has_ability(def.info, "Woodsman") + if (inv->info_has_ability(atk.info, "Woodsman") + && !inv->info_has_ability(def.info, "Woodsman") && tiles[ground.tiles[ground.at(def.x, def.y)]].name == "Forest") bs.emplace_back(1.0f/3, Bonus::Id::ability, true); - if (info_has_ability(atk.info, "Volley") && atk.hp >= 50) + if (inv->info_has_ability(atk.info, "Volley") && atk.hp >= 50) bs.emplace_back(1.0f/3, Bonus::Id::ability, true); - if (info_has_ability(atk.info, "Frenzy")) + if (inv->info_has_ability(atk.info, "Frenzy")) bs.emplace_back(1/atk.hp, Bonus::Id::ability, true); Player &player_atk = players[atk.owner]; @@ -188,7 +192,7 @@ float Gst::get_damage (Entity &atk, Entity &def) { bool Gst::get_first_strike (Entity &atk, Entity &def) { bool fs { false }; - fs = info_has_ability(atk.info, "First Strike"); + fs = inv->info_has_ability(atk.info, "First Strike"); return fs; } @@ -200,12 +204,12 @@ float clamp_hp (float hp) { BattleResult Gst::battle_res (Entity &atk, Entity &def) { BattleResult result { atk.hp, def.hp }; - bool first_strike_atk = info_has_ability(atk.info, "First Strike"); - bool first_strike_def = info_has_ability(def.info, "First Strike"); - bool skirmish_atk = info_has_ability(atk.info, "Skirmish"); - bool skirmish_def = info_has_ability(def.info, "Skirmish"); - bool anticav_atk = info_has_ability(atk.info, "Anti-Cavalry"); - bool anticav_def = info_has_ability(def.info, "Anti-Cavalry"); + bool first_strike_atk = inv->info_has_ability(atk.info, "First Strike"); + bool first_strike_def = inv->info_has_ability(def.info, "First Strike"); + bool skirmish_atk = inv->info_has_ability(atk.info, "Skirmish"); + bool skirmish_def = inv->info_has_ability(def.info, "Skirmish"); + bool anticav_atk = inv->info_has_ability(atk.info, "Anti-Cavalry"); + bool anticav_def = inv->info_has_ability(def.info, "Anti-Cavalry"); first_strike_atk = first_strike_atk || (skirmish_atk && def.info->range == 1); first_strike_def = first_strike_def @@ -225,32 +229,32 @@ BattleResult Gst::battle_res (Entity &atk, Entity &def) { result.atk_hp = clamp_hp( result.atk_hp - get_damage(def, atk, result.def_hp)); } - if (!info_has_ability(atk.info, "No Counter")) + if (!inv->info_has_ability(atk.info, "No Counter")) if (result.atk_hp > 0) result.def_hp = clamp_hp( result.def_hp - get_damage(atk, def, result.atk_hp)); } else { result.def_hp = clamp_hp( result.def_hp - get_damage(atk, def, result.atk_hp)); - if (!info_has_ability(def.info, "No Counter") && def_inrange) + if (!inv->info_has_ability(def.info, "No Counter") && def_inrange) if (result.def_hp > 0) result.atk_hp = clamp_hp( result.atk_hp - get_damage(def, atk, result.def_hp)); } - if (info_has_ability(atk.info, "Rapid Fire")) + if (inv->info_has_ability(atk.info, "Rapid Fire")) if (result.def_hp > 0) result.def_hp = clamp_hp( result.def_hp - get_damage(atk, def, result.def_hp)); - if (info_has_ability(def.info, "Rapid Fire") && def_inrange) + if (inv->info_has_ability(def.info, "Rapid Fire") && def_inrange) if (result.atk_hp > 0) result.atk_hp = clamp_hp( result.atk_hp - get_damage(def, atk, result.def_hp)); - if (result.atk_hp > 0 && info_has_ability(atk.info, "Zeal")) + if (result.atk_hp > 0 && inv->info_has_ability(atk.info, "Zeal")) result.atk_hp = clamp_hp(result.atk_hp + 20); - if (result.def_hp > 0 && info_has_ability(def.info, "Zeal")) + if (result.def_hp > 0 && inv->info_has_ability(def.info, "Zeal")) result.def_hp = clamp_hp(result.def_hp + 20); return result; @@ -285,6 +289,8 @@ void Gst::clear_dead() { int Gst::get_range (Entity &ent) { int range = ent.info->range; if (range > 1) { + auto &tiles = inv->tiles; + auto &ground = inv->ground; range += tiles[ground.tiles[ground.at(ent.x, ent.y)]].range_bonus; } if (range < 1) range = 1; @@ -306,7 +312,7 @@ void Gst::convert (Entity &atk, Entity &def) { if (player.has_tech(53)) { amt += 0.10f; } // tech faith // caution, randomness std::uniform_real_distribution odds(0, 1); - float value = odds(engine); + float value = odds(inv->engine); std::cout << value << " / " << amt << " odds\n"; if (value < amt) { def.owner = atk.owner; @@ -320,7 +326,7 @@ std::vector Gst::get_possible_trains (Entity &ent) { std::vector trains; if (ent.info->id == 107) { // market special case std::vector candidates; - for (EntityInfo &info : infos) { + for (EntityInfo &info : inv->infos) { if (info.id == 0) continue; // villager only in train_id if (info.level > player.level) continue; if (info.level < player.level && info.upgrade != -1) continue; @@ -329,14 +335,14 @@ std::vector Gst::get_possible_trains (Entity &ent) { candidates.push_back(info.id); } } - std::shuffle(candidates.begin(), candidates.end(), engine); + std::shuffle(candidates.begin(), candidates.end(), inv->engine); // pick 3 cands at random for (int i=0; i<3; i++) trains.push_back(candidates[i]); return trains; } for (int id : ent.info->train_id) { - auto info = get_info(id); + auto info = inv->get_info(id); if (info->level > player.level) continue; if (info->level < player.level && info->upgrade != -1) continue; trains.push_back(id); @@ -361,7 +367,7 @@ std::vector Gst::get_possible_trains (Entity &ent) { std::vector Gst::get_possible_builds (Entity &ent) { std::vector builds; for (int id : ent.info->build) { - if (check_req_build(ent, get_info(id))) { + if (check_req_build(ent, inv->get_info(id))) { builds.push_back(id); } } @@ -370,6 +376,7 @@ std::vector Gst::get_possible_builds (Entity &ent) { bool Gst::check_req_build(Entity &ent, EntityInfo *info) { + auto &ground = inv->ground; Player &player = players[ent.owner]; if (player.level < info->level) return false; for (int id : info->adjacent) { @@ -476,7 +483,7 @@ bool Gst::check_req_level (Player &player) { } std::map lv_techs; - for (int id : player.techs) lv_techs[get_tech(id)->level] ++; + for (int id : player.techs) lv_techs[inv->get_tech(id)->level] ++; if (player.level == 0) { if (lv_techs[0] >= 3) return true; } @@ -538,7 +545,7 @@ void Gst::level_upgrade (Player &player) { for (Entity &e : entities) { if (get_player(e.owner) == player) { if (e.info->upgrade != -1 && e.info->level == player.level) { - e.info = get_info(e.info->upgrade); + e.info = inv->get_info(e.info->upgrade); } } } @@ -548,7 +555,7 @@ void Gst::level_upgrade (Player &player) { void Gst::update_tech_lookup (Player &player) { player.tech_lookup.map_id.clear(); for (int i : player.techs) { - Tech *tech = get_tech(i); + Tech *tech = inv->get_tech(i); std::vector ids { }; bool noaff = true; if (tech->bonus.aff_id.size() > 0) { @@ -556,7 +563,7 @@ void Gst::update_tech_lookup (Player &player) { noaff = false; } else { if (tech->bonus.aff_level != -1) { - for (EntityInfo info : infos) { + for (EntityInfo info : inv->infos) { if (info.level == tech->bonus.aff_level) { ids.push_back(info.id); } @@ -564,7 +571,7 @@ void Gst::update_tech_lookup (Player &player) { noaff = false; } if (tech->bonus.aff_class.size() > 0) { - for (EntityInfo info : infos) { + for (EntityInfo info : inv->infos) { auto &cls = tech->bonus.aff_class; if (std::find(cls.begin(), cls.end(), info.ent_class) != cls.end()) @@ -575,7 +582,7 @@ void Gst::update_tech_lookup (Player &player) { noaff = false; } } - if (noaff) { for (auto info : infos) ids.push_back(info.id); } + if (noaff) { for (auto info : inv->infos) ids.push_back(info.id); } for (int id : ids) { player.tech_lookup.map_id[id] = player.tech_lookup.map_id[id] + tech->bonus; diff --git a/game/gst.h b/game/gst.h index dc68b31..e86ddc5 100644 --- a/game/gst.h +++ b/game/gst.h @@ -56,13 +56,17 @@ class Inv { std::vector tiles; Ground ground; - private: + Tech* get_tech (int id); + EntityInfo* get_info (std::string name); + EntityInfo* get_info (int id); + bool info_has_ability (EntityInfo* info, std::string name); + std::default_random_engine engine = std::default_random_engine{}; -} +}; class Gst { public: - Gst() { } + Gst(Inv *inv) : inv(inv) { } Inv *inv; @@ -73,10 +77,7 @@ class Gst { int day { 0 }; Player& get_player (int id); - Tech* get_tech (int id); - EntityInfo* get_info (std::string name); - EntityInfo* get_info (int id); - bool info_has_ability (EntityInfo* info, std::string name); + Entity& get_at (int x, int y); std::vector get_cost (EntityInfo *info, Player &player); float get_trade_rate (Player &player); diff --git a/game/load.cpp b/game/load.cpp index 4b58ff0..9f58c7d 100644 --- a/game/load.cpp +++ b/game/load.cpp @@ -32,8 +32,8 @@ std::vector load_abilities () { return abs; } -void load_json (Gst &gst) { - gst.abilities = load_abilities(); +void load_json (Inv &inv) { + inv.abilities = load_abilities(); std::ifstream file_tiles("content/tiles.json"); json j_tiles; file_tiles >> j_tiles; @@ -44,7 +44,7 @@ void load_json (Gst &gst) { tile.defence_bonus = it["defence_bonus"]; tile.range_bonus = it["range_bonus"]; tile.spritebounds = vec2 { it["spritebounds"][0], it["spritebounds"][1] }; - gst.tiles.push_back(tile); + inv.tiles.push_back(tile); } std::ifstream file_ents("content/entities.json"); @@ -86,8 +86,8 @@ void load_json (Gst &gst) { it["class"].get()); for (auto ab : it["abilities"]) { int index = 0; - for (int i=0; iunit == 1) { - if (gst.ground.move_area(gst, ent).size() > 0 + if (gst.inv->ground.move_area(gst, ent).size() > 0 && ent.moved == 0) { view.menu_unit.options.emplace_back("Move", Menu_unit::Opts::move); } - if (gst.ground.attack_targets(gst, ent).size() > 0 - && (!gst.info_has_ability(ent.info, "No Move & Attack") + if (gst.inv->ground.attack_targets(gst, ent).size() > 0 + && (!gst.inv->info_has_ability(ent.info, "No Move & Attack") || ent.moved == 0)) { view.menu_unit.options.emplace_back("Attack", Menu_unit::Opts::attack); @@ -28,14 +28,14 @@ void open_unit_menu (Gst &gst, View &view, Fsm &fsm, int p) { view.menu_unit.options.emplace_back("Build", Menu_unit::Opts::build); } - if (gst.ground.heal_targets(gst, ent).size() > 0 - && (gst.info_has_ability(ent.info, "Heal"))) + if (gst.inv->ground.heal_targets(gst, ent).size() > 0 + && (gst.inv->info_has_ability(ent.info, "Heal"))) { view.menu_unit.options.emplace_back("Heal", Menu_unit::Opts::heal); } - if (gst.ground.convert_targets(gst, ent).size() > 0 - && (gst.info_has_ability(ent.info, "Convert"))) + if (gst.inv->ground.convert_targets(gst, ent).size() > 0 + && (gst.inv->info_has_ability(ent.info, "Convert"))) { view.menu_unit.options.emplace_back("Convert", Menu_unit::Opts::convert); @@ -107,7 +107,7 @@ Player_control::Player_control () { [](Gst &gst, View &view, Fsm &fsm, int p) { view.menu_day.close(); view.menu_tech.tech_options.clear(); - for (Tech &tech : gst.techs) { + for (Tech &tech : gst.inv->techs) { view.menu_tech.tech_options.emplace_back(tech.name, &tech); } view.menu_tech.open(view.res); @@ -121,7 +121,7 @@ Player_control::Player_control () { if (p == -1) return menu_tech; Player &player = gst.players[gst.turn]; - Tech *tech = gst.get_tech(p); + Tech *tech = gst.inv->get_tech(p); if (!gst.check_req_tech(tech, player)) { return menu_tech; } @@ -171,8 +171,7 @@ Player_control::Player_control () { view.menu_train.options.clear(); auto trains = gst.get_possible_trains(ent); for (int id : trains) { - EntityInfo *info = gst.get_info(id); - std::cout << id << " " << gst.get_info(id)->name << "\n"; + EntityInfo *info = gst.inv->get_info(id); Option opt { info->name, id }; opt.cost = gst.get_cost(info, player); if (ent.info->id == 107) { // market @@ -195,7 +194,7 @@ Player_control::Player_control () { view.menu_train.close(); Entity &ent = gst.entities[view.selected_entity]; ent.done = true; - Entity entb { ent.x, ent.y, gst.get_info(p), ent.owner }; + Entity entb { ent.x, ent.y, gst.inv->get_info(p), ent.owner }; entb.building = -1; entb.done = true; entb.hp = 50; @@ -215,9 +214,8 @@ Player_control::Player_control () { Player &player = gst.players[ent.owner]; view.menu_build.options.clear(); for (int id : ent.info->build) { - EntityInfo *info = gst.get_info(id); + EntityInfo *info = gst.inv->get_info(id); if(!gst.check_req_build(ent, info)) continue; - std::cout << id << " " << gst.get_info(id)->name << "\n"; Option opt { info->name, id }; opt.cost = gst.get_cost(info, player); view.menu_build.options.push_back(opt); @@ -233,7 +231,7 @@ Player_control::Player_control () { std::cout << "building " << p << "\n"; Entity &ent = gst.entities[view.selected_entity]; ent.done = true; - Entity entb { ent.x, ent.y, gst.get_info(p), ent.owner }; + Entity entb { ent.x, ent.y, gst.inv->get_info(p), ent.owner }; entb.building = -1; entb.done = true; entb.hp = 50; @@ -250,7 +248,7 @@ Player_control::Player_control () { view.menu_unit.close(); std::cout << "move " << p << "\n"; Entity &ent = gst.entities[view.selected_entity]; - view.moves = gst.ground.move_area(gst, ent); + view.moves = gst.inv->ground.move_area(gst, ent); return move; } ); @@ -260,8 +258,8 @@ Player_control::Player_control () { std::cout << "moved to " << p << "\n"; Entity &ent = gst.entities[view.selected_entity]; view.moves.clear(); - ent.x = p % gst.ground.sizex; - ent.y = p / gst.ground.sizex; + ent.x = p % gst.inv->ground.sizex; + ent.y = p / gst.inv->ground.sizex; ent.moved = 1; open_unit_menu(gst, view, fsm, p); return menu_unit; @@ -273,7 +271,7 @@ Player_control::Player_control () { view.menu_unit.close(); std::cout << "attack " << p << "\n"; Entity &ent = gst.entities[view.selected_entity]; - view.attacks = gst.ground.attack_targets(gst, ent); + view.attacks = gst.inv->ground.attack_targets(gst, ent); return attack; } ); @@ -282,8 +280,8 @@ Player_control::Player_control () { [](Gst &gst, View &view, Fsm &fsm, int p) { std::cout << "attacked " << p << "\n"; Entity &atk = gst.entities[view.selected_entity]; - int x = view.cursor_ground % gst.ground.sizex; - int y = view.cursor_ground / gst.ground.sizex; + int x = view.cursor_ground % gst.inv->ground.sizex; + int y = view.cursor_ground / gst.inv->ground.sizex; std::cout << "selg " << x << " " << y << "\n"; Entity &def = gst.get_at(x, y); atk.done = true; @@ -375,7 +373,7 @@ Player_control::Player_control () { Player &player = gst.players[gst.turn]; view.menu_unit.close(); Entity &ent = gst.entities[view.selected_entity]; - view.heals = gst.ground.heal_targets(gst, ent); + view.heals = gst.inv->ground.heal_targets(gst, ent); std::cout << "heal targeting " << p << "\n"; return target_heal; } @@ -385,8 +383,8 @@ Player_control::Player_control () { [](Gst &gst, View &view, Fsm &fsm, int p) { std::cout << "healed " << p << "\n"; Entity &atk = gst.entities[view.selected_entity]; - int x = view.cursor_ground % gst.ground.sizex; - int y = view.cursor_ground / gst.ground.sizex; + int x = view.cursor_ground % gst.inv->ground.sizex; + int y = view.cursor_ground / gst.inv->ground.sizex; std::cout << "selg " << x << " " << y << "\n"; Entity &def = gst.get_at(x, y); atk.done = true; @@ -402,7 +400,7 @@ Player_control::Player_control () { Player &player = gst.players[gst.turn]; view.menu_unit.close(); Entity &ent = gst.entities[view.selected_entity]; - view.converts = gst.ground.convert_targets(gst, ent); + view.converts = gst.inv->ground.convert_targets(gst, ent); std::cout << "convert targeting " << p << "\n"; return target_convert; } @@ -412,8 +410,8 @@ Player_control::Player_control () { [](Gst &gst, View &view, Fsm &fsm, int p) { std::cout << "converted " << p << "\n"; Entity &atk = gst.entities[view.selected_entity]; - int x = view.cursor_ground % gst.ground.sizex; - int y = view.cursor_ground / gst.ground.sizex; + int x = view.cursor_ground % gst.inv->ground.sizex; + int y = view.cursor_ground / gst.inv->ground.sizex; std::cout << "selg " << x << " " << y << "\n"; Entity &def = gst.get_at(x, y); atk.done = true; diff --git a/game/view.cpp b/game/view.cpp index 78a9932..190bd53 100644 --- a/game/view.cpp +++ b/game/view.cpp @@ -1,7 +1,7 @@ #include "view.h" void View::process (Gst &gst, vec2 cam, vec2 mouse, int *mheld) { - Ground &gr = gst.ground; + Ground &gr = gst.inv->ground; std::vector &entities = gst.entities; vec2 absmouse { mouse }; -- cgit v1.2.3-54-g00ecf