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:
petethegoat@gmail.com
2013-01-10 23:45:57 +00:00
parent 2f7fd88116
commit f27399bcd5
17 changed files with 426 additions and 2 deletions

View 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--

View 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()

View 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)

View 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)

View 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

View 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()

View 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)

View 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

View 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)

View 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

View 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)

View File

@@ -0,0 +1,5 @@
/datum/event/spacevine
oneShot = 1
/datum/event/spacevine/start()
spacevine_infestation()

View 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