Skip to content

Commit eea43b6

Browse files
committed
tutorial: moved tut1 logic from common code, add event handler for building archector post
1 parent 54dcf21 commit eea43b6

File tree

7 files changed

+140
-103
lines changed

7 files changed

+140
-103
lines changed

CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ file(GLOB EMPIRE_FILES ${PROJECT_SOURCE_DIR}/src/empire/*.cpp)
236236
file(GLOB FIGURE_FILES ${PROJECT_SOURCE_DIR}/src/figure/*.cpp)
237237
file(GLOB FIGURETYPE_FILES ${PROJECT_SOURCE_DIR}/src/figuretype/*.cpp)
238238
file(GLOB GAME_FILES ${PROJECT_SOURCE_DIR}/src/game/*.cpp)
239+
file(GLOB TUTORIAL_FILES ${PROJECT_SOURCE_DIR}/src/tutorial/*.cpp)
239240
file(GLOB INPUT_FILES ${PROJECT_SOURCE_DIR}/src/input/*.cpp)
240241
file(GLOB GRID_FILES ${PROJECT_SOURCE_DIR}/src/grid/*.cpp)
241242
file(GLOB GRID_ROUTING_FILES ${PROJECT_SOURCE_DIR}/src/grid/routing/*.cpp)
@@ -332,6 +333,7 @@ if(MSVC)
332333
source_group("figure" FILES ${FIGURE_FILES})
333334
source_group("figuretype" FILES ${FIGURETYPE_FILES})
334335
source_group("game" FILES ${GAME_FILES})
336+
source_group("tutorial" FILES ${TUTORIAL_FILES})
335337
source_group("input" FILES ${INPUT_FILES})
336338
source_group("grid" FILES ${GRID_FILES})
337339
source_group("grid/routing" FILES ${GRID_ROUTING_FILES})
@@ -385,6 +387,7 @@ set(SOURCE_FILES
385387
${FIGURE_FILES}
386388
${FIGURETYPE_FILES}
387389
${GAME_FILES}
390+
${TUTORIAL_FILES}
388391
${INPUT_FILES}
389392
${GRID_FILES}
390393
${SCENARIO_FILES}

src/building/building.h

+2
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ class building_farm;
146146

147147
building* building_get(building_id id);
148148

149+
struct event_building_create { building_id bid; };
150+
149151
class building {
150152
public:
151153
enum { max_figures = 4 };

src/city/city_buildings.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ building *building_create(e_building_type type, tile2i tile, int orientation) {
7070

7171
memset(b->runtime_data, 0, sizeof(b->runtime_data));
7272
b->new_fill_in_data_for_type(type, tile, orientation);
73+
g_city_events.enqueue(event_building_create{ b->id });
7374

7475
return b;
7576
}

src/city/city_house_population.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ int house_population_add_to_city(int num_people) {
2626
}
2727

2828
auto house = building_get(building_id)->dcast_house();
29-
if (house->state() == BUILDING_STATE_VALID && house->distance_from_entry() > 0 && house->house_population() > 0) {
29+
if (house && house->state() == BUILDING_STATE_VALID && house->distance_from_entry() > 0 && house->house_population() > 0) {
3030
city_population_set_last_used_house_add(building_id);
3131
int max_people = model_get_house(house->house_level())->max_people;
3232
if (house->is_merged()) {

src/game/tutorial.cpp

+18-101
Original file line numberDiff line numberDiff line change
@@ -168,60 +168,6 @@ void tutorial_map_update(int tut) {
168168
}
169169
}
170170

171-
void tutorial1_handle_fire(event_fire_damage) {
172-
if (g_tutorials_flags.tutorial_1.fire) {
173-
return;
174-
}
175-
176-
g_city_events.removeListener(typeid(event_fire_damage), &tutorial1_handle_fire);
177-
178-
g_tutorials_flags.tutorial_1.fire = true;
179-
g_scenario_data.add_fire_damage.clear();
180-
181-
building_menu_update(tutorial_stage.tutorial_fire);
182-
post_message(MESSAGE_TUTORIAL_FIRE_IN_THE_VILLAGE);
183-
}
184-
185-
void tutorial1_handle_population_150(event_population_changed ev) {
186-
if (g_tutorials_flags.tutorial_1.population_150_reached || ev.value < 150) {
187-
return;
188-
}
189-
190-
g_city_events.removeListener(typeid(event_population_changed), &tutorial1_handle_population_150);
191-
192-
g_tutorials_flags.tutorial_1.population_150_reached = true;
193-
building_menu_update(tutorial_stage.tutorial_food);
194-
post_message(MESSAGE_TUTORIAL_FOOD_OR_FAMINE);
195-
}
196-
197-
void tutorial1_handle_collapse(event_collase_damage) {
198-
if (g_tutorials_flags.tutorial_1.collapse) {
199-
return;
200-
}
201-
202-
g_city_events.removeListener(typeid(event_collase_damage), &tutorial1_handle_collapse);
203-
204-
g_tutorials_flags.tutorial_1.collapse = true;
205-
building_menu_update(tutorial_stage.tutorial_collapse);
206-
post_message(MESSAGE_TUTORIAL_COLLAPSED_BUILDING);
207-
}
208-
209-
void tutorial1_on_filled_granary(event_granary_filled ev) {
210-
if (g_tutorials_flags.tutorial_1.gamemeat_400_stored) {
211-
return;
212-
}
213-
214-
if (ev.amount <= 400) {
215-
return;
216-
}
217-
218-
g_city_events.removeListener(typeid(event_granary_filled), &tutorial1_on_filled_granary);
219-
220-
g_tutorials_flags.tutorial_1.gamemeat_400_stored = true;
221-
building_menu_update(tutorial_stage.tutorial_water);
222-
post_message(MESSAGE_TUTORIAL_CLEAN_WATER);
223-
}
224-
225171
void tutorial3_on_filled_granary(event_granary_filled ev) {
226172
if (g_tutorials_flags.tutorial_3.figs_800_stored) {
227173
return;
@@ -245,31 +191,9 @@ void tutorial3_on_filled_granary(event_granary_filled ev) {
245191
post_message(MESSAGE_TUTORIAL_INDUSTRY);
246192
}
247193

248-
bool tutorial1_is_success() {
249-
auto &tut = g_tutorials_flags.tutorial_1;
250-
return tut.fire && tut.collapse && tut.population_150_reached && tut.gamemeat_400_stored;
251-
}
252-
253194
bool tutorial_menu_update(int tut) {
254195
if (tut == 1) {
255-
if (g_tutorials_flags.tutorial_1.fire) building_menu_update(tutorial_stage.tutorial_fire);
256-
else g_city_events.appendListener(typeid(event_fire_damage), &tutorial1_handle_fire);
257-
258-
if (g_tutorials_flags.tutorial_1.population_150_reached) building_menu_update(tutorial_stage.tutorial_food);
259-
else g_city_events.appendListener(typeid(event_population_changed), &tutorial1_handle_population_150);
260-
261-
//if (!g_tutorials_flags.tutorial_1.architector_built) {
262-
// g_city_events.appendListener(typeid(event_building_create), &tutorial1_handle_building_create);
263-
//}
264-
265-
if (g_tutorials_flags.tutorial_1.collapse) building_menu_update(tutorial_stage.tutorial_collapse);
266-
else g_city_events.appendListener(typeid(event_collase_damage), &tutorial1_handle_collapse);
267-
268-
if (g_tutorials_flags.tutorial_1.gamemeat_400_stored) building_menu_update(tutorial_stage.tutorial_water);
269-
else g_city_events.appendListener(typeid(event_granary_filled), &tutorial1_on_filled_granary);
270-
271-
g_city.victory_state.add_condition(&tutorial1_is_success);
272-
196+
tutorial_1::init();
273197
return true;
274198
}
275199

@@ -472,33 +396,27 @@ void tutorial_on_house_evolve(e_house_level level) {
472396
}
473397
}
474398

475-
void tutorial_update_step(pcstr s) {
476-
const xstring step(s);
477-
if (step == tutorial_stage.tutorial_fire) {
478-
g_tutorials_flags.tutorial_1.fire = false;
479-
tutorial1_handle_fire({0});
480-
} else if (step == tutorial_stage.tutorial_food) {
481-
building_menu_update(step);
399+
void tutorial_update_step(xstring s) {
400+
tutorial_1::update_step(s);
401+
if (s == tutorial_stage.tutorial_food) {
402+
building_menu_update(s);
482403
post_message(MESSAGE_TUTORIAL_FOOD_OR_FAMINE);
483-
} else if (step == tutorial_stage.tutorial_water) {
484-
building_menu_update(step);
404+
} else if (s == tutorial_stage.tutorial_water) {
405+
building_menu_update(s);
485406
post_message(MESSAGE_TUTORIAL_CLEAN_WATER);
486-
} else if (step == tutorial_stage.tutorial_collapse) {
487-
g_tutorials_flags.tutorial_1.collapse = false;
488-
tutorial1_handle_collapse({0});
489-
} else if (step == tutorial_stage.tutorial_gods) {
490-
building_menu_update(step);
407+
} else if (s == tutorial_stage.tutorial_gods) {
408+
building_menu_update(s);
491409
post_message(MESSAGE_TUTORIAL_GODS_OF_EGYPT);
492-
} else if (step == tutorial_stage.tutorial_entertainment) {
493-
building_menu_update(step);
494-
} else if (step == tutorial_stage.tutorial_industry) {
495-
building_menu_update(step);
410+
} else if (s == tutorial_stage.tutorial_entertainment) {
411+
building_menu_update(s);
412+
} else if (s == tutorial_stage.tutorial_industry) {
413+
building_menu_update(s);
496414
post_message(MESSAGE_TUTORIAL_INDUSTRY);
497-
} else if (step == tutorial_stage.tutorial_health) {
498-
building_menu_update(step);
415+
} else if (s == tutorial_stage.tutorial_health) {
416+
building_menu_update(s);
499417
post_message(MESSAGE_TUTORIAL_BASIC_HEALTHCARE);
500-
} else if (step == tutorial_stage.tutorial_gardens) {
501-
building_menu_update(step);
418+
} else if (s == tutorial_stage.tutorial_gardens) {
419+
building_menu_update(s);
502420
post_message(MESSAGE_TUTORIAL_MUNICIPAL_STRUCTURES);
503421
}
504422
}
@@ -609,6 +527,5 @@ io_buffer* iob_tutorial_flags = new io_buffer([](io_buffer* iob, size_t version)
609527
iob->bind(BIND_SIGNATURE_UINT8, &g_tutorials_flags.pharaoh.flags[35]);
610528
iob->bind(BIND_SIGNATURE_UINT8, &g_tutorials_flags.pharaoh.flags[36]); // goal: entertainment
611529
iob->bind(BIND_SIGNATURE_UINT8, &g_tutorials_flags.pharaoh.flags[37]); // goal: temples
612-
iob->bind(BIND_SIGNATURE_UINT8, &g_tutorials_flags.pharaoh.flags[38]);
613-
iob->bind(BIND_SIGNATURE_UINT8, &g_tutorials_flags.pharaoh.flags[39]);
530+
iob->bind(BIND_SIGNATURE_UINT16, &g_tutorials_flags.pharaoh.last_action);
614531
});

src/game/tutorial.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ struct tutorial_stage_t {
2525
#undef _RR
2626
};
2727

28+
struct tutorial_1 {
29+
static void init();
30+
static void update_step(xstring s);
31+
};
32+
2833
struct tutorial_flags_t {
2934
struct {
3035
bool started;
@@ -77,6 +82,7 @@ struct tutorial_flags_t {
7782
bool crime;
7883
bool tut7_start;
7984
bool tut8_start;
85+
uint16_t last_action;
8086

8187
} pharaoh;
8288

@@ -112,4 +118,4 @@ void tutorial_check_resources_on_storageyard();
112118
void tutorial_on_day_tick();
113119
void tutorial_on_month_tick();
114120

115-
void tutorial_update_step(pcstr step);
121+
void tutorial_update_step(xstring step);

src/tutorial/tutorial1.cpp

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#include "game/tutorial.h"
2+
3+
#include "city/city.h"
4+
#include "game/game.h"
5+
#include "building/maintenance.h"
6+
#include "building/building_menu.h"
7+
#include "building/building_granary.h"
8+
#include "city/message.h"
9+
10+
void tutorial1_handle_fire(event_fire_damage) {
11+
if (g_tutorials_flags.tutorial_1.fire) {
12+
return;
13+
}
14+
15+
g_city_events.removeListener(typeid(event_fire_damage), &tutorial1_handle_fire);
16+
g_tutorials_flags.pharaoh.last_action = game.simtime.absolute_day();
17+
g_tutorials_flags.tutorial_1.fire = true;
18+
g_scenario_data.add_fire_damage.clear();
19+
20+
building_menu_update(tutorial_stage.tutorial_fire);
21+
city_message_post(true, MESSAGE_TUTORIAL_FIRE_IN_THE_VILLAGE, 0, 0);
22+
}
23+
24+
void tutorial1_handle_population_150(event_population_changed ev) {
25+
if (g_tutorials_flags.tutorial_1.population_150_reached || ev.value < 150) {
26+
return;
27+
}
28+
29+
g_city_events.removeListener(typeid(event_population_changed), &tutorial1_handle_population_150);
30+
g_tutorials_flags.pharaoh.last_action = game.simtime.absolute_day();
31+
g_tutorials_flags.tutorial_1.population_150_reached = true;
32+
building_menu_update(tutorial_stage.tutorial_food);
33+
city_message_post(true, MESSAGE_TUTORIAL_FOOD_OR_FAMINE, 0, 0);
34+
}
35+
36+
void tutorial1_handle_collapse(event_collase_damage) {
37+
if (g_tutorials_flags.tutorial_1.collapse) {
38+
return;
39+
}
40+
41+
g_city_events.removeListener(typeid(event_collase_damage), &tutorial1_handle_collapse);
42+
g_tutorials_flags.pharaoh.last_action = game.simtime.absolute_day();
43+
g_tutorials_flags.tutorial_1.collapse = true;
44+
building_menu_update(tutorial_stage.tutorial_collapse);
45+
city_message_post(true, MESSAGE_TUTORIAL_COLLAPSED_BUILDING, 0, 0);
46+
}
47+
48+
void tutorial1_on_filled_granary(event_granary_filled ev) {
49+
if (g_tutorials_flags.tutorial_1.gamemeat_400_stored) {
50+
return;
51+
}
52+
53+
if (ev.amount <= 400) {
54+
return;
55+
}
56+
57+
g_city_events.removeListener(typeid(event_granary_filled), &tutorial1_on_filled_granary);
58+
g_tutorials_flags.pharaoh.last_action = game.simtime.absolute_day();
59+
g_tutorials_flags.tutorial_1.gamemeat_400_stored = true;
60+
building_menu_update(tutorial_stage.tutorial_water);
61+
city_message_post(true, MESSAGE_TUTORIAL_CLEAN_WATER, 0, 0);
62+
}
63+
64+
void tutorial1_handle_building_create(event_building_create ev) {
65+
if (g_tutorials_flags.tutorial_1.architector_built) {
66+
return;
67+
}
68+
69+
g_city_events.removeListener(typeid(event_building_create), &tutorial1_handle_building_create);
70+
g_tutorials_flags.pharaoh.last_action = game.simtime.absolute_day();
71+
}
72+
73+
bool tutorial1_is_success() {
74+
auto &tut = g_tutorials_flags.tutorial_1;
75+
const bool may_finish = (tut.fire && tut.collapse && tut.population_150_reached && tut.gamemeat_400_stored);
76+
const bool some_days_after_last_action = (game.simtime.absolute_day() - g_tutorials_flags.pharaoh.last_action) > 3;
77+
return may_finish && some_days_after_last_action;
78+
}
79+
80+
void tutorial_1::init() {
81+
if (g_tutorials_flags.tutorial_1.fire) building_menu_update(tutorial_stage.tutorial_fire);
82+
else g_city_events.appendListener(typeid(event_fire_damage), &tutorial1_handle_fire);
83+
84+
if (g_tutorials_flags.tutorial_1.population_150_reached) building_menu_update(tutorial_stage.tutorial_food);
85+
else g_city_events.appendListener(typeid(event_population_changed), &tutorial1_handle_population_150);
86+
87+
if (!g_tutorials_flags.tutorial_1.architector_built) {
88+
g_city_events.appendListener(typeid(event_building_create), &tutorial1_handle_building_create);
89+
}
90+
91+
if (g_tutorials_flags.tutorial_1.collapse) building_menu_update(tutorial_stage.tutorial_collapse);
92+
else g_city_events.appendListener(typeid(event_collase_damage), &tutorial1_handle_collapse);
93+
94+
if (g_tutorials_flags.tutorial_1.gamemeat_400_stored) building_menu_update(tutorial_stage.tutorial_water);
95+
else g_city_events.appendListener(typeid(event_granary_filled), &tutorial1_on_filled_granary);
96+
97+
g_city.victory_state.add_condition(&tutorial1_is_success);
98+
}
99+
100+
void tutorial_1::update_step(xstring s) {
101+
if (s == tutorial_stage.tutorial_fire) {
102+
g_tutorials_flags.tutorial_1.fire = false;
103+
tutorial1_handle_fire({ 0 });
104+
} else if (s == tutorial_stage.tutorial_collapse) {
105+
g_tutorials_flags.tutorial_1.collapse = false;
106+
tutorial1_handle_collapse({ 0 });
107+
}
108+
}

0 commit comments

Comments
 (0)