Skip to content

Commit

Permalink
Add Health rating overlay
Browse files Browse the repository at this point in the history
Many thanks to @dvincent56 / Awatibala
  • Loading branch information
Ouaz committed Jan 30, 2024
1 parent fdf9cc6 commit cf17d95
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 31 deletions.
65 changes: 38 additions & 27 deletions src/city/health.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,43 @@ static void adjust_sickness_level_in_plague_buildings(int hospital_coverage_bonu
}
}

int city_health_get_house_health_level(building *b)
{
int house_health = 0;

if (building_is_house(b->type)) {
house_health = calc_bound(b->subtype.house_level, 0, 10);
if (b->data.house.clinic && b->data.house.hospital) {
house_health += 50;
city_data.health.population_access.clinic += b->house_population;
} else if (b->data.house.hospital) {
house_health += 40;
} else if (b->data.house.clinic) {
house_health += 30;
city_data.health.population_access.clinic += b->house_population;
}
if (b->data.house.bathhouse) {
house_health += 20;
city_data.health.population_access.baths += b->house_population;
}
if (b->data.house.barber) {
house_health += 10;
city_data.health.population_access.barber += b->house_population;
}
house_health += b->data.house.num_foods * 15;

int mausoleum_health = building_count_active(BUILDING_SMALL_MAUSOLEUM);
mausoleum_health += building_count_active(BUILDING_LARGE_MAUSOLEUM) * 2;

house_health += calc_bound(mausoleum_health, 0, 10);

int health_cap = (model_get_house(b->subtype.house_level)->food_types && !b->data.house.num_foods) ?
40 : 100;
house_health = calc_bound(house_health, 0, health_cap);
}
return house_health;
}

void city_health_update(void)
{
if (city_data.population.population < 200 || scenario_is_tutorial_1() || scenario_is_tutorial_2()) {
Expand All @@ -319,34 +356,8 @@ void city_health_update(void)
b->sickness_level = 0;
continue;
}
int house_health = calc_bound(b->subtype.house_level, 0, 10);
if (b->data.house.clinic && b->data.house.hospital) {
house_health += 50;
city_data.health.population_access.clinic += b->house_population;
} else if (b->data.house.hospital) {
house_health += 40;
} else if (b->data.house.clinic) {
house_health += 30;
city_data.health.population_access.clinic += b->house_population;
}
if (b->data.house.bathhouse) {
house_health += 20;
city_data.health.population_access.baths += b->house_population;
}
if (b->data.house.barber) {
house_health += 10;
city_data.health.population_access.barber += b->house_population;
}
house_health += b->data.house.num_foods * 15;

int mausoleum_health = building_count_active(BUILDING_SMALL_MAUSOLEUM);
mausoleum_health += building_count_active(BUILDING_LARGE_MAUSOLEUM) * 2;

house_health += calc_bound(mausoleum_health, 0, 10);
int house_health = city_health_get_house_health_level(b);

int health_cap = (model_get_house(b->subtype.house_level)->food_types && !b->data.house.num_foods) ?
40 : 100;
house_health = calc_bound(house_health, 0, health_cap);
total_population += b->house_population;
healthy_population += calc_adjust_with_percentage(b->house_population, house_health);
adjust_sickness_level_in_house(b, house_health, population_health_offset, hospital_coverage_bonus);
Expand Down
2 changes: 2 additions & 0 deletions src/city/health.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ void city_health_change(int amount);

void city_health_set(int new_value);

int city_health_get_house_health_level(building *b);

void city_health_update(void);

void city_health_update_sickness_level_in_building(int building_id);
Expand Down
1 change: 1 addition & 0 deletions src/core/hotkey_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ static const char *ini_keys[] = {
"show_overlay_school",
"show_overlay_library",
"show_overlay_academy",
"show_overlay_health",
"show_overlay_barber",
"show_overlay_bathhouse",
"show_overlay_clinic",
Expand Down
1 change: 1 addition & 0 deletions src/core/hotkey_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ typedef enum {
HOTKEY_SHOW_OVERLAY_SCHOOL,
HOTKEY_SHOW_OVERLAY_LIBRARY,
HOTKEY_SHOW_OVERLAY_ACADEMY,
HOTKEY_SHOW_OVERLAY_HEALTH,
HOTKEY_SHOW_OVERLAY_BARBER,
HOTKEY_SHOW_OVERLAY_BATHHOUSE,
HOTKEY_SHOW_OVERLAY_CLINIC,
Expand Down
1 change: 1 addition & 0 deletions src/game/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ enum {
OVERLAY_SICKNESS = 38,
OVERLAY_EFFICIENCY = 39,
OVERLAY_STORAGES = 40,
OVERLAY_HEALTH = 41,
};

void game_state_init(void);
Expand Down
4 changes: 4 additions & 0 deletions src/input/hotkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,10 @@ static void set_definition_for_action(hotkey_action action, hotkey_definition *d
def->action = &data.hotkey_state.show_overlay;
def->value = OVERLAY_ACADEMY;
break;
case HOTKEY_SHOW_OVERLAY_HEALTH:
def->action = &data.hotkey_state.show_overlay;
def->value = OVERLAY_HEALTH;
break;
case HOTKEY_SHOW_OVERLAY_BARBER:
def->action = &data.hotkey_state.show_overlay;
def->value = OVERLAY_BARBER;
Expand Down
16 changes: 15 additions & 1 deletion src/translation/english.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,13 +788,26 @@ static translation_string all_strings[] = {
{TR_BUILDING_WAREHOUSE_NO_GOODS, "No goods stored at this warehouse."},
{TR_BUILDING_HOUSE_DISEASE_DESC, "Pestilence has struck! Without adequate healthcare, residents dwelling here have died. This house is in quarantine while a doctor or surgeon decontaminates the area."},
{TR_BUILDING_FUMIGATION_DESC, "The building is being cleansed of disease. The fumigation should last a few days."},
{TR_OVERLAY_HEALTH, "Rating"},
{TR_OVERLAY_SICKNESS, "Sickness"},
{TR_ADVISOR_HEALTH_RATING, "Rating:"},
{TR_ADVISOR_HEALTH_SURVEILLANCE, "Disease surveillance:"},
{TR_ADVISOR_SICKNESS_LEVEL_LOW, "Disease is a rare occurrence in the city. The high standard of healthcare provided to the vast majority of residents effectively prevents epidemics spreading here."},
{TR_ADVISOR_SICKNESS_LEVEL_MEDIUM, "Some infectious diseases have appeared in areas of the city with a lacking hygiene, but the situation is under control. A sufficiently high level of healthcare will mitigate the impact of epidemics in the city."},
{TR_ADVISOR_SICKNESS_LEVEL_HIGH, "Infectious diseases spread in areas of the city having a poor level of hygiene. If the situation is not remedied soon, some buildings may be quarantined. Greater access to healthcare would effectively prevent epidemics from breaking out."},
{TR_ADVISOR_SICKNESS_LEVEL_PLAGUE, "The plague has come to some unhealthy areas in the city! Citizens fall ill and buildings have been quarantined or burned to prevent the further spread of disease. Available doctors and surgeons have been requisitioned to decontaminate the afflicted places. Action must be taken!"},
{TR_ADVISOR_SICKNESS_LEVEL_PLAGUE, "The plague has come to some unhealthy areas in the city! Buildings have been quarantined or burned to prevent the further spread of disease. Doctors and surgeons have been requisitioned to decontaminate the afflicted places."},
{TR_TOOLTIP_OVERLAY_HEALTH_NONE, "No citizen lives here yet"},
{TR_TOOLTIP_OVERLAY_HEALTH_0, "Health in this house is appalling (0-9)"},
{TR_TOOLTIP_OVERLAY_HEALTH_1, "Health in this house is terrible (10-19)"},
{TR_TOOLTIP_OVERLAY_HEALTH_2, "Health in this house is bad (20-29)"},
{TR_TOOLTIP_OVERLAY_HEALTH_3, "Health in this house is poor (30-39)"},
{TR_TOOLTIP_OVERLAY_HEALTH_4, "Health in this house is below average (40-49)"},
{TR_TOOLTIP_OVERLAY_HEALTH_5, "Health in this house is average (50-59)"},
{TR_TOOLTIP_OVERLAY_HEALTH_6, "Health in this house is good (60-69)"},
{TR_TOOLTIP_OVERLAY_HEALTH_7, "Health in this house is very good (70-79)"},
{TR_TOOLTIP_OVERLAY_HEALTH_8, "Health in this house is excellent (80-89)"},
{TR_TOOLTIP_OVERLAY_HEALTH_9, "Health in this house is almost perfect (90-99)"},
{TR_TOOLTIP_OVERLAY_HEALTH_10, "Health in this house is perfect (100)"},
{TR_TOOLTIP_OVERLAY_SICKNESS_NONE, "No disease"},
{TR_TOOLTIP_OVERLAY_SICKNESS_LOW, "Very few diseases"},
{TR_TOOLTIP_OVERLAY_SICKNESS_MEDIUM, "A few infectious diseases"},
Expand Down Expand Up @@ -825,6 +838,7 @@ static translation_string all_strings[] = {
{TR_HOTKEY_SHOW_OVERLAY_SCHOOL, "Schools overlay" },
{TR_HOTKEY_SHOW_OVERLAY_LIBRARY, "Library overlay" },
{TR_HOTKEY_SHOW_OVERLAY_ACADEMY, "Academy overlay" },
{TR_HOTKEY_SHOW_OVERLAY_HEALTH, "Health overlay" },
{TR_HOTKEY_SHOW_OVERLAY_BARBER, "Barber overlay" },
{TR_HOTKEY_SHOW_OVERLAY_BATHHOUSE, "Baths overlay" },
{TR_HOTKEY_SHOW_OVERLAY_CLINIC, "Clinics overlay" },
Expand Down
14 changes: 14 additions & 0 deletions src/translation/translation.h
Original file line number Diff line number Diff line change
Expand Up @@ -783,13 +783,26 @@ typedef enum {
TR_BUILDING_WAREHOUSE_NO_GOODS,
TR_BUILDING_HOUSE_DISEASE_DESC,
TR_BUILDING_FUMIGATION_DESC,
TR_OVERLAY_HEALTH,
TR_OVERLAY_SICKNESS,
TR_ADVISOR_HEALTH_RATING,
TR_ADVISOR_HEALTH_SURVEILLANCE,
TR_ADVISOR_SICKNESS_LEVEL_LOW,
TR_ADVISOR_SICKNESS_LEVEL_MEDIUM,
TR_ADVISOR_SICKNESS_LEVEL_HIGH,
TR_ADVISOR_SICKNESS_LEVEL_PLAGUE,
TR_TOOLTIP_OVERLAY_HEALTH_NONE,
TR_TOOLTIP_OVERLAY_HEALTH_0,
TR_TOOLTIP_OVERLAY_HEALTH_1,
TR_TOOLTIP_OVERLAY_HEALTH_2,
TR_TOOLTIP_OVERLAY_HEALTH_3,
TR_TOOLTIP_OVERLAY_HEALTH_4,
TR_TOOLTIP_OVERLAY_HEALTH_5,
TR_TOOLTIP_OVERLAY_HEALTH_6,
TR_TOOLTIP_OVERLAY_HEALTH_7,
TR_TOOLTIP_OVERLAY_HEALTH_8,
TR_TOOLTIP_OVERLAY_HEALTH_9,
TR_TOOLTIP_OVERLAY_HEALTH_10,
TR_TOOLTIP_OVERLAY_SICKNESS_NONE,
TR_TOOLTIP_OVERLAY_SICKNESS_LOW,
TR_TOOLTIP_OVERLAY_SICKNESS_MEDIUM,
Expand Down Expand Up @@ -820,6 +833,7 @@ typedef enum {
TR_HOTKEY_SHOW_OVERLAY_SCHOOL,
TR_HOTKEY_SHOW_OVERLAY_LIBRARY,
TR_HOTKEY_SHOW_OVERLAY_ACADEMY,
TR_HOTKEY_SHOW_OVERLAY_HEALTH,
TR_HOTKEY_SHOW_OVERLAY_BARBER,
TR_HOTKEY_SHOW_OVERLAY_BATHHOUSE,
TR_HOTKEY_SHOW_OVERLAY_CLINIC,
Expand Down
82 changes: 82 additions & 0 deletions src/widget/city_overlay_health.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
#include "game/state.h"
#include "translation/translation.h"

static int show_building_health(const building *b)
{
return b->type == BUILDING_HOSPITAL || b->type == BUILDING_DOCTOR ||
b->type == BUILDING_BARBER || b->type == BUILDING_BATHHOUSE ||
b->type == BUILDING_SMALL_MAUSOLEUM || b->type == BUILDING_LARGE_MAUSOLEUM;
}

static int show_building_barber(const building *b)
{
return b->type == BUILDING_BARBER;
Expand Down Expand Up @@ -31,6 +38,12 @@ static int show_building_sickness(const building *b)
b->type == BUILDING_SMALL_MAUSOLEUM || b->type == BUILDING_LARGE_MAUSOLEUM;
}

static int show_figure_health(const figure *f)
{
return f->type == FIGURE_SURGEON || f->type == FIGURE_DOCTOR ||
f->type == FIGURE_BARBER || f->type == FIGURE_BATHHOUSE_WORKER;
}

static int show_figure_barber(const figure *f)
{
return f->type == FIGURE_BARBER;
Expand Down Expand Up @@ -69,6 +82,17 @@ static int show_figure_sickness(const figure *f)
return 0;
}

static int get_column_height_health(const building *b)
{
int house_health = city_health_get_house_health_level(b);

if (b->house_population > 0 && house_health < 1 ) {
house_health += 1;
}

return b->house_size && house_health ? house_health / 10 : NO_COLUMN;
}

static int get_column_height_barber(const building *b)
{
return b->house_size && b->data.house.barber ? b->data.house.barber / 10 : NO_COLUMN;
Expand All @@ -94,6 +118,48 @@ static int get_column_height_sickness(const building *b)
return b->sickness_level ? b->sickness_level / 10 : NO_COLUMN;
}

static int get_tooltip_health(tooltip_context *c, const building *b)
{
if (building_is_house(b->type)) {
int house_health = city_health_get_house_health_level(b);

if (house_health < 40) {
if (b->house_population < 1 && house_health < 1) {
c->translation_key = TR_TOOLTIP_OVERLAY_HEALTH_NONE;
} else if (b->house_population >= 1 && house_health < 10) {
c->translation_key = TR_TOOLTIP_OVERLAY_HEALTH_0;
} else if (house_health < 20) {
c->translation_key = TR_TOOLTIP_OVERLAY_HEALTH_1;
} else if (house_health < 30) {
c->translation_key = TR_TOOLTIP_OVERLAY_HEALTH_2;
} else {
c->translation_key = TR_TOOLTIP_OVERLAY_HEALTH_3;
}
} else if (house_health < 60) {
if (house_health < 50) {
c->translation_key = TR_TOOLTIP_OVERLAY_HEALTH_4;
} else {
c->translation_key = TR_TOOLTIP_OVERLAY_HEALTH_5;
}
} else if (house_health < 80) {
if (house_health < 70) {
c->translation_key = TR_TOOLTIP_OVERLAY_HEALTH_6;
} else {
c->translation_key = TR_TOOLTIP_OVERLAY_HEALTH_7;
}
} else if (house_health < 100) {
if (house_health < 90) {
c->translation_key = TR_TOOLTIP_OVERLAY_HEALTH_8;
} else {
c->translation_key = TR_TOOLTIP_OVERLAY_HEALTH_9;
}
} else {
c->translation_key = TR_TOOLTIP_OVERLAY_HEALTH_10;
}
}
return 0;
}

static int get_tooltip_barber(tooltip_context *c, const building *b)
{
if (b->data.house.barber <= 0) {
Expand Down Expand Up @@ -165,6 +231,22 @@ static int get_tooltip_sickness(tooltip_context *c, const building *b)
return 0;
}

const city_overlay *city_overlay_for_health(void)
{
static city_overlay overlay = {
OVERLAY_HEALTH,
COLUMN_COLOR_GREEN_TO_RED,
show_building_health,
show_figure_health,
get_column_height_health,
0,
get_tooltip_health,
0,
0
};
return &overlay;
}

const city_overlay *city_overlay_for_barber(void)
{
static city_overlay overlay = {
Expand Down
2 changes: 2 additions & 0 deletions src/widget/city_overlay_health.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include "city_overlay.h"

const city_overlay *city_overlay_for_health(void);

const city_overlay *city_overlay_for_bathhouse(void);

const city_overlay *city_overlay_for_barber(void);
Expand Down
6 changes: 5 additions & 1 deletion src/widget/city_with_overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ static const city_overlay *get_city_overlay(void)
return city_overlay_for_library();
case OVERLAY_ACADEMY:
return city_overlay_for_academy();
case OVERLAY_HEALTH:
return city_overlay_for_health();
case OVERLAY_BARBER:
return city_overlay_for_barber();
case OVERLAY_BATHHOUSE:
Expand Down Expand Up @@ -704,7 +706,9 @@ int city_with_overlay_get_tooltip_text(tooltip_context *c, int grid_offset)
overlay_type != OVERLAY_WATER && overlay_type != OVERLAY_FIRE && overlay_type != OVERLAY_LEVY &&
overlay_type != OVERLAY_DAMAGE && overlay_type != OVERLAY_NATIVE && overlay_type != OVERLAY_DESIRABILITY &&
overlay_type != OVERLAY_PROBLEMS && overlay_type != OVERLAY_MOTHBALL && overlay_type != OVERLAY_ENEMY &&
overlay_type != OVERLAY_LOGISTICS && overlay_type != OVERLAY_SICKNESS && overlay_type != OVERLAY_EFFICIENCY;
overlay_type != OVERLAY_LOGISTICS && overlay_type != OVERLAY_SICKNESS && overlay_type != OVERLAY_EFFICIENCY &&
overlay_type != OVERLAY_HEALTH
;
building *b = building_get(building_id);
if (overlay_requires_house && !b->house_size) {
return 0;
Expand Down
1 change: 1 addition & 0 deletions src/window/hotkey_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ static hotkey_widget hotkey_widgets[] = {
{HOTKEY_SHOW_OVERLAY_SCHOOL, TR_HOTKEY_SHOW_OVERLAY_SCHOOL},
{HOTKEY_SHOW_OVERLAY_LIBRARY, TR_HOTKEY_SHOW_OVERLAY_LIBRARY},
{HOTKEY_SHOW_OVERLAY_ACADEMY, TR_HOTKEY_SHOW_OVERLAY_ACADEMY},
{HOTKEY_SHOW_OVERLAY_HEALTH, TR_HOTKEY_SHOW_OVERLAY_HEALTH},
{HOTKEY_SHOW_OVERLAY_BARBER, TR_HOTKEY_SHOW_OVERLAY_BARBER},
{HOTKEY_SHOW_OVERLAY_BATHHOUSE, TR_HOTKEY_SHOW_OVERLAY_BATHHOUSE},
{HOTKEY_SHOW_OVERLAY_CLINIC, TR_HOTKEY_SHOW_OVERLAY_CLINIC},
Expand Down
4 changes: 2 additions & 2 deletions src/window/overlay_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ static generic_button submenu_buttons[] = {

static const int MENU_ID_TO_OVERLAY[OVERLAY_BUTTONS] = { OVERLAY_NONE, OVERLAY_WATER, 1, 3, 5, 6, 7, OVERLAY_RELIGION, OVERLAY_ROADS, OVERLAY_DESIRABILITY, OVERLAY_SENTIMENT };
static const int MENU_ID_TO_SUBMENU_ID[OVERLAY_BUTTONS] = { 0, 0, 1, 2, 3, 4, 5, 0, 0 };
static const int ADDITIONAL_OVERLAY_TR[] = { TR_OVERLAY_ROADS, TR_OVERLAY_LEVY, TR_OVERLAY_TAVERN, TR_OVERLAY_ARENA_COL, TR_OVERLAY_SENTIMENT, TR_OVERLAY_MOTHBALL, TR_OVERLAY_ENEMY, TR_OVERLAY_LOGISTICS, TR_OVERLAY_SICKNESS, TR_OVERLAY_EFFICIENCY, TR_OVERLAY_STORAGES };
static const int ADDITIONAL_OVERLAY_TR[] = { TR_OVERLAY_ROADS, TR_OVERLAY_LEVY, TR_OVERLAY_TAVERN, TR_OVERLAY_ARENA_COL, TR_OVERLAY_SENTIMENT, TR_OVERLAY_MOTHBALL, TR_OVERLAY_ENEMY, TR_OVERLAY_LOGISTICS, TR_OVERLAY_SICKNESS, TR_OVERLAY_EFFICIENCY, TR_OVERLAY_STORAGES, TR_OVERLAY_HEALTH };

static const int SUBMENU_ID_TO_OVERLAY[6][OVERLAY_BUTTONS] = {
{0},
{OVERLAY_FIRE, OVERLAY_DAMAGE, OVERLAY_CRIME, OVERLAY_NATIVE, OVERLAY_PROBLEMS, OVERLAY_ENEMY, 0},
{OVERLAY_ENTERTAINMENT, OVERLAY_TAVERN, OVERLAY_THEATER, OVERLAY_AMPHITHEATER, OVERLAY_ARENA, OVERLAY_COLOSSEUM, OVERLAY_HIPPODROME, 0},
{OVERLAY_EDUCATION, OVERLAY_SCHOOL, OVERLAY_LIBRARY, OVERLAY_ACADEMY, 0},
{OVERLAY_BARBER, OVERLAY_BATHHOUSE, OVERLAY_CLINIC, OVERLAY_HOSPITAL, OVERLAY_SICKNESS, 0},
{OVERLAY_HEALTH, OVERLAY_BARBER, OVERLAY_BATHHOUSE, OVERLAY_CLINIC, OVERLAY_HOSPITAL, OVERLAY_SICKNESS, 0},
{OVERLAY_TAX_INCOME, OVERLAY_LEVY, OVERLAY_EFFICIENCY, OVERLAY_FOOD_STOCKS, OVERLAY_MOTHBALL, OVERLAY_LOGISTICS, 0},
};

Expand Down

0 comments on commit cf17d95

Please sign in to comment.