forked from bvschaik/julius
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhealth.c
148 lines (139 loc) · 4.76 KB
/
health.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "health.h"
#include "building/building.h"
#include "building/destruction.h"
#include "city/data_private.h"
#include "city/message.h"
#include "core/calc.h"
#include "core/random.h"
#include "game/tutorial.h"
#include "scenario/property.h"
int city_health(void)
{
return city_data.health.value;
}
void city_health_change(int amount)
{
city_data.health.value = calc_bound(city_data.health.value + amount, 0, 100);
}
static void cause_disease(int total_people)
{
if (city_data.health.value >= 40) {
return;
}
int chance_value = random_byte() & 0x3f;
if (city_data.religion.venus_curse_active) {
// force plague
chance_value = 0;
city_data.religion.venus_curse_active = 0;
}
if (chance_value > 40 - city_data.health.value) {
return;
}
int sick_people = calc_adjust_with_percentage(total_people, 7 + (random_byte() & 3));
if (sick_people <= 0) {
return;
}
city_health_change(10);
int people_to_kill = sick_people - city_data.health.num_hospital_workers;
if (people_to_kill <= 0) {
city_message_post(1, MESSAGE_HEALTH_ILLNESS, 0, 0);
return;
}
if (city_data.health.num_hospital_workers > 0) {
city_message_post(1, MESSAGE_HEALTH_DISEASE, 0, 0);
} else {
city_message_post(1, MESSAGE_HEALTH_PESTILENCE, 0, 0);
}
tutorial_on_disease();
// kill people who don't have access to a doctor
for (int i = 1; i < MAX_BUILDINGS; i++) {
building *b = building_get(i);
if (b->state == BUILDING_STATE_IN_USE && b->house_size && b->house_population) {
if (!b->data.house.clinic) {
people_to_kill -= b->house_population;
building_destroy_by_plague(b);
if (people_to_kill <= 0) {
return;
}
}
}
}
// kill people in tents
for (int i = 1; i < MAX_BUILDINGS; i++) {
building *b = building_get(i);
if (b->state == BUILDING_STATE_IN_USE && b->house_size && b->house_population) {
if (b->subtype.house_level <= HOUSE_LARGE_TENT) {
people_to_kill -= b->house_population;
building_destroy_by_plague(b);
if (people_to_kill <= 0) {
return;
}
}
}
}
// kill anyone
for (int i = 1; i < MAX_BUILDINGS; i++) {
building *b = building_get(i);
if (b->state == BUILDING_STATE_IN_USE && b->house_size && b->house_population) {
people_to_kill -= b->house_population;
building_destroy_by_plague(b);
if (people_to_kill <= 0) {
return;
}
}
}
}
void city_health_update(void)
{
if (city_data.population.population < 200 || scenario_is_tutorial_1() || scenario_is_tutorial_2()) {
city_data.health.value = 50;
city_data.health.target_value = 50;
return;
}
int total_population = 0;
int healthy_population = 0;
for (int i = 1; i < MAX_BUILDINGS; i++) {
building *b = building_get(i);
if (b->state != BUILDING_STATE_IN_USE || !b->house_size || !b->house_population) {
continue;
}
total_population += b->house_population;
if (b->subtype.house_level <= HOUSE_LARGE_TENT) {
if (b->data.house.clinic) {
healthy_population += b->house_population;
} else {
healthy_population += b->house_population / 4;
}
} else if (b->data.house.clinic) {
if (b->house_days_without_food == 0) {
healthy_population += b->house_population;
} else {
healthy_population += b->house_population / 4;
}
} else if (b->house_days_without_food == 0) {
healthy_population += b->house_population / 4;
}
}
city_data.health.target_value = calc_percentage(healthy_population, total_population);
if (city_data.health.value < city_data.health.target_value) {
city_data.health.value += 2;
if (city_data.health.value > city_data.health.target_value) {
city_data.health.value = city_data.health.target_value;
}
} else if (city_data.health.value > city_data.health.target_value) {
city_data.health.value -= 2;
if (city_data.health.value < city_data.health.target_value) {
city_data.health.value = city_data.health.target_value;
}
}
city_data.health.value = calc_bound(city_data.health.value, 0, 100);
cause_disease(total_population);
}
void city_health_reset_hospital_workers(void)
{
city_data.health.num_hospital_workers = 0;
}
void city_health_add_hospital_workers(int amount)
{
city_data.health.num_hospital_workers += amount;
}