mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-28 19:11:37 +00:00
Random Event Overhaul
Alters the event controller based on http://baystation12.net/forums/viewtopic.php?f=5&t=10706. Exception is that there is always some start time variance to prevent metagaming. Mundane, moderate, and major events run on their own timers and start and run independantly of each other. Multiple events of the same severity degree can run at the same time. However, currently only one instance of the same event can be active at a time.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
|
||||
/datum/event/economic_event
|
||||
name = "Economic event"
|
||||
endWhen = 50 //this will be set randomly, later
|
||||
announceWhen = 15
|
||||
var/event_type = 0
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
/datum/event/mundane_news
|
||||
name = "Mundande news"
|
||||
endWhen = 10
|
||||
|
||||
/datum/event/mundane_news/announce()
|
||||
@@ -127,6 +128,7 @@
|
||||
news_network.add_news("Nyx Daily", newMsg)
|
||||
|
||||
/datum/event/trivial_news
|
||||
name = "Trivial news"
|
||||
endWhen = 10
|
||||
|
||||
/datum/event/trivial_news/announce()
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/datum/event/carp_migration
|
||||
name = "Carp Migration"
|
||||
announceWhen = 50
|
||||
oneShot = 1
|
||||
endWhen = 900
|
||||
endWhen = 900
|
||||
|
||||
var/list/spawned_carp = list()
|
||||
|
||||
/datum/event/carp_migration/setup()
|
||||
@@ -9,12 +11,28 @@
|
||||
endWhen = rand(600,1200)
|
||||
|
||||
/datum/event/carp_migration/announce()
|
||||
command_announcement.Announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
|
||||
var/announcement = ""
|
||||
if(severity == EVENT_LEVEL_MAJOR)
|
||||
announcement = "Massive migration of unknown biological entities has been detected near [station_name()], please stand-by."
|
||||
else
|
||||
announcement = "Unknown biological [spawned_carp.len == 1 ? "entity has" : "entities have"] been detected near [station_name()], please stand-by."
|
||||
command_announcement.Announce(announcement, "Lifesign Alert")
|
||||
|
||||
/datum/event/carp_migration/start()
|
||||
if(severity == EVENT_LEVEL_MAJOR)
|
||||
for(var/i = 1 to rand(3,5))
|
||||
spawn_fish(landmarks_list.len)
|
||||
else if(severity == EVENT_LEVEL_MODERATE)
|
||||
spawn_fish(landmarks_list.len)
|
||||
else
|
||||
spawn_fish(rand(1, 5))
|
||||
|
||||
/datum/event/carp_migration/proc/spawn_fish(var/limit)
|
||||
for(var/obj/effect/landmark/C in landmarks_list)
|
||||
if(C.name == "carpspawn")
|
||||
spawned_carp.Add(new /mob/living/simple_animal/hostile/carp(C.loc))
|
||||
if(spawned_carp.len >= limit)
|
||||
return
|
||||
|
||||
/datum/event/carp_migration/end()
|
||||
for(var/mob/living/simple_animal/hostile/carp/C in spawned_carp)
|
||||
|
||||
@@ -1,10 +1,56 @@
|
||||
/datum/event_meta
|
||||
var/weight = 1
|
||||
var/min_weight = 1
|
||||
var/max_weight = 1
|
||||
var/severity = 0
|
||||
var/has_fired = 0
|
||||
var/list/role_weights = list()
|
||||
var/datum/event/event_type
|
||||
|
||||
/datum/event_meta/New(var/event_severity, var/datum/event/type, var/event_weight, var/list/job_weights, var/min_event_weight, var/max_event_weight)
|
||||
severity = event_severity
|
||||
event_type = type
|
||||
weight = event_weight
|
||||
if(job_weights)
|
||||
role_weights = job_weights
|
||||
|
||||
/datum/event_meta/proc/get_weight(var/list/active_with_role)
|
||||
var/job_weight = 0
|
||||
for(var/role in role_weights)
|
||||
job_weight = active_with_role[role] * role_weights[role]
|
||||
|
||||
var/total_weight = weight + job_weight
|
||||
|
||||
// Only min/max the weight if the values are set
|
||||
if(min_weight && total_weight < min_weight) total_weight = min_weight
|
||||
if(max_weight && total_weight > max_weight) total_weight = max_weight
|
||||
|
||||
return total_weight
|
||||
|
||||
/datum/event_meta/alien/get_weight(var/list/active_with_role)
|
||||
if(aliens_allowed)
|
||||
return ..(active_with_role)
|
||||
return 0
|
||||
|
||||
/datum/event_meta/ninja/get_weight(var/list/active_with_role)
|
||||
if(toggle_space_ninja)
|
||||
return ..(active_with_role)
|
||||
return 0
|
||||
|
||||
/datum/event //NOTE: Times are measured in master controller ticks!
|
||||
var/name = ""//Name of the event
|
||||
var/startWhen = 0 //When in the lifetime to call start().
|
||||
var/announceWhen = 0 //When in the lifetime to call announce().
|
||||
var/endWhen = 0 //When in the lifetime the event should end.
|
||||
var/oneShot = 0 //If true, then the event removes itself from the list of potential events on creation.
|
||||
|
||||
var/severity = 0 //Severity. Lower means less severe, higher means more severe. Does not have to be supported. Is set on New().
|
||||
var/activeFor = 0 //How long the event has existed. You don't need to change this.
|
||||
var/isRunning = 1 //If this event is currently running. You should not change this.
|
||||
var/datum/event_meta/event_meta = null
|
||||
|
||||
/datum/event/nothing
|
||||
name = "Nothing"
|
||||
|
||||
//Called first before processing.
|
||||
//Allows you to setup your event, such as randomly
|
||||
@@ -42,21 +88,21 @@
|
||||
return
|
||||
|
||||
|
||||
|
||||
//Do not override this proc, instead use the appropiate procs.
|
||||
//This proc will handle the calls to the appropiate procs.
|
||||
/datum/event/proc/process()
|
||||
|
||||
if(activeFor > startWhen && activeFor < endWhen)
|
||||
tick()
|
||||
|
||||
if(activeFor == startWhen)
|
||||
isRunning = 1
|
||||
start()
|
||||
|
||||
if(activeFor == announceWhen)
|
||||
announce()
|
||||
|
||||
if(activeFor == endWhen)
|
||||
isRunning = 0
|
||||
end()
|
||||
|
||||
// Everything is done, let's clean up.
|
||||
@@ -65,19 +111,24 @@
|
||||
|
||||
activeFor++
|
||||
|
||||
|
||||
//Garbage collects the event by removing it from the global events list,
|
||||
//which should be the only place it's referenced.
|
||||
//Called when start(), announce() and end() has all been called.
|
||||
/datum/event/proc/kill()
|
||||
events.Remove(src)
|
||||
// If this event was forcefully killed run end() for individual cleanup
|
||||
if(isRunning)
|
||||
isRunning = 0
|
||||
end()
|
||||
|
||||
event_manager.active_events -= src
|
||||
event_manager.event_complete(src)
|
||||
|
||||
/datum/event/New(var/datum/event_meta/EM)
|
||||
// event needs to be responsible for this, as stuff like APLUs currently make their own events for curious reasons
|
||||
event_manager.active_events += src
|
||||
|
||||
event_meta = EM
|
||||
severity = event_meta.severity
|
||||
if(severity < EVENT_LEVEL_MUNDANE) severity = EVENT_LEVEL_MUNDANE
|
||||
if(severity > EVENT_LEVEL_MAJOR) severity = EVENT_LEVEL_MAJOR
|
||||
|
||||
//Adds the event to the global events list, and removes it from the list
|
||||
//of potential events.
|
||||
/datum/event/New()
|
||||
setup()
|
||||
events.Add(src)
|
||||
/*if(oneShot)
|
||||
potentialRandomEvents.Remove(type)*/
|
||||
..()
|
||||
|
||||
@@ -187,7 +187,7 @@ var/list/event_last_fired = list()
|
||||
// Returns how many characters are currently active(not logged out, not AFK for more than 10 minutes)
|
||||
// with a specific role.
|
||||
// Note that this isn't sorted by department, because e.g. having a roboticist shouldn't make meteors spawn.
|
||||
/proc/number_active_with_role(role)
|
||||
/proc/number_active_with_role()
|
||||
var/list/active_with_role = list()
|
||||
active_with_role["Engineer"] = 0
|
||||
active_with_role["Medical"] = 0
|
||||
@@ -197,6 +197,7 @@ var/list/event_last_fired = list()
|
||||
active_with_role["Cyborg"] = 0
|
||||
active_with_role["Janitor"] = 0
|
||||
active_with_role["Gardener"] = 0
|
||||
active_with_role["Any"] = player_list.len
|
||||
|
||||
for(var/mob/M in player_list)
|
||||
if(!M.mind || !M.client || M.client.inactivity > 10 * 10 * 60) // longer than 10 minutes AFK counts them as inactive
|
||||
|
||||
@@ -1,23 +1,130 @@
|
||||
var/list/allEvents = typesof(/datum/event) - /datum/event
|
||||
var/list/potentialRandomEvents = typesof(/datum/event) - /datum/event
|
||||
//var/list/potentialRandomEvents = typesof(/datum/event) - /datum/event - /datum/event/spider_infestation - /datum/event/alien_infestation
|
||||
#define ASSIGNMENT_ANY "Any"
|
||||
#define ASSIGNMENT_AI "AI"
|
||||
#define ASSIGNMENT_CYBORG "Cyborg"
|
||||
#define ASSIGNMENT_ENGINEER "Engineer"
|
||||
#define ASSIGNMENT_GARDENER "Gardener"
|
||||
#define ASSIGNMENT_JANITOR "Janitor"
|
||||
#define ASSIGNMENT_MEDICAL "Medical"
|
||||
#define ASSIGNMENT_SCIENTIST "Scientist"
|
||||
#define ASSIGNMENT_SECURITY "Security"
|
||||
|
||||
var/eventTimeLower = 12000 //20 minutes
|
||||
var/eventTimeUpper = 24000 //40 minutes
|
||||
var/scheduledEvent = null
|
||||
/datum/event_manager
|
||||
var/list/available_events = list(
|
||||
EVENT_LEVEL_MUNDANE = list(
|
||||
// Severity level, even type, base weight, role weights, min weight, max weight. Last two only used if set and non-zero
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 25, 200),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 5, 50),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/money_hacker, 0, list(ASSIGNMENT_ANY = 4), 25, 200),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/economic_event, 300),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/trivial_news, 400),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/mundane_news, 300),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/carp_migration, 20, list(ASSIGNMENT_SECURITY = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/brand_intelligence, 20, list(ASSIGNMENT_JANITOR = 25)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)),
|
||||
),
|
||||
EVENT_LEVEL_MODERATE = list(
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/nothing, 10),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/carp_migration, 20, list(ASSIGNMENT_SECURITY = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/rogue_drone, 5, list(ASSIGNMENT_ENGINEER = 25, ASSIGNMENT_SECURITY = 25)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/spacevine, 10, list(ASSIGNMENT_ENGINEER = 5)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/meteor_shower, 0, list(ASSIGNMENT_ENGINEER = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/communications_blackout, 50, list(ASSIGNMENT_AI = 25, ASSIGNMENT_SECURITY = 25)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/grid_check, 25, list(ASSIGNMENT_ENGINEER = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/electrical_storm, 15, list(ASSIGNMENT_ENGINEER = 5, ASSIGNMENT_JANITOR = 15)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/radiation_storm, 0, list(ASSIGNMENT_MEDICAL = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/spontaneous_appendicitis, 0, list(ASSIGNMENT_MEDICAL = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/spider_infestation, 5, list(ASSIGNMENT_SECURITY = 5)),
|
||||
new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, /datum/event/alien_infestation, 2.5,list(ASSIGNMENT_SECURITY = 1), max_event_weight = 5),
|
||||
new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 1), max_event_weight = 5),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 25, ASSIGNMENT_CYBORG = 25, ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_SCIENTIST = 5)),
|
||||
),
|
||||
EVENT_LEVEL_MAJOR = list(
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/nothing, 100),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 10)),
|
||||
)
|
||||
)
|
||||
|
||||
var/list/datum/event/active_events = list()
|
||||
var/list/datum/event/finished_events = list()
|
||||
|
||||
//Currently unused. Needs an admin panel for messing with events.
|
||||
/*/proc/addPotentialEvent(var/type)
|
||||
potentialRandomEvents |= type
|
||||
var/list/datum/event/allEvents
|
||||
|
||||
/proc/removePotentialEvent(var/type)
|
||||
potentialRandomEvents -= type*/
|
||||
var/list/last_event_time = list()
|
||||
var/list/next_event_time = list(EVENT_LEVEL_MUNDANE = 1, EVENT_LEVEL_MODERATE = 0, EVENT_LEVEL_MAJOR = 0)
|
||||
var/list/delay_modifier = list(EVENT_LEVEL_MUNDANE = 1, EVENT_LEVEL_MODERATE = 1, EVENT_LEVEL_MAJOR = 1)
|
||||
|
||||
/datum/event_manager/New()
|
||||
allEvents = typesof(/datum/event) - /datum/event
|
||||
|
||||
/proc/checkEvent()
|
||||
if(!scheduledEvent)
|
||||
//more players = more time between events, less players = less time between events
|
||||
/datum/event_manager/proc/process()
|
||||
for(var/datum/event/E in event_manager.active_events)
|
||||
E.process()
|
||||
|
||||
for(var/i = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
|
||||
if(next_event_time[i] == 0)
|
||||
// Our first time running, setup start times
|
||||
set_event_delay(i)
|
||||
else
|
||||
// Is it time to fire a new event of this severity level?
|
||||
if(world.timeofday > next_event_time[i])
|
||||
start_event(i)
|
||||
|
||||
/datum/event_manager/proc/start_event(var/severity)
|
||||
var/datum/event_meta/EM = acquire_event(available_events[severity])
|
||||
if(!EM)
|
||||
// If no event was available now, check again in one minute (rather than next process tick)
|
||||
next_event_time[severity] = next_event_time[severity] + (60 * 10)
|
||||
return
|
||||
|
||||
log_debug("Starting event of severity [severity].")
|
||||
new EM.event_type(EM)
|
||||
|
||||
// Remove the event meta data from the list of available events
|
||||
available_events[severity] -= EM
|
||||
|
||||
/datum/event_manager/proc/acquire_event(var/list/events)
|
||||
if(events.len == 0)
|
||||
return
|
||||
var/active_with_role = number_active_with_role()
|
||||
|
||||
var/list/possible_events = list()
|
||||
for(var/datum/event_meta/EM in events)
|
||||
var/event_weight = EM.get_weight(active_with_role)
|
||||
if(event_weight)
|
||||
possible_events[EM] = event_weight
|
||||
|
||||
for(var/event_meta in last_event_time) if(possible_events[event_meta])
|
||||
var/time_passed = world.time - event_last_fired[event_meta]
|
||||
var/weight_modifier = max(0, (config.expected_round_length - time_passed) / 300)
|
||||
var/new_weight = max(possible_events[event_meta] - weight_modifier, 0)
|
||||
|
||||
if(new_weight)
|
||||
possible_events[event_meta] = new_weight
|
||||
else
|
||||
possible_events -= event_meta
|
||||
|
||||
if(possible_events.len == 0)
|
||||
return null
|
||||
|
||||
var/picked_event = pickweight(possible_events)
|
||||
last_event_time[picked_event] = world.time
|
||||
|
||||
return picked_event
|
||||
|
||||
/datum/event_manager/proc/set_event_delay(var/severity)
|
||||
// If the next event time has not yet been set and we have a custom first time start
|
||||
if(next_event_time[severity] == 0 && config.event_first_run[severity])
|
||||
var/lower = config.event_first_run[severity]["lower"]
|
||||
var/upper = config.event_first_run[severity]["upper"]
|
||||
var/event_delay = rand(lower, upper)
|
||||
next_event_time[severity] = world.timeofday + event_delay
|
||||
// Otherwise, follow the standard setup process
|
||||
else
|
||||
var/playercount_modifier = 1
|
||||
switch(player_list.len)
|
||||
if(0 to 10)
|
||||
@@ -30,36 +137,30 @@ var/scheduledEvent = null
|
||||
playercount_modifier = 0.9
|
||||
if(36 to 100000)
|
||||
playercount_modifier = 0.8
|
||||
playercount_modifier = playercount_modifier * delay_modifier[severity]
|
||||
|
||||
if(ticker.mode && ticker.mode.name == "calamity") //Calamity mode lowers the time required between events drastically.
|
||||
playercount_modifier = playercount_modifier * 0.5
|
||||
var/event_delay = rand(config.event_delay_lower[severity], config.event_delay_upper[severity]) * playercount_modifier
|
||||
next_event_time[severity] = world.timeofday + event_delay
|
||||
|
||||
var/next_event_delay = rand(eventTimeLower, eventTimeUpper) * playercount_modifier
|
||||
scheduledEvent = world.timeofday + next_event_delay
|
||||
log_debug("Next event in [next_event_delay/600] minutes.")
|
||||
log_debug("Next event of severity [severity] in [(next_event_time[severity] - world.timeofday)/600] minutes.")
|
||||
|
||||
else if(world.timeofday > scheduledEvent)
|
||||
spawn_dynamic_event()
|
||||
|
||||
scheduledEvent = null
|
||||
checkEvent()
|
||||
|
||||
//unused, see proc/dynamic_event()
|
||||
/*
|
||||
/proc/spawnEvent()
|
||||
if(!config.allow_random_events)
|
||||
/datum/event_manager/proc/event_complete(var/datum/event/E)
|
||||
if(!E.event_meta) // datum/event is used here and there for random reasons
|
||||
log_debug("Event of '[E.type]' with missing meta-data has completed.")
|
||||
return
|
||||
|
||||
var/Type = pick(potentialRandomEvents)
|
||||
if(!Type)
|
||||
return
|
||||
finished_events += E
|
||||
// Add the event back to the list of available events, unless it's a oneShot
|
||||
if(!E.oneShot)
|
||||
var/list/datum/event_meta/AE = available_events[E.event_meta.severity]
|
||||
AE.Add(E.event_meta)
|
||||
|
||||
//The event will add itself to the MC's event list
|
||||
//and start working via the constructor.
|
||||
new Type
|
||||
*/
|
||||
log_debug("Event '[E.name]' has completed.")
|
||||
|
||||
/client/proc/forceEvent(var/type in allEvents)
|
||||
/proc/debugStartEvent(var/severity)
|
||||
event_manager.start_event(severity)
|
||||
|
||||
/client/proc/forceEvent(var/type in event_manager.allEvents)
|
||||
set name = "Trigger Event (Debug Only)"
|
||||
set category = "Debug"
|
||||
|
||||
@@ -67,5 +168,15 @@ var/scheduledEvent = null
|
||||
return
|
||||
|
||||
if(ispath(type))
|
||||
new type
|
||||
new type(new /datum/event_meta(EVENT_LEVEL_MAJOR))
|
||||
message_admins("[key_name_admin(usr)] has triggered an event. ([type])", 1)
|
||||
|
||||
#undef ASSIGNMENT_ANY
|
||||
#undef ASSIGNMENT_AI
|
||||
#undef ASSIGNMENT_CYBORG
|
||||
#undef ASSIGNMENT_ENGINEER
|
||||
#undef ASSIGNMENT_GARDENER
|
||||
#undef ASSIGNMENT_JANITOR
|
||||
#undef ASSIGNMENT_MEDICAL
|
||||
#undef ASSIGNMENT_SCIENTIST
|
||||
#undef ASSIGNMENT_SECURITY
|
||||
@@ -1,58 +1,57 @@
|
||||
/datum/event/radiation_storm
|
||||
announceWhen = 1
|
||||
oneShot = 1
|
||||
var/const/enterBelt = 60
|
||||
var/const/leaveBelt = 170
|
||||
var/const/revokeAccess = 230
|
||||
|
||||
endWhen = revokeAccess
|
||||
oneShot = 1
|
||||
|
||||
var/postStartTicks
|
||||
|
||||
/datum/event/radiation_storm/announce()
|
||||
// Don't do anything, we want to pack the announcement with the actual event
|
||||
command_announcement.Announce("High levels of radiation detected near the station. Please evacuate into one of the shielded maintenance tunnels.", "Anomaly Alert", new_sound = 'sound/AI/radiation.ogg')
|
||||
|
||||
/datum/event/radiation_storm/start()
|
||||
spawn()
|
||||
command_announcement.Announce("High levels of radiation detected near the station. Please evacuate into one of the shielded maintenance tunnels.", "Anomaly Alert", new_sound = 'sound/AI/radiation.ogg')
|
||||
make_maint_all_access()
|
||||
|
||||
|
||||
sleep(600)
|
||||
|
||||
make_maint_all_access()
|
||||
|
||||
/datum/event/radiation_storm/tick()
|
||||
if(activeFor == enterBelt)
|
||||
command_announcement.Announce("The station has entered the radiation belt. Please remain in a sheltered area until we have passed the radiation belt.", "Anomaly Alert")
|
||||
radiate()
|
||||
|
||||
for(var/i = 0, i < 10, i++)
|
||||
for(var/mob/living/carbon/human/H in living_mob_list)
|
||||
var/turf/T = get_turf(H)
|
||||
if(!T)
|
||||
continue
|
||||
if(T.z != 1)
|
||||
continue
|
||||
if(istype(T.loc, /area/maintenance) || istype(T.loc, /area/crew_quarters))
|
||||
continue
|
||||
|
||||
if(istype(H,/mob/living/carbon/human))
|
||||
H.apply_effect((rand(15,35)),IRRADIATE,0)
|
||||
if(prob(5))
|
||||
H.apply_effect((rand(40,70)),IRRADIATE,0)
|
||||
if (prob(75))
|
||||
randmutb(H) // Applies bad mutation
|
||||
domutcheck(H,null,MUTCHK_FORCED)
|
||||
else
|
||||
randmutg(H) // Applies good mutation
|
||||
domutcheck(H,null,MUTCHK_FORCED)
|
||||
|
||||
|
||||
for(var/mob/living/carbon/monkey/M in living_mob_list)
|
||||
var/turf/T = get_turf(M)
|
||||
if(!T)
|
||||
continue
|
||||
if(T.z != 1)
|
||||
continue
|
||||
M.apply_effect((rand(5,25)),IRRADIATE,0)
|
||||
sleep(100)
|
||||
if(activeFor > enterBelt && activeFor < leaveBelt)
|
||||
postStartTicks++
|
||||
|
||||
if(postStartTicks == 10)
|
||||
postStartTicks = 0
|
||||
radiate()
|
||||
|
||||
else if(activeFor == leaveBelt)
|
||||
command_announcement.Announce("The station has passed the radiation belt. Please report to medbay if you experience any unusual symptoms. Maintenance will lose all access again shortly.", "Anomaly Alert")
|
||||
|
||||
/datum/event/radiation_storm/proc/radiate()
|
||||
for(var/mob/living/carbon/C in living_mob_list)
|
||||
var/turf/T = get_turf(C)
|
||||
if(!T)
|
||||
continue
|
||||
if(!(T.z in config.station_levels))
|
||||
continue
|
||||
if(istype(T.loc, /area/maintenance) || istype(T.loc, /area/crew_quarters))
|
||||
continue
|
||||
|
||||
sleep(600) // Want to give them time to get out of maintenance.
|
||||
if(istype(C,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = C
|
||||
H.apply_effect((rand(15,35)),IRRADIATE,0)
|
||||
if(prob(5))
|
||||
H.apply_effect((rand(40,70)),IRRADIATE,0)
|
||||
if (prob(75))
|
||||
randmutb(H) // Applies bad mutation
|
||||
domutcheck(H,null,MUTCHK_FORCED)
|
||||
else
|
||||
randmutg(H) // Applies good mutation
|
||||
domutcheck(H,null,MUTCHK_FORCED)
|
||||
else if(istype(C,/mob/living/carbon/monkey))
|
||||
C.apply_effect((rand(5,25)),IRRADIATE,0)
|
||||
|
||||
|
||||
revoke_maint_all_access()
|
||||
/datum/event/radiation_storm/end()
|
||||
revoke_maint_all_access()
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
|
||||
datum/event/viral_infection
|
||||
var/severity = 1
|
||||
|
||||
datum/event/viral_infection/setup()
|
||||
announceWhen = rand(0, 3000)
|
||||
endWhen = announceWhen + 1
|
||||
severity = rand(1, 3)
|
||||
|
||||
datum/event/viral_infection/announce()
|
||||
command_announcement.Announce("Confirmed outbreak of level five biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak5.ogg')
|
||||
@@ -18,7 +13,9 @@ datum/event/viral_infection/start()
|
||||
if(!candidates.len) return
|
||||
candidates = shuffle(candidates)//Incorporating Donkie's list shuffle
|
||||
|
||||
while(severity > 0 && candidates.len)
|
||||
severity = severity == 1 ? 1 : severity - 1
|
||||
var/actual_severity = severity * rand(1, 3)
|
||||
while(actual_severity > 0 && candidates.len)
|
||||
infect_mob_random_lesser(candidates[1])
|
||||
candidates.Remove(candidates[1])
|
||||
severity--
|
||||
actual_severity--
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
/turf/simulated/wall
|
||||
|
||||
|
||||
datum/event/wallrot
|
||||
var/severity = 1
|
||||
|
||||
datum/event/wallrot/setup()
|
||||
announceWhen = rand(0, 300)
|
||||
endWhen = announceWhen + 1
|
||||
severity = rand(5, 10)
|
||||
|
||||
datum/event/wallrot/announce()
|
||||
command_announcement.Announce("Harmful fungi detected on station. Station structures may be contaminated.", "Biohazard Alert")
|
||||
|
||||
datum/event/wallrot/start()
|
||||
spawn()
|
||||
var/turf/center = null
|
||||
var/turf/simulated/wall/center = null
|
||||
|
||||
// 100 attempts
|
||||
for(var/i=0, i<100, i++)
|
||||
@@ -24,14 +17,15 @@ datum/event/wallrot/start()
|
||||
|
||||
if(center)
|
||||
// Make sure at least one piece of wall rots!
|
||||
center:rot()
|
||||
center.rot()
|
||||
|
||||
// Have a chance to rot lots of other walls.
|
||||
var/rotcount = 0
|
||||
var/actual_severity = severity * rand(5, 10)
|
||||
for(var/turf/simulated/wall/W in range(5, center)) if(prob(50))
|
||||
W:rot()
|
||||
W.rot()
|
||||
rotcount++
|
||||
|
||||
// Only rot up to severity walls
|
||||
if(rotcount >= severity)
|
||||
if(rotcount >= actual_severity)
|
||||
break
|
||||
Reference in New Issue
Block a user