diff options
| author | Aldrik Ramaekers <aldrikboy@gmail.com> | 2024-12-01 09:37:37 +0100 |
|---|---|---|
| committer | Aldrik Ramaekers <aldrikboy@gmail.com> | 2024-12-01 09:37:37 +0100 |
| commit | 6da1c3d002cf52ba2de729da1b875ea2dfeec8b0 (patch) | |
| tree | ba4b55841cb1fa33c26906233c6348f18e5dea93 /src | |
| parent | c43f1674df9c3bbd4123be4eadb3fb6124bdb548 (diff) | |
random events
Diffstat (limited to 'src')
| -rw-r--r-- | src/include/world.h | 3 | ||||
| -rw-r--r-- | src/main.c | 7 | ||||
| -rw-r--r-- | src/scenes/world_map.c | 1 | ||||
| -rw-r--r-- | src/world.c | 111 |
4 files changed, 112 insertions, 10 deletions
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
@@ -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++)
|
