1 #include "request.h"
2 
3 #include "building/warehouse.h"
4 #include "city/finance.h"
5 #include "city/message.h"
6 #include "city/population.h"
7 #include "city/ratings.h"
8 #include "city/resource.h"
9 #include "core/random.h"
10 #include "game/resource.h"
11 #include "game/time.h"
12 #include "game/tutorial.h"
13 #include "scenario/data.h"
14 
scenario_request_init(void)15 void scenario_request_init(void)
16 {
17     for (int i = 0; i < MAX_REQUESTS; i++) {
18         random_generate_next();
19         if (scenario.requests[i].resource) {
20             scenario.requests[i].month = (random_byte() & 7) + 2;
21             scenario.requests[i].months_to_comply = 12 * scenario.requests[i].deadline_years;
22         }
23     }
24 }
25 
scenario_request_process(void)26 void scenario_request_process(void)
27 {
28     for (int i = 0; i < MAX_REQUESTS; i++) {
29         if (!scenario.requests[i].resource || scenario.requests[i].state > REQUEST_STATE_DISPATCHED_LATE) {
30             continue;
31         }
32         int state = scenario.requests[i].state;
33         if (state == REQUEST_STATE_DISPATCHED || state == REQUEST_STATE_DISPATCHED_LATE) {
34             --scenario.requests[i].months_to_comply;
35             if (scenario.requests[i].months_to_comply <= 0) {
36                 if (state == REQUEST_STATE_DISPATCHED) {
37                     city_message_post(1, MESSAGE_REQUEST_RECEIVED, i, 0);
38                     city_ratings_change_favor(scenario.requests[i].favor);
39                 } else {
40                     city_message_post(1, MESSAGE_REQUEST_RECEIVED_LATE, i, 0);
41                     city_ratings_change_favor(scenario.requests[i].favor / 2);
42                 }
43                 scenario.requests[i].state = REQUEST_STATE_RECEIVED;
44                 scenario.requests[i].visible = 0;
45             }
46         } else {
47             // normal or overdue
48             if (scenario.requests[i].visible) {
49                 --scenario.requests[i].months_to_comply;
50                 if (state == REQUEST_STATE_NORMAL) {
51                     if (scenario.requests[i].months_to_comply == 12) {
52                         // reminder
53                         city_message_post(1, MESSAGE_REQUEST_REMINDER, i, 0);
54                     } else if (scenario.requests[i].months_to_comply <= 0) {
55                         city_message_post(1, MESSAGE_REQUEST_REFUSED, i, 0);
56                         scenario.requests[i].state = REQUEST_STATE_OVERDUE;
57                         scenario.requests[i].months_to_comply = 24;
58                         city_ratings_reduce_favor_missed_request(3);
59                     }
60                 } else if (state == REQUEST_STATE_OVERDUE) {
61                     if (scenario.requests[i].months_to_comply <= 0) {
62                         city_message_post(1, MESSAGE_REQUEST_REFUSED_OVERDUE, i, 0);
63                         scenario.requests[i].state = REQUEST_STATE_IGNORED;
64                         scenario.requests[i].visible = 0;
65                         city_ratings_reduce_favor_missed_request(5);
66                     }
67                 }
68                 if (!scenario.requests[i].can_comply_dialog_shown &&
69                     city_resource_count(scenario.requests[i].resource) >= scenario.requests[i].amount) {
70                     scenario.requests[i].can_comply_dialog_shown = 1;
71                     city_message_post(1, MESSAGE_REQUEST_CAN_COMPLY, i, 0);
72                 }
73             } else {
74                 // request is not visible
75                 int year = scenario.start_year;
76                 if (!tutorial_adjust_request_year(&year)) {
77                     return;
78                 }
79                 if (game_time_year() == year + scenario.requests[i].year &&
80                     game_time_month() == scenario.requests[i].month) {
81                     scenario.requests[i].visible = 1;
82                     if (city_resource_count(scenario.requests[i].resource) >= scenario.requests[i].amount) {
83                         scenario.requests[i].can_comply_dialog_shown = 1;
84                     }
85                     if (scenario.requests[i].resource == RESOURCE_DENARII) {
86                         city_message_post(1, MESSAGE_CAESAR_REQUESTS_MONEY, i, 0);
87                     } else if (scenario.requests[i].resource == RESOURCE_TROOPS) {
88                         city_message_post(1, MESSAGE_CAESAR_REQUESTS_ARMY, i, 0);
89                     } else {
90                         city_message_post(1, MESSAGE_CAESAR_REQUESTS_GOODS, i, 0);
91                     }
92                 }
93             }
94         }
95     }
96 }
97 
scenario_request_dispatch(int id)98 void scenario_request_dispatch(int id)
99 {
100     if (scenario.requests[id].state == REQUEST_STATE_NORMAL) {
101         scenario.requests[id].state = REQUEST_STATE_DISPATCHED;
102     } else {
103         scenario.requests[id].state = REQUEST_STATE_DISPATCHED_LATE;
104     }
105     scenario.requests[id].months_to_comply = (random_byte() & 3) + 1;
106     scenario.requests[id].visible = 0;
107     int amount = scenario.requests[id].amount;
108     if (scenario.requests[id].resource == RESOURCE_DENARII) {
109         city_finance_process_sundry(amount);
110     } else if (scenario.requests[id].resource == RESOURCE_TROOPS) {
111         city_population_remove_for_troop_request(amount);
112         building_warehouses_remove_resource(RESOURCE_WEAPONS, amount);
113     } else {
114         building_warehouses_remove_resource(scenario.requests[id].resource, amount);
115     }
116 }
117 
scenario_request_get(int id)118 const scenario_request *scenario_request_get(int id)
119 {
120     static scenario_request request;
121     request.id = id;
122     request.amount = scenario.requests[id].amount;
123     request.resource = scenario.requests[id].resource;
124     request.state = scenario.requests[id].state;
125     request.months_to_comply = scenario.requests[id].months_to_comply;
126     return &request;
127 }
128 
scenario_request_foreach_visible(int start_index,void (* callback)(int index,const scenario_request * request))129 int scenario_request_foreach_visible(int start_index, void (*callback)(int index, const scenario_request *request))
130 {
131     int index = start_index;
132     for (int i = 0; i < MAX_REQUESTS; i++) {
133         if (scenario.requests[i].resource && scenario.requests[i].visible) {
134             callback(index, scenario_request_get(i));
135             index++;
136         }
137     }
138     return index;
139 }
140 
scenario_request_get_visible(int index)141 const scenario_request *scenario_request_get_visible(int index)
142 {
143     for (int i = 0; i < MAX_REQUESTS; i++) {
144         if (scenario.requests[i].resource && scenario.requests[i].visible &&
145             scenario.requests[i].state <= 1) {
146             if (index == 0) {
147                 return scenario_request_get(i);
148             }
149             index--;
150         }
151     }
152     return 0;
153 }
154