From 6da1c3d002cf52ba2de729da1b875ea2dfeec8b0 Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Sun, 1 Dec 2024 09:37:37 +0100 Subject: random events --- src/include/world.h | 3 +- src/main.c | 7 ++++ src/scenes/world_map.c | 1 + src/world.c | 111 +++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 112 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/include/world.h b/src/include/world.h index 7e6f149..2d58f3b 100644 --- a/src/include/world.h +++ b/src/include/world.h @@ -49,7 +49,7 @@ typedef struct t_employee employee; #define DIESEL_PRICE_PER_LITER 1.4f #define INVALID_ID 0 -#define MAX_WORKED_HOURS_WEEKLY (45.0f) +#define MAX_WORKED_HOURS_WEEKLY (50.0f) #define MINIMUM_EMPLOYEE_HAPPINESS (0.4f) #define EMPLOYEE_MAX_UNHAPPY_DAYS_BEFORE_QUITTING (30.0f) @@ -268,6 +268,7 @@ typedef enum t_event_type EVENT_TYPE_MISSED_SHIPMENT_NOT_AT_LOCATION, // go to schedule EVENT_TYPE_MISSED_SHIPMENT_NO_ASSIGNEE, // go to schedule EVENT_TYPE_EMPLOYEE_QUIT, // go to schedule + EVENT_TYPE_FINED, // go to employee detail } event_type; #define MAX_EVENT_MESSAGE_LENGTH 200 diff --git a/src/main.c b/src/main.c index 0a4e2bd..41a47ba 100644 --- a/src/main.c +++ b/src/main.c @@ -99,6 +99,13 @@ static void draw_debug_overlay(platform_window* window) sprintf(deltabuf, "FPS: %.0f", 1.0f/frame_delta); renderer->render_text(fnt, 10, 10+(fnt->px_h+2)*2, deltabuf, rgb(255,0,0)); } + if (_active_world) { + char deltabuf[30]; + sprintf(deltabuf, "Random event: %d", _active_world->days_since_last_random_event); + renderer->render_text(fnt, 10, 10+(fnt->px_h+2)*3, deltabuf, rgb(255,0,0)); + } + + renderer->set_render_depth(19); } diff --git a/src/scenes/world_map.c b/src/scenes/world_map.c index 2cf7446..57c1500 100644 --- a/src/scenes/world_map.c +++ b/src/scenes/world_map.c @@ -672,6 +672,7 @@ static void world_map_draw_event_log(platform_window* window) if (is_left_clicked()) { switch (e->type) { + case EVENT_TYPE_FINED: case EVENT_TYPE_MISSED_SHIPMENT_NO_TRUCK: place_detail_show_employee_detail((employee*)e->data); break; diff --git a/src/world.c b/src/world.c index bae50d9..e94e7c3 100644 --- a/src/world.c +++ b/src/world.c @@ -8,6 +8,8 @@ static vec2f get_world_location_for_job(platform_window* window, world* world, a static employee* get_employee_by_id(world_location* location, u32 id); static void end_contract_with_employee(world* world, employee* emp); vec2f px_to_coords(platform_window* window, double x, double y); +static bool world_check_location_accessibility(world_location* orig, world_location* source, int depth, double dist); +static void world_update_location_scores(world* world); float dotsize = 5; @@ -562,7 +564,7 @@ world* world_create_new() new_world->active_jobs = array_create(sizeof(active_job)); new_world->investments = (company_investments){0}; new_world->simulation_speed = 1; - new_world->days_since_last_random_event = 300;//-365; // No random events in the first year. + new_world->days_since_last_random_event = 0;//-365; // No random events in the first year. new_world->log.events = array_create(sizeof(event)); new_world->log.write_cursor = 0; new_world->log.has_unread_messages = false; @@ -618,6 +620,7 @@ world* world_create_new() world_assign_new_job_offers(new_world, true); enable_insights_for_current_month(new_world); + world_update_location_scores(new_world); return new_world; } @@ -1174,6 +1177,89 @@ static void enable_insights_for_current_month(world* world) } } +static world_location* get_random_owned_location(world* world) +{ + s32 count = 0; + for (s32 i = 0; i < world->locations.length; i++) + { + world_location* location = array_at(&world->locations, i); + if (!location->is_owned) continue; + count++; + } + + s32 rand_nr = get_random_number(0, count); + + for (s32 i = 0; i < world->locations.length; i++) + { + world_location* location = array_at(&world->locations, i); + if (!location->is_owned) continue; + if (i == rand_nr) return location; + } + return 0; +} + +static void end_contract_with_random_employee(world* world) +{ + world_location* location = get_random_owned_location(world); + employee* emp = *(employee**)array_at(&location->employees, get_random_number(0, location->employees.length)); + + char error_msg[MAX_EVENT_MESSAGE_LENGTH]; + snprintf(error_msg, MAX_EVENT_MESSAGE_LENGTH, "%s quit their job. Their routes need a new assignee!", emp->name); + world_report_event(world, error_msg, EVENT_TYPE_EMPLOYEE_QUIT, get_world_location_by_id(world, emp->original_location_id)); + end_contract_with_employee(world, emp); +} + +static void end_contract_with_random_job(world* world) +{ + world_location* location = get_random_owned_location(world); + if (location->schedule.jobs.length == 0) return; + scheduled_job* scheduled_job = array_at(&location->schedule.jobs, get_random_number(0, location->schedule.jobs.length)); + + char error_msg[MAX_EVENT_MESSAGE_LENGTH]; + snprintf(error_msg, MAX_EVENT_MESSAGE_LENGTH, "%s cancelled a contract for location %s.", scheduled_job->offer.company->name, location->name); + world_report_event(world, error_msg, EVENT_TYPE_EMPLOYEE_QUIT,location); + + array_remove_by(&location->schedule.jobs, scheduled_job); +} + +static void give_random_fine(world* world) +{ + world_location* location = get_random_owned_location(world); + employee* emp = *(employee**)array_at(&location->employees, get_random_number(0, location->employees.length)); + + s32 fine = get_random_number(world->money / 20, world->money / 10); // fine is between 5% and 10% of current money. minimum 2k. + if (fine < 2000) fine = 2000; + + char error_msg[MAX_EVENT_MESSAGE_LENGTH]; + s32 rand_event = get_random_number(0, 3); + switch(rand_event) { + case 0: snprintf(error_msg, MAX_EVENT_MESSAGE_LENGTH, "You were fined $%d because %s did not use their tachograph correctly.", fine, emp->name); break; + case 1: snprintf(error_msg, MAX_EVENT_MESSAGE_LENGTH, "You were fined $%d because %s did not secure their load correctly.", fine, emp->name); break; + case 2: snprintf(error_msg, MAX_EVENT_MESSAGE_LENGTH, "You were fined $%d because %s had the incorrect shipping papers on their trip.", fine, emp->name); break; + } + world->money -= fine; + ADD_EXPENSE(world, location, expenses_from_utility, fine); + world_report_event(world, error_msg, EVENT_TYPE_FINED, emp); +} + +static void brake_down_random_truck(world* world) +{ + retry:; + world_location* location = get_random_owned_location(world); + employee* emp = *(employee**)array_at(&location->employees, get_random_number(0, location->employees.length)); + + if (emp->assigned_truck == 0) goto retry; + + s32 fine = emp->assigned_truck->price / 5.0f; + + char error_msg[MAX_EVENT_MESSAGE_LENGTH]; + snprintf(error_msg, MAX_EVENT_MESSAGE_LENGTH, "%s's truck broke down and was repaired for $%d", emp->name, fine); + + world->money -= fine; + ADD_EXPENSE(world, location, expenses_from_repairs, fine); + world_report_event(world, error_msg, EVENT_TYPE_FINED, emp); +} + static void world_start_random_events(world* world) { world->days_since_last_random_event++; @@ -1181,15 +1267,24 @@ static void world_start_random_events(world* world) // Minor events { #define MIN_DELAY_BETWEEN_EVENTS (60) - float change_of_random_event = 0.0f; + float chance_of_random_event = 0.0f; if (world->days_since_last_random_event > MIN_DELAY_BETWEEN_EVENTS) { - change_of_random_event = ((world->days_since_last_random_event - MIN_DELAY_BETWEEN_EVENTS)*0.5f)/100.0f; - if (change_of_random_event > 1.0f) change_of_random_event = 1.0f; + chance_of_random_event = ((world->days_since_last_random_event - MIN_DELAY_BETWEEN_EVENTS)*0.5f)/100.0f; + if (chance_of_random_event > 1.0f) chance_of_random_event = 1.0f; - bool run_event = change_of_random_event >= (get_random_number(0, 100)/100.0f); + bool run_event = chance_of_random_event >= (get_random_number(0, 100)/100.0f); - //world_report_event(world, "Random event", ); - (void)run_event; // TODO start event. + if (run_event) { + s32 rand_event = get_random_number(0, 4); + switch(rand_event) { + case 0: end_contract_with_random_employee(world); break; + case 1: end_contract_with_random_job(world); break; + case 2: give_random_fine(world); break; + case 3: brake_down_random_truck(world); break; + } + + world->days_since_last_random_event = 0; + } } } } @@ -1231,8 +1326,6 @@ static void end_contract_with_employee(world* world, employee* emp) if (curr_loc) array_remove_by(&curr_loc->employees, &emp); } -static bool world_check_location_accessibility(world_location* orig, world_location* source, int depth, double dist); - static void world_update_location_scores(world* world) { for (s32 i = 0; i < world->locations.length; i++) -- cgit v1.2.3-70-g09d2