mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-29 06:57:42 +01:00
Event system refactor and changes (#29420)
* meta resolution * emerald resolution * delta resolution * fartgas resolution * box box * stay out stay out * metastation fixes * faragus fix * delta fix * Changes to role impact on event weight * adds disaster level to the event config * weight changes and starts adding disaster level to the ui * ui fixes * adjust disaster level timing * changes disaster timing, weights, disease outbreak role requirements and weights * lots of weight an requirement adjustments * Update tear.dm * some fixes * meta changes * Starting over with farragus * Starting over in faragus * faragus changes * Update cerestation.dmm * Update cerestation.dmm * Update cerestation.dmm * Update cerestation.dmm * Update cerestation.dmm * resolving some faragus conflicts * resolve faragus conflicts * resolves delta conflicts * resolves cyberiad conflicts * resolves emerald conflicts * fixes cables in faragus * fixes meta cables * fixes delta cables * more meta fixes * more farragus cable fixes * more cable fixes * meta and faragus fixes * box and delta fixes * more mapping fixes * hopefully the last fix * Update metastation.dmm * Update metastation.dmm * fixes shorts on cyberiad cerebron and farragus * CI fixes * move new event listing to new system * Adds tracking and cost calculation for blob * finishes setting up blob event detection and costs * minor boolog corrections * fixes events being created at the wrong severity * adds ongoing cost to disease outbreak * moves terror spider event to new system * moves to component based event cost calculation * morph abductor and carps adjusted for new system * various fixes and adjusts rev event * Update revenant_spawn_event.dm * various fixes and adjusts demon incursion to the new system * adjusts some major event weights * correct wrong values of autoend on vendor uprising and rev * Update event_container.dm * more event timing adjustments * adds requirements to traders and incursion * slightly lowers requirements for biohazards * timing changes * temporarily disable loading event times from the config and increases major nothing chance * adjustments to costs and weights of various events * Update event_container.dm * additional adjustments to weights and requirements. moves rev to major * typo fix * ion storm adjustment * Update event_container.dm * more moderate changes * e * Update meteors_event.dm * removes cooldown from nothing event and changes its weight based on the number of remaining enabled events in the container * increases morph event requirements and chance of nothing moderate event * makes morph a major event * Update morph_event.dm * adds viro requirement for disease outbreak and fixes a bug with incorrect resource calculation * allows varediting extra roles for the event system for debug and testing * Adjust weights of traders and abductors and corrects wrong nominal severity for demonic incursion * Adds crew cound to rev weight * makes disasters start rolling later * reduces weight of communications blackout and increases weight of major nothing * adjusts door runtime and prisonbreak weights to make them less frequent. kudzu now scales with total crew * apc overload made less frequent * oopsy * Gives the scrubber clog event a name * fixes a type in a define name * adjusts demonic incursion weight * changes brand intelligence weight an d reduces door runtime weight * more adjustments to demon incursion. Makes additional weight from surplus roles diminish * adjustments to some minor events * Increases event length and requirements of some engineering events and lowers their weight slightly. Also increases cost of ongoing diseases events * fixes a type * Update meteors_event.dm * corrects traders nominal severity and adjusts demon weights * shifts anomaly weights down and increases costs * rebalance rod requirements * Update cerestation.dmm * moves net resource calculation to its own proc and changes the ASSIGNMENT_TOTAL macro to ASSIGNMENT_CREW. * Adds individual first run time for some events and makes majors start rolling slightly later * reduces weight of major nothing * minor reduction to rev and apc overload weight * Changes the way event weight is calculated * end time corrections for anomaly rod and meteors * slightly adjusts down the weights of nothing and some minor events * Adjusts moedrates towards about 3.5 per round and mundanes towards 8 per round * adds first run restrictions on traders and incursion and increases the cooldown time of events * resolve faragus conflicts * resolve emerald conflict * fix some faragus cabling * more cabling correction in faragus * more cable fixes * Update cerestation.dmm * remove doubled scrubber pipe on tile * reduces moderates nothing chance * slightly reduces crew requirements for disasters and also reduces crew weight for disasters * fixes meteor event not removing the alert, and makes it announce a bit later * Adds an event debugging window for real time midround event data * Revert "Adds an event debugging window for real time midround event data" This reverts commitecd99a6c9e. * Adds a resource view button to the event manager window and fixes a null in the total resource list * various bug fixes * slightly lowers chance of meteor and similar events * Slightly lowers requirement weights on disaster level events * resolves faragus conflict * changes the default power input of engineering SMES to 200kw and 80kW respectively * connects power monitoring computers to the grid that weren't * meta station elec maints improvements * adds missing power monitoring computers on box and delta * removes dirt from wall * corrects area boundry on meta * adds missing cable on box sci * removes dirt from wall on box * connects cyberiad bridge to the rest of the powernet * connects box brig to powernet * Adds catwalks to box maints * adds catwalks to meta * Adds catwalks to delta * Update deltastation.dmm * adds ability to insulate cables * Moves stations to using extra insulated cables for high power network * Removes catwalks from meta * Removes catwalks from box * Removes catwalks from delta * Delays moderates and majors more and increases disaster chance * resolves box conflicts * Update cable.dm * remove floating request console * corrects position of fire alarm and removes extra intercom on metastation * resolves faragus conflict * reduces meteor variant weights. meaty ores event now has the correct nominal severity * meaty ore weight to 8 * fixes a stray light bulb and light switch in maints as well as a doubled power * Delays meteor type events to 40 minutes at the earliest. Moves the time check to be against round time instead of world time * wires kerberos security checkpoint to the grid * Update cerestation.dmm * Removes stray extinguisher cabinet from meta station * resolves area conflict on faragus * resolves more faragus issues * fixes faragus cabling issues * Update cerestation.dmm * removes another stray fire extinguisher cabinet * insulates the APC in delta PTL room * increases pop requirement and weight for demons and increases medbay and viro weights for diseases * connect delta fore starboard solars to the high power grid instead of the low power * Update deltastation.dmm * deconflict * solves some unconnected cables * connects delta customs to network and finishes resolving conflicts * Update deltastation.dmm * adds the new cables. needs coils and mapping * moves connection perms to the heavy duty cables. toggled with engineering permission ID. box gets new cables * sorts cables on stations * faragus cable connections * cable corrections. Adds heavy duty cables to the autolathe * CI fix * more fixes and makes the new cables show up on t ray scanners * box station mapping fixes * delta mapping fixes * meta fix * Update deltastation.dmm * delta and faragus fixes * Update emeraldstation.dmm * removes APC overloard(major) from event pool * adds diagonal sprites to heavy duty cables. allows sillicons to toggle them and * Makes borg versions of the heavy duty cable coil * palete consolidation * Improves visibility of high power cables * converts shuttle event to new system * makes disaster event last run calc use round time instead of world time * fixes wrong define being used in some event requirements. further increases requirements for demons and meteors. lowers weight of major diseases * Update slaughterevent.dm * reduces cargo requirements for shuttle load event * reduces base weight of major disease event and further increases medical requirements * fixes a wrong wire under the pet store maints door in delta station * resolve mapping conflicts * Revert "resolve mapping conflicts" This reverts commit129db52501. * Revert "Merge branch 'HighPowerMaints' into event_timing" This reverts commit2594ac8928, reversing changes made toa738b5f2f2. * fixes some wonky stuff with xeno code * Adds a crew cost to diseases * makes player contribution towards events variable * changes major event weights and slightly increases demon requirements * slightly increases major disease outbreak weight * comment changes * Adds safeties to protect against null events getting into container or the active list * blob fix * Adds a confirmation to random event toggle * Adjust particulate event weight to fit the new moderate weights * Adds additional security costs to changeling and vamp * Update revenant_spawn_event.dm * uses correct path for rev event cost proc * changes some lists to alists * correctly accesses the event container list and actually uses the config for the event timing --------- Co-authored-by: FunnyMan3595 (Charlie Nolan) <funnyman3595@gmail.com> Co-authored-by: warriorstar-orion <orion@snowfrost.garden>
This commit is contained in:
co-authored by
FunnyMan3595
warriorstar-orion
parent
bee4f00416
commit
e609a7faf7
@@ -988,6 +988,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
if(!check_rights(R_SERVER|R_EVENT))
|
||||
return
|
||||
|
||||
if(tgui_alert(usr, "[GLOB.configuration.event.enable_random_events ? "Disable" : "Enable"] random events?", "Confirm", list("Yes", "No")) != "Yes")
|
||||
return
|
||||
|
||||
if(!GLOB.configuration.event.enable_random_events)
|
||||
GLOB.configuration.event.enable_random_events = TRUE
|
||||
to_chat(usr, "Random events enabled")
|
||||
|
||||
@@ -607,4 +607,7 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
other_team.add_antag_objective(red_team)
|
||||
red_team.pair_up(blue_team, TRUE)
|
||||
|
||||
/datum/antagonist/proc/antag_event_resource_cost()
|
||||
return list(ASSIGNMENT_SECURITY = 1)
|
||||
|
||||
#undef SUCCESSFUL_DETACH
|
||||
|
||||
@@ -49,3 +49,6 @@
|
||||
messages.Add("<span class='userdanger'>You are a scientist of [our_team.name]!</span>")
|
||||
messages.Add("<span class='boldnotice'>With the help of your teammate, kidnap and experiment on station crew members! Use your tool and ship consoles to support the agent and retrieve humanoid specimens.</span>")
|
||||
return messages
|
||||
|
||||
/datum/antagonist/abductor/antag_event_resource_cost()
|
||||
return list(ASSIGNMENT_SECURITY = 1.5)
|
||||
|
||||
@@ -473,3 +473,7 @@ RESTRICT_TYPE(/datum/antagonist/changeling)
|
||||
|
||||
/datum/antagonist/changeling/custom_blurb()
|
||||
return "We awaken on the [station_name()], [get_area_name(owner.current, TRUE)]...\nWe have our tasks to attend to..."
|
||||
|
||||
// Ling Stronk
|
||||
/datum/antagonist/changeling/antag_event_resource_cost()
|
||||
return list(ASSIGNMENT_SECURITY = 3)
|
||||
|
||||
@@ -409,3 +409,7 @@ RESTRICT_TYPE(/datum/antagonist/vampire)
|
||||
|
||||
/datum/antagonist/vampire/custom_blurb()
|
||||
return "On the date [GLOB.current_date_string], at [station_time_timestamp()],\n in the [station_name()], [get_area_name(owner.current, TRUE)]...\nThe hunt begins again..."
|
||||
|
||||
// Ramps up as you get more powerfull
|
||||
/datum/antagonist/vampire/antag_event_resource_cost()
|
||||
return list(ASSIGNMENT_SECURITY = 1 + bloodtotal / 500)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/datum/event/economic_event
|
||||
name = "Economic News"
|
||||
endWhen = 50 // this will be set randomly, later
|
||||
announceWhen = 15
|
||||
var/datum/event_news/economic/news_story
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/datum/event/mundane_news
|
||||
name = "Mundane News"
|
||||
endWhen = 10
|
||||
|
||||
/datum/event/mundane_news/announce()
|
||||
@@ -19,6 +20,7 @@
|
||||
NC.alert_news(message.title)
|
||||
|
||||
/datum/event/trivial_news
|
||||
name = "Trivial News"
|
||||
endWhen = 10
|
||||
|
||||
/datum/event/trivial_news/announce()
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
/datum/event/abductor
|
||||
name = "Abductor Visit"
|
||||
noAutoEnd = TRUE
|
||||
nominal_severity = EVENT_LEVEL_MAJOR
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 5)
|
||||
role_requirements = list(ASSIGNMENT_SECURITY = 3)
|
||||
var/datum/team/abductor/ayys
|
||||
var/spawned = FALSE
|
||||
|
||||
/datum/event/abductor/process()
|
||||
if(ayys && length(ayys.members) && spawned)
|
||||
kill()
|
||||
return ..()
|
||||
|
||||
/// abductor costs are calculated independently of event
|
||||
/datum/event/abductor/event_resource_cost()
|
||||
return list()
|
||||
|
||||
/datum/event/abductor/start()
|
||||
INVOKE_ASYNC(src, PROC_REF(try_makeAbductorTeam))
|
||||
@@ -23,7 +39,8 @@
|
||||
mind.active = TRUE
|
||||
minds += mind
|
||||
|
||||
var/datum/team/abductor/ayys = new /datum/team/abductor(minds)
|
||||
ayys = new /datum/team/abductor(minds)
|
||||
ayys.create_agent()
|
||||
ayys.create_scientist()
|
||||
spawned = TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
GLOBAL_LIST_INIT(xeno_things, list("xenos" = list(), "eggs" = list()))
|
||||
|
||||
/datum/event/alien_infestation
|
||||
announceWhen = 400
|
||||
name = "Alien Infestation"
|
||||
announceWhen = 400
|
||||
noAutoEnd = TRUE
|
||||
var/highpop_trigger = 80
|
||||
var/spawncount = 2
|
||||
var/list/playercount
|
||||
var/successSpawn = FALSE //So we don't make a command report if nothing gets spawned.
|
||||
nominal_severity = EVENT_LEVEL_DISASTER
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 3, ASSIGNMENT_CREW = 0.9, ASSIGNMENT_MEDICAL = 3)
|
||||
role_requirements = list(ASSIGNMENT_SECURITY = 4, ASSIGNMENT_CREW = 50, ASSIGNMENT_MEDICAL = 4)
|
||||
|
||||
/datum/event/alien_infestation/setup()
|
||||
announceWhen = rand(announceWhen, announceWhen + 50)
|
||||
@@ -14,6 +21,17 @@
|
||||
else
|
||||
log_and_message_admins("Warning: Could not spawn any mobs for event Alien Infestation")
|
||||
|
||||
/datum/event/alien_infestation/process()
|
||||
// Check for completion every minute
|
||||
if(!activeFor % 30)
|
||||
if(successSpawn && !length(event_category_cost(EVENT_XENOS)))
|
||||
kill()
|
||||
. = ..()
|
||||
|
||||
/// Xeno costs are calculated independently from the event itself
|
||||
/datum/event/alien_infestation/event_resource_cost()
|
||||
return list()
|
||||
|
||||
/datum/event/alien_infestation/start()
|
||||
playercount = length(GLOB.clients)//grab playercount when event starts not when game starts
|
||||
if(playercount >= highpop_trigger) //spawn with 4 if highpop
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/datum/event/anomaly/anomaly_bluespace
|
||||
name = "Anomaly event"
|
||||
name = "Bluespace Anomaly"
|
||||
startWhen = 3
|
||||
announceWhen = 10
|
||||
anomaly_path = /obj/effect/anomaly/bluespace
|
||||
prefix_message = "Unstable bluespace anomaly detected on long range scanners."
|
||||
announce_sound = 'sound/AI/anomaly_bluespace.ogg'
|
||||
role_weights = list(ASSIGNMENT_SCIENCE = 1, ASSIGNMENT_ENGINEERING = 1)
|
||||
role_requirements = list(ASSIGNMENT_SCIENCE = 1, ASSIGNMENT_ENGINEERING = 2)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/event/anomaly/anomaly_cryo
|
||||
name = "Anomaly event"
|
||||
name = "Cryo Anomaly"
|
||||
startWhen = 3
|
||||
announceWhen = 10
|
||||
anomaly_path = /obj/effect/anomaly/cryo
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
/datum/event/anomaly
|
||||
name = "Anomaly: Energetic Flux"
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
noAutoEnd = TRUE
|
||||
role_weights = list(ASSIGNMENT_SCIENCE = 1, ASSIGNMENT_ENGINEERING = 1)
|
||||
role_requirements = list(ASSIGNMENT_SCIENCE = 1, ASSIGNMENT_ENGINEERING = 1)
|
||||
var/obj/effect/anomaly/anomaly_path = /obj/effect/anomaly/flux
|
||||
var/turf/target_turf
|
||||
announceWhen = 1
|
||||
@@ -9,8 +13,15 @@
|
||||
var/prefix_message = "Localized hyper-energetic flux wave detected on long range scanners."
|
||||
/// Sound effect used
|
||||
var/announce_sound = 'sound/AI/anomaly_flux.ogg'
|
||||
var/spawned = FALSE
|
||||
|
||||
|
||||
/datum/event/anomaly/tick()
|
||||
if(spawned && QDELETED(anomaly_path))
|
||||
// Add 15 minutes for cleanup
|
||||
endWhen = activeFor + 450
|
||||
noAutoEnd = FALSE
|
||||
|
||||
/datum/event/anomaly/setup()
|
||||
target_turf = find_targets(TRUE)
|
||||
|
||||
@@ -45,7 +56,8 @@
|
||||
GLOB.minor_announcement.Announce("[prefix_message] Expected location: [target.name].", "Anomaly Alert", announce_sound)
|
||||
|
||||
/datum/event/anomaly/start()
|
||||
var/newAnomaly = new anomaly_path(target_turf)
|
||||
announce_to_ghosts(newAnomaly)
|
||||
anomaly_path = new anomaly_path(target_turf)
|
||||
announce_to_ghosts(anomaly_path)
|
||||
spawned = TRUE
|
||||
|
||||
#undef TURF_FIND_TRIES
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/datum/event/anomaly/anomaly_flux
|
||||
name = "Anomaly event"
|
||||
name = "Flux Anomaly"
|
||||
startWhen = 10
|
||||
announceWhen = 3
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/event/anomaly/anomaly_grav
|
||||
name = "Anomaly event"
|
||||
name = "Gravitational Anomaly"
|
||||
startWhen = 3
|
||||
announceWhen = 20
|
||||
anomaly_path = /obj/effect/anomaly/grav
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/event/anomaly/anomaly_pyro
|
||||
name = "Anomaly event"
|
||||
name = "Pyro Anomaly"
|
||||
startWhen = 3
|
||||
announceWhen = 10
|
||||
anomaly_path = /obj/effect/anomaly/pyro
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/datum/event/anomaly/anomaly_vortex
|
||||
name = "Anomaly event"
|
||||
name = "Vortex Anomaly"
|
||||
startWhen = 10
|
||||
announceWhen = 3
|
||||
anomaly_path = /obj/effect/anomaly/bhole
|
||||
prefix_message = "Localized high-intensity vortex anomaly detected on long range scanners."
|
||||
announce_sound = 'sound/AI/anomaly_vortex.ogg'
|
||||
role_weights = list(ASSIGNMENT_SCIENCE = 1, ASSIGNMENT_ENGINEERING = 1)
|
||||
role_requirements = list(ASSIGNMENT_SCIENCE = 1, ASSIGNMENT_ENGINEERING = 3)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#define APC_BREAK_PROBABILITY 25 // the probability that a given APC will be broken
|
||||
|
||||
/datum/event/apc_overload
|
||||
name = "APC Overload"
|
||||
nominal_severity = EVENT_LEVEL_MAJOR
|
||||
role_weights = list(ASSIGNMENT_ENGINEERING = 4, ASSIGNMENT_CREW = 0.5)
|
||||
role_requirements = list(ASSIGNMENT_ENGINEERING = 5, ASSIGNMENT_CREW = 30)
|
||||
var/const/announce_after_mc_ticks = 5
|
||||
var/const/delayed = FALSE
|
||||
var/const/event_max_duration_mc_ticks = announce_after_mc_ticks * 2
|
||||
@@ -9,7 +13,7 @@
|
||||
announceWhen = announce_after_mc_ticks
|
||||
|
||||
/datum/event/apc_overload/setup()
|
||||
endWhen = rand(event_min_duration_mc_ticks, event_max_duration_mc_ticks)
|
||||
endWhen = rand(event_min_duration_mc_ticks, event_max_duration_mc_ticks) + 2700
|
||||
|
||||
/datum/event/apc_overload/start()
|
||||
apc_overload_failure(announce=delayed)
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
#define APC_BREAK_PROBABILITY 25 // the probability that a given APC will be disabled
|
||||
|
||||
/datum/event/apc_short
|
||||
var/const/announce_after_mc_ticks = 5
|
||||
name = "APC Short"
|
||||
// Keeps engies busy for a while
|
||||
role_weights = list(ASSIGNMENT_ENGINEERING = 3)
|
||||
role_requirements = list(ASSIGNMENT_ENGINEERING = 3)
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
var/const/announce_after_mc_ticks = 5
|
||||
var/const/event_max_duration_mc_ticks = announce_after_mc_ticks * 2
|
||||
var/const/event_min_duration_mc_ticks = announce_after_mc_ticks
|
||||
|
||||
announceWhen = announce_after_mc_ticks
|
||||
|
||||
/datum/event/apc_short/setup()
|
||||
endWhen = rand(event_min_duration_mc_ticks, event_max_duration_mc_ticks)
|
||||
endWhen = rand(event_min_duration_mc_ticks, event_max_duration_mc_ticks) + 1800
|
||||
|
||||
/datum/event/apc_short/start()
|
||||
power_failure(announce = FALSE)
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
/mob/living/basic/blob/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.blob_minions |= src
|
||||
AddComponent(/datum/component/event_tracker, EVENT_BLOB)
|
||||
|
||||
/mob/living/basic/blob/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_SECURITY = 0.5, ASSIGNMENT_CREW = 3, ASSIGNMENT_MEDICAL = 0.5)
|
||||
|
||||
/mob/living/basic/blob/Destroy()
|
||||
GLOB.blob_minions -= src
|
||||
@@ -209,6 +215,11 @@
|
||||
if(name == "blobbernaut")
|
||||
name = "blobbernaut ([rand(1, 1000)])"
|
||||
|
||||
/mob/living/basic/blob/blobbernaut/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_SECURITY = 0.5, ASSIGNMENT_CREW = 3, ASSIGNMENT_MEDICAL = 0.5)
|
||||
|
||||
/datum/action/innate/communicate_overmind_blob
|
||||
name = "Speak with the overmind"
|
||||
button_icon = 'icons/mob/guardian.dmi'
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
var/image/C = new('icons/mob/blob.dmi', "blob_core_overlay")
|
||||
overlays += C
|
||||
|
||||
/obj/structure/blob/core/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z))
|
||||
return list(ASSIGNMENT_SECURITY = 2, ASSIGNMENT_CREW = 15, ASSIGNMENT_MEDICAL = 2)
|
||||
|
||||
/obj/structure/blob/core/Destroy()
|
||||
if(overmind)
|
||||
|
||||
@@ -27,4 +27,9 @@ GLOBAL_VAR_INIT(spores_active, 0)
|
||||
if(overmind)
|
||||
overmind.add_mob_to_overmind(BS)
|
||||
|
||||
/obj/structure/blob/factory/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z))
|
||||
return list(ASSIGNMENT_SECURITY = 0.33, ASSIGNMENT_CREW = 1)
|
||||
|
||||
#undef MAX_GLOBAL_SPORES
|
||||
|
||||
@@ -33,3 +33,8 @@
|
||||
Pulse(5, i, color)
|
||||
obj_integrity = min(max_integrity, obj_integrity + 1)
|
||||
color = null
|
||||
|
||||
/obj/structure/blob/node/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z))
|
||||
return list(ASSIGNMENT_SECURITY = 0.1, ASSIGNMENT_CREW = 1)
|
||||
|
||||
@@ -35,6 +35,12 @@ GLOBAL_LIST_EMPTY(blob_minions)
|
||||
COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered)
|
||||
)
|
||||
AddElement(/datum/element/connect_loc, loc_connections)
|
||||
AddComponent(/datum/component/event_tracker, EVENT_BLOB)
|
||||
|
||||
/obj/structure/blob/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z))
|
||||
return list(ASSIGNMENT_CREW = 0.07)
|
||||
|
||||
/obj/structure/blob/Destroy()
|
||||
if(atmosblock)
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
/datum/event/blob
|
||||
announceWhen = 180
|
||||
endWhen = 240
|
||||
var/successSpawn = FALSE //So we don't make a command report if nothing gets spawned.
|
||||
name = "Blob"
|
||||
announceWhen = 180
|
||||
noAutoEnd = TRUE
|
||||
nominal_severity = EVENT_LEVEL_DISASTER
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 2, ASSIGNMENT_CREW = 0.7, ASSIGNMENT_MEDICAL = 2)
|
||||
role_requirements = list(ASSIGNMENT_SECURITY = 3, ASSIGNMENT_CREW = 45, ASSIGNMENT_MEDICAL = 3)
|
||||
/// So we don't make a command report if nothing gets spawned.
|
||||
var/successSpawn = FALSE
|
||||
/// List of all blob cores and blob mice related to this event
|
||||
var/list/blob_things = list("cores" = list(), "mice" = 0)
|
||||
|
||||
/datum/event/blob/announce(false_alarm)
|
||||
if(successSpawn || false_alarm)
|
||||
@@ -12,6 +19,15 @@
|
||||
/datum/event/blob/start()
|
||||
INVOKE_ASYNC(src, PROC_REF(make_blob))
|
||||
|
||||
/datum/event/blob/process()
|
||||
if(!(length(blob_things["cores"]) + blob_things["mice"]) && successSpawn)
|
||||
return kill()
|
||||
return ..()
|
||||
|
||||
/// Blob costs are calculated independently from the event itself
|
||||
/datum/event/blob/event_resource_cost()
|
||||
return list()
|
||||
|
||||
/datum/event/blob/proc/make_blob()
|
||||
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a blob infested mouse?", ROLE_BLOB, TRUE, source = /mob/living/basic/mouse/blobinfected)
|
||||
if(!length(candidates))
|
||||
@@ -29,7 +45,8 @@
|
||||
B.mind.special_role = SPECIAL_ROLE_BLOB
|
||||
B.forceMove(vent)
|
||||
B.add_ventcrawl(vent)
|
||||
|
||||
RegisterSignal(B, COMSIG_BLOB_MOUSE_BURST, PROC_REF(record_core))
|
||||
blob_things["mice"]++
|
||||
// Mark it on antag HUD
|
||||
var/datum/atom_hud/antag/antaghud = GLOB.huds[ANTAG_HUD_BLOB]
|
||||
antaghud.join_hud(B.mind.current)
|
||||
@@ -40,3 +57,14 @@
|
||||
notify_ghosts("Infected Mouse has appeared in [get_area(B)].", source = B, action = NOTIFY_FOLLOW)
|
||||
successSpawn = TRUE
|
||||
SSevents.biohazards_this_round += BIOHAZARD_BLOB
|
||||
|
||||
/datum/event/blob/proc/record_core(atom/source, obj/structure/blob/core/core)
|
||||
SIGNAL_HANDLER // COMSIG_BLOB_MOUSE_BURST
|
||||
if(core)
|
||||
blob_things["cores"] += list(core)
|
||||
RegisterSignal(core, COMSIG_PARENT_QDELETING, PROC_REF(remove_core))
|
||||
blob_things["mice"]--
|
||||
|
||||
/datum/event/blob/proc/remove_core(obj/structure/blob/core/source)
|
||||
if(source)
|
||||
blob_things["cores"] -= source
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/datum/event/brand_intelligence
|
||||
name = "Brand Intelligence"
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
role_weights = list(ASSIGNMENT_ENGINEERING = 1, ASSIGNMENT_CREW = 0.4)
|
||||
role_requirements = list(ASSIGNMENT_ENGINEERING = 2, ASSIGNMENT_CREW = 10)
|
||||
noAutoEnd = TRUE
|
||||
announceWhen = 21
|
||||
endWhen = 1000 //Ends when all vending machines are subverted anyway.
|
||||
|
||||
var/list/obj/machinery/economy/vending/vendingMachines = list()
|
||||
var/list/obj/machinery/economy/vending/infectedMachines = list()
|
||||
@@ -47,7 +51,7 @@
|
||||
log_debug("Original brand intelligence machine: [originMachine] ([ADMIN_VV(originMachine,"VV")]) [ADMIN_JMP(originMachine)]")
|
||||
|
||||
/datum/event/brand_intelligence/tick()
|
||||
if(originMachine.shut_up || originMachine.wires.is_all_cut()) //if the original vending machine is missing or has it's voice switch flipped
|
||||
if(originMachine?.shut_up || originMachine?.wires.is_all_cut()) //if the original vending machine is missing or has it's voice switch flipped
|
||||
origin_machine_defeated()
|
||||
return
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/datum/event/bureaucratic_error
|
||||
name = "Bureaucratic Error"
|
||||
announceWhen = 1
|
||||
/// Jobs that are not allowed to be picked for the bureaucratic error
|
||||
var/list/blacklisted_jobs = list(
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/datum/event/camera_failure
|
||||
name = "Camera Failure"
|
||||
role_weights = list(ASSIGNMENT_ENGINEERING = 10)
|
||||
|
||||
/datum/event/camera_failure/start()
|
||||
var/failed_cameras
|
||||
var/failure_limit = rand(1, 3)
|
||||
|
||||
@@ -1,14 +1,35 @@
|
||||
/datum/event/carp_migration
|
||||
name = "Carp Migration"
|
||||
announceWhen = 50
|
||||
endWhen = 900
|
||||
|
||||
noAutoEnd = TRUE
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
role_weights = list(ASSIGNMENT_ENGINEERING = 1, ASSIGNMENT_SECURITY = 2)
|
||||
role_requirements = list(ASSIGNMENT_ENGINEERING = 1, ASSIGNMENT_SECURITY = 1.5)
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
var/list/spawned_mobs = list(
|
||||
/mob/living/basic/carp = 95,
|
||||
/mob/living/basic/carp/megacarp = 5)
|
||||
/// Carps spawned by the event
|
||||
var/list/my_carps = list()
|
||||
/// Did we manage to spawn carps
|
||||
var/spawned = FALSE
|
||||
|
||||
/datum/event/carp_migration/process()
|
||||
if(!length(my_carps) && spawned)
|
||||
kill()
|
||||
return ..()
|
||||
|
||||
// Resource calculation independent of event
|
||||
/datum/event/carp_migration/event_resource_cost()
|
||||
return list()
|
||||
|
||||
/datum/event/carp_migration/proc/remove_carp(mob/source)
|
||||
SIGNAL_HANDLER // COMSIG_MOB_DEATH
|
||||
my_carps -= source
|
||||
UnregisterSignal(source, COMSIG_MOB_DEATH)
|
||||
|
||||
/datum/event/carp_migration/setup()
|
||||
announceWhen = rand(40, 60)
|
||||
endWhen = rand(600, 1200)
|
||||
|
||||
/datum/event/carp_migration/announce()
|
||||
var/announcement = ""
|
||||
@@ -40,5 +61,8 @@
|
||||
var/group_size = rand(group_size_min, group_size_max)
|
||||
for(var/j = 1, j <= group_size, j++)
|
||||
var/carptype = pickweight(spawned_mobs)
|
||||
new carptype(spawn_locations[i])
|
||||
var/mob/carp = new carptype(spawn_locations[i])
|
||||
RegisterSignal(carp, COMSIG_MOB_DEATH, PROC_REF(remove_carp))
|
||||
my_carps += carp
|
||||
spawned = TRUE
|
||||
i++
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "disposals clog"
|
||||
startWhen = 10
|
||||
endWhen = 35
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
var/notify_title = "Clogged Disposals"
|
||||
var/notify_image = "disposal-flush"
|
||||
var/list/bins = list()
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/datum/event/communications_blackout
|
||||
name = "Communication Blackout"
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
|
||||
/datum/event/communications_blackout/announce(false_alarm)
|
||||
var/alert = pick( "Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you*%fj00)`5vc-BZZT", \
|
||||
"Ionospheric anomalies detected. Temporary telecommunication failu*3mga;b4;'1v?-BZZZT", \
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
name = "demon incursion"
|
||||
/// Corresponds to the number of process() runs the event has lasted for. Roughly 2 minutes here.
|
||||
announceWhen = 60
|
||||
/// Corresponds to the number of process() runs the event has lasted for. Roughly 2 minutes here.
|
||||
endWhen = 60
|
||||
noAutoEnd = TRUE
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 4, ASSIGNMENT_CREW = 1, ASSIGNMENT_MEDICAL = 2)
|
||||
role_requirements = list(ASSIGNMENT_SECURITY = 3, ASSIGNMENT_CREW = 35, ASSIGNMENT_MEDICAL = 3)
|
||||
nominal_severity = EVENT_LEVEL_MAJOR
|
||||
/// The name of the notification for dchat
|
||||
var/notify_title = "Demonic Incursion"
|
||||
/// The icon of the notification
|
||||
@@ -12,6 +14,17 @@
|
||||
var/list/portal_list = list()
|
||||
/// The target number of portals
|
||||
var/target_portals = 100
|
||||
/// Toggled when the first portal is spawned
|
||||
var/spawned = FALSE
|
||||
|
||||
|
||||
/datum/event/demon_incursion/tick()
|
||||
if(!length(portal_list) && spawned)
|
||||
kill()
|
||||
|
||||
// Costs are calculated independently of event
|
||||
/datum/event/demon_incursion/event_resource_cost()
|
||||
return list()
|
||||
|
||||
/datum/event/demon_incursion/setup()
|
||||
impact_area = findEventArea()
|
||||
@@ -55,6 +68,7 @@
|
||||
if(length(portal_list) > target_portals)
|
||||
target_portals *= 2
|
||||
prepare_spawn_elite()
|
||||
spawned = TRUE
|
||||
|
||||
/datum/event/demon_incursion/proc/prepare_spawn_elite()
|
||||
var/obj/structure/spawner/nether/demon_incursion/elite_portal = pick(portal_list)
|
||||
@@ -148,6 +162,17 @@
|
||||
if(turf_to_spread)
|
||||
spread_turf()
|
||||
SSticker.mode.incursion_portals += src
|
||||
AddComponent(/datum/component/event_tracker, EVENT_DEMONIC)
|
||||
|
||||
/obj/structure/spawner/nether/demon_incursion/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z))
|
||||
return list(ASSIGNMENT_SECURITY = 1, ASSIGNMENT_CREW = 5, ASSIGNMENT_MEDICAL = 1)
|
||||
|
||||
/obj/structure/spawner/nether/demon_incursion/Destroy()
|
||||
if(linked_incursion)
|
||||
linked_incursion.portal_list -= src
|
||||
. = ..()
|
||||
|
||||
/obj/structure/spawner/nether/demon_incursion/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -2,8 +2,12 @@ GLOBAL_LIST_EMPTY(current_pending_diseases)
|
||||
/datum/event/disease_outbreak
|
||||
// We only want the announcement to happen after the virus has spawned on station
|
||||
announceWhen = -1
|
||||
// Keep the event running until we announce it
|
||||
// Keep the event running for as long as we have infected
|
||||
noAutoEnd = TRUE
|
||||
name = "Disease Outbreak"
|
||||
role_weights = list(ASSIGNMENT_MEDICAL = 5, ASSIGNMENT_VIROLOGIST = 5, ASSIGNMENT_BOTANIST = 2, ASSIGNMENT_CHEMIST = 2)
|
||||
role_requirements = list(ASSIGNMENT_MEDICAL = 4, ASSIGNMENT_VIROLOGIST = 1, ASSIGNMENT_BOTANIST = 0, ASSIGNMENT_CHEMIST = 1)
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
/// The type of disease that patient zero will be infected with.
|
||||
var/datum/disease/chosen_disease
|
||||
|
||||
@@ -17,6 +21,7 @@ GLOBAL_LIST_EMPTY(current_pending_diseases)
|
||||
var/static/list/diseases_moderate_major = list()
|
||||
var/force_disease_time = 300
|
||||
var/list/infected_players = list()
|
||||
var/first_infection = FALSE
|
||||
|
||||
/datum/event/disease_outbreak/setup()
|
||||
if(isemptylist(diseases_minor) && isemptylist(diseases_moderate_major))
|
||||
@@ -57,10 +62,10 @@ GLOBAL_LIST_EMPTY(current_pending_diseases)
|
||||
GLOB.minor_announcement.Announce("Moderate contagion detected aboard [station_name()].", new_sound = 'sound/misc/notice2.ogg', new_title = "Contagion Alert")
|
||||
if(EVENT_LEVEL_MUNDANE)
|
||||
GLOB.minor_announcement.Announce("Minor contagion detected aboard [station_name()].", new_sound = 'sound/misc/notice2.ogg', new_title = "Contagion Alert")
|
||||
// We did our announcement, the event no longer needs to run
|
||||
kill()
|
||||
|
||||
/datum/event/disease_outbreak/process()
|
||||
if(length(infected_players) > 0)
|
||||
first_infection = TRUE
|
||||
if(activeFor == force_disease_time)
|
||||
for(var/list/disease_event in GLOB.current_pending_diseases)
|
||||
if(chosen_disease == disease_event["disease"])
|
||||
@@ -71,8 +76,16 @@ GLOBAL_LIST_EMPTY(current_pending_diseases)
|
||||
break
|
||||
if(length(infected_players) > 2 && announceWhen <= 0)
|
||||
announceWhen = activeFor + 180
|
||||
// The event ends when everyone is cured
|
||||
if(length(infected_players) <= 0 && first_infection)
|
||||
kill()
|
||||
. = ..()
|
||||
|
||||
/// Cost of ongoing disease outbreak. 1 medical personnal per 2 infected at major severity.
|
||||
/datum/event/disease_outbreak/event_resource_cost()
|
||||
return list("[ASSIGNMENT_MEDICAL]" = (severity / nominal_severity) * (length(infected_players) / 3), "[ASSIGNMENT_VIROLOGIST]" = 1)
|
||||
|
||||
|
||||
//Creates a virus with a harmful effect, guaranteed to be spreadable by contact or airborne
|
||||
/datum/event/disease_outbreak/proc/create_virus(max_severity = 6)
|
||||
var/datum/disease/advance/A = new /datum/disease/advance(_event = UID())
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/datum/event/door_runtime
|
||||
name = "Door Runtime"
|
||||
role_weights = list(ASSIGNMENT_CREW = 0.2)
|
||||
role_requirements = list(ASSIGNMENT_CREW = 0)
|
||||
|
||||
/datum/event/door_runtime/announce()
|
||||
GLOB.minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.", "Network Alert", 'sound/AI/door_runtimes.ogg')
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
/datum/event/electrical_storm
|
||||
name = "Electrical Storm"
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
role_weights = list(ASSIGNMENT_ENGINEERING = 4, ASSIGNMENT_JANITOR = 3)
|
||||
role_requirements = list(ASSIGNMENT_ENGINEERING = 3, ASSIGNMENT_JANITOR = 1)
|
||||
var/lightsoutAmount = 1
|
||||
var/lightsoutRange = 25
|
||||
|
||||
|
||||
@@ -1,44 +1,50 @@
|
||||
/datum/event_meta
|
||||
var/name = ""
|
||||
var/name = ""
|
||||
/// Whether or not the event is available for random selection at all.
|
||||
var/enabled = TRUE
|
||||
var/enabled = TRUE
|
||||
/// The base weight of this event. A zero means it may never fire, but see get_weight()
|
||||
var/weight
|
||||
/// The minimum weight that this event will have. Only used if non-zero.
|
||||
var/min_weight
|
||||
/// The maximum weight that this event will have.
|
||||
var/max_weight
|
||||
/// the current severity of this event
|
||||
var/severity
|
||||
/// If true, then the event will not be re-added to the list of available events
|
||||
var/one_shot
|
||||
/// A modifier applied to all event weights (role and base), respects min and max
|
||||
var/weight_mod = 1
|
||||
/// A list of roles that add weight to the event
|
||||
var/list/role_weights = list()
|
||||
var/datum/event/event_type
|
||||
/// Event held by this meta event. Used to do things like calculate weight.
|
||||
var/datum/event/skeleton
|
||||
/// How early this specific event can run
|
||||
var/first_run_time = 0
|
||||
|
||||
/datum/event_meta/New(event_severity, event_name, datum/event/type, event_weight, list/job_weights, is_one_shot = FALSE, min_event_weight = 0, max_event_weight = INFINITY)
|
||||
name = event_name
|
||||
severity = event_severity
|
||||
event_type = type
|
||||
/datum/event_meta/New(event_severity, type, event_weight, is_one_shot = FALSE, min_event_weight = 0, max_event_weight = INFINITY, _first_run_time)
|
||||
if(type)
|
||||
skeleton = new type(EM = src, skeleton = TRUE, _severity = event_severity)
|
||||
name = skeleton.name
|
||||
one_shot = is_one_shot
|
||||
weight = event_weight
|
||||
min_weight = min_event_weight
|
||||
max_weight = max_event_weight
|
||||
if(job_weights)
|
||||
role_weights = job_weights
|
||||
first_run_time = _first_run_time
|
||||
|
||||
/datum/event_meta/proc/get_weight(list/active_with_role)
|
||||
if(!enabled)
|
||||
/datum/event_meta/proc/change_event(type)
|
||||
var/event_severity = 0
|
||||
if(skeleton)
|
||||
event_severity = skeleton.severity
|
||||
skeleton.event_meta = null
|
||||
qdel(skeleton)
|
||||
skeleton = new type(EM = src, skeleton = TRUE, _severity = event_severity)
|
||||
|
||||
/datum/event_meta/proc/get_weight(list/total_resources)
|
||||
if(!enabled || !skeleton)
|
||||
return 0
|
||||
|
||||
var/job_weight = 0
|
||||
for(var/role in role_weights)
|
||||
if(role in active_with_role)
|
||||
job_weight += active_with_role[role] * role_weights[role]
|
||||
|
||||
return clamp((weight + job_weight) * weight_mod, min_weight, max_weight)
|
||||
var/resource_effect = skeleton.get_weight(total_resources)
|
||||
var/new_weight = weight
|
||||
if(resource_effect > 0)
|
||||
new_weight *= (1.003 ** resource_effect)
|
||||
if(resource_effect < 0)
|
||||
new_weight *= 0.95 ** -resource_effect
|
||||
return clamp((new_weight) * weight_mod, min_weight, max_weight)
|
||||
|
||||
/*/datum/event_meta/ninja/get_weight(var/list/active_with_role)
|
||||
if(toggle_space_ninja)
|
||||
@@ -57,6 +63,8 @@
|
||||
var/endWhen = 0
|
||||
/// Severity. Lower means less severe, higher means more severe. Does not have to be supported. Is set on New().
|
||||
var/severity = 0
|
||||
/// The severity the event has normally
|
||||
var/nominal_severity = EVENT_LEVEL_MUNDANE
|
||||
/// How long the event has existed. You don't need to change this.
|
||||
var/activeFor = 0
|
||||
/// If this event is currently running. You should not change this.
|
||||
@@ -70,8 +78,29 @@
|
||||
/// The area the event will hit
|
||||
var/area/impact_area
|
||||
var/datum/event_meta/event_meta = null
|
||||
/// The base weight of each role on the event for the purpose of calculating event weight and resource cost
|
||||
var/list/role_weights = list()
|
||||
/// A baseline requirement of different roles the event has at it's nominal severity
|
||||
var/list/role_requirements = list()
|
||||
|
||||
/datum/event/nothing
|
||||
name = "Nothing"
|
||||
|
||||
/datum/event/nothing/has_cooldown()
|
||||
return FALSE
|
||||
|
||||
/datum/event/nothing/is_relative()
|
||||
return TRUE
|
||||
|
||||
/// Calculate the weight for rolling the event based on round circumstances.
|
||||
/datum/event/proc/get_weight(list/total_resources)
|
||||
var/job_weight = 0
|
||||
for(var/role in role_weights)
|
||||
var/role_available = total_resources[role] ? total_resources[role] : 0
|
||||
var/difference = (role_available - role_requirements[role] * (severity / nominal_severity)) * role_weights[role]
|
||||
// We add difference if it's negative, or the square root if it's positive
|
||||
job_weight += difference
|
||||
return job_weight
|
||||
|
||||
/**
|
||||
* Called first before processing.
|
||||
@@ -177,18 +206,27 @@
|
||||
SSevents.active_events -= src
|
||||
SSevents.event_complete(src)
|
||||
|
||||
/datum/event/New(datum/event_meta/EM, skeleton = FALSE)
|
||||
// Events have cooldown by default
|
||||
/datum/event/proc/has_cooldown()
|
||||
return TRUE
|
||||
|
||||
/datum/event/proc/is_relative()
|
||||
return FALSE
|
||||
|
||||
/datum/event/New(datum/event_meta/EM, skeleton = FALSE, _severity)
|
||||
// event needs to be responsible for this, as stuff like APLUs currently make their own events for curious reasons
|
||||
if(!skeleton)
|
||||
SSevents.active_events += src
|
||||
|
||||
if(!EM)
|
||||
EM = new /datum/event_meta(EVENT_LEVEL_MAJOR, "Unknown, Most likely admin called", src.type)
|
||||
|
||||
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
|
||||
|
||||
severity = _severity ? _severity : nominal_severity
|
||||
if(severity < EVENT_LEVEL_MUNDANE)
|
||||
severity = EVENT_LEVEL_MUNDANE
|
||||
log_debug("Event of '[type]' with severity below mundane run has run")
|
||||
if(severity > EVENT_LEVEL_DISASTER)
|
||||
severity = EVENT_LEVEL_DISASTER
|
||||
log_debug("Event of '[type]' with severity above disaster has run")
|
||||
|
||||
startedAt = world.time
|
||||
|
||||
@@ -208,3 +246,7 @@
|
||||
/// If this proc returns TRUE, the regular Announce() won't be called.
|
||||
/datum/event/proc/fake_announce()
|
||||
return FALSE
|
||||
|
||||
/// The amount of people in different roles needed to handle an ongoing event.
|
||||
/datum/event/proc/event_resource_cost()
|
||||
return role_requirements
|
||||
|
||||
@@ -1,16 +1,4 @@
|
||||
#define ASSIGNMENT_ANY "Any"
|
||||
#define ASSIGNMENT_AI "AI"
|
||||
#define ASSIGNMENT_CYBORG "Cyborg"
|
||||
#define ASSIGNMENT_ENGINEER "Engineer"
|
||||
#define ASSIGNMENT_BOTANIST "Botanist"
|
||||
#define ASSIGNMENT_JANITOR "Janitor"
|
||||
#define ASSIGNMENT_MEDICAL "Medical"
|
||||
#define ASSIGNMENT_SCIENTIST "Scientist"
|
||||
#define ASSIGNMENT_SECURITY "Security"
|
||||
#define ASSIGNMENT_CHEMIST "Chemist"
|
||||
#define ASSIGNMENT_CARGO "Cargo Bay"
|
||||
|
||||
GLOBAL_LIST_INIT(severity_to_string, list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT_LEVEL_MODERATE = "Moderate", EVENT_LEVEL_MAJOR = "Major"))
|
||||
GLOBAL_LIST_INIT(severity_to_string, alist(EVENT_LEVEL_MUNDANE = "Mundane", EVENT_LEVEL_MODERATE = "Moderate", EVENT_LEVEL_MAJOR = "Major", EVENT_LEVEL_DISASTER = "Disaster"))
|
||||
GLOBAL_LIST_EMPTY(event_last_fired)
|
||||
|
||||
/datum/event_container
|
||||
@@ -23,6 +11,12 @@ GLOBAL_LIST_EMPTY(event_last_fired)
|
||||
var/datum/event_meta/next_event = null
|
||||
|
||||
var/last_world_time = 0
|
||||
/// Records the initial amount of events in the available event list
|
||||
var/initial_event_count = 0
|
||||
|
||||
/datum/event_container/New()
|
||||
. = ..()
|
||||
initial_event_count = length(available_events)
|
||||
|
||||
/datum/event_container/process()
|
||||
if(!next_event_time)
|
||||
@@ -47,38 +41,48 @@ GLOBAL_LIST_EMPTY(event_last_fired)
|
||||
set_event_delay()
|
||||
next_event.enabled = !next_event.one_shot // This event will no longer be available in the random rotation if one shot
|
||||
|
||||
new next_event.event_type(next_event) // Events are added and removed from the processing queue in their New/kill procs
|
||||
new next_event.skeleton.type(next_event, _severity = next_event.skeleton.severity) // Events are added and removed from the processing queue in their New/kill procs
|
||||
|
||||
log_debug("Starting event '[next_event.name]' of severity [GLOB.severity_to_string[severity]].")
|
||||
SSblackbox.record_feedback("nested tally", "events", 1, list(GLOB.severity_to_string[severity], next_event.name))
|
||||
log_debug("Starting event '[next_event.skeleton.name]' of severity [GLOB.severity_to_string[severity]].")
|
||||
SSblackbox.record_feedback("nested tally", "events", 1, list(GLOB.severity_to_string[severity], next_event.skeleton.name))
|
||||
GLOB.event_last_fired[next_event] = world.time
|
||||
next_event = null // When set to null, a random event will be selected next time
|
||||
var/datum/event_meta/meta = next_event
|
||||
next_event = null // When set to null, a random event will be selected next time
|
||||
// Used for checks about the event we just ran
|
||||
return meta
|
||||
else
|
||||
// If not, wait for one minute, instead of one tick, before checking again.
|
||||
next_event_time += (60 * 10)
|
||||
|
||||
|
||||
|
||||
/datum/event_container/proc/acquire_event()
|
||||
if(length(available_events) == 0)
|
||||
return
|
||||
var/active_with_role = number_active_with_role()
|
||||
// A list of the net available resources of each department depending on staffing and active threats/events
|
||||
var/list/total_resources = get_total_resources()
|
||||
|
||||
var/list/possible_events = list()
|
||||
for(var/datum/event_meta/EM in available_events)
|
||||
var/event_weight = EM.get_weight(active_with_role)
|
||||
if(EM.enabled && event_weight)
|
||||
possible_events[EM] = event_weight
|
||||
var/event_weight = EM.get_weight(total_resources)
|
||||
// We use the amount of non disabled events to adjust the value of Nothing, so we count 0 weight events
|
||||
if(EM.enabled && EM.first_run_time < world.time - SSticker.time_game_started)
|
||||
possible_events[EM] = max(event_weight, 0)
|
||||
// For events like nothing we want to have their weight adjusted depending on how many events are left of the original list
|
||||
if(EM.skeleton.is_relative())
|
||||
possible_events[EM] *= (length(available_events) / initial_event_count)
|
||||
|
||||
for(var/event_meta in last_event_time) if(possible_events[event_meta])
|
||||
var/time_passed = world.time - GLOB.event_last_fired[event_meta]
|
||||
var/half_of_round = GLOB.configuration.event.expected_round_length / 2
|
||||
var/weight_modifier = min(1, 1 - ((half_of_round - time_passed) / half_of_round))
|
||||
//With this formula, an event ran 30 minutes ago has half weight, and an event ran an hour ago, has 100 % weight. This works better in general for events, as super high weight events are impacted in a meaningful way.
|
||||
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
|
||||
for(var/datum/event_meta/event_meta in last_event_time)
|
||||
if(!event_meta.skeleton)
|
||||
continue
|
||||
if(event_meta.skeleton.has_cooldown() && possible_events[event_meta])
|
||||
var/time_passed = world.time - GLOB.event_last_fired[event_meta]
|
||||
var/cooldown = GLOB.configuration.event.expected_round_length / 2
|
||||
var/weight_modifier = 1 - max(0, 0.5 * ((cooldown - time_passed) / cooldown))
|
||||
// Events that just ran have their base weight reduced by half, tapering to no reduction over half an hour
|
||||
var/new_weight = max(possible_events[event_meta] * weight_modifier, 0)
|
||||
if(new_weight)
|
||||
possible_events[event_meta] = new_weight
|
||||
|
||||
if(length(possible_events) == 0)
|
||||
return null
|
||||
@@ -88,6 +92,23 @@ GLOBAL_LIST_EMPTY(event_last_fired)
|
||||
available_events -= picked_event
|
||||
return picked_event
|
||||
|
||||
/datum/event_container/proc/get_playercount_modifier()
|
||||
switch(length(GLOB.player_list))
|
||||
if(0 to 10)
|
||||
return 1.1
|
||||
if(11 to 15)
|
||||
return 1.05
|
||||
if(16 to 25)
|
||||
return 1
|
||||
if(26 to 35)
|
||||
return 0.95
|
||||
if(36 to 50)
|
||||
return 0.9
|
||||
if(50 to 80)
|
||||
return 0.85
|
||||
if(80 to 10000)
|
||||
return 0.8
|
||||
|
||||
/datum/event_container/proc/set_event_delay()
|
||||
// If the next event time has not yet been set and we have a custom first time start
|
||||
if(next_event_time == 0 && GLOB.configuration.event.first_run_times[severity])
|
||||
@@ -97,30 +118,14 @@ GLOBAL_LIST_EMPTY(event_last_fired)
|
||||
next_event_time = world.time + event_delay
|
||||
// Otherwise, follow the standard setup process
|
||||
else
|
||||
var/playercount_modifier = 1
|
||||
switch(length(GLOB.player_list))
|
||||
if(0 to 10)
|
||||
playercount_modifier = 1.2
|
||||
if(11 to 15)
|
||||
playercount_modifier = 1.1
|
||||
if(16 to 25)
|
||||
playercount_modifier = 1
|
||||
if(26 to 35)
|
||||
playercount_modifier = 0.9
|
||||
if(36 to 50)
|
||||
playercount_modifier = 0.8
|
||||
if(50 to 80)
|
||||
playercount_modifier = 0.7
|
||||
if(80 to 10000)
|
||||
playercount_modifier = 0.6
|
||||
|
||||
playercount_modifier = playercount_modifier * delay_modifier
|
||||
|
||||
var/event_delay = rand(GLOB.configuration.event.delay_lower_bound[severity], GLOB.configuration.event.delay_upper_bound[severity]) * playercount_modifier
|
||||
var/event_delay = calculate_event_delay()
|
||||
next_event_time = world.time + event_delay
|
||||
|
||||
log_debug("Next event of severity [GLOB.severity_to_string[severity]] in [(next_event_time - world.time)/600] minutes.")
|
||||
|
||||
/datum/event_container/proc/calculate_event_delay()
|
||||
return rand(GLOB.configuration.event.delay_lower_bound[severity], GLOB.configuration.event.delay_upper_bound[severity]) * delay_modifier * get_playercount_modifier()
|
||||
|
||||
/datum/event_container/proc/SelectEvent()
|
||||
var/datum/event_meta/EM = input("Select an event to queue up.", "Event Selection", null) as null|anything in available_events
|
||||
if(!EM)
|
||||
@@ -135,98 +140,118 @@ GLOBAL_LIST_EMPTY(event_last_fired)
|
||||
severity = EVENT_LEVEL_MUNDANE
|
||||
available_events = list(
|
||||
// Severity level, event name, event type, base weight, role weights, one shot, min weight, max weight. Last two only used if set.
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 1100),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), FALSE, 25, 50),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Economic News", /datum/event/economic_event, 300),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Mundane News", /datum/event/mundane_news, 300),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Sentience", /datum/event/sentience, 50),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Fungal Growth", /datum/event/wallrot/fungus, 50, list(ASSIGNMENT_CHEMIST = 50)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Koi School", /datum/event/carp_migration/koi, 80),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Camera Failure", /datum/event/camera_failure, 100, list(ASSIGNMENT_ENGINEER = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Fake Virus", /datum/event/fake_virus, 50),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Bureaucratic Error",/datum/event/bureaucratic_error, 40, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Disease Outbreak", /datum/event/disease_outbreak, 50, list(ASSIGNMENT_MEDICAL = 25), TRUE)
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/nothing, 252),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/pda_spam, 9),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/economic_event, 7),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/trivial_news, 7),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/mundane_news, 7),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/infestation, 11),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/sentience, 15),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/wallrot, 10),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/wallrot/fungus, 10),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/carp_migration/koi, 12),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/camera_failure, 12),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/fake_virus, 12),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/bureaucratic_error, 12, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, /datum/event/disease_outbreak, 12, TRUE)
|
||||
)
|
||||
|
||||
/datum/event_container/moderate
|
||||
severity = EVENT_LEVEL_MODERATE
|
||||
available_events = list(
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Nothing", /datum/event/nothing, 1230),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "False Alarm", /datum/event/falsealarm, 200),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Appendicitis", /datum/event/spontaneous_appendicitis, 0, list(ASSIGNMENT_MEDICAL = 10), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School", /datum/event/carp_migration, 200, list(ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_SECURITY = 20), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 0, list(ASSIGNMENT_SECURITY = 20)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Vines", /datum/event/spacevine, 250, list(ASSIGNMENT_ENGINEER = 10)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 25)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Solar Flare", /datum/event/solar_flare, 0, list(ASSIGNMENT_ENGINEER = 25)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meaty Ores", /datum/event/dust/meaty, 0, list(ASSIGNMENT_ENGINEER = 20)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Communication Blackout", /datum/event/communications_blackout, 500, list(ASSIGNMENT_AI = 150, ASSIGNMENT_SECURITY = 120)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/nothing, 800),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/falsealarm, 20),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/spontaneous_appendicitis, 5, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/carp_migration, 10, , TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/rogue_drone, 7),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/spacevine, 15),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/meteor_wave, 8, _first_run_time = 40 MINUTES),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/solar_flare, 12),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/dust/meaty, 8, _first_run_time = 40 MINUTES),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/communications_blackout, 10),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/prison_break, 7),
|
||||
//new /datum/event_meta(EVENT_LEVEL_MODERATE, "Virology Breach", /datum/event/prison_break/virology, 0, list(ASSIGNMENT_MEDICAL = 100)),
|
||||
//new /datum/event_meta(EVENT_LEVEL_MODERATE, "Xenobiology Breach", /datum/event/prison_break/xenobiology, 0, list(ASSIGNMENT_SCIENCE = 100)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "APC Short", /datum/event/apc_short, 200, list(ASSIGNMENT_ENGINEER = 60)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 250, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_JANITOR = 150)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 25, list(ASSIGNMENT_MEDICAL = 50), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ion_storm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/apc_short, 12),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/electrical_storm, 12),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/radiation_storm, 10, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/spider_infestation, 10, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/ion_storm, 10),
|
||||
//new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 15), TRUE),
|
||||
// NON-BAY EVENTS
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Mass Hallucination", /datum/event/mass_hallucination, 300),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Brand Intelligence", /datum/event/brand_intelligence, 50, list(ASSIGNMENT_ENGINEER = 25), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Dimensional Tear", /datum/event/tear, 0, list(ASSIGNMENT_SECURITY = 35)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Honknomoly", /datum/event/tear/honk, 0, list(ASSIGNMENT_SECURITY = 15)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Vent Clog", /datum/event/vent_clog, 250),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Disposals Clog", /datum/event/disposals_clog, 250),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Wormholes", /datum/event/wormholes, 150),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Pyro Anomaly", /datum/event/anomaly/anomaly_pyro, 75, list(ASSIGNMENT_ENGINEER = 60)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Cryo Anomaly", /datum/event/anomaly/anomaly_cryo, 75, list(ASSIGNMENT_ENGINEER = 60)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Vortex Anomaly", /datum/event/anomaly/anomaly_vortex, 75, list(ASSIGNMENT_ENGINEER = 25)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Bluespace Anomaly", /datum/event/anomaly/anomaly_bluespace, 75, list(ASSIGNMENT_ENGINEER = 25)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Flux Anomaly", /datum/event/anomaly/anomaly_flux, 75, list(ASSIGNMENT_ENGINEER = 50)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravitational Anomaly", /datum/event/anomaly/anomaly_grav, 200),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Revenant", /datum/event/revenant, 150),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Morph Spawn", /datum/event/spawn_morph, 40, list(ASSIGNMENT_SECURITY = 10), is_one_shot = TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Disease Outbreak", /datum/event/disease_outbreak, 50, list(ASSIGNMENT_MEDICAL = 30), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Door Runtime", /datum/event/door_runtime, 50, list(ASSIGNMENT_ENGINEER = 25, ASSIGNMENT_AI = 150), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Tourist Arrivals", /datum/event/tourist_arrivals, 100, list(ASSIGNMENT_SECURITY = 15), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Shuttle Loan", /datum/event/shuttle_loan, 100, list(ASSIGNMENT_CARGO = 15, ASSIGNMENT_SECURITY = 10), is_one_shot = TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Anomalous Particulate", /datum/event/anomalous_particulate_event, 250, is_one_shot = TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/mass_hallucination, 10),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/brand_intelligence, 5, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/tear, 15),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/tear/honk, 10),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/vent_clog, 12),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/disposals_clog, 12),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/wormholes, 15),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/anomaly/anomaly_pyro, 7),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/anomaly/anomaly_cryo, 7),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/anomaly/anomaly_vortex, 7),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/anomaly/anomaly_bluespace, 7),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/anomaly/anomaly_flux, 7),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/anomaly/anomaly_grav, 7),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/disease_outbreak, 15, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/door_runtime, 10, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/tourist_arrivals, 40, TRUE, _first_run_time = 35 MINUTES),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/shuttle_loan, 50, is_one_shot = TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/anomalous_particulate_event, 60, is_one_shot = TRUE),
|
||||
)
|
||||
|
||||
/datum/event_container/major
|
||||
severity = EVENT_LEVEL_MAJOR
|
||||
available_events = list(
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 590),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 10, list(ASSIGNMENT_SECURITY = 3), TRUE),
|
||||
//new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station, 0, list(ASSIGNMENT_ANY = 5)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "APC Overload", /datum/event/apc_overload, 0),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 20, list(ASSIGNMENT_ENGINEER = 4), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 10), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Abductor Visit", /datum/event/abductor, 20, list(ASSIGNMENT_SECURITY = 3), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 15, list(ASSIGNMENT_SECURITY = 3), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Traders", /datum/event/traders, 85, is_one_shot = TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Terror Spiders", /datum/event/spider_terror, 15, list(ASSIGNMENT_SECURITY = 3), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Slaughter Demon", /datum/event/spawn_slaughter, 20, is_one_shot = TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Shadow Demon", /datum/event/spawn_slaughter/shadow, 20, is_one_shot = TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Demonic Incursion", /datum/event/demon_incursion, 20, list(ASSIGNMENT_SECURITY = 3)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Immovable Rod", /datum/event/immovable_rod, 0, list(ASSIGNMENT_ENGINEER = 10), TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Disease Outbreak", /datum/event/disease_outbreak, 15, list(ASSIGNMENT_MEDICAL = 4), TRUE),
|
||||
//new /datum/event_meta(EVENT_LEVEL_MAJOR, "Floor Cluwne", /datum/event/spawn_floor_cluwne, 15, is_one_shot = TRUE)
|
||||
//new /datum/event_meta(EVENT_LEVEL_MAJOR, "Pulse Demon Infiltration", /datum/event/spawn_pulsedemon, 20, is_one_shot = TRUE)
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/nothing, 275),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/carp_migration, 13, TRUE),
|
||||
//new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/prison_break/station, 10),
|
||||
//new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/apc_overload, 11),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/meteor_wave, 9, TRUE, _first_run_time = 40 MINUTES),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/abductor, 12, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/traders, 13, is_one_shot = TRUE, _first_run_time = 35 MINUTES),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_slaughter, 8, is_one_shot = TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_slaughter/shadow, 8, is_one_shot = TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/immovable_rod, 9, TRUE, _first_run_time = 40 MINUTES),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/demon_incursion, 10, TRUE, _first_run_time = 35 MINUTES),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/disease_outbreak, 8, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/revenant, 9),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_morph, 16, is_one_shot = TRUE),
|
||||
//new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_floor_cluwne, 15, is_one_shot = TRUE)
|
||||
//new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_pulsedemon, 20, is_one_shot = TRUE)
|
||||
)
|
||||
|
||||
// The weights here are set up to roll an event about 1 in 3 rounds, assuming you roll as much as possible
|
||||
/datum/event_container/disaster
|
||||
severity = EVENT_LEVEL_DISASTER
|
||||
available_events = list(
|
||||
new /datum/event_meta(EVENT_LEVEL_DISASTER, /datum/event/nothing, 5730),
|
||||
new /datum/event_meta(EVENT_LEVEL_DISASTER, /datum/event/blob, 100, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_DISASTER, /datum/event/alien_infestation, 100, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_DISASTER, /datum/event/spider_terror, 100, TRUE)
|
||||
)
|
||||
var/activation_counter = 0
|
||||
var/event_rolls = 0
|
||||
|
||||
#undef ASSIGNMENT_ANY
|
||||
#undef ASSIGNMENT_AI
|
||||
#undef ASSIGNMENT_CYBORG
|
||||
#undef ASSIGNMENT_ENGINEER
|
||||
#undef ASSIGNMENT_BOTANIST
|
||||
#undef ASSIGNMENT_JANITOR
|
||||
#undef ASSIGNMENT_MEDICAL
|
||||
#undef ASSIGNMENT_SCIENTIST
|
||||
#undef ASSIGNMENT_SECURITY
|
||||
#undef ASSIGNMENT_CHEMIST
|
||||
#undef ASSIGNMENT_CARGO
|
||||
/datum/event_container/disaster/get_playercount_modifier()
|
||||
return 1
|
||||
|
||||
/datum/event_container/disaster/acquire_event()
|
||||
// We should only be getting one none nothing disaster roll per round, and doing it this way leaves more room for admins to play around with it.
|
||||
if(activation_counter > 0)
|
||||
for(var/datum/event_meta/meta in available_events)
|
||||
if(istype(meta.skeleton, /datum/event/nothing))
|
||||
return meta
|
||||
event_rolls++
|
||||
. = ..()
|
||||
|
||||
/datum/event_container/disaster/start_event()
|
||||
. = ..()
|
||||
var/datum/event_meta/meta = .
|
||||
if(!istype(meta.skeleton, /datum/event/nothing))
|
||||
activation_counter++
|
||||
|
||||
/datum/event_container/disaster/calculate_event_delay()
|
||||
. = ..()
|
||||
if(world.time - SSticker.time_game_started + . <= 120 MINUTES && world.time - SSticker.time_game_started + . >= 95 MINUTES)
|
||||
. += 30 MINUTES
|
||||
return
|
||||
|
||||
@@ -55,61 +55,66 @@
|
||||
|
||||
// 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.
|
||||
// Note that this isn't sorted just by department, because e.g. having a roboticist shouldn't make meteors spawn.
|
||||
/proc/number_active_with_role()
|
||||
var/list/active_with_role = list()
|
||||
active_with_role["Engineer"] = 0
|
||||
active_with_role["Medical"] = 0
|
||||
active_with_role["Security"] = 0
|
||||
active_with_role["Scientist"] = 0
|
||||
active_with_role["AI"] = 0
|
||||
active_with_role["Cyborg"] = 0
|
||||
active_with_role["Janitor"] = 0
|
||||
active_with_role["Botanist"] = 0
|
||||
active_with_role["Chemist"] = 0
|
||||
active_with_role["Any"] = length(GLOB.player_list)
|
||||
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.mind || !M.client || M.client.inactivity > 10 * 10 * 60) // longer than 10 minutes AFK counts them as inactive
|
||||
var/list/active_with_role = list()
|
||||
active_with_role[ASSIGNMENT_CREW] = 0
|
||||
active_with_role[ASSIGNMENT_COMMAND] = 0
|
||||
active_with_role[ASSIGNMENT_ENGINEERING] = 0
|
||||
active_with_role[ASSIGNMENT_MEDICAL] = 0
|
||||
active_with_role[ASSIGNMENT_SECURITY] = 0
|
||||
active_with_role[ASSIGNMENT_SCIENCE] = 0
|
||||
active_with_role[ASSIGNMENT_CARGO] = 0
|
||||
|
||||
if(length(SSevents.debug_resources))
|
||||
active_with_role = SSevents.debug_resources.Copy()
|
||||
|
||||
for(var/mob/player in GLOB.player_list)
|
||||
if(!player.mind?.assigned_role || player.stat == DEAD || !player.client || player.client.inactivity > 10 * 10 * 60) // longer than 10 minutes AFK counts them as inactive
|
||||
continue
|
||||
|
||||
if(isrobot(M))
|
||||
var/mob/living/silicon/robot/R = M
|
||||
var/capacity = player.get_event_capacity()
|
||||
|
||||
if(!capacity)
|
||||
continue
|
||||
|
||||
if(player.mind.assigned_role in (GLOB.exp_jobsmap[EXP_TYPE_CREW]["titles"]))
|
||||
active_with_role[ASSIGNMENT_CREW] += capacity
|
||||
|
||||
if(active_with_role[player.mind.assigned_role])
|
||||
active_with_role[player.mind.assigned_role]+= capacity
|
||||
else
|
||||
active_with_role[player.mind.assigned_role] = capacity
|
||||
|
||||
if(isrobot(player))
|
||||
var/mob/living/silicon/robot/R = player
|
||||
if(R.module && (R.module.name == "engineering robot module"))
|
||||
active_with_role["Engineer"]++
|
||||
active_with_role[ASSIGNMENT_ENGINEERING]+= capacity
|
||||
|
||||
if(R.module && (R.module.name == "medical robot module"))
|
||||
active_with_role["Medical"]++
|
||||
active_with_role[ASSIGNMENT_MEDICAL]+= capacity
|
||||
|
||||
if(R.module && (R.module.name == "security robot module"))
|
||||
active_with_role["Security"]++
|
||||
active_with_role[ASSIGNMENT_SECURITY]+= capacity
|
||||
|
||||
if(M.mind.assigned_role in list("Chief Engineer", "Station Engineer"))
|
||||
active_with_role["Engineer"]++
|
||||
if(player.mind.assigned_role in GLOB.engineering_positions)
|
||||
active_with_role[ASSIGNMENT_ENGINEERING]+= capacity
|
||||
|
||||
if(M.mind.assigned_role in list("Chief Medical Officer", "Medical Doctor"))
|
||||
active_with_role["Medical"]++
|
||||
if(player.mind.assigned_role in GLOB.medical_positions)
|
||||
active_with_role[ASSIGNMENT_MEDICAL]+= capacity
|
||||
|
||||
if(M.mind.assigned_role in GLOB.active_security_positions)
|
||||
active_with_role["Security"]++
|
||||
if(player.mind.assigned_role in GLOB.active_security_positions)
|
||||
active_with_role[ASSIGNMENT_SECURITY]+= capacity
|
||||
|
||||
if(M.mind.assigned_role in list("Research Director", "Scientist"))
|
||||
active_with_role["Scientist"]++
|
||||
if(player.mind.assigned_role in GLOB.science_positions)
|
||||
active_with_role[ASSIGNMENT_SCIENCE]+= capacity
|
||||
|
||||
if(M.mind.assigned_role == "AI")
|
||||
active_with_role["AI"]++
|
||||
if(player.mind.assigned_role in GLOB.supply_positions)
|
||||
active_with_role[ASSIGNMENT_CARGO]+= capacity
|
||||
|
||||
if(M.mind.assigned_role == "Cyborg")
|
||||
active_with_role["Cyborg"]++
|
||||
|
||||
if(M.mind.assigned_role == "Janitor")
|
||||
active_with_role["Janitor"]++
|
||||
|
||||
if(M.mind.assigned_role == "Botanist")
|
||||
active_with_role["Botanist"]++
|
||||
|
||||
if(M.mind.assigned_role == "Chemist")
|
||||
active_with_role["Chemist"]++
|
||||
if(player.mind.assigned_role in GLOB.command_positions)
|
||||
active_with_role[ASSIGNMENT_COMMAND]+= capacity
|
||||
|
||||
return active_with_role
|
||||
|
||||
@@ -119,3 +124,58 @@
|
||||
if(P.client)
|
||||
players++
|
||||
return players
|
||||
|
||||
/proc/event_category_cost(category)
|
||||
. = list()
|
||||
if(!category)
|
||||
return
|
||||
for(var/datum/component/event_tracker/tracker in GLOB.event_trackers["[category]"])
|
||||
var/costs = tracker.event_cost()
|
||||
for(var/key in costs)
|
||||
.["[key]"] += costs[key]
|
||||
|
||||
/proc/event_total_cost()
|
||||
. = list()
|
||||
for(var/category in GLOB.event_trackers)
|
||||
var/costs = event_category_cost(category)
|
||||
for(var/key in costs)
|
||||
.["[key]"] += costs[key]
|
||||
|
||||
/// Returns the net resources available for event rolling
|
||||
/proc/get_total_resources()
|
||||
// A list of the amount of active players in each role/department
|
||||
var/active_with_role = number_active_with_role()
|
||||
// A list of the net available resources of each department depending on staffing and active threats/events
|
||||
var/list/total_resources = list()
|
||||
|
||||
// Add resources from staffing
|
||||
for(var/assignment in active_with_role)
|
||||
total_resources[assignment] += active_with_role[assignment] * ASSIGNMENT_STAFFING_VALUE
|
||||
|
||||
// Subtract resources from active antags
|
||||
for(var/datum/antagonist/active in GLOB.antagonists)
|
||||
var/list/antag_costs = active.antag_event_resource_cost()
|
||||
for(var/assignment in antag_costs)
|
||||
if(total_resources[assignment])
|
||||
total_resources[assignment] -= antag_costs[assignment]
|
||||
else
|
||||
total_resources[assignment] = -antag_costs[assignment]
|
||||
|
||||
// Subtract resources from active events
|
||||
for(var/datum/event/active in SSevents.active_events)
|
||||
var/list/event_costs = active.event_resource_cost()
|
||||
for(var/assignment in event_costs)
|
||||
if(total_resources[assignment])
|
||||
total_resources[assignment] -= event_costs[assignment]
|
||||
else
|
||||
total_resources[assignment] = -event_costs[assignment]
|
||||
|
||||
// Subtract resources from various elements
|
||||
var/list/misc_costs = event_total_cost()
|
||||
for(var/assignment in misc_costs)
|
||||
if(total_resources[assignment])
|
||||
total_resources[assignment] -= misc_costs[assignment]
|
||||
else
|
||||
total_resources[assignment] = -misc_costs[assignment]
|
||||
|
||||
return total_resources
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/datum/event/fake_virus
|
||||
name = "Fake Virus"
|
||||
|
||||
/datum/event/fake_virus/start()
|
||||
var/list/valid_targets = list()
|
||||
for(var/mob/living/carbon/human/victim in shuffle(GLOB.player_list))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/datum/event/falsealarm
|
||||
name = "False Alarm"
|
||||
endWhen = 1
|
||||
var/static/list/possible_event_types = list(
|
||||
/datum/event/alien_infestation,
|
||||
|
||||
@@ -8,7 +8,13 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
*/
|
||||
|
||||
/datum/event/immovable_rod
|
||||
name = "Immovable Rod"
|
||||
announceWhen = 5
|
||||
// We assume the event keeps engies busy for about 30 minutes
|
||||
endWhen = 900
|
||||
nominal_severity = EVENT_LEVEL_MAJOR
|
||||
role_weights = list(ASSIGNMENT_ENGINEERING = 5)
|
||||
role_requirements = list(ASSIGNMENT_ENGINEERING = 6)
|
||||
|
||||
/datum/event/immovable_rod/announce()
|
||||
GLOB.minor_announcement.Announce("What the fuck was that?!", "General Alert")
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#define VERM_SPIDERS 2
|
||||
|
||||
/datum/event/infestation
|
||||
name = "Vermin Infestation"
|
||||
role_weights = list(ASSIGNMENT_JANITOR = 0.5)
|
||||
role_requirements = list(ASSIGNMENT_JANITOR = 1)
|
||||
announceWhen = 10
|
||||
endWhen = 11
|
||||
/// Which kind of vermin we'll be spawning (one of the three defines)
|
||||
|
||||
@@ -3,13 +3,17 @@
|
||||
#define ION_ANNOUNCE 1
|
||||
|
||||
/datum/event/ion_storm
|
||||
name = "Ion Storm"
|
||||
role_weights = list(ASSIGNMENT_COMMAND = 1)
|
||||
role_requirements = list(ASSIGNMENT_COMMAND = 1)
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
var/botEmagChance = 10
|
||||
var/announceEvent = ION_NOANNOUNCEMENT // -1 means don't announce, 0 means have it randomly announce, 1 means
|
||||
var/ionMessage = null
|
||||
var/ionAnnounceChance = 33
|
||||
announceWhen = 1
|
||||
|
||||
/datum/event/ion_storm/New(datum/event_meta/EM, skeleton = FALSE, botEmagChance = 10, announceEvent = ION_NOANNOUNCEMENT, ionMessage = null, ionAnnounceChance = 33)
|
||||
/datum/event/ion_storm/New(datum/event_meta/EM, skeleton = FALSE, _severity, botEmagChance = 10, announceEvent = ION_NOANNOUNCEMENT, ionMessage = null, ionAnnounceChance = 33)
|
||||
src.botEmagChance = botEmagChance
|
||||
src.announceEvent = announceEvent
|
||||
src.ionMessage = ionMessage
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/datum/event/carp_migration/koi
|
||||
name = "Koi School"
|
||||
spawned_mobs = list(
|
||||
/mob/living/simple_animal/hostile/retaliate/carp/koi = 98,
|
||||
/mob/living/simple_animal/hostile/retaliate/carp/koi/honk = 2)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/// at least 75% rad armor is required to be immune to this event
|
||||
#define RAD_ARMOR_TO_IMMUNITY 150
|
||||
|
||||
/datum/event/mass_hallucination
|
||||
name = "Mass Hallucination"
|
||||
|
||||
/datum/event/mass_hallucination/setup()
|
||||
announceWhen = rand(0, 20)
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/datum/event/dust/meaty
|
||||
name = "Meaty Ores"
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
role_weights = list(ASSIGNMENT_ENGINEERING = 4)
|
||||
role_requirements = list(ASSIGNMENT_ENGINEERING = 4)
|
||||
|
||||
/datum/event/dust/meaty/announce()
|
||||
if(prob(16))
|
||||
GLOB.minor_announcement.Announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
|
||||
@@ -6,6 +12,7 @@
|
||||
|
||||
/datum/event/dust/meaty/setup()
|
||||
qnty = rand(45,125)
|
||||
endWhen = 600 // Make it take up engineering staffing for 20 minutes
|
||||
|
||||
/datum/event/dust/meaty/start()
|
||||
INVOKE_ASYNC(src, PROC_REF(spawn_meaty_ores))
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
/datum/event/meteor_wave
|
||||
name = "Meteor Wave"
|
||||
startWhen = 5
|
||||
endWhen = 7
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
// We set this when the station clears the meteor storm to keep the event ongoing for a bit so it keeps having a cost
|
||||
noAutoEnd = TRUE
|
||||
role_weights = list(ASSIGNMENT_ENGINEERING = 5)
|
||||
role_requirements = list(ASSIGNMENT_ENGINEERING = 4)
|
||||
var/next_meteor = 6
|
||||
var/waves = 1
|
||||
var/atom/movable/screen/alert/augury/meteor/screen_alert
|
||||
/// The time at which we clear the storm. This is set during the event run so we initialize it to an unreachable value
|
||||
var/clear_time = -1
|
||||
|
||||
/datum/event/meteor_wave/setup()
|
||||
for(var/mob/dead/observer/O in GLOB.dead_mob_list)
|
||||
@@ -22,15 +29,25 @@
|
||||
//meteor showers are lighter and more common,
|
||||
/datum/event/meteor_wave/tick()
|
||||
// keep observers updated with the alert
|
||||
for(var/mob/dead/observer/O in GLOB.dead_mob_list)
|
||||
O.throw_alert("\ref[src]_augury", /atom/movable/screen/alert/augury/meteor)
|
||||
if(screen_alert)
|
||||
for(var/mob/dead/observer/O in GLOB.dead_mob_list)
|
||||
O.throw_alert("\ref[src]_augury", /atom/movable/screen/alert/augury/meteor)
|
||||
if(waves && activeFor >= next_meteor)
|
||||
INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(spawn_meteors), get_meteor_count(), get_meteors())
|
||||
next_meteor += rand(15, 30) / severity
|
||||
waves--
|
||||
endWhen = (waves ? next_meteor + 1 : activeFor + 15)
|
||||
// When the storm is done we set a timer for the event end instead of finishing it.
|
||||
// This is so it still incurs a cost for the event system for a while.
|
||||
if(!waves && noAutoEnd)
|
||||
// Set a 15 cycle(30 second) timer before we announce clearing the storm.
|
||||
// This is to give the last meteor enough time to finish moving
|
||||
clear_time = activeFor + 15
|
||||
endWhen = activeFor + 700
|
||||
noAutoEnd = FALSE
|
||||
if(activeFor == clear_time)
|
||||
announce_clear()
|
||||
|
||||
/datum/event/meteor_wave/end()
|
||||
/datum/event/meteor_wave/proc/announce_clear()
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
M.clear_alert("\ref[src]_augury")
|
||||
QDEL_NULL(screen_alert)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/datum/event/pda_spam
|
||||
name = "PDA Spam"
|
||||
role_weights = list(ASSIGNMENT_CREW = 4)
|
||||
endWhen = 36000
|
||||
var/last_spam_time = 0
|
||||
var/obj/machinery/message_server/useMS
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
/datum/event/prison_break
|
||||
name = "Prison Break"
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 0.8, ASSIGNMENT_CREW = 0.2)
|
||||
role_requirements = list(ASSIGNMENT_SECURITY = 2, ASSIGNMENT_CREW = 0)
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
startWhen = 40
|
||||
announceWhen = 75
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/datum/event/radiation_storm
|
||||
name = "Radiation Storm"
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
role_weights = list(ASSIGNMENT_MEDICAL = 5)
|
||||
role_requirements = list(ASSIGNMENT_MEDICAL = 5)
|
||||
|
||||
/datum/event/radiation_storm/setup()
|
||||
startWhen = 3
|
||||
endWhen = startWhen + 1
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
#define REVENANT_SPAWN_THRESHOLD 10
|
||||
|
||||
/datum/event/revenant
|
||||
name = "Revenant"
|
||||
nominal_severity = EVENT_LEVEL_MAJOR
|
||||
noAutoEnd = TRUE
|
||||
role_weights = list(ASSIGNMENT_CHAPLAIN = 5, ASSIGNMENT_CREW = 0.8)
|
||||
role_requirements = list(ASSIGNMENT_CHAPLAIN = 1, ASSIGNMENT_CREW = 30)
|
||||
var/key_of_revenant
|
||||
|
||||
// Calculated separately from event
|
||||
/datum/event/revenant/event_resource_cost()
|
||||
return list()
|
||||
|
||||
/datum/event/revenant/proc/on_revenant_death(mob/source)
|
||||
SIGNAL_HANDLER // COMSIG_MOB_DEATH
|
||||
UnregisterSignal(source, COMSIG_MOB_DEATH)
|
||||
kill()
|
||||
|
||||
/datum/event/revenant/proc/get_revenant(end_if_fail = 0)
|
||||
var/deadMobs = 0
|
||||
@@ -10,6 +23,7 @@
|
||||
deadMobs++
|
||||
if(deadMobs < REVENANT_SPAWN_THRESHOLD)
|
||||
message_admins("Random event attempted to spawn a revenant, but there were only [deadMobs]/[REVENANT_SPAWN_THRESHOLD] dead mobs.")
|
||||
kill()
|
||||
return
|
||||
|
||||
spawn()
|
||||
@@ -36,6 +50,7 @@
|
||||
kill()
|
||||
return
|
||||
var/mob/living/basic/revenant/revvie = new /mob/living/basic/revenant/(pick(spawn_locs))
|
||||
RegisterSignal(revvie, COMSIG_MOB_DEATH, PROC_REF(on_revenant_death))
|
||||
player_mind.transfer_to(revvie)
|
||||
dust_if_respawnable(C)
|
||||
player_mind.assigned_role = SPECIAL_ROLE_REVENANT
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/datum/event/rogue_drone
|
||||
name = "Rogue Drones"
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 2)
|
||||
role_requirements = list(ASSIGNMENT_SECURITY = 1)
|
||||
startWhen = 10
|
||||
endWhen = 1000
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
var/list/drones_list = list()
|
||||
|
||||
/datum/event/rogue_drone/start()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/datum/event/sentience
|
||||
name = "Sentience"
|
||||
|
||||
/datum/event/sentience/start()
|
||||
INVOKE_ASYNC(src, PROC_REF(make_sentient_mob))
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
name = "Shuttle Loan"
|
||||
announceWhen = 1
|
||||
endWhen = 500
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
role_weights = list(ASSIGNMENT_CARGO = 2, ASSIGNMENT_SECURITY = 2)
|
||||
role_requirements = list(ASSIGNMENT_CARGO = 2, ASSIGNMENT_SECURITY = 2)
|
||||
/// what type of shuttle loan situation the station faces.
|
||||
var/datum/shuttle_loan_situation/situation
|
||||
/// Whether the station has let Centcom commandeer the shuttle yet.
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
/datum/event/spawn_slaughter
|
||||
name = "Slaughter Demon"
|
||||
noAutoEnd = TRUE
|
||||
var/key_of_slaughter
|
||||
var/mob/living/simple_animal/demon/demon = /mob/living/simple_animal/demon/slaughter/lesser
|
||||
nominal_severity = EVENT_LEVEL_MAJOR
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 5, ASSIGNMENT_JANITOR = 5, ASSIGNMENT_MEDICAL = 3, ASSIGNMENT_CREW = 0.7)
|
||||
role_requirements = list(ASSIGNMENT_SECURITY = 4, ASSIGNMENT_JANITOR = 1, ASSIGNMENT_MEDICAL = 2, ASSIGNMENT_CREW = 25)
|
||||
|
||||
/datum/event/spawn_slaughter/tick()
|
||||
if(!demon || demon.stat == DEAD)
|
||||
kill()
|
||||
|
||||
/datum/event/spawn_slaughter/proc/get_slaughter()
|
||||
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a [initial(demon.name)]?", ROLE_DEMON, TRUE, source = demon)
|
||||
@@ -44,10 +53,15 @@
|
||||
INVOKE_ASYNC(src, PROC_REF(get_slaughter))
|
||||
|
||||
/datum/event/spawn_slaughter/greater
|
||||
name = "Greater Slaughter Demon"
|
||||
demon = /mob/living/simple_animal/demon/slaughter
|
||||
|
||||
/datum/event/spawn_slaughter/shadow
|
||||
name = "Shadow Demon"
|
||||
demon = /mob/living/simple_animal/demon/shadow
|
||||
// Same as slaughter but without Jani
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 5, ASSIGNMENT_MEDICAL = 3, ASSIGNMENT_CREW = 0.7)
|
||||
role_requirements = list(ASSIGNMENT_SECURITY = 4, ASSIGNMENT_MEDICAL = 2, ASSIGNMENT_CREW = 25)
|
||||
|
||||
/datum/event/spawn_slaughter/shadow/get_spawn_loc()
|
||||
var/turf/spawn_center = ..()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/datum/event/solar_flare
|
||||
name = "Solar Flare"
|
||||
startWhen = 2
|
||||
endWhen = 3
|
||||
announceWhen = 1
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/datum/event/spacevine
|
||||
name = "Space Vines"
|
||||
role_weights = list(ASSIGNMENT_CREW = 0.4, ASSIGNMENT_ENGINEERING = 1, ASSIGNMENT_BOTANIST = 2)
|
||||
role_requirements = list(ASSIGNMENT_CREW = 25 , ASSIGNMENT_BOTANIST = 1, ASSIGNMENT_ENGINEERING = 1)
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
|
||||
/datum/event/spacevine/start()
|
||||
var/list/turfs = list() //list of all the empty floor turfs in the hallway areas
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/datum/event/spider_infestation
|
||||
name = "Spider Infestation"
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 30)
|
||||
announceWhen = 400
|
||||
var/spawncount = 1
|
||||
var/successSpawn = FALSE //So we don't make a command report if nothing gets spawned.
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
#define TS_HIGHPOP_TRIGGER 80
|
||||
|
||||
/datum/event/spider_terror
|
||||
name = "terror spiders"
|
||||
announceWhen = 240
|
||||
noAutoEnd = TRUE
|
||||
nominal_severity = EVENT_LEVEL_DISASTER
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 2, ASSIGNMENT_CREW = 0.8, ASSIGNMENT_MEDICAL = 2.5)
|
||||
role_requirements = list(ASSIGNMENT_SECURITY = 3, ASSIGNMENT_CREW = 45, ASSIGNMENT_MEDICAL = 4)
|
||||
var/spawncount = 1
|
||||
var/successSpawn = FALSE //So we don't make a command report if nothing gets spawned.
|
||||
|
||||
@@ -19,6 +24,16 @@
|
||||
// It is necessary to wrap this to avoid the event triggering repeatedly.
|
||||
INVOKE_ASYNC(src, PROC_REF(wrappedstart))
|
||||
|
||||
/// Terror spider costs are calculated independently from the event itself
|
||||
/datum/event/spider_terror/event_resource_cost()
|
||||
return list()
|
||||
|
||||
/datum/event/spider_terror/process()
|
||||
// End the event once all spiders, eggs and spiderlings are gone from the station Z level.
|
||||
if(!length(event_category_cost(EVENT_TERROR_SPIDERS)) && successSpawn)
|
||||
kill()
|
||||
. = ..()
|
||||
|
||||
/datum/event/spider_terror/proc/wrappedstart()
|
||||
var/spider_type
|
||||
var/infestation_type
|
||||
@@ -66,6 +81,8 @@
|
||||
S.give_intro_text()
|
||||
spawncount--
|
||||
successSpawn = TRUE
|
||||
if(!successSpawn)
|
||||
kill()
|
||||
SSticker.record_biohazard_start(infestation_type)
|
||||
SSevents.biohazards_this_round += infestation_type
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/datum/event/spontaneous_appendicitis
|
||||
name = "Appendicitis"
|
||||
role_weights = list(ASSIGNMENT_MEDICAL = 1)
|
||||
role_requirements = list(ASSIGNMENT_MEDICAL = 1)
|
||||
|
||||
/datum/event/spontaneous_appendicitis/start()
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
|
||||
if(issmall(H)) //don't infect monkies; that's a waste.
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
*/
|
||||
/datum/event/tear
|
||||
name = "dimensional tear"
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 2)
|
||||
role_requirements = list(ASSIGNMENT_SECURITY = 2)
|
||||
announceWhen = 6
|
||||
endWhen = 14
|
||||
var/notify_title = "Dimensional Rift"
|
||||
|
||||
@@ -4,6 +4,10 @@ GLOBAL_LIST_INIT(unused_trade_stations, list("sol"))
|
||||
// Heavily copy-pasted from "heist" gamemode.
|
||||
|
||||
/datum/event/traders
|
||||
name = "Traders"
|
||||
role_weights = list(ASSIGNMENT_CREW = 0.5)
|
||||
role_requirements = list(ASSIGNMENT_CREW = 30)
|
||||
nominal_severity = EVENT_LEVEL_MAJOR
|
||||
var/success_spawn = 0
|
||||
var/station = null
|
||||
var/spawn_count = 2
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/event/vent_clog
|
||||
name = "Scrubber Clog"
|
||||
startWhen = 5
|
||||
endWhen = 35
|
||||
nominal_severity = EVENT_LEVEL_MODERATE
|
||||
var/interval = 2
|
||||
var/list/vents = list()
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/datum/event/wallrot
|
||||
name = "Wallrot"
|
||||
role_weights = list(ASSIGNMENT_ENGINEERING = 5)
|
||||
role_requirements = list(ASSIGNMENT_ENGINEERING = 1)
|
||||
|
||||
/datum/event/wallrot/start()
|
||||
INVOKE_ASYNC(src, PROC_REF(spawn_wallrot))
|
||||
|
||||
@@ -36,6 +41,9 @@
|
||||
break
|
||||
|
||||
/datum/event/wallrot/fungus
|
||||
name = "Fungal Growth"
|
||||
role_weights = list(ASSIGNMENT_CHEMIST = 5)
|
||||
role_weights = list(ASSIGNMENT_CHEMIST = 0)
|
||||
|
||||
/datum/event/wallrot/fungus/is_valid_candidate(turf/T)
|
||||
return istype(get_area(T), /area/station/maintenance)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/datum/event/wormholes
|
||||
name = "Wormholes"
|
||||
role_weights = "Vent Clog"
|
||||
announceWhen = 10
|
||||
endWhen = 60
|
||||
|
||||
|
||||
@@ -213,6 +213,7 @@
|
||||
|
||||
/mob/living/basic/mouse/blobinfected/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/event_tracker, EVENT_BLOB)
|
||||
apply_status_effect(STATUS_EFFECT_BLOB_BURST, 120 SECONDS, CALLBACK(src, PROC_REF(burst), FALSE))
|
||||
|
||||
/mob/living/basic/mouse/blobinfected/Life()
|
||||
@@ -252,6 +253,7 @@
|
||||
if(core)
|
||||
core.admin_spawned = admin_spawned
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_BLOB_MOUSE_BURST, core)
|
||||
SSticker.record_biohazard_start(BIOHAZARD_BLOB)
|
||||
|
||||
/mob/living/basic/mouse/blobinfected/get_scooped(mob/living/carbon/grabber)
|
||||
|
||||
@@ -68,6 +68,12 @@
|
||||
. = ..()
|
||||
carp_randomify(rarechance)
|
||||
AddComponent(/datum/component/aggro_emote, emote_list = list("gnashes"))
|
||||
AddComponent(/datum/component/event_tracker, EVENT_CARP)
|
||||
|
||||
/mob/living/basic/carp/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_CREW = 0.1)
|
||||
|
||||
/mob/living/basic/carp/proc/carp_randomify(rarechance)
|
||||
if(random_color)
|
||||
|
||||
@@ -45,6 +45,13 @@
|
||||
/mob/living/basic/hellhound/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/ai_retaliate)
|
||||
AddComponent(/datum/component/event_tracker)
|
||||
|
||||
/mob/living/basic/hellhound/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_SECURITY = 0.5, ASSIGNMENT_CREW = 1, ASSIGNMENT_MEDICAL = 0.5)
|
||||
|
||||
|
||||
/mob/living/basic/hellhound/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -156,6 +156,11 @@
|
||||
remove_from_all_data_huds()
|
||||
giveSpells()
|
||||
RegisterSignal(src, COMSIG_BODY_TRANSFER_TO, PROC_REF(make_revenant_antagonist))
|
||||
AddComponent(/datum/component/event_tracker, EVENT_REVENTANT)
|
||||
|
||||
/mob/living/basic/revenant/event_cost()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_CHAPLAIN = 1, ASSIGNMENT_CREW = 10, ASSIGNMENT_MEDICAL = 2)
|
||||
|
||||
/mob/living/basic/revenant/proc/make_revenant_antagonist(revenant)
|
||||
SIGNAL_HANDLER // COMSIG_BODY_TRANSFER_TO
|
||||
|
||||
@@ -37,6 +37,13 @@
|
||||
/mob/living/basic/skeleton/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/ai_retaliate)
|
||||
AddComponent(/datum/component/event_tracker)
|
||||
|
||||
/mob/living/basic/skeleton/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_SECURITY = 0.5, ASSIGNMENT_CREW = 1, ASSIGNMENT_MEDICAL = 0.5)
|
||||
|
||||
|
||||
/mob/living/basic/skeleton/arctic
|
||||
name = "undead arctic explorer"
|
||||
|
||||
@@ -36,3 +36,9 @@
|
||||
update_appearance(UPDATE_NAME)
|
||||
color = "#5494DA"
|
||||
AddElement(/datum/element/ai_retaliate)
|
||||
AddComponent(/datum/component/event_tracker, EVENT_DEMONIC)
|
||||
|
||||
/mob/living/basic/netherworld/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_SECURITY = 0.5, ASSIGNMENT_CREW = 1, ASSIGNMENT_MEDICAL = 0.5)
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
set_default_language(GLOB.all_languages["Galactic Common"])
|
||||
AddElement(/datum/element/ai_retaliate)
|
||||
update_icons()
|
||||
AddComponent(/datum/component/event_tracker, EVENT_DRONE)
|
||||
|
||||
/mob/living/basic/malf_drone/proc/create_trail(datum/source, atom/oldloc, _dir, forced)
|
||||
var/turf/T = get_turf(oldloc)
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
for(var/organ_path in get_caste_organs())
|
||||
var/obj/item/organ/internal/organ = new organ_path()
|
||||
organ.insert(src)
|
||||
AddComponent(/datum/component/event_tracker, EVENT_XENOS)
|
||||
|
||||
/mob/living/carbon/alien/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z))
|
||||
return list(ASSIGNMENT_SECURITY = 1, ASSIGNMENT_CREW = 3, ASSIGNMENT_MEDICAL = 1)
|
||||
|
||||
/// returns the list of type paths of the organs that we need to insert into
|
||||
/// this particular xeno upon its creation
|
||||
|
||||
@@ -15,6 +15,11 @@
|
||||
name = "alien hunter ([rand(1, 1000)])"
|
||||
real_name = name
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z))
|
||||
return list(ASSIGNMENT_SECURITY = 0.8, ASSIGNMENT_CREW = 4, ASSIGNMENT_MEDICAL = 0.4)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/get_caste_organs()
|
||||
. = ..()
|
||||
. += /obj/item/organ/internal/alien/plasmavessel/hunter
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
name = "alien sentinel ([rand(1, 1000)])"
|
||||
real_name = name
|
||||
|
||||
/mob/living/carbon/alien/humenoid/sentinel/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z))
|
||||
return list(ASSIGNMENT_SECURITY = 0.5, ASSIGNMENT_CREW = 3, ASSIGNMENT_MEDICAL = 0.2)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/sentinel/get_caste_organs()
|
||||
. = ..()
|
||||
. += list(
|
||||
|
||||
@@ -32,6 +32,7 @@ GLOBAL_LIST_INIT(strippable_alien_humanoid_items, create_strippable_list(list(
|
||||
AddSpell(new /datum/spell/alien_spell/regurgitate)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -11)
|
||||
AddComponent(/datum/component/event_tracker, EVENT_XENOS)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_strippable_items(datum/source, list/items)
|
||||
items |= GLOB.strippable_alien_humanoid_items
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
ADD_TRAIT(src, TRAIT_FORCE_DOORS, UNIQUE_TRAIT_SOURCE(src))
|
||||
AddSpell(new /datum/spell/alien_spell/tail_lash)
|
||||
|
||||
/mob/living/carbon/alien/humenoid/queen/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z))
|
||||
return list(ASSIGNMENT_SECURITY = 2, ASSIGNMENT_CREW = 12, ASSIGNMENT_MEDICAL = 1)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/queen/get_caste_organs()
|
||||
. = ..()
|
||||
. += list(
|
||||
|
||||
@@ -31,6 +31,11 @@
|
||||
var/datum/action/innate/hide/alien_larva_hide/hide = new()
|
||||
hide.Grant(src)
|
||||
|
||||
/mob/living/carbon/alien/larva/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z))
|
||||
return list(ASSIGNMENT_SECURITY = 0.2, ASSIGNMENT_CREW = 1)
|
||||
|
||||
/mob/living/carbon/alien/larva/Destroy()
|
||||
for(var/datum/action/innate/hide/alien_larva_hide/hide in actions)
|
||||
hide.Remove(src)
|
||||
|
||||
@@ -235,8 +235,15 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
|
||||
orig_vendor.forceMove(src)
|
||||
orig_vendor.aggressive = FALSE // just to be safe, in case this was converted
|
||||
|
||||
AddComponent(/datum/component/event_tracker, EVENT_BRAND_INTELLIGENCE)
|
||||
|
||||
return ..(mapload, base, creator, destroy_original = FALSE)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/vendor/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_SECURITY = 0.5, ASSIGNMENT_CREW = 1)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/vendor/AttackingTarget()
|
||||
. = ..()
|
||||
if(. && target && Adjacent(target))
|
||||
|
||||
@@ -97,6 +97,10 @@
|
||||
else
|
||||
visible_message("<span class='danger'>[src] bites [target], but cannot inject venom into [target.p_their()] [inject_target]!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/green/event_cost()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_SECURITY = 0.5, ASSIGNMENT_CREW = 2, ASSIGNMENT_MEDICAL = 0.2)
|
||||
|
||||
/obj/structure/spider/terrorweb/green
|
||||
name = "slimy web"
|
||||
desc = "This web is partly composed of strands of green slime."
|
||||
|
||||
@@ -109,3 +109,7 @@
|
||||
if(hit_something)
|
||||
visible_message("<span class='danger'>[src] slams into [hit_atom]!</span>", "<span class='userdanger'>You slam into [hit_atom]!</span>")
|
||||
playsound(get_turf(src), 'sound/effects/meteorimpact.ogg', 100, TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/prince/event_cost()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_SECURITY = 2, ASSIGNMENT_CREW = 20, ASSIGNMENT_MEDICAL = 3)
|
||||
|
||||
@@ -123,3 +123,6 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/queen/princess/event_cost()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_SECURITY = 2, ASSIGNMENT_CREW = 15, ASSIGNMENT_MEDICAL = 2)
|
||||
|
||||
@@ -348,6 +348,9 @@
|
||||
. += "<span class='notice'>[p_they(TRUE)] has laid [eggslaid] egg[eggslaid != 1 ? "s" : ""].</span>"
|
||||
. += "<span class='notice'>[p_they(TRUE)] has lived for [MinutesAlive()] minutes.</span>"
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/queen/event_cost()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_SECURITY = 3, ASSIGNMENT_CREW = 30, ASSIGNMENT_MEDICAL = 2)
|
||||
|
||||
/obj/item/projectile/terrorqueenspit
|
||||
name = "acid spit"
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
GLOB.ts_spiderling_list += src
|
||||
if(is_away_level(z))
|
||||
spider_awaymission = TRUE
|
||||
AddComponent(/datum/component/event_tracker, EVENT_TERROR_SPIDERS)
|
||||
|
||||
/obj/structure/spider/spiderling/terror_spiderling/Destroy()
|
||||
GLOB.ts_spiderling_list -= src
|
||||
@@ -216,6 +217,7 @@
|
||||
name = "prince of terror eggs"
|
||||
if(/mob/living/simple_animal/hostile/poison/terror_spider/queen)
|
||||
name = "queen of terror eggs"
|
||||
AddComponent(/datum/component/event_tracker, EVENT_TERROR_SPIDERS)
|
||||
|
||||
/obj/structure/spider/eggcluster/terror_eggcluster/Destroy()
|
||||
GLOB.ts_egg_list -= src
|
||||
|
||||
@@ -238,6 +238,10 @@ GLOBAL_LIST_EMPTY(ts_infected_list)
|
||||
fed++
|
||||
qdel(J)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/event_cost()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_SECURITY = 0.2, ASSIGNMENT_CREW = 1.5, ASSIGNMENT_MEDICAL = 0.2)
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// --------------------- TERROR SPIDERS: PROC OVERRIDES ---------------------------
|
||||
// --------------------------------------------------------------------------------
|
||||
@@ -287,6 +291,7 @@ GLOBAL_LIST_EMPTY(ts_infected_list)
|
||||
var/datum/atom_hud/U = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
|
||||
U.add_hud_to(src)
|
||||
spider_creation_time = world.time
|
||||
AddComponent(/datum/component/event_tracker, EVENT_TERROR_SPIDERS)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/proc/announcetoghosts()
|
||||
if(stat == DEAD)
|
||||
|
||||
@@ -51,6 +51,10 @@
|
||||
LoseTarget()
|
||||
GLOB.move_manager.move_away(src,L,2,1)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/white/event_cost()
|
||||
if(is_station_level((get_turf(src)).z) && stat != DEAD)
|
||||
return list(ASSIGNMENT_SECURITY = 1, ASSIGNMENT_CREW = 5, ASSIGNMENT_MEDICAL = 2)
|
||||
|
||||
/proc/IsTSInfected(mob/living/carbon/C) // Terror AI requires this
|
||||
if(C.get_int_organ(/obj/item/organ/internal/body_egg))
|
||||
return 1
|
||||
@@ -59,6 +63,12 @@
|
||||
/obj/item/organ/internal/body_egg/terror_eggs/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.ts_infected_list += src
|
||||
AddComponent(/datum/component/event_tracker, EVENT_TERROR_SPIDERS)
|
||||
|
||||
/obj/item/organ/internal/body_egg/terror_eggs/event_cost()
|
||||
. = list()
|
||||
if(is_station_level((get_turf(src)).z) && owner)
|
||||
return list(ASSIGNMENT_MEDICAL = 1)
|
||||
|
||||
/obj/item/organ/internal/body_egg/terror_eggs/insert(mob/living/carbon/M, special)
|
||||
. = ..()
|
||||
|
||||
@@ -1642,3 +1642,17 @@ GLOBAL_LIST_INIT(holy_areas, typecacheof(list(
|
||||
client.mouse_pointer_icon = null
|
||||
return
|
||||
client.mouse_pointer_icon = mousepointers["[lowest_prio]"]
|
||||
|
||||
/mob/proc/get_event_capacity()
|
||||
. = 1
|
||||
var/max_symptom_severity = 0
|
||||
for(var/datum/disease/advance/virus in viruses)
|
||||
for(var/datum/symptom/curr_symptom in virus.symptoms)
|
||||
if(curr_symptom.severity > max_symptom_severity)
|
||||
max_symptom_severity = curr_symptom.severity
|
||||
switch(max_symptom_severity)
|
||||
if(4)
|
||||
. *= 0.5
|
||||
if(5 to 6)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -294,7 +294,7 @@
|
||||
/obj/machinery/satellite/meteor_shield/proc/change_meteor_chance(mod)
|
||||
for(var/datum/event_container/container in SSevents.event_containers)
|
||||
for(var/datum/event_meta/M in container.available_events)
|
||||
if(M.event_type == /datum/event/meteor_wave)
|
||||
if(M.skeleton.type == /datum/event/meteor_wave)
|
||||
M.weight_mod *= mod
|
||||
|
||||
/obj/machinery/satellite/meteor_shield/Destroy()
|
||||
|
||||
Reference in New Issue
Block a user