summaryrefslogtreecommitdiff
path: root/src/world.c
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrikboy@gmail.com>2024-12-01 09:37:37 +0100
committerAldrik Ramaekers <aldrikboy@gmail.com>2024-12-01 09:37:37 +0100
commit6da1c3d002cf52ba2de729da1b875ea2dfeec8b0 (patch)
treeba4b55841cb1fa33c26906233c6348f18e5dea93 /src/world.c
parentc43f1674df9c3bbd4123be4eadb3fb6124bdb548 (diff)
random events
Diffstat (limited to 'src/world.c')
-rw-r--r--src/world.c111
1 files changed, 102 insertions, 9 deletions
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++)