aboutsummaryrefslogtreecommitdiff
path: root/game
diff options
context:
space:
mode:
Diffstat (limited to 'game')
-rw-r--r--game/entity.h2
-rw-r--r--game/ground.cpp4
-rw-r--r--game/gst.cpp142
-rw-r--r--game/gst.h18
-rw-r--r--game/load.cpp16
-rw-r--r--game/menu.cpp48
-rw-r--r--game/menu.h25
-rw-r--r--game/player.h2
-rw-r--r--game/playercontrol.cpp47
-rw-r--r--game/playercontrol.h1
-rw-r--r--game/tech.h3
-rw-r--r--game/view.cpp55
-rw-r--r--game/view.h2
13 files changed, 295 insertions, 70 deletions
diff --git a/game/entity.h b/game/entity.h
index 36c8198..eeab110 100644
--- a/game/entity.h
+++ b/game/entity.h
@@ -49,7 +49,7 @@ class Entity {
return x == oth.x && y == oth.y && info->unit == oth.info->unit;
}
- int building = 0;
+ int building { 0 };
float hp; /**/
int x, y;
bool done = false;
diff --git a/game/ground.cpp b/game/ground.cpp
index 0ea273d..e6055bf 100644
--- a/game/ground.cpp
+++ b/game/ground.cpp
@@ -88,9 +88,7 @@ std::vector<int> Ground::move_area (Gst &gst, Entity &ent) {
std::vector<int> Ground::attack_targets (Gst &gst, Entity &ent) {
std::vector<int> attacks;
- int range = ent.info->range;
- range += gst.tiles[gst.ground.tiles[gst.ground.at(ent.x, ent.y)]]
- .range_bonus;
+ 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");
for (Entity &e : gst.entities) {
diff --git a/game/gst.cpp b/game/gst.cpp
index f6d5aa1..0a524fc 100644
--- a/game/gst.cpp
+++ b/game/gst.cpp
@@ -28,25 +28,25 @@ Entity& Gst::get_at (int x, int y) {
}
float Gst::get_type_bonus (Entity &atk, Entity &def) {
- float b = 1;
+ float b = 0;
switch(atk.info->ent_class) {
case EntityInfo::Class::inf:
- if (def.info->ent_class == EntityInfo::Class::bld) b += 1.0/3;
- if (def.info->ent_class == EntityInfo::Class::sie) b += 1.0/3;
+ if (def.info->ent_class == EntityInfo::Class::bld) b += 1.0f/3.0f;
+ if (def.info->ent_class == EntityInfo::Class::sie) b += 1.0f/3.0f;
break;
case EntityInfo::Class::cav:
if (def.info->ent_class == EntityInfo::Class::bld) b += -0.5;
- if (def.info->ent_class == EntityInfo::Class::inf) b += 1.0/3;
- if (def.info->ent_class == EntityInfo::Class::ran) b += 1.0/3;
+ if (def.info->ent_class == EntityInfo::Class::inf) b += 1.0f/3.0f;
+ if (def.info->ent_class == EntityInfo::Class::ran) b += 1.0f/3.0f;
break;
case EntityInfo::Class::ran:
- if (def.info->ent_class == EntityInfo::Class::bld) b += -0.5;
+ if (def.info->ent_class == EntityInfo::Class::bld) b += -0.5f;
break;
case EntityInfo::Class::sie:
- if (def.info->ent_class == EntityInfo::Class::bld) b += +0.5;
+ if (def.info->ent_class == EntityInfo::Class::bld) b += +0.5f;
break;
}
return b;
@@ -54,15 +54,24 @@ float Gst::get_type_bonus (Entity &atk, Entity &def) {
std::vector<Bonus> Gst::get_bonuses (Entity &atk, Entity &def) {
std::vector<Bonus> bs;
- bs.emplace_back(
- tiles[ground.tiles[ground.at(atk.x, atk.y)]].attack_bonus,
- Bonus::Id::ground, true);
- bs.emplace_back(
- tiles[ground.tiles[ground.at(def.x, def.y)]].defence_bonus,
- Bonus::Id::ground, false);
+ if (tiles[ground.tiles[ground.at(atk.x, atk.y)]].attack_bonus != 0) {
- bs.emplace_back(get_type_bonus(atk, def), Bonus::Id::type, true);
- bs.emplace_back(get_type_bonus(def, atk), Bonus::Id::type, false);
+ bs.emplace_back(
+ tiles[ground.tiles[ground.at(atk.x, atk.y)]].attack_bonus,
+ Bonus::Id::ground, true);
+ }
+ if (tiles[ground.tiles[ground.at(def.x, def.y)]].defence_bonus != 0) {
+ bs.emplace_back(
+ tiles[ground.tiles[ground.at(def.x, def.y)]].defence_bonus,
+ Bonus::Id::ground, false);
+ }
+
+ if (get_type_bonus(atk, def) != 0) {
+ bs.emplace_back(get_type_bonus(atk, def), Bonus::Id::type, true);
+ }
+ if (get_type_bonus(def, atk) != 0) {
+ bs.emplace_back(get_type_bonus(def, atk), Bonus::Id::type, false);
+ }
if (info_has_ability(atk.info, "Causes Fear"))
bs.emplace_back(-1.0f/3, Bonus::Id::ability, false);
@@ -95,11 +104,10 @@ std::vector<Bonus> Gst::get_bonuses (Entity &atk, Entity &def) {
if (info_has_ability(atk.info, "Frenzy"))
bs.emplace_back(1/atk.hp, Bonus::Id::ability, true);
-
return bs;
}
-float Gst::get_damage (Entity &atk, Entity &def) {
+float Gst::get_damage (Entity &atk, Entity &def, float atk_hp) {
float atkmul = 1;
float defmul = 1;
@@ -109,24 +117,30 @@ float Gst::get_damage (Entity &atk, Entity &def) {
else { defmul += bonus.amt; }
}
- float dam = (atk.info->attack * atk.hp * atkmul)
+ float dam = (atk.info->attack * atk_hp * atkmul)
/ (2.0f*def.info->defence * defmul);
return dam;
}
+float Gst::get_damage (Entity &atk, Entity &def) {
+ return get_damage(atk, def, atk.hp);
+}
+
bool Gst::get_first_strike (Entity &atk, Entity &def) {
bool fs { false };
fs = info_has_ability(atk.info, "First Strike");
return fs;
}
-float clamp (float hp) { if (hp > 100) hp = 100; return hp; }
+float clamp (float hp) {
+ if (hp > 100) hp = 100;
+ if (hp < 0) hp = 0;
+ return hp;
+}
-void Gst::battle (Entity &atk, Entity &def) {
- std::cout << "! attack " << atk.info->name << "(hp:" << atk.hp << "), "
- << def.info->name << "(hp:" << def.hp << ") \n";
-
+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");
@@ -142,30 +156,54 @@ void Gst::battle (Entity &atk, Entity &def) {
first_strike_def = first_strike_def
|| (anticav_def && atk.info->ent_class == EntityInfo::Class::cav);
+ int dist = abs(atk.x-def.x) + abs(atk.y-def.y);
+ bool def_inrange = (dist <= get_range(def)) ? true : false;
+
bool swap = false;
if (first_strike_def && !first_strike_atk) swap = true;
if (swap) {
- atk.hp = clamp(atk.hp - get_damage(def, atk));
+ if (def_inrange) {
+ result.atk_hp = clamp(
+ result.atk_hp - get_damage(def, atk, result.def_hp));
+ }
if (!info_has_ability(atk.info, "No Counter"))
- if (atk.hp > 0) def.hp -= get_damage(atk, def);
+ if (result.atk_hp > 0)
+ result.def_hp = clamp(
+ result.def_hp - get_damage(atk, def, result.atk_hp));
} else {
- def.hp = clamp(def.hp - get_damage(atk, def));
- if (!info_has_ability(def.info, "No Counter"))
- if (def.hp > 0) atk.hp -= get_damage(def, atk);
+ result.def_hp = clamp(
+ result.def_hp - get_damage(atk, def, result.atk_hp));
+ if (!info_has_ability(def.info, "No Counter") && def_inrange)
+ if (result.def_hp > 0)
+ result.atk_hp = clamp(
+ result.atk_hp - get_damage(def, atk, result.def_hp));
}
if (info_has_ability(atk.info, "Rapid Fire"))
- if (def.hp > 0)
- def.hp = clamp(def.hp - get_damage(atk, def));
+ if (result.def_hp > 0)
+ result.def_hp = clamp(
+ result.def_hp - get_damage(atk, def, result.def_hp));
+
+ if (info_has_ability(def.info, "Rapid Fire") && def_inrange)
+ if (result.atk_hp > 0)
+ result.atk_hp = clamp(
+ result.atk_hp - get_damage(def, atk, result.def_hp));
- if (info_has_ability(def.info, "Rapid Fire"))
- if (atk.hp > 0)
- atk.hp = clamp(atk.hp - get_damage(def, atk));
+ if (result.atk_hp > 0 && info_has_ability(atk.info, "Zeal"))
+ result.atk_hp = clamp(result.atk_hp + 20);
+ if (result.def_hp > 0 && info_has_ability(def.info, "Zeal"))
+ result.def_hp = clamp(result.def_hp + 20);
+
+ return result;
+}
+
+void Gst::battle (Entity &atk, Entity &def) {
+ std::cout << "! attack " << atk.info->name << "(hp:" << atk.hp << "), "
+ << def.info->name << "(hp:" << def.hp << ") \n";
- if (atk.hp > 0 && info_has_ability(atk.info, "Zeal"))
- atk.hp = clamp(atk.hp + 20);
- if (def.hp > 0 && info_has_ability(def.info, "Zeal"))
- def.hp = clamp(def.hp + 20);
+ auto result = battle_res(atk, def);
+ atk.hp = result.atk_hp;
+ def.hp = result.def_hp;
std::cout << "! result " << atk.info->name << "(hp:" << atk.hp << "), "
<< def.info->name << "(hp:" << def.hp << ") \n";
@@ -182,6 +220,15 @@ void Gst::clear_dead() {
}
}
+int Gst::get_range (Entity &ent) {
+ int range = ent.info->range;
+ if (range > 1) {
+ range += tiles[ground.tiles[ground.at(ent.x, ent.y)]].range_bonus;
+ }
+ if (range < 1) range = 1;
+ return range;
+}
+
std::vector<int> Gst::get_possible_builds (Entity &ent) {
std::vector<int> builds;
for (int id : ent.info->build) {
@@ -196,7 +243,7 @@ bool Gst::check_req_build(Entity &ent, EntityInfo *info) {
for (int id : info->adjacent) {
bool adj = false;
for (Entity &e : entities) {
- if (e.info->id == id) {
+ if (e.info->id == id && ent.owner == e.owner) {
int dist = abs(e.x-ent.x) + abs(e.y-ent.y);
if (dist == 1) {
adj = true;
@@ -213,7 +260,7 @@ bool Gst::check_req_build(Entity &ent, EntityInfo *info) {
}
int mindist = 9999;
for (Entity &e : entities) {
- if (e.info->id == 100) {
+ if (e.info->id == 100 && ent.owner == e.owner) {
int dist = abs(e.x-ent.x) + abs(ent.y-e.y);
if (dist < mindist) {
mindist = dist;
@@ -260,4 +307,21 @@ void Gst::end_day () {
turn = 0;
day++;
}
+ for (Entity &e : entities) {
+ e.done = false;
+ e.moved = 0;
+ if (e.owner == turn) {
+ Player &player = players[e.owner];
+ for (int i=0; i<player.res.size(); i++) {
+ player.res[i] += e.info->prod[i];
+ }
+ // todo heal when on top of building
+ if (e.building < 0) {
+ e.building++;
+ if (e.building == 0) {
+ e.hp += 50; if (e.hp > 100) e.hp = 100;
+ }
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/game/gst.h b/game/gst.h
index ef6929a..906b372 100644
--- a/game/gst.h
+++ b/game/gst.h
@@ -24,6 +24,21 @@ class Bonus {
Bonus(float amt, int id, bool atk) : amt(amt), id(id), atk(atk) {}
float amt; int id; bool atk;
enum Id { ground, type, ability, tech };
+ std::string id_string () {
+ switch (id) {
+ case ground: return "Ground";
+ case type: return "Class";
+ case ability: return "Ability";
+ case tech: return "Tech";
+ }
+ }
+};
+
+class BattleResult {
+ public:
+ BattleResult(float atk_hp, float def_hp)
+ : atk_hp(atk_hp), def_hp(def_hp) {}
+ float atk_hp, def_hp;
};
class Gst {
@@ -47,9 +62,12 @@ class Gst {
float get_type_bonus (Entity &atk, Entity &def);
std::vector<Bonus> get_bonuses (Entity &atk, Entity &def);
float get_damage (Entity &atk, Entity &def);
+ float get_damage (Entity &atk, Entity &def, float atk_hp);
bool get_first_strike (Entity &atk, Entity &def);
+ BattleResult battle_res (Entity &atk, Entity &def);
void battle (Entity &atk, Entity &def);
void clear_dead();
+ int get_range(Entity &ent);
std::vector<int> get_possible_builds (Entity &ent);
diff --git a/game/load.cpp b/game/load.cpp
index d1a1722..5baae6c 100644
--- a/game/load.cpp
+++ b/game/load.cpp
@@ -41,6 +41,8 @@ void load_json (Gst &gst) {
Tile tile;
tile.name = it["name"];
tile.move_cost = it["move_cost"];
+ 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);
}
@@ -88,4 +90,18 @@ void load_json (Gst &gst) {
ent.spritebounds = vec2 { it["spritebounds"][0], it["spritebounds"][1] };
gst.infos.push_back(ent);
}
+
+ std::ifstream file_techs("content/techs.json");
+ json j_techs; file_techs >> j_techs;
+ for (auto it : j_techs) {
+ Tech tech;
+ tech.name = it["name"];
+ tech.id = it["id"];
+ tech.level = it["level"];
+ tech.req_id = it["req_id"];
+ for (int i=0; i<it["cost"].size(); i++) {
+ tech.cost[i] = it["cost"][i];
+ }
+ gst.techs.push_back(tech);
+ }
} \ No newline at end of file
diff --git a/game/menu.cpp b/game/menu.cpp
index a9ec886..b5a91b9 100644
--- a/game/menu.cpp
+++ b/game/menu.cpp
@@ -1,3 +1,5 @@
+#include <iostream>
+
#include "menu.h"
void Menu::close () {
@@ -5,6 +7,7 @@ void Menu::close () {
}
void Menu::open (vec2 res) {
+ over = -1;
active = true;
pos = vec2 { (float)res.x, (float)res.y };
float height = options.size() * 20;
@@ -26,4 +29,49 @@ int Menu::mouse_option (vec2 mouse) {
i++;
}
return -1;
+}
+
+
+void Menu_tech::open (vec2 res) {
+ over = -1;
+ active = true;
+ pos = vec2 { (float)res.x, (float)res.y };
+
+ tech_opt_ordered.clear();
+ tech_opt_ordered.emplace_back();
+ tech_opt_ordered.emplace_back();
+ tech_opt_ordered.emplace_back();
+ tech_opt_ordered.emplace_back();
+
+ for (OptionTech opt : tech_options) {
+ tech_opt_ordered[opt.tech->level].emplace_back(opt);
+ }
+ int maxsize = 0;
+ for (auto v : tech_opt_ordered) {
+ maxsize = maxsize < v.size() ? v.size() : maxsize;
+ }
+
+ float width = 150 * tech_opt_ordered.size();
+ float height = maxsize * 10;
+ size = vec2 { width, height+20 };
+ pos *= 0.5f;
+ pos -= size/2;
+}
+
+int Menu_tech::mouse_option (vec2 mouse) {
+ float x = 0, y = 0;
+ for (auto v : tech_opt_ordered) {
+ for (auto opt : v) {
+ vec2 off { x*150, 10.0f + y*10 };
+ vec2 sizeopt { 150, 10 };
+ off += pos;
+ if (off.x < mouse.x && mouse.x < off.x+sizeopt.x
+ && off.y < mouse.y && mouse.y < off.y+sizeopt.y ) {
+ return opt.tech->id;
+ }
+ y++;
+ }
+ x++; y=0;
+ }
+ return -1;
} \ No newline at end of file
diff --git a/game/menu.h b/game/menu.h
index bf181b5..462d893 100644
--- a/game/menu.h
+++ b/game/menu.h
@@ -5,6 +5,7 @@
#include <string>
#include "../umath/vec2.h"
+#include "tech.h"
class Option {
public:
@@ -22,10 +23,11 @@ class Menu {
bool active { false };
std::vector<Option> options;
vec2 pos, size;
+ int over;
- void open (vec2 res);
void close ();
- int mouse_option (vec2 mouse);
+ virtual void open (vec2 res);
+ virtual int mouse_option (vec2 mouse);
};
class Menu_unit : public Menu {
@@ -55,4 +57,23 @@ class Menu_train : public Menu {
Menu_train () {}
};
+
+class OptionTech {
+ public:
+ OptionTech(std::string name, Tech *tech) : name(name), tech(tech) {}
+
+ std::string name;
+ Tech *tech;
+};
+
+class Menu_tech : public Menu {
+ public:
+ Menu_tech () {}
+ std::vector<OptionTech> tech_options;
+ std::vector<std::vector<OptionTech>> tech_opt_ordered;
+
+ void open (vec2 res) override;
+ int mouse_option (vec2 mouse) override;
+};
+
#endif \ No newline at end of file
diff --git a/game/player.h b/game/player.h
index ec4657e..01d8ee9 100644
--- a/game/player.h
+++ b/game/player.h
@@ -11,6 +11,8 @@ class Player {
std::vector<int> res { 0, 0 };
std::vector<int> techs;
+ int level { 0 };
+
int r, g, b;
};
diff --git a/game/playercontrol.cpp b/game/playercontrol.cpp
index 647f487..90e063e 100644
--- a/game/playercontrol.cpp
+++ b/game/playercontrol.cpp
@@ -63,23 +63,6 @@ Player_control::Player_control () {
view.menu_day.close();
view.selected_ground = -1;
gst.end_day();
- for (Entity &e : gst.entities) {
- e.done = false;
- e.moved = 0;
- if (e.owner == gst.turn) {
- Player &player = gst.players[e.owner];
- for (int i=0; i<player.res.size(); i++) {
- player.res[i] += e.info->prod[i];
- }
- // todo heal when on top of building
- if (e.building < 0) {
- e.building++;
- if (e.building == 0) {
- e.hp += 50; if (e.hp > 100) e.hp = 100;
- }
- }
- }
- }
std::cout << "end day " << p << "\n";
return select;
}
@@ -93,6 +76,36 @@ Player_control::Player_control () {
}
);
fsm.arcs.emplace_back(
+ menu_day, opt, Menu_day::Opts::tech,
+ [](Gst &gst, View &view, Fsm &fsm, int p) {
+ view.menu_day.close();
+ view.menu_tech.tech_options.clear();
+ for (Tech &tech : gst.techs) {
+ view.menu_tech.tech_options.emplace_back(tech.name, &tech);
+ }
+ view.menu_tech.open(view.res);
+ std::cout << "tech screen " << "\n";
+ return menu_tech;
+ }
+ );
+ fsm.arcs.emplace_back(
+ menu_tech, opt, -1,
+ [](Gst &gst, View &view, Fsm &fsm, int p) {
+ view.menu_tech.close();
+ view.selected_ground = -1;
+ std::cout << "selected tech " << p << "\n";
+ return select;
+ }
+ );
+ fsm.arcs.emplace_back(
+ menu_tech, back, -1,
+ [](Gst &gst, View &view, Fsm &fsm, int p) {
+ view.menu_tech.close();
+ view.selected_ground = -1;
+ return select;
+ }
+ );
+ fsm.arcs.emplace_back(
select, sel_unit, -1,
[](Gst &gst, View &view, Fsm &fsm, int p) {
view.selected_entity = p;
diff --git a/game/playercontrol.h b/game/playercontrol.h
index 62de46d..3096ada 100644
--- a/game/playercontrol.h
+++ b/game/playercontrol.h
@@ -31,6 +31,7 @@ enum pc_state {
target_power,
menu_unit,
menu_day,
+ menu_tech,
end
};
diff --git a/game/tech.h b/game/tech.h
index a8de9c1..84ef05c 100644
--- a/game/tech.h
+++ b/game/tech.h
@@ -11,6 +11,9 @@ class Tech {
Tech() {}
std::string name;
+ int id;
+ int level;
+ int req_id;
std::vector<int> cost { 0, 0 };
vec2 spritebounds { 0, 0 };
diff --git a/game/view.cpp b/game/view.cpp
index d00fd2a..095a99a 100644
--- a/game/view.cpp
+++ b/game/view.cpp
@@ -11,6 +11,36 @@ void View::process (Gst &gst, vec2 cam, vec2 mouse, int *mheld) {
cursor_entity = -1;
back = -1;
opt = -1;
+ hover_ground = -1;
+
+ bool hfound = false;
+ for (int y=0; y<gr.sizey && !hfound; y++) {
+ for (int x=0; x<gr.sizex && !hfound; x++) {
+ vec2 pos { (float)x*32, (float)y*32 };
+ if (pos.x < absmouse.x && absmouse.x <= pos.x+32
+ && pos.y < absmouse.y && absmouse.y <= pos.y+32)
+ {
+ hover_ground = x+y*gr.sizex;
+ hfound = true;
+ }
+ }
+ }
+
+ if (menu_train.active) {
+ menu_train.over = menu_train.mouse_option(mouse);
+ }
+ if (menu_build.active) {
+ menu_build.over = menu_build.mouse_option(mouse);
+ }
+ if (menu_unit.active) {
+ menu_unit.over = menu_unit.mouse_option(mouse);
+ }
+ if (menu_day.active) {
+ menu_day.over = menu_day.mouse_option(mouse);
+ }
+ if (menu_tech.active) {
+ menu_tech.over = menu_tech.mouse_option(mouse);
+ }
if (mheld[0] == 1) {
bool found = false;
@@ -27,8 +57,8 @@ void View::process (Gst &gst, vec2 cam, vec2 mouse, int *mheld) {
}
if (!valid) continue;
vec2 pos { (float)x*32, (float)y*32 };
- if (pos.x < absmouse.x && absmouse.x < pos.x+32
- && pos.y < absmouse.y && absmouse.y < pos.y+32)
+ if (pos.x < absmouse.x && absmouse.x <= pos.x+32
+ && pos.y < absmouse.y && absmouse.y <= pos.y+32)
{
cursor_ground = moves[i];
}
@@ -41,8 +71,8 @@ void View::process (Gst &gst, vec2 cam, vec2 mouse, int *mheld) {
int x = attacks[i] % gr.sizex;
int y = attacks[i] / gr.sizex;
vec2 pos { (float)x*32, (float)y*32 };
- if (pos.x < absmouse.x && absmouse.x < pos.x+32
- && pos.y < absmouse.y && absmouse.y < pos.y+32)
+ if (pos.x < absmouse.x && absmouse.x <= pos.x+32
+ && pos.y < absmouse.y && absmouse.y <= pos.y+32)
{
cursor_ground = attacks[i];
}
@@ -85,13 +115,22 @@ void View::process (Gst &gst, vec2 cam, vec2 mouse, int *mheld) {
back = 1; found = 1;
}
}
+
+ if (menu_tech.active && !found) {
+ int selected = menu_tech.mouse_option(mouse);
+ if (selected != -1) {
+ opt = selected; found = true;
+ } else {
+ back = 1; found = 1;
+ }
+ }
for (int i=0; i<entities.size() && !found; i++) {
if (entities[i].done) continue;
if (entities[i].owner != gst.turn) continue;
vec2 pos { (float)entities[i].x*32, (float)entities[i].y*32 };
- if (pos.x < absmouse.x && absmouse.x < pos.x+32
- && pos.y < absmouse.y && absmouse.y < pos.y+32)
+ if (pos.x < absmouse.x && absmouse.x <= pos.x+32
+ && pos.y < absmouse.y && absmouse.y <= pos.y+32)
{
cursor_entity = i;
if (entities[i].info->unit == 1) {
@@ -104,8 +143,8 @@ void View::process (Gst &gst, vec2 cam, vec2 mouse, int *mheld) {
for (int y=0; y<gr.sizey && !found; y++) {
for (int x=0; x<gr.sizex && !found; x++) {
vec2 pos { (float)x*32, (float)y*32 };
- if (pos.x < absmouse.x && absmouse.x < pos.x+32
- && pos.y < absmouse.y && absmouse.y < pos.y+32)
+ if (pos.x < absmouse.x && absmouse.x <= pos.x+32
+ && pos.y < absmouse.y && absmouse.y <= pos.y+32)
{
cursor_ground = x+y*gr.sizex;
found = true;
diff --git a/game/view.h b/game/view.h
index a9d196b..5aab193 100644
--- a/game/view.h
+++ b/game/view.h
@@ -13,6 +13,7 @@ class View {
vec2 res;
+ int hover_ground {-1};
int selected_ground {-1};
int selected_entity {-1};
int cursor_ground {-1};
@@ -27,6 +28,7 @@ class View {
Menu_day menu_day;
Menu_build menu_build;
Menu_train menu_train;
+ Menu_tech menu_tech;
void process (Gst &gst, vec2 cam, vec2 mouse, int *mheld);
};