mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Added a new events system!
The old one still exists, mainly so the associated admin buttons still work. At some point I'll add a nice little panel for event stuff and remove the old procs. event.dm is pretty well commented, and it should be pretty easy to figure it out. Casualties of the change are space dust (which should probably be implemented separately if we want it back), the black hole event (which was awful), space ninjas (which didn't turn up), ionstorms (the non-admin ones sucked anyway) and CLANG, which I will probably add at some point, if no one else does first. Also, I removed pierott's throat from the disease outbreak list. f that s. Thanks to Sukasa and BS12, as my system is loosely based off of theirs. Thanks Giacom for help with structuring and especially commenting this. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@5511 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
32
code/modules/events/alien_infestation.dm
Normal file
32
code/modules/events/alien_infestation.dm
Normal file
@@ -0,0 +1,32 @@
|
||||
/datum/event/alien_infestation
|
||||
announceWhen = 75
|
||||
endWhen = 75
|
||||
oneShot = 1
|
||||
|
||||
var/spawncount = 1
|
||||
|
||||
/datum/event/alien_infestation/announce()
|
||||
command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert")
|
||||
world << sound('sound/AI/aliens.ogg')
|
||||
|
||||
|
||||
/datum/event/alien_infestation/start()
|
||||
var/list/vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world)
|
||||
if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network)
|
||||
if(temp_vent.network.normal_members.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology
|
||||
vents += temp_vent
|
||||
|
||||
var/list/candidates = get_alien_candidates()
|
||||
|
||||
if(prob(50)) spawncount++ //sometimes, have two larvae spawn instead of one
|
||||
while((spawncount >= 1) && vents.len && candidates.len)
|
||||
var/obj/vent = pick(vents)
|
||||
var/candidate = pick(candidates)
|
||||
|
||||
var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc)
|
||||
new_xeno.key = candidate
|
||||
|
||||
candidates -= candidate
|
||||
vents -= vent
|
||||
spawncount--
|
||||
25
code/modules/events/blob.dm
Normal file
25
code/modules/events/blob.dm
Normal file
@@ -0,0 +1,25 @@
|
||||
/datum/event/blob
|
||||
announceWhen = 12
|
||||
endWhen = 120
|
||||
|
||||
var/obj/effect/blob/core/Blob
|
||||
|
||||
|
||||
/datum/event/blob/announce()
|
||||
command_alert("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
|
||||
world << sound('sound/AI/outbreak5.ogg')
|
||||
|
||||
|
||||
/datum/event/blob/start()
|
||||
var/turf/T = pick(blobstart)
|
||||
if(!T) kill()
|
||||
Blob = new /obj/effect/blob/core(T, 200)
|
||||
Blob.Life()
|
||||
Blob.Life()
|
||||
Blob.Life()
|
||||
|
||||
|
||||
/datum/event/blob/tick()
|
||||
if(!Blob) kill()
|
||||
if(IsMultiple(activeFor, 3))
|
||||
Blob.Life()
|
||||
14
code/modules/events/carp_migration.dm
Normal file
14
code/modules/events/carp_migration.dm
Normal file
@@ -0,0 +1,14 @@
|
||||
/datum/event/carp_migration
|
||||
announceWhen = 50
|
||||
endWhen = 50
|
||||
oneShot = 1
|
||||
|
||||
|
||||
/datum/event/carp_migration/announce()
|
||||
command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
|
||||
|
||||
|
||||
/datum/event/carp_migration/start()
|
||||
for(var/obj/effect/landmark/C in landmarks_list)
|
||||
if(C.name == "carpspawn")
|
||||
new /mob/living/simple_animal/hostile/carp(C.loc)
|
||||
17
code/modules/events/communications_blackout.dm
Normal file
17
code/modules/events/communications_blackout.dm
Normal file
@@ -0,0 +1,17 @@
|
||||
/datum/event/communications_blackout
|
||||
var/silent = 1 //most of the time, we don't want an announcement, so as to allow AIs to fake blackouts.
|
||||
|
||||
/datum/event/communications_blackout/announce()
|
||||
if(!silent)
|
||||
command_alert("Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT")
|
||||
|
||||
|
||||
/datum/event/communications_blackout/start()
|
||||
if(prob(25))
|
||||
silent = 0
|
||||
for(var/mob/living/silicon/ai/A in player_list) //AIs are always aware of communication blackouts.
|
||||
A << "<br>"
|
||||
A << "<span class='warning'><b>Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT<b></span>"
|
||||
A << "<br>"
|
||||
for(var/obj/machinery/telecomms/T in telecomms_list)
|
||||
T.emp_act(1)
|
||||
44
code/modules/events/disease_outbreak.dm
Normal file
44
code/modules/events/disease_outbreak.dm
Normal file
@@ -0,0 +1,44 @@
|
||||
/datum/event/disease_outbreak
|
||||
announceWhen = 15
|
||||
endWhen = 15
|
||||
oneShot = 1
|
||||
|
||||
|
||||
/datum/event/disease_outbreak/announce()
|
||||
command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
|
||||
world << sound('sound/AI/outbreak7.ogg')
|
||||
|
||||
/datum/event/disease_outbreak/start()
|
||||
var/virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis)
|
||||
|
||||
for(var/mob/living/carbon/human/H in shuffle(living_mob_list))
|
||||
var/foundAlready = 0 // don't infect someone that already has the virus
|
||||
var/turf/T = get_turf(H)
|
||||
if(!T)
|
||||
continue
|
||||
if(T.z != 1)
|
||||
continue
|
||||
for(var/datum/disease/D in H.viruses)
|
||||
foundAlready = 1
|
||||
if(H.stat == 2 || foundAlready)
|
||||
continue
|
||||
|
||||
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
|
||||
if((!H.dna) || (H.sdisabilities & BLIND)) //A blindness disease would be the worst.
|
||||
continue
|
||||
var/datum/disease/dnaspread/D = new
|
||||
D.strain_data["name"] = H.real_name
|
||||
D.strain_data["UI"] = H.dna.uni_identity
|
||||
D.strain_data["SE"] = H.dna.struc_enzymes
|
||||
D.carrier = 1
|
||||
D.holder = H
|
||||
D.affected_mob = H
|
||||
H.viruses += D
|
||||
break
|
||||
else
|
||||
var/datum/disease/D = new virus_type
|
||||
D.carrier = 1
|
||||
D.holder = H
|
||||
D.affected_mob = H
|
||||
H.viruses += D
|
||||
break
|
||||
28
code/modules/events/electrical_storm.dm
Normal file
28
code/modules/events/electrical_storm.dm
Normal file
@@ -0,0 +1,28 @@
|
||||
/datum/event/electrical_storm
|
||||
var/lightsoutAmount = 1
|
||||
var/lightsoutRange = 25
|
||||
|
||||
|
||||
/datum/event/electrical_storm/announce()
|
||||
command_alert("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert")
|
||||
|
||||
|
||||
/datum/event/electrical_storm/start()
|
||||
var/list/epicentreList = list()
|
||||
|
||||
for(var/i=1, i <= lightsoutAmount, i++)
|
||||
var/list/possibleEpicentres = list()
|
||||
for(var/obj/effect/landmark/newEpicentre in landmarks_list)
|
||||
if(newEpicentre.name == "lightsout" && !(newEpicentre in epicentreList))
|
||||
possibleEpicentres += newEpicentre
|
||||
if(possibleEpicentres.len)
|
||||
epicentreList += pick(possibleEpicentres)
|
||||
else
|
||||
break
|
||||
|
||||
if(!epicentreList.len)
|
||||
return
|
||||
|
||||
for(var/obj/effect/landmark/epicentre in epicentreList)
|
||||
for(var/obj/machinery/power/apc/apc in range(epicentre,lightsoutRange))
|
||||
apc.overload_lighting()
|
||||
82
code/modules/events/event.dm
Normal file
82
code/modules/events/event.dm
Normal file
@@ -0,0 +1,82 @@
|
||||
/datum/event //NOTE: Times are measured in master controller ticks!
|
||||
var/startWhen = 0 //When in the lifetime to call start().
|
||||
var/announceWhen = 0 //When in the lifetime to call announce().
|
||||
var/endWhen = 0 //When in the lifetime the event should end. Include time for delayed announcements.
|
||||
var/oneShot = 0 //If true, then the event removes itself from the list of potential events on creation.
|
||||
|
||||
var/activeFor = 0 //How long the event has existed. You don't need to change this.
|
||||
|
||||
|
||||
|
||||
|
||||
//Called when the tick is equal to the startWhen variable.
|
||||
//Allows you to announce before starting or vice versa.
|
||||
//Only called once.
|
||||
/datum/event/proc/start()
|
||||
return
|
||||
|
||||
//Called when the tick is equal to the announceWhen variable.
|
||||
//Allows you to start before announcing or vice versa.
|
||||
//Only called once.
|
||||
/datum/event/proc/announce()
|
||||
return
|
||||
|
||||
//Called on or after the tick counter is equal to startWhen.
|
||||
//You can include code related to your event or add your own
|
||||
//time stamped events.
|
||||
//Called more than once.
|
||||
/datum/event/proc/tick()
|
||||
return
|
||||
|
||||
//Called on or after the tick is equal or more than endWhen
|
||||
//You can include code related to the event ending.
|
||||
//Do not place spawn() in here, instead use tick() to check for
|
||||
//the activeFor variable.
|
||||
//For example: if(activeFor == myOwnVariable + 30) doStuff()
|
||||
//Only called once.
|
||||
/datum/event/proc/end()
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
//Do not override this proc, instead use the appropiate procs.
|
||||
//This proc will handle the calls to the appropiate procs.
|
||||
/datum/event/proc/process()
|
||||
if(activeFor == startWhen)
|
||||
start()
|
||||
|
||||
if(activeFor > startWhen)
|
||||
tick()
|
||||
|
||||
if(activeFor == announceWhen)
|
||||
announce()
|
||||
|
||||
if(activeFor >= endWhen)
|
||||
end()
|
||||
kill()
|
||||
|
||||
activeFor++
|
||||
|
||||
|
||||
//Garbage collects the event by removing it from the global events list,
|
||||
//which should be the only place it's referenced.
|
||||
/datum/event/proc/kill()
|
||||
events.Remove(src)
|
||||
|
||||
|
||||
//Adds the event to the global events list, and removes it from the list
|
||||
//of potential events.
|
||||
/datum/event/New()
|
||||
events.Add(src)
|
||||
|
||||
if(oneShot)
|
||||
potentialRandomEvents.Remove(type)
|
||||
|
||||
|
||||
//This shouldn't be called, but it ensures that the event doesn't persist in
|
||||
//the events list if it'd deleted instead of garbage collected with kill().
|
||||
//The master controller will also remove it from the events list if it
|
||||
//doesn't exist, so there's redundancy here.
|
||||
/datum/event/Del()
|
||||
events.Remove(src)
|
||||
39
code/modules/events/event_manager.dm
Normal file
39
code/modules/events/event_manager.dm
Normal file
@@ -0,0 +1,39 @@
|
||||
var/list/allEvents = typesof(/datum/event) - /datum/event
|
||||
var/list/potentialRandomEvents = typesof(/datum/event) - /datum/event
|
||||
|
||||
var/eventTimeLower = 5000
|
||||
var/eventTimeUpper = 10000
|
||||
|
||||
var/scheduledEvent = null
|
||||
|
||||
|
||||
//Currently unused. Needs an admin panel for messing with events.
|
||||
/proc/addPotentialEvent(var/type)
|
||||
potentialRandomEvents |= type
|
||||
|
||||
/proc/removePotentialEvent(var/type)
|
||||
potentialRandomEvents -= type
|
||||
|
||||
|
||||
/proc/checkEvent()
|
||||
if(!scheduledEvent)
|
||||
scheduledEvent = world.timeofday + rand(eventTimeLower, eventTimeUpper)
|
||||
|
||||
else if(world.timeofday > scheduledEvent)
|
||||
spawnEvent()
|
||||
|
||||
scheduledEvent = null
|
||||
checkEvent()
|
||||
|
||||
|
||||
/proc/spawnEvent()
|
||||
if(!config.allow_random_events)
|
||||
return
|
||||
|
||||
var/Type = pick(potentialRandomEvents)
|
||||
if(!Type)
|
||||
return
|
||||
|
||||
//The event will add itself to the MC's event list
|
||||
//and start working via the constructor.
|
||||
new Type
|
||||
12
code/modules/events/meteor_wave.dm
Normal file
12
code/modules/events/meteor_wave.dm
Normal file
@@ -0,0 +1,12 @@
|
||||
/datum/event/meteor_wave
|
||||
startWhen = 6
|
||||
endWhen = 66
|
||||
|
||||
/datum/event/meteor_wave/announce()
|
||||
command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert")
|
||||
world << sound('sound/AI/meteors.ogg')
|
||||
|
||||
|
||||
/datum/event/meteor_wave/tick()
|
||||
if(IsMultiple(activeFor, 3))
|
||||
spawn_meteors(5)
|
||||
46
code/modules/events/prison_break.dm
Normal file
46
code/modules/events/prison_break.dm
Normal file
@@ -0,0 +1,46 @@
|
||||
/datum/event/prison_break
|
||||
announceWhen = 50
|
||||
endWhen = 50
|
||||
oneShot = 1
|
||||
|
||||
var/releaseWhen = 25
|
||||
var/list/area/prisonAreas = list()
|
||||
|
||||
|
||||
/datum/event/prison_break/announce()
|
||||
if(prisonAreas && prisonAreas.len > 0)
|
||||
command_alert("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert")
|
||||
else
|
||||
world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area."
|
||||
|
||||
|
||||
/datum/event/prison_break/start()
|
||||
for(var/area/A in world)
|
||||
if(istype(A, /area/security/prison) || istype(A, /area/security/brig))
|
||||
prisonAreas += A
|
||||
|
||||
if(prisonAreas && prisonAreas.len > 0)
|
||||
for(var/area/A in prisonAreas)
|
||||
for(var/obj/machinery/light/L in A)
|
||||
L.flicker(10)
|
||||
|
||||
|
||||
/datum/event/prison_break/tick()
|
||||
if(activeFor == releaseWhen)
|
||||
if(prisonAreas && prisonAreas.len > 0)
|
||||
for(var/area/A in prisonAreas)
|
||||
for(var/obj/machinery/power/apc/temp_apc in A)
|
||||
temp_apc.overload_lighting()
|
||||
|
||||
for(var/obj/structure/closet/secure_closet/brig/temp_closet in A)
|
||||
temp_closet.locked = 0
|
||||
temp_closet.icon_state = temp_closet.icon_closed
|
||||
|
||||
for(var/obj/machinery/door/airlock/security/temp_airlock in A)
|
||||
temp_airlock.prison_open()
|
||||
|
||||
for(var/obj/machinery/door/airlock/glass_security/temp_glassairlock in A)
|
||||
temp_glassairlock.prison_open()
|
||||
|
||||
for(var/obj/machinery/door_timer/temp_timer in A)
|
||||
temp_timer.releasetime = 1
|
||||
37
code/modules/events/radiation_storm.dm
Normal file
37
code/modules/events/radiation_storm.dm
Normal file
@@ -0,0 +1,37 @@
|
||||
/datum/event/radiation_storm
|
||||
announceWhen = 5
|
||||
endWhen = 5
|
||||
oneShot = 1
|
||||
|
||||
|
||||
/datum/event/radiation_storm/announce()
|
||||
command_alert("High levels of radiation detected near the station. Please report to the Med-bay if you feel strange.", "Anomaly Alert")
|
||||
world << sound('sound/AI/radiation.ogg')
|
||||
|
||||
|
||||
/datum/event/radiation_storm/start()
|
||||
for(var/mob/living/carbon/human/H in living_mob_list)
|
||||
var/turf/T = get_turf(H)
|
||||
if(!T)
|
||||
continue
|
||||
if(T.z != 1)
|
||||
continue
|
||||
if(istype(H,/mob/living/carbon/human))
|
||||
H.apply_effect((rand(15,75)),IRRADIATE,0)
|
||||
if(prob(5))
|
||||
H.apply_effect((rand(90,150)),IRRADIATE,0)
|
||||
if(prob(25))
|
||||
if (prob(75))
|
||||
randmutb(H)
|
||||
domutcheck(H,null,1)
|
||||
else
|
||||
randmutg(H)
|
||||
domutcheck(H,null,1)
|
||||
|
||||
for(var/mob/living/carbon/monkey/M in living_mob_list)
|
||||
var/turf/T = get_turf(M)
|
||||
if(!T)
|
||||
continue
|
||||
if(T.z != 1)
|
||||
continue
|
||||
M.apply_effect((rand(15,75)),IRRADIATE,0)
|
||||
5
code/modules/events/spacevine.dm
Normal file
5
code/modules/events/spacevine.dm
Normal file
@@ -0,0 +1,5 @@
|
||||
/datum/event/spacevine
|
||||
oneShot = 1
|
||||
|
||||
/datum/event/spacevine/start()
|
||||
spacevine_infestation()
|
||||
13
code/modules/events/spontaneous_appendicitis.dm
Normal file
13
code/modules/events/spontaneous_appendicitis.dm
Normal file
@@ -0,0 +1,13 @@
|
||||
/datum/event/spontaneous_appendicitis/start()
|
||||
for(var/mob/living/carbon/human/H in living_mob_list)
|
||||
var/foundAlready = 0 //don't infect someone that already has the virus
|
||||
for(var/datum/disease/D in H.viruses)
|
||||
foundAlready = 1
|
||||
if(H.stat == 2 || foundAlready)
|
||||
continue
|
||||
|
||||
var/datum/disease/D = new /datum/disease/appendicitis
|
||||
D.holder = H
|
||||
D.affected_mob = H
|
||||
H.viruses += D
|
||||
break
|
||||
Reference in New Issue
Block a user