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/world.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 9 deletions(-) (limited to 'src/world.c') 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