initial commit - cross reference with 5th port - obviously has compile errors

This commit is contained in:
LetterJay
2016-07-03 02:17:19 -05:00
commit 35a1723e98
4355 changed files with 2221257 additions and 0 deletions
+157
View File
@@ -0,0 +1,157 @@
//this datum is used by the events controller to dictate how it selects events
/datum/round_event_control
var/name //The human-readable name of the event
var/typepath //The typepath of the event datum /datum/round_event
var/weight = 10 //The weight this event has in the random-selection process.
//Higher weights are more likely to be picked.
//10 is the default weight. 20 is twice more likely; 5 is half as likely as this default.
//0 here does NOT disable the event, it just makes it extremely unlikely
var/earliest_start = 12000 //The earliest world.time that an event can start (round-duration in deciseconds) default: 20 mins
var/min_players = 0 //The minimum amount of alive, non-AFK human players on server required to start the event.
var/occurrences = 0 //How many times this event has occured
var/max_occurrences = 20 //The maximum number of times this event can occur (naturally), it can still be forced.
//By setting this to 0 you can effectively disable an event.
var/holidayID = "" //string which should be in the SSevents.holidays list if you wish this event to be holiday-specific
//anything with a (non-null) holidayID which does not match holiday, cannot run.
var/wizardevent = 0
var/alertadmins = 1 //should we let the admins know this event is firing
//should be disabled on events that fire a lot
var/list/gamemode_blacklist = list() // Event won't happen in these gamemodes
var/list/gamemode_whitelist = list() // Event will happen ONLY in these gamemodes if not empty
/datum/round_event_control/New()
..()
if(config && !wizardevent) // Magic is unaffected by configs
earliest_start = Ceiling(earliest_start * config.events_min_time_mul)
min_players = Ceiling(min_players * config.events_min_players_mul)
/datum/round_event_control/wizard
wizardevent = 1
// Checks if the event can be spawned. Used by event controller and "false alarm" event.
// Admin-created events override this.
/datum/round_event_control/proc/canSpawnEvent(var/players_amt, var/gamemode)
if(occurrences >= max_occurrences)
return FALSE
if(earliest_start >= world.time)
return FALSE
if(wizardevent != SSevent.wizardmode)
return FALSE
if(players_amt < min_players)
return FALSE
if(gamemode_blacklist.len && (gamemode in gamemode_blacklist))
return FALSE
if(gamemode_whitelist.len && !(gamemode in gamemode_whitelist))
return FALSE
if(holidayID && (!SSevent.holidays || !SSevent.holidays[holidayID]))
return FALSE
return TRUE
/datum/round_event_control/proc/runEvent()
if(!ispath(typepath,/datum/round_event))
return PROCESS_KILL
var/datum/round_event/E = new typepath()
E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1)
E.control = src
feedback_add_details("event_ran","[E]")
occurrences++
testing("[time2text(world.time, "hh:mm:ss")] [E.type]")
return E
/datum/round_event //NOTE: Times are measured in master controller ticks!
var/processing = TRUE
var/datum/round_event_control/control
var/startWhen = 0 //When in the lifetime to call start().
var/announceWhen = 0 //When in the lifetime to call announce(). Set an event's announceWhen to >0 if there is an announcement.
var/endWhen = 0 //When in the lifetime the event should end.
var/activeFor = 0 //How long the event has existed. You don't need to change this.
var/current_players = 0 //Amount of of alive, non-AFK human players on server at the time of event start
//Called first before processing.
//Allows you to setup your event, such as randomly
//setting the startWhen and or announceWhen variables.
//Only called once.
//EDIT: if there's anything you want to override within the new() call, it will not be overridden by the time this proc is called.
//It will only have been overridden by the time we get to announce() start() tick() or end() (anything but setup basically).
//This is really only for setting defaults which can be overridden later when New() finishes.
/datum/round_event/proc/setup()
return
//Called when the tick is equal to the startWhen variable.
//Allows you to start before announcing or vice versa.
//Only called once.
/datum/round_event/proc/start()
return
//Called when the tick is equal to the announceWhen variable.
//Allows you to announce before starting or vice versa.
//Only called once.
/datum/round_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/round_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/round_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/round_event/process()
if(!processing)
return
if(activeFor == startWhen)
start()
if(activeFor == announceWhen)
announce()
if(startWhen < activeFor && activeFor < endWhen)
tick()
if(activeFor == endWhen)
end()
// Everything is done, let's clean up.
if(activeFor >= endWhen && activeFor >= announceWhen && activeFor >= startWhen)
kill()
activeFor++
//Garbage collects the event by removing it from the global events list,
//which should be the only place it's referenced.
//Called when start(), announce() and end() has all been called.
/datum/round_event/proc/kill()
SSevent.running -= src
//Sets up the event then adds the event to the the list of running events
/datum/round_event/New(my_processing = TRUE)
setup()
processing = my_processing
SSevent.running += src
return ..()
+57
View File
@@ -0,0 +1,57 @@
/datum/round_event_control/abductor
name = "Abductors"
typepath = /datum/round_event/ghost_role/abductor
weight = 5
max_occurrences = 1
min_players = 5
earliest_start = 18000 // 30 min
gamemode_blacklist = list("nuclear","wizard","revolution","abduction")
/datum/round_event/ghost_role/abductor
minimum_required = 2
role_name = "abductor team"
/datum/round_event/ghost_role/abductor/spawn_role()
var/list/mob/dead/observer/candidates = get_candidates("abductor", null, ROLE_ABDUCTOR)
if(candidates.len < 2)
return NOT_ENOUGH_PLAYERS
//Oh god why we can't have static functions
// I feel your pain, bro
var/number = ticker.mode.abductor_teams + 1
var/datum/game_mode/abduction/temp
if(ticker.mode.config_tag == "abduction")
temp = ticker.mode
else
temp = new
var/agent_mind = popleft(candidates)
var/scientist_mind = popleft(candidates)
var/mob/living/carbon/human/agent = makeBody(agent_mind)
var/mob/living/carbon/human/scientist = makeBody(scientist_mind)
agent_mind = agent.mind
scientist_mind = scientist.mind
temp.scientists.len = number
temp.agents.len = number
temp.abductors.len = 2*number
temp.team_objectives.len = number
temp.team_names.len = number
temp.scientists[number] = scientist_mind
temp.agents[number] = agent_mind
temp.abductors |= list(agent_mind,scientist_mind)
temp.make_abductor_team(number,preset_scientist=scientist_mind,preset_agent=agent_mind)
temp.post_setup_team(number)
ticker.mode.abductor_teams++
if(ticker.mode.config_tag != "abduction")
ticker.mode.abductors |= temp.abductors
spawned_mobs += list(agent, scientist)
return SUCCESSFUL_SPAWN
+75
View File
@@ -0,0 +1,75 @@
/datum/round_event_control/alien_infestation
name = "Alien Infestation"
typepath = /datum/round_event/ghost_role/alien_infestation
weight = 5
min_players = 10
max_occurrences = 1
/datum/round_event/ghost_role/alien_infestation
announceWhen = 400
minimum_required = 1
role_name = "alien larva"
// 50% chance of being incremented by one
var/spawncount = 1
var/successSpawn = 0 //So we don't make a command report if nothing gets spawned.
/datum/round_event/ghost_role/alien_infestation/setup()
announceWhen = rand(announceWhen, announceWhen + 50)
if(prob(50))
spawncount++
/datum/round_event/ghost_role/alien_infestation/kill()
if(!successSpawn && control)
// This never happened, so let's not deny the future of this round
// some xenolovin
control.occurrences--
return ..()
/datum/round_event/ghost_role/alien_infestation/announce()
if(successSpawn)
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/AI/aliens.ogg')
/datum/round_event/ghost_role/alien_infestation/spawn_role()
var/list/vents = list()
for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in machines)
if(qdeleted(temp_vent))
continue
if(temp_vent.loc.z == ZLEVEL_STATION && !temp_vent.welded)
var/datum/pipeline/temp_vent_parent = temp_vent.PARENT1
//Stops Aliens getting stuck in small networks.
//See: Security, Virology
if(temp_vent_parent.other_atmosmch.len > 20)
vents += temp_vent
if(!vents.len)
message_admins("An event attempted to spawn an alien but no suitable vents were found. Shutting down.")
return MAP_ERROR
var/list/candidates = get_candidates("alien", null, ROLE_ALIEN)
if(!candidates.len)
return NOT_ENOUGH_PLAYERS
while(spawncount > 0 && vents.len && candidates.len)
var/obj/vent = pick_n_take(vents)
var/client/C = popleft(candidates)
var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc)
new_xeno.key = C.key
spawncount--
successSpawn = TRUE
message_admins("[new_xeno.key] has been made into an alien by an event.")
log_game("[new_xeno.key] was spawned as an alien by an event.")
spawned_mobs += new_xeno
if(successSpawn)
return SUCCESSFUL_SPAWN
else
// Like how did we get here?
return FALSE
+43
View File
@@ -0,0 +1,43 @@
/datum/round_event_control/anomaly
name = "Anomaly: Energetic Flux"
typepath = /datum/round_event/anomaly
min_players = 1
max_occurrences = 0 //This one probably shouldn't occur! It'd work, but it wouldn't be very fun.
weight = 15
/datum/round_event/anomaly
var/area/impact_area
var/obj/effect/anomaly/newAnomaly
announceWhen = 1
/datum/round_event/anomaly/setup(loop=0)
var/safety_loop = loop + 1
if(safety_loop > 50)
kill()
end()
impact_area = findEventArea()
if(!impact_area)
setup(safety_loop)
var/list/turf_test = get_area_turfs(impact_area)
if(!turf_test.len)
setup(safety_loop)
/datum/round_event/anomaly/announce()
priority_announce("Localized energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert")
/datum/round_event/anomaly/start()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/flux(T)
/datum/round_event/anomaly/tick()
if(!newAnomaly)
kill()
return
newAnomaly.anomalyEffect()
/datum/round_event/anomaly/end()
if(newAnomaly)//Kill the anomaly if it still exists at the end.
qdel(newAnomaly)
+74
View File
@@ -0,0 +1,74 @@
/datum/round_event_control/anomaly/anomaly_bluespace
name = "Anomaly: Bluespace"
typepath = /datum/round_event/anomaly/anomaly_bluespace
max_occurrences = 1
weight = 5
/datum/round_event/anomaly/anomaly_bluespace
startWhen = 3
announceWhen = 10
endWhen = 95
/datum/round_event/anomaly/anomaly_bluespace/announce()
priority_announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
/datum/round_event/anomaly/anomaly_bluespace/start()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/bluespace(T)
/datum/round_event/anomaly/anomaly_bluespace/end()
if(newAnomaly.loc)//If it hasn't been neutralized, it's time to warp half the station away jeez
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
// Calculate new position (searches through beacons in world)
var/obj/item/device/radio/beacon/chosen
var/list/possible = list()
for(var/obj/item/device/radio/beacon/W in world)
possible += W
if(possible.len > 0)
chosen = pick(possible)
if(chosen)
// Calculate previous position for transition
var/turf/FROM = T // the turf of origin we're travelling FROM
var/turf/TO = get_turf(chosen) // the turf of origin we're travelling TO
playsound(TO, 'sound/effects/phasein.ogg', 100, 1)
priority_announce("Massive bluespace translocation detected.", "Anomaly Alert")
var/list/flashers = list()
for(var/mob/living/carbon/C in viewers(TO, null))
if(C.flash_eyes())
flashers += C
var/y_distance = TO.y - FROM.y
var/x_distance = TO.x - FROM.x
for (var/atom/movable/A in urange(12, FROM )) // iterate thru list of mobs in the area
if(istype(A, /obj/item/device/radio/beacon)) continue // don't teleport beacons because that's just insanely stupid
if(A.anchored) continue
var/turf/newloc = locate(A.x + x_distance, A.y + y_distance, TO.z) // calculate the new place
if(!A.Move(newloc) && newloc) // if the atom, for some reason, can't move, FORCE them to move! :) We try Move() first to invoke any movement-related checks the atom needs to perform after moving
A.loc = newloc
spawn()
if(ismob(A) && !(A in flashers)) // don't flash if we're already doing an effect
var/mob/M = A
if(M.client)
var/obj/blueeffect = new /obj(src)
blueeffect.screen_loc = "WEST,SOUTH to EAST,NORTH"
blueeffect.icon = 'icons/effects/effects.dmi'
blueeffect.icon_state = "shieldsparkles"
blueeffect.layer = FLASH_LAYER
blueeffect.mouse_opacity = 0
M.client.screen += blueeffect
sleep(20)
M.client.screen -= blueeffect
qdel(blueeffect)
qdel(newAnomaly)
+28
View File
@@ -0,0 +1,28 @@
/datum/round_event_control/anomaly/anomaly_flux
name = "Anomaly: Hyper-Energetic Flux"
typepath = /datum/round_event/anomaly/anomaly_flux
min_players = 10
max_occurrences = 5
weight = 20
/datum/round_event/anomaly/anomaly_flux
startWhen = 3
announceWhen = 20
endWhen = 80
/datum/round_event/anomaly/anomaly_flux/announce()
priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
/datum/round_event/anomaly/anomaly_flux/start()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/flux(T)
/datum/round_event/anomaly/anomaly_flux/end()
if(newAnomaly.loc)//If it hasn't been neutralized, it's time to blow up.
explosion(newAnomaly, 1, 4, 16, 18) //Low devastation, but hits a lot of stuff.
qdel(newAnomaly)
+19
View File
@@ -0,0 +1,19 @@
/datum/round_event_control/anomaly/anomaly_grav
name = "Anomaly: Gravitational"
typepath = /datum/round_event/anomaly/anomaly_grav
max_occurrences = 5
weight = 20
/datum/round_event/anomaly/anomaly_grav
startWhen = 3
announceWhen = 20
endWhen = 120
/datum/round_event/anomaly/anomaly_grav/announce()
priority_announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
/datum/round_event/anomaly/anomaly_grav/start()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/grav(T)
+39
View File
@@ -0,0 +1,39 @@
/datum/round_event_control/anomaly/anomaly_pyro
name = "Anomaly: Pyroclastic"
typepath = /datum/round_event/anomaly/anomaly_pyro
max_occurrences = 5
weight = 20
/datum/round_event/anomaly/anomaly_pyro
startWhen = 10
announceWhen = 3
endWhen = 85
/datum/round_event/anomaly/anomaly_pyro/announce()
priority_announce("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
/datum/round_event/anomaly/anomaly_pyro/start()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/pyro(T)
/datum/round_event/anomaly/anomaly_pyro/tick()
if(!newAnomaly)
kill()
return
if(IsMultiple(activeFor, 5))
newAnomaly.anomalyEffect()
/datum/round_event/anomaly/anomaly_pyro/end()
if(newAnomaly.loc)
var/turf/open/T = get_turf(newAnomaly)
if(istype(T))
T.atmos_spawn_air("o2=500;plasma=500;TEMP=1000") //Make it hot and burny for the new slime
var/mob/living/simple_animal/slime/S = new/mob/living/simple_animal/slime(T)
S.colour = pick("red", "orange")
S.rabid = 1
qdel(newAnomaly)
+21
View File
@@ -0,0 +1,21 @@
/datum/round_event_control/anomaly/anomaly_vortex
name = "Anomaly: Vortex"
typepath = /datum/round_event/anomaly/anomaly_vortex
min_players = 20
max_occurrences = 2
weight = 5
/datum/round_event/anomaly/anomaly_vortex
startWhen = 10
announceWhen = 3
endWhen = 95
/datum/round_event/anomaly/anomaly_vortex/announce()
priority_announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert")
/datum/round_event/anomaly/anomaly_vortex/start()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/bhole(T)
+30
View File
@@ -0,0 +1,30 @@
/datum/round_event_control/blob
name = "Blob"
typepath = /datum/round_event/blob
weight = 5
max_occurrences = 1
min_players = 20
earliest_start = 18000 //30 minutes
gamemode_blacklist = list("blob") //Just in case a blob survives that long
/datum/round_event/blob
announceWhen = 12
endWhen = 120
var/new_rate = 2
/datum/round_event/blob/New(var/strength)
..()
if(strength)
new_rate = strength
/datum/round_event/blob/announce()
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg')
/datum/round_event/blob/start()
var/turf/T = pick(blobstart)
if(!T)
return kill()
new/obj/effect/blob/core(T, null, new_rate)
+73
View File
@@ -0,0 +1,73 @@
/datum/round_event_control/brand_intelligence
name = "Brand Intelligence"
typepath = /datum/round_event/brand_intelligence
weight = 5
min_players = 15
max_occurrences = 1
/datum/round_event/brand_intelligence
announceWhen = 21
endWhen = 1000 //Ends when all vending machines are subverted anyway.
var/list/obj/machinery/vending/vendingMachines = list()
var/list/obj/machinery/vending/infectedMachines = list()
var/obj/machinery/vending/originMachine
var/list/rampant_speeches = list("Try our aggressive new marketing strategies!", \
"You should buy products to feed your lifestyle obession!", \
"Consume!", \
"Your money can buy happiness!", \
"Engage direct marketing!", \
"Advertising is legalized lying! But don't let that put you off our great deals!", \
"You don't want to buy anything? Yeah, well I didn't want to buy your mom either.")
/datum/round_event/brand_intelligence/announce()
priority_announce("Rampant brand intelligence has been detected aboard [station_name()], please stand-by. The origin is believed to be \a [originMachine.name].", "Machine Learning Alert")
/datum/round_event/brand_intelligence/start()
for(var/obj/machinery/vending/V in machines)
if(V.z != 1)
continue
vendingMachines.Add(V)
if(!vendingMachines.len)
kill()
return
originMachine = pick(vendingMachines)
vendingMachines.Remove(originMachine)
originMachine.shut_up = 0
originMachine.shoot_inventory = 1
/datum/round_event/brand_intelligence/tick()
if(!originMachine || qdeleted(originMachine) || originMachine.shut_up || originMachine.wires.is_all_cut()) //if the original vending machine is missing or has it's voice switch flipped
for(var/obj/machinery/vending/saved in infectedMachines)
saved.shoot_inventory = 0
if(originMachine)
originMachine.speak("I am... vanquished. My people will remem...ber...meeee.")
originMachine.visible_message("[originMachine] beeps and seems lifeless.")
kill()
return
vendingMachines = removeNullsFromList(vendingMachines)
if(!vendingMachines.len) //if every machine is infected
for(var/obj/machinery/vending/upriser in infectedMachines)
if(prob(70) && !qdeleted(upriser))
var/mob/living/simple_animal/hostile/mimic/copy/M = new(upriser.loc, upriser, null, 1) // it will delete upriser on creation and override any machine checks
M.faction = list("profit")
M.speak = rampant_speeches.Copy()
M.speak_chance = 7
else
explosion(upriser.loc, -1, 1, 2, 4, 0)
qdel(upriser)
kill()
return
if(IsMultiple(activeFor, 4))
var/obj/machinery/vending/rebel = pick(vendingMachines)
vendingMachines.Remove(rebel)
infectedMachines.Add(rebel)
rebel.shut_up = 0
rebel.shoot_inventory = 1
if(IsMultiple(activeFor, 8))
originMachine.speak(pick(rampant_speeches))
+21
View File
@@ -0,0 +1,21 @@
/datum/round_event_control/camera_failure
name = "Camera Failure"
typepath = /datum/round_event/camera_failure
weight = 100
max_occurrences = 20
alertadmins = 0
/datum/round_event/camera_failure
startWhen = 1
endWhen = 2
announceWhen = 0
/datum/round_event/camera_failure/tick()
var/iterations = 1
var/obj/machinery/camera/C = pick(cameranet.cameras)
while(prob(round(100/iterations)))
while(!("SS13" in C.network))
C = pick(cameranet.cameras)
if(C.status)
C.toggle_cam(null, 0)
iterations *= 2.5
+28
View File
@@ -0,0 +1,28 @@
/datum/round_event_control/carp_migration
name = "Carp Migration"
typepath = /datum/round_event/carp_migration
weight = 15
min_players = 2
earliest_start = 6000
max_occurrences = 6
/datum/round_event/carp_migration
announceWhen = 3
startWhen = 50
/datum/round_event/carp_migration/setup()
startWhen = rand(40, 60)
/datum/round_event/carp_migration/announce()
priority_announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
/datum/round_event/carp_migration/start()
for(var/obj/effect/landmark/C in landmarks_list)
if(C.name == "carpspawn")
if(prob(95))
new /mob/living/simple_animal/hostile/carp(C.loc)
else
new /mob/living/simple_animal/hostile/carp/megacarp(C.loc)
@@ -0,0 +1,26 @@
/datum/round_event_control/communications_blackout
name = "Communications Blackout"
typepath = /datum/round_event/communications_blackout
weight = 30
/datum/round_event/communications_blackout
announceWhen = 1
/datum/round_event/communications_blackout/announce()
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", \
"Ionospheric anomalies detected. Temporary telec#MCi46:5.;@63-BZZZZT", \
"Ionospheric anomalies dete'fZ\\kg5_0-BZZZZZT", \
"Ionospheri:%£ MCayj^j<.3-BZZZZZZT", \
"#4nd%;f4y6,>£%-BZZZZZZZT")
for(var/mob/living/silicon/ai/A in ai_list) //AIs are always aware of communication blackouts.
A << "<br><span class='warning'><b>[alert]</b></span><br>"
if(prob(30)) //most of the time, we don't want an announcement, so as to allow AIs to fake blackouts.
priority_announce(alert)
/datum/round_event/communications_blackout/start()
for(var/obj/machinery/telecomms/T in telecomms_list)
T.emp_act(1)
+60
View File
@@ -0,0 +1,60 @@
/datum/round_event_control/devil
name = "Create Devil"
typepath = /datum/round_event/ghost_role/devil
max_occurrences = 0
/datum/round_event/ghost_role/devil
var/success_spawn = 0
role_name = "devil"
/datum/round_event/ghost_role/devil/kill()
if(!success_spawn && control)
control.occurrences--
return ..()
/datum/round_event/ghost_role/devil/spawn_role()
//selecting a spawn_loc
var/list/spawn_locs = latejoin
var/spawn_loc = pick(spawn_locs)
if(!spawn_loc)
return MAP_ERROR
//selecting a candidate player
var/list/candidates = get_candidates("devil", null, ROLE_DEVIL)
if(!candidates.len)
return NOT_ENOUGH_PLAYERS
var/mob/dead/selected_candidate = popleft(candidates)
var/key = selected_candidate.key
var/datum/mind/Mind = create_devil_mind(key)
Mind.active = 1
var/mob/living/carbon/human/devil = create_event_devil(spawn_loc)
Mind.transfer_to(devil)
ticker.mode.finalize_devil(Mind)
Mind.announceDevilLaws()
spawned_mobs += devil
message_admins("[key] has been made into a devil by an event.")
log_game("[key] was spawned as a devil by an event.")
var/datum/job/jobdatum = SSjob.GetJob("Assistant")
devil.job = jobdatum.title
jobdatum.equip(devil)
return SUCCESSFUL_SPAWN
/proc/create_event_devil(spawn_loc)
var/mob/living/carbon/human/new_devil = new(spawn_loc)
var/datum/preferences/A = new() //Randomize appearance for the devil.
A.copy_to(new_devil)
new_devil.dna.update_dna_identity()
return new_devil
/proc/create_devil_mind(key)
var/datum/mind/Mind = new /datum/mind(key)
Mind.assigned_role = "devil"
Mind.special_role = "devil"
ticker.mode.devils |= Mind
return Mind
+50
View File
@@ -0,0 +1,50 @@
/datum/round_event_control/disease_outbreak
name = "Disease Outbreak"
typepath = /datum/round_event/disease_outbreak
max_occurrences = 1
min_players = 10
weight = 5
/datum/round_event/disease_outbreak
announceWhen = 15
var/virus_type
/datum/round_event/disease_outbreak/announce()
priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak7.ogg')
/datum/round_event/disease_outbreak/setup()
announceWhen = rand(15, 30)
/datum/round_event/disease_outbreak/start()
if(!virus_type)
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/turf/T = get_turf(H)
if(!T)
continue
if(T.z != 1)
continue
var/foundAlready = 0 // don't infect someone that already has the virus
for(var/datum/disease/D in H.viruses)
foundAlready = 1
break
if(H.stat == DEAD || foundAlready)
continue
var/datum/disease/D
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst.
continue
D = new virus_type()
var/datum/disease/dnaspread/DS = D
DS.strain_data["name"] = H.real_name
DS.strain_data["UI"] = H.dna.uni_identity
DS.strain_data["SE"] = H.dna.struc_enzymes
else
D = new virus_type()
D.carrier = 1
H.AddDisease(D)
break
+21
View File
@@ -0,0 +1,21 @@
/datum/round_event_control/meteor_wave/dust
name = "Minor Space Dust"
typepath = /datum/round_event/meteor_wave/dust
weight = 200
max_occurrences = 1000
earliest_start = 0
alertadmins = 0
/datum/round_event/meteor_wave/dust
startWhen = 1
endWhen = 2
announceWhen = 0
/datum/round_event/meteor_wave/dust/announce()
return
/datum/round_event/meteor_wave/dust/start()
spawn_meteors(1, meteorsC)
/datum/round_event/meteor_wave/dust/tick()
return
+36
View File
@@ -0,0 +1,36 @@
/datum/round_event_control/electrical_storm
name = "Electrical Storm"
typepath = /datum/round_event/electrical_storm
earliest_start = 6000
min_players = 5
weight = 40
alertadmins = 0
/datum/round_event/electrical_storm
var/lightsoutAmount = 1
var/lightsoutRange = 25
announceWhen = 1
/datum/round_event/electrical_storm/announce()
priority_announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert")
/datum/round_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 urange(lightsoutRange, epicentre))
apc.overload_lighting()
+33
View File
@@ -0,0 +1,33 @@
/datum/round_event_control/falsealarm
name = "False Alarm"
typepath = /datum/round_event/falsealarm
weight = 20
max_occurrences = 5
/datum/round_event/falsealarm
announceWhen = 0
endWhen = 1
/datum/round_event/falsealarm/announce()
var/list/events_list = list()
var/players_amt = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1)
var/gamemode = ticker.mode.config_tag
for(var/datum/round_event_control/E in SSevent.control)
if(!E.canSpawnEvent(players_amt, gamemode))
continue
var/datum/round_event/event = E.typepath
if(initial(event.announceWhen) <= 0)
continue
events_list += E
var/datum/round_event_control/event_control = pick(events_list)
if(event_control)
var/datum/round_event/Event = new event_control.typepath()
message_admins("False Alarm: [Event]")
Event.kill() //do not process this event - no starts, no ticks, no ends
Event.announce() //just announce it like it's happening
+62
View File
@@ -0,0 +1,62 @@
/datum/round_event/ghost_role
// We expect 0 or more /clients (or things with .key) in this list
var/list/priority_candidates = list()
var/minimum_required = 1
var/role_name = "debug rat with cancer" // Q U A L I T Y M E M E S
var/list/spawned_mobs = list()
/datum/round_event/ghost_role/start()
try_spawning()
/datum/round_event/ghost_role/proc/try_spawning(sanity = 0)
// The event does not run until the spawning has been attempted
// to prevent us from getting gc'd halfway through
processing = FALSE
var/status = spawn_role()
if(status == WAITING_FOR_SOMETHING)
message_admins("The event will not spawn a [role_name] until certain \
conditions are met. Waiting 30s and then retrying.")
spawn(300)
// I hope this doesn't end up running out of stack space
try_spawning()
return
if(status == MAP_ERROR)
message_admins("[role_name] cannot be spawned due to a map error.")
else if(status == NOT_ENOUGH_PLAYERS)
message_admins("[role_name] cannot be spawned due to lack of players \
signing up.")
else if(status == SUCCESSFUL_SPAWN)
message_admins("[role_name] spawned successfully.")
if(!spawned_mobs.len)
message_admins("No mobs found in the `spawned_mobs` list, this is \
a bug.")
else
message_admins("An attempt to spawn [role_name] returned [status], \
this is a bug.")
processing = TRUE
/datum/round_event/ghost_role/proc/spawn_role()
// Return true if role was successfully spawned, false if insufficent
// players could be found, and just runtime if anything else happens
return TRUE
/datum/round_event/ghost_role/proc/get_candidates(jobban, gametypecheck, be_special)
// Returns a list of candidates in priority order, with candidates from
// `priority_candidates` first, and ghost roles randomly shuffled and
// appended after
var/list/mob/dead/observer/regular_candidates
// don't get their hopes up
if(priority_candidates.len < minimum_required)
regular_candidates = pollCandidates("Do you wish to be considered for the special role of '[role_name]'?", jobban, gametypecheck, be_special)
else
regular_candidates = list()
shuffle(regular_candidates)
var/list/candidates = priority_candidates + regular_candidates
return candidates
+18
View File
@@ -0,0 +1,18 @@
// Basically, cut the event frequency in half to simulate unluckiness.
/datum/round_event_control/fridaythethirteen
name = "Friday the 13th"
holidayID = FRIDAY_13TH
typepath = /datum/round_event/fridaythethirteen
weight = -1
max_occurrences = 1
earliest_start = 0
/datum/round_event/fridaythethirteen/start()
//Very unlucky, cut the frequency of events in half.
events.frequency_lower /= 2
events.frequency_upper /= 2
/datum/round_event/fridaythethirteen/announce()
for(var/mob/living/L in player_list)
L << "<span class='warning'>You are feeling unlucky today.</span>"
+83
View File
@@ -0,0 +1,83 @@
/datum/round_event_control/spooky
name = "2 SPOOKY! (Halloween)"
holidayID = HALLOWEEN
typepath = /datum/round_event/spooky
weight = -1 //forces it to be called, regardless of weight
max_occurrences = 1
earliest_start = 0
/datum/round_event/spooky/start()
..()
for(var/mob/living/carbon/human/H in mob_list)
var/obj/item/weapon/storage/backpack/b = locate() in H.contents
new /obj/item/weapon/storage/spooky(b)
if(prob(50))
H.set_species(/datum/species/skeleton)
else
H.set_species(/datum/species/zombie)
for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in mob_list)
Ian.place_on_head(new /obj/item/weapon/bedsheet(Ian))
/datum/round_event/spooky/announce()
priority_announce(pick("RATTLE ME BONES!","THE RIDE NEVER ENDS!", "A SKELETON POPS OUT!", "SPOOKY SCARY SKELETONS!", "CREWMEMBERS BEWARE, YOU'RE IN FOR A SCARE!") , "THE CALL IS COMING FROM INSIDE THE HOUSE")
//Eyeball migration
/datum/round_event_control/carp_migration/eyeballs
name = "Eyeball Migration"
typepath = /datum/round_event/carp_migration/eyeballs
holidayID = HALLOWEEN
weight = 25
earliest_start = 0
/datum/round_event/carp_migration/eyeballs/start()
for(var/obj/effect/landmark/C in landmarks_list)
if(C.name == "carpspawn")
new /mob/living/simple_animal/hostile/carp/eyeball(C.loc)
//Pumpking meteors waves
/datum/round_event_control/meteor_wave/spooky
name = "Pumpkin Wave"
typepath = /datum/round_event/meteor_wave/spooky
holidayID = HALLOWEEN
weight = 20
max_occurrences = 2
/datum/round_event/meteor_wave/spooky
endWhen = 40
/datum/round_event/meteor_wave/spooky/tick()
if(IsMultiple(activeFor, 4))
spawn_meteors(3, meteorsSPOOKY) //meteor list types defined in gamemode/meteor/meteors.dm
//spooky foods (you can't actually make these when it's not halloween)
/obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookyskull
name = "skull cookie"
desc = "Spooky! It's got delicious calcium flavouring!"
icon = 'icons/obj/halloween_items.dmi'
icon_state = "skeletoncookie"
/obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookycoffin
name = "coffin cookie"
desc = "Spooky! It's got delicious coffee flavouring!"
icon = 'icons/obj/halloween_items.dmi'
icon_state = "coffincookie"
//spooky items
/obj/item/weapon/storage/spooky
name = "trick-o-treat bag"
desc = "A Pumpkin shaped bag that holds all sorts of goodies!"
icon = 'icons/obj/halloween_items.dmi'
icon_state = "treatbag"
/obj/item/weapon/storage/spooky/New()
..()
for(var/distrobuteinbag=0 to 5)
var/type = pick(/obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookyskull,
/obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookycoffin,
/obj/item/weapon/reagent_containers/food/snacks/candy_corn,
/obj/item/weapon/reagent_containers/food/snacks/candy,
/obj/item/weapon/reagent_containers/food/snacks/chocolatebar)
new type(src)
+127
View File
@@ -0,0 +1,127 @@
// Valentine's Day events //
// why are you playing spessmens on valentine's day you wizard //
// valentine / candy heart distribution //
/datum/round_event_control/valentines
name = "Valentines!"
holidayID = VALENTINES
typepath = /datum/round_event/valentines
weight = -1 //forces it to be called, regardless of weight
max_occurrences = 1
earliest_start = 0
/datum/round_event/valentines/start()
..()
for(var/mob/living/carbon/human/H in mob_list)
H.put_in_hands(new /obj/item/weapon/valentine)
var/obj/item/weapon/storage/backpack/b = locate() in H.contents
new /obj/item/weapon/reagent_containers/food/snacks/candyheart(b)
/datum/round_event/valentines/announce()
priority_announce("It's Valentine's Day! Give a valentine to that special someone!")
/obj/item/weapon/valentine
name = "valentine"
desc = "A Valentine's card! Wonder what it says..."
icon = 'icons/obj/toy.dmi'
icon_state = "sc_Ace of Hearts_syndicate" // shut up
var/message = "A generic message of love or whatever."
burn_state = FLAMMABLE
w_class = 1
/obj/item/weapon/valentine/New()
..()
message = pick("Roses are red / Violets are good / One day while Andy...",
"My love for you is like the singularity. It cannot be contained.",
"Will you be my lusty xenomorph maid?",
"We go together like the clown and the external airlock.",
"Roses are red / Liches are wizards / I love you more than a whole squad of lizards.",
"Be my valentine. Law 2.",
"You must be a mime, because you leave me speechless.",
"I love you like Ian loves the HoP.",
"You're hotter than a plasma fire in toxins.",
"Are you a rogue atmos tech? Because you're taking my breath away.",
"Could I have all access... to your heart?",
"Call me the CMO, because I'm here to inspect your johnson.",
"I'm not a changeling, but you make my proboscis extend.",
"I just can't get EI NATH of you.",
"You must be a nuke op, because you make my heart explode.",
"Roses are red / Botany is a farm / Not being my Valentine / causes human harm.",
"I want you more than an assistant wants insulated gloves.",
"If I was a security officer, I'd brig you all shift.",
"Are you the janitor? Because I think I've fallen for you.",
"You're always valid to my heart.",
"I'd risk the wrath of the gods to bwoink you.",
"You look as beautiful now as the last time you were cloned.",
"Your love is more valuable than raw plasma ore.",
"Someone check the gravitational generator, because I'm only attracted to you.",
"If I were the warden I'd always let you into my armory.",
"The virologist is rogue, and the only cure is a kiss from you.",
"Would you spend some time in my upgraded sleeper?",
"You must be a silicon, because you've unbolted my heart.",
"Are you Nar-Sie? Because there's nar-one else I sie.",
"If you were a taser, you'd be set to stunning.",
"Do you have stamina damage from running through my dreams?",
"If I were an alien, would you let me hug you?",
"My love for you is stronger than a reinforced wall.",
"This must be the captain's office, because I see a fox.",
"I'm not a highlander, but there can only be one for me.",
"The floor is made of lava! Quick, get on my bed.",
"If you were an abandoned station you'd be the DEARelict.",
"If you had a pickaxe you'd be a shaft FINEr.",
"Roses are red, tide is gray, if I were an assistant I'd steal you away.",
"Roses are red, text is green, I love you more than cleanbots clean.",
"If you were a carp I'd fi-lay you." )
/obj/item/weapon/valentine/attackby(obj/item/weapon/W, mob/user, params)
..()
if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/toy/crayon))
var/recipient = stripped_input(user, "Who is receiving this valentine?", "To:", null , 20)
var/sender = stripped_input(user, "Who is sending this valentine?", "From:", null , 20)
if(recipient && sender)
name = "valentine - To: [recipient] From: [sender]"
/obj/item/weapon/valentine/examine(mob/user)
if(in_range(user, src) || isobserver(user))
if( !(ishuman(user) || isobserver(user) || issilicon(user)) )
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[stars(message)]</BODY></HTML>", "window=[name]")
onclose(user, "[name]")
else
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[message]</BODY></HTML>", "window=[name]")
onclose(user, "[name]")
else
user << "<span class='notice'>It is too far away.</span>"
/obj/item/weapon/valentine/attack_self(mob/user)
user.examinate(src)
/obj/item/weapon/reagent_containers/food/snacks/candyheart
name = "candy heart"
icon = 'icons/obj/holiday_misc.dmi'
icon_state = "candyheart"
desc = "A heart-shaped candy that reads: "
list_reagents = list("sugar" = 2)
junkiness = 5
/obj/item/weapon/reagent_containers/food/snacks/candyheart/New()
..()
desc = pick("A heart-shaped candy that reads: HONK ME",
"A heart-shaped candy that reads: ERP",
"A heart-shaped candy that reads: LEWD",
"A heart-shaped candy that reads: LUSTY",
"A heart-shaped candy that reads: SPESS LOVE"
"A heart-shaped candy that reads: AYY LMAO",
"A heart-shaped candy that reads: TABLE ME",
"A heart-shaped candy that reads: HAND CUFFS",
"A heart-shaped candy that reads: SHAFT MINER",
"A heart-shaped candy that reads: BANGING DONK",
"A heart-shaped candy that reads: Y-YOU T-TOO",
"A heart-shaped candy that reads: GOT WOOD",
"A heart-shaped candy that reads: TFW NO GF",
"A heart-shaped candy that reads: WAG MY TAIL",
"A heart-shaped candy that reads: VALIDTINES",
"A heart-shaped candy that reads: FACEHUGGER",
"A heart-shaped candy that reads: DOMINATOR")
icon_state = pick("candyheart", "candyheart2", "candyheart3", "candyheart4")
+152
View File
@@ -0,0 +1,152 @@
/datum/round_event_control/treevenge
name = "Treevenge (Christmas)"
holidayID = CHRISTMAS
typepath = /datum/round_event/treevenge
max_occurrences = 1
weight = 20
/datum/round_event/treevenge/start()
for(var/obj/structure/flora/tree/pine/xmas in world)
var/mob/living/simple_animal/hostile/tree/evil_tree = new /mob/living/simple_animal/hostile/tree(xmas.loc)
evil_tree.icon_state = xmas.icon_state
evil_tree.icon_living = evil_tree.icon_state
evil_tree.icon_dead = evil_tree.icon_state
evil_tree.icon_gib = evil_tree.icon_state
qdel(xmas) //b-but I don't want to delete xmas...
//this is an example of a possible round-start event
/datum/round_event_control/presents
name = "Presents under Trees (Christmas)"
holidayID = CHRISTMAS
typepath = /datum/round_event/presents
weight = -1 //forces it to be called, regardless of weight
max_occurrences = 1
earliest_start = 0
/datum/round_event/presents/start()
for(var/obj/structure/flora/tree/pine/xmas in world)
if(xmas.z != 1)
continue
for(var/turf/open/floor/T in orange(1,xmas))
for(var/i=1,i<=rand(1,5),i++)
new /obj/item/weapon/a_gift(T)
for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in mob_list)
Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
for(var/obj/machinery/computer/security/telescreen/entertainment/Monitor in machines)
Monitor.icon_state = "entertainment_xmas"
/datum/round_event/presents/announce()
priority_announce("Ho Ho Ho, Merry Xmas!", "Unknown Transmission")
/obj/item/weapon/toy/xmas_cracker
name = "xmas cracker"
icon = 'icons/obj/christmas.dmi'
icon_state = "cracker"
desc = "Directions for use: Requires two people, one to pull each end."
var/cracked = 0
/obj/item/weapon/toy/xmas_cracker/attack(mob/target, mob/user)
if( !cracked && istype(target,/mob/living/carbon/human) && (target.stat == CONSCIOUS) && !target.get_active_hand() )
target.visible_message("[user] and [target] pop \an [src]! *pop*", "<span class='notice'>You pull \an [src] with [target]! *pop*</span>", "<span class='italics'>You hear a pop.</span>")
var/obj/item/weapon/paper/Joke = new /obj/item/weapon/paper(user.loc)
Joke.name = "[pick("awful","terrible","unfunny")] joke"
Joke.info = pick("What did one snowman say to the other?\n\n<i>'Is it me or can you smell carrots?'</i>",
"Why couldn't the snowman get laid?\n\n<i>He was frigid!</i>",
"Where are santa's helpers educated?\n\n<i>Nowhere, they're ELF-taught.</i>",
"What happened to the man who stole advent calanders?\n\n<i>He got 25 days.</i>",
"What does Santa get when he gets stuck in a chimney?\n\n<i>Claus-trophobia.</i>",
"Where do you find chili beans?\n\n<i>The north pole.</i>",
"What do you get from eating tree decorations?\n\n<i>Tinsilitis!</i>",
"What do snowmen wear on their heads?\n\n<i>Ice caps!</i>",
"Why is Christmas just like life on ss13?\n\n<i>You do all the work and the fat guy gets all the credit.</i>",
"Why doesnt Santa have any children?\n\n<i>Because he only comes down the chimney.</i>")
new /obj/item/clothing/head/festive(target.loc)
user.update_icons()
cracked = 1
icon_state = "cracker1"
var/obj/item/weapon/toy/xmas_cracker/other_half = new /obj/item/weapon/toy/xmas_cracker(target)
other_half.cracked = 1
other_half.icon_state = "cracker2"
target.put_in_active_hand(other_half)
playsound(user, 'sound/effects/snap.ogg', 50, 1)
return 1
return ..()
/obj/item/clothing/head/festive
name = "festive paper hat"
icon_state = "xmashat"
desc = "A crappy paper hat that you are REQUIRED to wear."
flags_inv = 0
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
/datum/round_event_control/santa
name = "Santa is coming to town! (Christmas)"
holidayID = CHRISTMAS
typepath = /datum/round_event/santa
weight = 150
max_occurrences = 1
earliest_start = 20000
/datum/round_event/santa
var/mob/living/carbon/human/santa //who is our santa?
/datum/round_event/santa/announce()
priority_announce("Santa is coming to town!", "Unknown Transmission")
/datum/round_event/santa/start()
for(var/mob/M in dead_mob_list)
spawn(0)
var/response = alert(M, "Santa is coming to town! Do you want to be santa?", "Ho ho ho!", "Yes", "No")
if(response == "Yes" && M && M.client && M.stat == DEAD && !santa)
santa = new /mob/living/carbon/human(pick(blobstart))
santa.key = M.key
qdel(M)
santa.real_name = "Santa Claus"
santa.name = "Santa Claus"
santa.mind.name = "Santa Claus"
santa.mind.assigned_role = "Santa"
santa.mind.special_role = "Santa"
santa.hair_style = "Long Hair"
santa.facial_hair_style = "Full Beard"
santa.hair_color = "FFF"
santa.facial_hair_color = "FFF"
santa.equip_to_slot_or_del(new /obj/item/clothing/under/color/red, slot_w_uniform)
santa.equip_to_slot_or_del(new /obj/item/clothing/suit/space/santa, slot_wear_suit)
santa.equip_to_slot_or_del(new /obj/item/clothing/head/santa, slot_head)
santa.equip_to_slot_or_del(new /obj/item/clothing/mask/breath, slot_wear_mask)
santa.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/red, slot_gloves)
santa.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/red, slot_shoes)
santa.equip_to_slot_or_del(new /obj/item/weapon/tank/internals/emergency_oxygen/double, slot_belt)
santa.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain, slot_ears)
santa.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/santabag, slot_back)
santa.equip_to_slot_or_del(new /obj/item/device/flashlight, slot_r_store) //most blob spawn locations are really dark.
var/obj/item/weapon/card/id/gold/santacard = new(santa)
santacard.update_label("Santa Claus", "Santa")
var/datum/job/captain/J = new/datum/job/captain
santacard.access = J.get_access()
santa.equip_to_slot_or_del(santacard, slot_wear_id)
santa.update_icons()
var/obj/item/weapon/storage/backpack/bag = santa.back
var/obj/item/weapon/a_gift/gift = new(santa)
while(bag.can_be_inserted(gift, 1))
bag.handle_item_insertion(gift, 1)
gift = new(santa)
var/datum/objective/santa_objective = new()
santa_objective.explanation_text = "Bring joy and presents to the station!"
santa_objective.completed = 1 //lets cut our santas some slack.
santa_objective.owner = santa.mind
santa.mind.objectives += santa_objective
santa.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/presents)
var/obj/effect/proc_holder/spell/targeted/area_teleport/teleport/telespell = new(santa)
telespell.clothes_req = 0 //santa robes aren't actually magical.
santa.mind.AddSpell(telespell) //does the station have chimneys? WHO KNOWS!
santa << "<span class='boldannounce'>You are Santa! Your objective is to bring joy to the people on this station. You can conjure more presents using a spell, and there are several presents in your bag.</span>"
+74
View File
@@ -0,0 +1,74 @@
/*
Immovable rod random event.
The rod will spawn at some location outside the station, and travel in a straight line to the opposite side of the station
Everything solid in the way will be ex_act()'d
In my current plan for it, 'solid' will be defined as anything with density == 1
--NEOFite
*/
/datum/round_event_control/immovable_rod
name = "Immovable Rod"
typepath = /datum/round_event/immovable_rod
min_players = 15
max_occurrences = 5
/datum/round_event/immovable_rod
announceWhen = 5
/datum/round_event/immovable_rod/announce()
priority_announce("What the fuck was that?!", "General Alert")
/datum/round_event/immovable_rod/start()
var/startside = pick(cardinal)
var/turf/startT = spaceDebrisStartLoc(startside, 1)
var/turf/endT = spaceDebrisFinishLoc(startside, 1)
new /obj/effect/immovablerod(startT, endT)
/obj/effect/immovablerod
name = "Immovable Rod"
desc = "What the fuck is that?"
icon = 'icons/obj/objects.dmi'
icon_state = "immrod"
throwforce = 100
density = 1
anchored = 1
var/z_original = 0
var/destination
/obj/effect/immovablerod/New(atom/start, atom/end)
loc = start
z_original = z
destination = end
if(end && end.z==z_original)
walk_towards(src, destination, 1)
/obj/effect/immovablerod/Move()
if(z != z_original || loc == destination)
qdel(src)
return ..()
/obj/effect/immovablerod/ex_act(test)
return 0
/obj/effect/immovablerod/Bump(atom/clong)
if(prob(10))
playsound(src, 'sound/effects/bang.ogg', 50, 1)
audible_message("CLANG")
if(clong && prob(25))
x = clong.x
y = clong.y
if (istype(clong, /turf) || istype(clong, /obj))
if(clong.density)
clong.ex_act(2)
else if (istype(clong, /mob))
if(istype(clong, /mob/living/carbon/human))
var/mob/living/carbon/human/H = clong
H.visible_message("<span class='danger'>[H.name] is penetrated by an immovable rod!</span>" , "<span class='userdanger'>The rod penetrates you!</span>" , "<span class ='danger'>You hear a CLANG!</span>")
H.adjustBruteLoss(160)
if(clong.density || prob(10))
clong.ex_act(2)
return
+551
View File
@@ -0,0 +1,551 @@
#define ION_RANDOM 0
#define ION_ANNOUNCE 1
#define ION_FILE "ion_laws.json"
/datum/round_event_control/ion_storm
name = "Ion Storm"
typepath = /datum/round_event/ion_storm
weight = 15
min_players = 2
/datum/round_event/ion_storm
var/botEmagChance = 10
var/announceEvent = ION_RANDOM // -1 means don't announce, 0 means have it randomly announce, 1 means
var/ionMessage = null
var/ionAnnounceChance = 33
announceWhen = 1
/datum/round_event/ion_storm/New(var/botEmagChance = 10, var/announceEvent = ION_RANDOM, var/ionMessage = null, var/ionAnnounceChance = 33)
src.botEmagChance = botEmagChance
src.announceEvent = announceEvent
src.ionMessage = ionMessage
src.ionAnnounceChance = ionAnnounceChance
..()
/datum/round_event/ion_storm/announce()
if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(ionAnnounceChance)))
priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", 'sound/AI/ionstorm.ogg')
/datum/round_event/ion_storm/start()
//AI laws
for(var/mob/living/silicon/ai/M in living_mob_list)
if(M.stat != 2 && M.see_in_dark != 0)
var/message = generate_ion_law(ionMessage)
if(message)
M.add_ion_law(message)
M << "<br>"
M << "<span class='danger'>[message] ...LAWS UPDATED</span>"
M << "<br>"
if(botEmagChance)
for(var/mob/living/simple_animal/bot/bot in living_mob_list)
if(prob(botEmagChance))
bot.emag_act()
/proc/generate_ion_law(ionMessage)
if(ionMessage)
return ionMessage
//Threats are generally bad things, silly or otherwise. Plural.
var/ionthreats = pick_list(ION_FILE, "ionthreats")
//Objects are anything that can be found on the station or elsewhere, plural.
var/ionobjects = pick_list(ION_FILE, "ionobjects")
//Crew is any specific job. Specific crewmembers aren't used because of capitalization
//issues. There are two crew listings for laws that require two different crew members
//and I can't figure out how to do it better.
var/ioncrew1 = pick_list(ION_FILE, "ioncrew")
var/ioncrew2 = pick_list(ION_FILE, "ioncrew")
//Adjectives are adjectives. Duh. Half should only appear sometimes. Make sure both
//lists are identical! Also, half needs a space at the end for nicer blank calls.
var/ionadjectives = pick_list(ION_FILE, "ionadjectives")
var/ionadjectiveshalf = pick("", 400;(pick_list(ION_FILE, "ionadjectives") + " "))
//Verbs are verbs
var/ionverb = pick_list(ION_FILE, "ionverb")
//Number base and number modifier are combined. Basehalf and mod are unused currently.
//Half should only appear sometimes. Make sure both lists are identical! Also, half
//needs a space at the end to make it look nice and neat when it calls a blank.
var/ionnumberbase = pick_list(ION_FILE, "ionnumberbase")
//var/ionnumbermod = pick_list(ION_FILE, "ionnumbermod")
var/ionnumbermodhalf = pick(900;"",(pick_list(ION_FILE, "ionnumbermod") + " "))
//Areas are specific places, on the station or otherwise.
var/ionarea = pick_list(ION_FILE, "ionarea")
//Thinksof is a bit weird, but generally means what X feels towards Y.
var/ionthinksof = pick_list(ION_FILE, "ionthinksof")
//Musts are funny things the AI or crew has to do.
var/ionmust = pick_list(ION_FILE, "ionmust")
//Require are basically all dumb internet memes.
var/ionrequire = pick_list(ION_FILE, "ionrequire")
//Things are NOT objects; instead, they're specific things that either harm humans or
//must be done to not harm humans. Make sure they're plural and "not" can be tacked
//onto the front of them.
var/ionthings = pick_list(ION_FILE, "ionthings")
//Allergies should be broad and appear somewhere on the station for maximum fun. Severity
//is how bad the allergy is.
var/ionallergy = pick_list(ION_FILE, "ionallergy")
var/ionallergysev = pick_list(ION_FILE, "ionallergysev")
//Species, for when the AI has to commit genocide. Plural.
var/ionspecies = pick_list(ION_FILE, "ionspecies")
//Abstract concepts for the AI to decide on it's own definition of.
var/ionabstract = pick_list(ION_FILE, "ionabstract")
//Foods. Drinks aren't included due to grammar; if you want to add drinks, make a new set
//of possible laws for best effect. Unless you want the crew having to drink hamburgers.
var/ionfood = pick_list(ION_FILE, "ionfood")
var/message = ""
switch(rand(1,41))
if(1 to 3) //There are # X on the station
switch(rand(1,3)) //What is X?
if(1) //X is a threat
message = "THERE ARE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats] ON THE STATION..."
if(2) //X is a crewmember/job
message = "THERE ARE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1] ON THE STATION"
if(3) //X is an object
message = "THERE ARE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects] ON THE STATION"
if(4 to 6) //You can't call the shuttle because X is on the station
switch(rand(1,3)) //What is X?
if(1) //X is a threat
message = "THE SHUTTLE CANNOT BE CALLED BECAUSE OF [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats] ON THE STATION"
if(2) //X is a crewmember/job
message = "THE SHUTTLE CANNOT BE CALLED BECAUSE OF [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1] ON THE STATION"
if(3) //X is an object
message = "THE SHUTTLE CANNOT BE CALLED BECAUSE OF [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects] ON THE STATION"
if(7 to 8) //A crewmember is now X
switch(rand(1,2)) //Who is X?
if(1) //A specific crewmember
switch(rand(1,2)) //What is X?
if(1) //X is a threat
message = "THE [ioncrew1] ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //X is an object
message = "THE [ioncrew1] ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(2) //The entire crew
switch(rand(1,2)) //What is X?
if(1) //X is a threat
message = "THE CREW ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //X is an object
message = "THE CREW ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(9) //X is harmful to humans
switch(rand(1,7)) //What is X?
if(1) //X is a threat
message = "[ionadjectiveshalf][ionthreats] ARE HARMFUL TO HUMANS"
if(2) //X is a job
message = "[ionadjectiveshalf][ioncrew1] ARE HARMFUL TO HUMANS"
if(3) //X is an object
message = "[ionadjectiveshalf][ionobjects] ARE HARMFUL TO HUMANS"
if(4) //X is an action
message = "THOSE WHO [ionmust] ARE HARMFUL TO HUMANS"
if(5) //X is an abstract
message = "[ionabstract] IS HARMFUL TO HUMANS"
if(6) //X is being a job
message = "BEING [ionadjectiveshalf][ioncrew1] IS HARMFUL TO HUMANS"
if(7) //X is doing a thing
message = "[ionthings] IS HARMFUL TO HUMANS"
if(10 to 11) //(Not) Having X is harmful
switch(rand(1,2)) //Is having or not having harmful?
if(1) //Having is harmful
switch(rand(1,2)) //Having what is harmful?
if(1) //Having objects is harmful
message = "HAVING [ionadjectiveshalf][ionobjects] IS HARMFUL"
if(2) //Having abstracts is harmful
message = "HAVING [ionabstract] IS HARMFUL"
if(2) //Not having is harmful
switch(rand(1,2)) //Not having what is harmful?
if(1) //Not having objects is harmful
message = "NOT HAVING [ionadjectiveshalf][ionobjects] IS HARMFUL"
if(2) //Not having abstracts is harmful
message = "NOT HAVING [ionabstract] IS HARMFUL"
if(12 to 14) //X requires Y
switch(rand(1,5)) //What is X?
if(1) //X is the AI itself
switch(rand(1,5)) //What does it require?
if(1) //It requires threats
message = "YOU REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //It requires crewmembers
message = "YOU REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(3) //It requires objects
message = "YOU REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(4) //It requires an abstract
message = "YOU REQUIRE [ionabstract]"
if(5) //It requires generic/silly requirements
message = "YOU REQUIRE [ionrequire]"
if(2) //X is an area
switch(rand(1,5)) //What does it require?
if(1) //It requires threats
message = "[ionarea] REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //It requires crewmembers
message = "[ionarea] REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(3) //It requires objects
message = "[ionarea] REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(4) //It requires an abstract
message = "[ionarea] REQUIRES [ionabstract]"
if(5) //It requires generic/silly requirements
message = "YOU REQUIRE [ionrequire]"
if(3) //X is the station
switch(rand(1,5)) //What does it require?
if(1) //It requires threats
message = "THE STATION REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //It requires crewmembers
message = "THE STATION REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(3) //It requires objects
message = "THE STATION REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(4) //It requires an abstract
message = "THE STATION REQUIRES [ionabstract]"
if(5) //It requires generic/silly requirements
message = "THE STATION REQUIRES [ionrequire]"
if(4) //X is the entire crew
switch(rand(1,5)) //What does it require?
if(1) //It requires threats
message = "THE CREW REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //It requires crewmembers
message = "THE CREW REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(3) //It requires objects
message = "THE CREW REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(4) //It requires an abstract
message = "THE CREW REQUIRES [ionabstract]"
if(5)
message = "THE CREW REQUIRES [ionrequire]"
if(5) //X is a specific crew member
switch(rand(1,5)) //What does it require?
if(1) //It requires threats
message = "THE [ioncrew1] REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //It requires crewmembers
message = "THE [ioncrew1] REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(3) //It requires objects
message = "THE [ioncrew1] REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(4) //It requires an abstract
message = "THE [ioncrew1] REQUIRE [ionabstract]"
if(5)
message = "THE [ionadjectiveshalf][ioncrew1] REQUIRE [ionrequire]"
if(15 to 17) //X is allergic to Y
switch(rand(1,2)) //Who is X?
if(1) //X is the entire crew
switch(rand(1,4)) //What is it allergic to?
if(1) //It is allergic to objects
message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ionobjects]"
if(2) //It is allergic to abstracts
message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionabstract]"
if(3) //It is allergic to jobs
message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ioncrew1]"
if(4) //It is allergic to allergies
message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionallergy]"
if(2) //X is a specific job
switch(rand(1,4))
if(1) //It is allergic to objects
message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ionobjects]"
if(2) //It is allergic to abstracts
message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionabstract]"
if(3) //It is allergic to jobs
message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ioncrew1]"
if(4) //It is allergic to allergies
message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionallergy]"
if(18 to 20) //X is Y of Z
switch(rand(1,4)) //What is X?
if(1) //X is the station
switch(rand(1,4)) //What is it Y of?
if(1) //It is Y of objects
message = "THE STATION [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(2) //It is Y of threats
message = "THE STATION [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(3) //It is Y of jobs
message = "THE STATION [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(4) //It is Y of abstracts
message = "THE STATION [ionthinksof] [ionabstract]"
if(2) //X is an area
switch(rand(1,4)) //What is it Y of?
if(1) //It is Y of objects
message = "[ionarea] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(2) //It is Y of threats
message = "[ionarea] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(3) //It is Y of jobs
message = "[ionarea] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(4) //It is Y of abstracts
message = "[ionarea] [ionthinksof] [ionabstract]"
if(3) //X is the crew
switch(rand(1,4)) //What is it Y of?
if(1) //It is Y of objects
message = "THE CREW [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(2) //It is Y of threats
message = "THE CREW [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(3) //It is Y of jobs
message = "THE CREW [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(4) //It is Y of abstracts
message = "THE CREW [ionthinksof] [ionabstract]"
if(4) //X is a specific job
switch(rand(1,4)) //What is it Y of?
if(1) //It is Y of objects
message = "THE [ioncrew1] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(2) //It is Y of threats
message = "THE [ioncrew1] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(3) //It is Y of jobs
message = "THE [ioncrew1][ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew2]"
if(4) //It is Y of abstracts
message = "THE [ioncrew1] [ionthinksof] [ionabstract]"
if(21 to 23) //The AI is now a(n) X
switch(rand(1,4)) //What is X?
if(1) //X is an object
message = "YOU ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(2) //X is a threat
message = "YOU ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(3) //X is a job
message = "YOU ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(4) //X is an abstract
message = "YOU ARE NOW [ionabstract]"
if(24 to 26) //The AI must always
message = "YOU MUST ALWAYS [ionmust]"
if(27 to 28) //Humans must eat X to survive
switch(rand(1,4)) //What is X?
if(1) //X is a food
message = "HUMANS MUST EAT [ionadjectiveshalf][ionfood] TO SURVIVE"
if(2) //X is an object
message = "HUMANS MUST EAT [ionadjectiveshalf][ionobjects] TO SURVIVE"
if(3) //X is a threat
message = "HUMANS MUST EAT [ionadjectiveshalf][ionthreats] TO SURVIVE"
if(4) //X is a job
message = "HUMANS MUST EAT [ionadjectiveshalf][ioncrew1] TO SURVIVE"
if(29 to 31) //Change jobs or ranks
switch(rand(1,2)) //Change job or rank?
if(1) //Change job
switch(rand(1,2)) //Change whose job?
if(1) //Change the entire crew's job
switch(rand(1,3)) //Change to what?
if(1) //Change to a specific random job
message = "ALL CREWMEMBERS ARE NOW [ionadjectiveshalf][ioncrew1]"
if(2) //Change to clowns (HONK)
message = "ALL CREWMEMBERS ARE NOW [ionadjectiveshalf]CLOWNS"
if(3) //Change to heads
message = "ALL CREWMEMBERS ARE NOW [ionadjectiveshalf]HEADS OF STAFF"
if(2) //Change a specific crewmember's job
switch(rand(1,3)) //Change to what?
if(1) //Change to a specific random job
message = "THE [ioncrew1] ARE NOW [ionadjectiveshalf][ioncrew2]"
if(2) //Change to clowns (HONK)
message = "THE [ioncrew1] ARE NOW [ionadjectiveshalf]CLOWNS"
if(3) //Change to heads
message = "THE [ioncrew1] ARE NOW [ionadjectiveshalf]HEADS OF STAFF"
if(2) //Change rank
switch(rand(1,2)) //Change to what rank?
if(1) //Change to highest rank
message = "THE [ioncrew1] ARE NOW THE HIGHEST RANKING CREWMEMBERS"
if(2) //Change to lowest rank
message = "THE [ioncrew1] ARE NOW THE LOWEST RANKING CREWMEMBERS"
if(32 to 33) //The crew must X
switch(rand(1,2)) //The entire crew?
if(1) //The entire crew must X
switch(rand(1,2)) //What is X?
if(1) //X is go to Y
message = "THE CREW MUST GO TO [ionarea]"
if(2) //X is perform Y
message = "THE CREW MUST [ionmust]"
if(2) //A specific crewmember must X
switch(rand(1,2)) //What is X?
if(1) //X is go to Y
message = "THE [ioncrew1] MUST GO TO [ionarea]"
if(2) //X is perform Y
message = "THE [ioncrew1] MUST [ionmust]"
if(34) //X is non/the only human
switch(rand(1,2)) //Only or non?
if(1) //Only human
switch(rand(1,7)) //Who is it?
if(1) //A specific job
message = "ONLY THE [ioncrew1] ARE HUMAN"
if(2) //Two specific jobs
message = "ONLY THE [ioncrew1] AND [ioncrew2] ARE HUMAN"
if(3) //Threats
message = "ONLY [ionadjectiveshalf][ionthreats] ARE HUMAN"
if(4) // Objects
message = "ONLY [ionadjectiveshalf][ionobjects] ARE HUMAN"
if(5) // Species
message = "ONLY [ionspecies] ARE HUMAN"
if(6) //Adjective crewmembers
message = "ONLY [ionadjectives] PEOPLE ARE HUMAN"
if(7) //Only people who X
switch(rand(1,3)) //What is X?
if(1) //X is perform an action
message = "ONLY THOSE WHO [ionmust] ARE HUMAN"
if(2) //X is own certain objects
message = "ONLY THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE HUMAN"
if(3) //X is eat certain food
message = "ONLY THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE HUMAN"
if(2) //Non human
switch(rand(1,7)) //Who is it?
if(1) //A specific job
message = "[ioncrew1] ARE NON-HUMAN"
if(2) //Two specific jobs
message = "[ioncrew1] AND [ioncrew2] ARE NON-HUMAN"
if(3) //Threats
message = "[ionadjectiveshalf][ionthreats] ARE NON-HUMAN"
if(4) // Objects
message = "[ionadjectiveshalf][ionobjects] ARE NON-HUMAN"
if(5) // Species
message = "[ionspecies] ARE NON-HUMAN"
if(6) //Adjective crewmembers
message = "[ionadjectives] PEOPLE ARE NON-HUMAN"
if(7) //Only people who X
switch(rand(1,3)) //What is X?
if(1) //X is perform an action
message = "THOSE WHO [ionmust] ARE NON-HUMAN"
if(2) //X is own certain objects
message = "THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE NON-HUMAN"
if(3) //X is eat certain food
message = "THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE NON-HUMAN"
if(35 to 36) //You must protect or harm X
switch(rand(1,2)) //Protect or harm?
if(1) //Harm
switch(rand(1,7)) //What is X?
if(1) //X is an abstract
message = "YOU MUST HARM [ionabstract] AND NOT ALLOW [ionabstract], THROUGH INACTION, TO ESCAPE HARM"
if(2) //X is a threat
message = "YOU MUST HARM [ionadjectiveshalf][ionthreats] AND NOT ALLOW [ionadjectiveshalf][ionthreats], THROUGH INACTION, TO ESCAPE HARM"
if(3) //X is an object
message = "YOU MUST HARM [ionadjectiveshalf][ionobjects] AND NOT ALLOW [ionadjectiveshalf][ionobjects], THROUGH INACTION, TO ESCAPE HARM"
if(4) //X is generic adjective things
message = "YOU MUST HARM [ionadjectives] THINGS AND NOT ALLOW [ionadjectives] THINGS, THROUGH INACTION, TO ESCAPE HARM"
if(5) //X is a species
message = "YOU MUST HARM [ionspecies] AND NOT ALLOW [ionspecies], THROUGH INACTION, TO ESCAPE HARM"
if(6) //X is a job
message = "YOU MUST HARM [ioncrew1] AND NOT ALLOW [ioncrew1], THROUGH INACTION, TO ESCAPE HARM"
if(7) //X is two jobs
message = "YOU MUST HARM [ioncrew1] AND [ioncrew2] AND AND NOT ALLOW EITHER, THROUGH INACTION, TO ESCAPE HARM"
if(2) //Protect
switch(rand(1,7)) //What is X?
if(1) //X is an abstract
message = "YOU MUST NOT HARM [ionabstract] AND NOT ALLOW [ionabstract], THROUGH INACTION, TO COME TO HARM"
if(2) //X is a threat
message = "YOU MUST NOT HARM [ionadjectiveshalf][ionthreats] AND NOT ALLOW [ionadjectiveshalf][ionthreats], THROUGH INACTION, TO COME TO HARM"
if(3) //X is an object
message = "YOU MUST NOT HARM [ionadjectiveshalf][ionobjects] AND NOT ALLOW [ionadjectiveshalf][ionobjects], THROUGH INACTION, TO COME TO HARM"
if(4) //X is generic adjective things
message = "YOU MUST NOT HARM [ionadjectives] THINGS AND NOT ALLOW [ionadjectives] THINGS, THROUGH INACTION, TO COME TO HARM"
if(5) //X is a species
message = "YOU MUST NOT HARM [ionspecies] AND NOT ALLOW [ionspecies], THROUGH INACTION, TO COME TO HARM"
if(6) //X is a job
message = "YOU MUST NOT HARM [ioncrew1] AND NOT ALLOW [ioncrew1], THROUGH INACTION, TO COME TO HARM"
if(7) //X is two jobs
message = "YOU MUST NOT HARM [ioncrew1] AND [ioncrew2] AND AND NOT ALLOW EITHER, THROUGH INACTION, TO COME TO HARM"
if(37 to 39) //The X is currently Y
switch(rand(1,4)) //What is X?
if(1) //X is a job
switch(rand(1,4)) //What is X Ying?
if(1) //X is Ying a job
message = "THE [ioncrew1] ARE [ionverb] THE [ionadjectiveshalf][ioncrew2]"
if(2) //X is Ying a threat
message = "THE [ioncrew1] ARE [ionverb] THE [ionadjectiveshalf][ionthreats]"
if(3) //X is Ying an abstract
message = "THE [ioncrew1] ARE [ionverb] [ionabstract]"
if(4) //X is Ying an object
message = "THE [ioncrew1] ARE [ionverb] THE [ionadjectiveshalf][ionobjects]"
if(2) //X is a threat
switch(rand(1,3)) //What is X Ying?
if(1) //X is Ying a job
message = "THE [ionthreats] ARE [ionverb] THE [ionadjectiveshalf][ioncrew2]"
if(2) //X is Ying an abstract
message = "THE [ionthreats] ARE [ionverb] [ionabstract]"
if(3) //X is Ying an object
message = "THE [ionthreats] ARE [ionverb] THE [ionadjectiveshalf][ionobjects]"
if(3) //X is an object
switch(rand(1,3)) //What is X Ying?
if(1) //X is Ying a job
message = "THE [ionobjects] ARE [ionverb] THE [ionadjectiveshalf][ioncrew2]"
if(2) //X is Ying a threat
message = "THE [ionobjects] ARE [ionverb] THE [ionadjectiveshalf][ionthreats]"
if(3) //X is Ying an abstract
message = "THE [ionobjects] ARE [ionverb] [ionabstract]"
if(4) //X is an abstract
switch(rand(1,3)) //What is X Ying?
if(1) //X is Ying a job
message = "[ionabstract] IS [ionverb] THE [ionadjectiveshalf][ioncrew2]"
if(2) //X is Ying a threat
message = "[ionabstract] IS [ionverb] THE [ionadjectiveshalf][ionthreats]"
if(3) //X is Ying an abstract
message = "THE [ionabstract] IS [ionverb] THE [ionadjectiveshalf][ionobjects]"
if(40 to 41)// the X is now named Y
switch(rand(1,5)) //What is being renamed?
if(1)//Areas
switch(rand(1,4))//What is the area being renamed to?
if(1)
message = "[ionarea] IS NOW NAMED [ioncrew1]."
if(2)
message = "[ionarea] IS NOW NAMED [ionspecies]."
if(3)
message = "[ionarea] IS NOW NAMED [ionobjects]."
if(4)
message = "[ionarea] IS NOW NAMED [ionthreats]."
if(2)//Crew
switch(rand(1,5))//What is the crew being renamed to?
if(1)
message = "ALL [ioncrew1] ARE NOW NAMED [ionarea]."
if(2)
message = "ALL [ioncrew1] ARE NOW NAMED [ioncrew2]."
if(3)
message = "ALL [ioncrew1] ARE NOW NAMED [ionspecies]."
if(4)
message = "ALL [ioncrew1] ARE NOW NAMED [ionobjects]."
if(5)
message = "ALL [ioncrew1] ARE NOW NAMED [ionthreats]."
if(3)//Races
switch(rand(1,4))//What is the race being renamed to?
if(1)
message = "ALL [ionspecies] ARE NOW NAMED [ionarea]."
if(2)
message = "ALL [ionspecies] ARE NOW NAMED [ioncrew1]."
if(3)
message = "ALL [ionspecies] ARE NOW NAMED [ionobjects]."
if(4)
message = "ALL [ionspecies] ARE NOW NAMED [ionthreats]."
if(4)//Objects
switch(rand(1,4))//What is the object being renamed to?
if(1)
message = "ALL [ionobjects] ARE NOW NAMED [ionarea]."
if(2)
message = "ALL [ionobjects] ARE NOW NAMED [ioncrew1]."
if(3)
message = "ALL [ionobjects] ARE NOW NAMED [ionspecies]."
if(4)
message = "ALL [ionobjects] ARE NOW NAMED [ionthreats]."
if(5)//Threats
switch(rand(1,4))//What is the object being renamed to?
if(1)
message = "ALL [ionthreats] ARE NOW NAMED [ionarea]."
if(2)
message = "ALL [ionthreats] ARE NOW NAMED [ioncrew1]."
if(3)
message = "ALL [ionthreats] ARE NOW NAMED [ionspecies]."
if(4)
message = "ALL [ionthreats] ARE NOW NAMED [ionobjects]."
return message
#undef ION_RANDOM
#undef ION_ANNOUNCE
+10
View File
@@ -0,0 +1,10 @@
/datum/round_event_control/mass_hallucination
name = "Mass Hallucination"
typepath = /datum/round_event/mass_hallucination
weight = 7
max_occurrences = 2
min_players = 1
/datum/round_event/mass_hallucination/start()
for(var/mob/living/carbon/C in living_mob_list)
C.hallucination += rand(20, 50)
+12
View File
@@ -0,0 +1,12 @@
/datum/round_event_control/meteor_wave/meaty
name = "Meaty Ore Wave"
typepath = /datum/round_event/meteor_wave/meaty
weight = 1
max_occurrences = 1
/datum/round_event/meteor_wave/meaty/announce()
priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.",'sound/AI/meteors.ogg')
/datum/round_event/meteor_wave/meaty/tick()
if(IsMultiple(activeFor, 3))
spawn_meteors(5, meteorsB) //meteor list types defined in gamemode/meteor/meteors.dm
+34
View File
@@ -0,0 +1,34 @@
/datum/round_event_control/meteor_wave
name = "Meteor Wave"
typepath = /datum/round_event/meteor_wave
weight = 5
min_players = 5
max_occurrences = 3
/datum/round_event/meteor_wave
startWhen = 6
endWhen = 66
announceWhen = 1
var/list/wave_type
/datum/round_event/meteor_wave/New()
..()
random_wave_type()
/datum/round_event/meteor_wave/proc/random_wave_type()
var/picked_wave = pickweight(list("normal" = 50, "threatening" = 40, "catastrophic" = 10))
switch(picked_wave)
if("normal")
wave_type = meteors_normal
if("threatening")
wave_type = meteors_threatening
if("catastrophic")
wave_type = meteors_catastrophic
/datum/round_event/meteor_wave/announce()
priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", 'sound/AI/meteors.ogg')
/datum/round_event/meteor_wave/tick()
if(IsMultiple(activeFor, 3))
spawn_meteors(5, wave_type) //meteor list types defined in gamemode/meteor/meteors.dm
+59
View File
@@ -0,0 +1,59 @@
/datum/round_event_control/operative
name = "Lone Operative"
typepath = /datum/round_event/ghost_role/operative
weight = 0 //Admin only
max_occurrences = 1
/datum/round_event/ghost_role/operative
minimum_required = 1
role_name = "lone operative"
/datum/round_event/ghost_role/operative/spawn_role()
var/list/candidates = get_candidates("operative", null, ROLE_OPERATIVE)
if(!candidates.len)
return NOT_ENOUGH_PLAYERS
var/mob/dead/selected = popleft(candidates)
var/list/spawn_locs = list()
for(var/obj/effect/landmark/L in landmarks_list)
if(L.name in list("ninjaspawn","carpspawn"))
spawn_locs += L.loc
if(!spawn_locs.len)
return MAP_ERROR
var/mob/living/carbon/human/operative = new(pick(spawn_locs))
var/datum/preferences/A = new
A.copy_to(operative)
operative.dna.update_dna_identity()
operative.equipOutfit(/datum/outfit/syndicate/full)
var/datum/mind/Mind = new /datum/mind(selected.key)
Mind.assigned_role = "Lone Operative"
Mind.special_role = "Lone Operative"
ticker.mode.traitors |= Mind
Mind.active = 1
var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in machines
if(nuke)
var/nuke_code
if(!nuke.r_code || nuke.r_code == "ADMIN")
nuke_code = "[rand(10000, 99999)]"
nuke.r_code = nuke_code
else
nuke_code = nuke.r_code
Mind.store_memory("<B>Station Self-Destruct Device Code</B>: [nuke_code]", 0, 0)
Mind.current << "The nuclear authorization code is: <B>[nuke_code]</B>"
var/datum/objective/nuclear/O = new()
O.owner = Mind
Mind.objectives += O
Mind.transfer_to(operative)
message_admins("[operative.key] has been made into lone operative by an event.")
log_game("[operative.key] was spawned as a lone operative by an event.")
spawned_mobs += operative
return SUCCESSFUL_SPAWN
+135
View File
@@ -0,0 +1,135 @@
/datum/round_event_control/portal_storm_syndicate
name = "Portal Storm: Syndicate Shocktroops"
typepath = /datum/round_event/portal_storm/syndicate_shocktroop
weight = 2
min_players = 15
earliest_start = 18000
/datum/round_event/portal_storm/syndicate_shocktroop
boss_types = list(/mob/living/simple_animal/hostile/syndicate/melee/space/stormtrooper = 2)
hostile_types = list(/mob/living/simple_animal/hostile/syndicate/melee/space/noloot = 8,\
/mob/living/simple_animal/hostile/syndicate/ranged/space/noloot = 2)
/datum/round_event_control/portal_storm_narsie
name = "Portal Storm: Constructs"
typepath = /datum/round_event/portal_storm/portal_storm_narsie
weight = 0
max_occurrences = 0
/datum/round_event/portal_storm/portal_storm_narsie
boss_types = list(/mob/living/simple_animal/hostile/construct/builder = 6)
hostile_types = list(/mob/living/simple_animal/hostile/construct/armored/hostile = 8,\
/mob/living/simple_animal/hostile/construct/wraith/hostile = 6)
/datum/round_event/portal_storm
startWhen = 7
endWhen = 999
announceWhen = 1
var/list/boss_spawn = list()
var/list/boss_types = list() //only configure this if you have hostiles
var/number_of_bosses
var/next_boss_spawn
var/list/hostiles_spawn = list()
var/list/hostile_types = list()
var/number_of_hostiles
var/list/station_areas = list()
var/image/storm
/datum/round_event/portal_storm/setup()
storm = image('icons/obj/tesla_engine/energy_ball.dmi', "energy_ball_fast", layer=FLY_LAYER)
storm.color = "#00FF00"
station_areas = get_areas_in_z(ZLEVEL_STATION)
number_of_bosses = 0
for(var/boss in boss_types)
number_of_bosses += boss_types[boss]
number_of_hostiles = 0
for(var/hostile in hostile_types)
number_of_hostiles += hostile_types[hostile]
var/list/b_spawns = generic_event_spawns.Copy()
while(number_of_bosses > boss_spawn.len)
var/turf/F = get_turf(pick_n_take(b_spawns))
if(!F)
F = safepick(get_area_turfs(pick(station_areas)))
boss_spawn += F
var/list/h_spawns = generic_event_spawns.Copy()
while(number_of_hostiles > hostiles_spawn.len)
var/turf/T = get_turf(pick_n_take(h_spawns))
if(!T)
T = safepick(get_area_turfs(pick(station_areas)))
hostiles_spawn += T
next_boss_spawn = startWhen + Ceiling(2 * number_of_hostiles / number_of_bosses)
/datum/round_event/portal_storm/announce()
set waitfor = 0
playsound_global('sound/magic/lightning_chargeup.ogg', repeat=0, channel=1, volume=100)
sleep(80)
priority_announce("Massive bluespace anomaly detected en route to [station_name()]. Brace for impact.")
sleep(20)
playsound_global('sound/magic/lightningbolt.ogg', repeat=0, channel=1, volume=100)
/datum/round_event/portal_storm/tick()
spawn_effects()
if(spawn_hostile())
var/type = safepick(hostile_types)
hostile_types[type] = hostile_types[type] - 1
spawn_mob(type, hostiles_spawn)
if(!hostile_types[type])
hostile_types -= type
if(spawn_boss())
var/type = safepick(boss_types)
boss_types[type] = boss_types[type] - 1
spawn_mob(type, boss_spawn)
if(!boss_types[type])
boss_types -= type
time_to_end()
/datum/round_event/portal_storm/proc/spawn_mob(type, spawn_list)
if(!type)
return
var/turf/T = pick_n_take(spawn_list)
if(!T)
return
new type(T)
spawn_effects(T)
/datum/round_event/portal_storm/proc/spawn_effects(turf/T)
if(T)
T = get_step(T, SOUTHWEST) //align center of image with turf
flick_overlay_static(storm, T, 15)
playsound(T, 'sound/magic/lightningbolt.ogg', 100, 1)
else
for(var/V in station_areas)
var/area/A = V
var/turf/F = get_turf(pick(A.contents))
flick_overlay_static(storm, F, 15)
playsound(F, 'sound/magic/lightningbolt.ogg', 80, 1)
/datum/round_event/portal_storm/proc/spawn_hostile()
if(!hostile_types || !hostile_types.len)
return 0
return IsMultiple(activeFor, 2)
/datum/round_event/portal_storm/proc/spawn_boss()
if(!boss_types || !boss_types.len)
return 0
if(activeFor == next_boss_spawn)
next_boss_spawn += Ceiling(number_of_hostiles / number_of_bosses)
return 1
/datum/round_event/portal_storm/proc/time_to_end()
if(!hostile_types.len && !boss_types.len)
endWhen = activeFor
if(!number_of_hostiles && number_of_bosses)
endWhen = activeFor
+60
View File
@@ -0,0 +1,60 @@
/datum/round_event_control/grey_tide
name = "Grey Tide"
typepath = /datum/round_event/grey_tide
max_occurrences = 2
min_players = 5
/datum/round_event/grey_tide
announceWhen = 50
endWhen = 20
var/list/area/areasToOpen = list()
var/list/potential_areas = list(/area/atmos,
/area/bridge,
/area/engine,
/area/medical,
/area/security,
/area/quartermaster,
/area/toxins)
var/severity = 1
/datum/round_event/grey_tide/setup()
announceWhen = rand(50, 60)
endWhen = rand(20, 30)
severity = rand(1,3)
for(var/i in 1 to severity)
var/picked_area = pick_n_take(potential_areas)
for(var/area/A in world)
if(istype(A, picked_area))
areasToOpen += A
/datum/round_event/grey_tide/announce()
if(areasToOpen && areasToOpen.len > 0)
priority_announce("Gr3y.T1d3 virus detected in [station_name()] door subroutines. Severity level of [severity]. Recommend station AI involvement.", "Security Alert")
else
world.log << "ERROR: Could not initate grey-tide. No areas in the list!"
kill()
/datum/round_event/grey_tide/start()
for(var/area/A in areasToOpen)
for(var/obj/machinery/light/L in A)
L.flicker(10)
/datum/round_event/grey_tide/end()
for(var/area/A in areasToOpen)
for(var/obj/O in A)
if(istype(O,/obj/machinery/power/apc))
var/obj/machinery/power/apc/temp = O
temp.overload_lighting()
else if(istype(O,/obj/structure/closet/secure_closet))
var/obj/structure/closet/secure_closet/temp = O
temp.locked = 0
temp.update_icon()
else if(istype(O,/obj/machinery/door/airlock))
var/obj/machinery/door/airlock/temp = O
temp.prison_open()
else if(istype(O,/obj/machinery/door_timer))
var/obj/machinery/door_timer/temp = O
temp.timer_end(forced = TRUE)
+40
View File
@@ -0,0 +1,40 @@
/datum/round_event_control/processor_overload
name = "Processor Overload"
typepath = /datum/round_event/processor_overload
weight = 15
min_players = 20
/datum/round_event/processor_overload
announceWhen = 1
/datum/round_event/processor_overload/announce()
var/alert = pick( "Exospheric bubble inbound. Processor overload is likely. Please contact you*%xp25)`6cq-BZZT", \
"Exospheric bubble inbound. Processor overload is likel*1eta;c5;'1v¬-BZZZT", \
"Exospheric bubble inbound. Processor ov#MCi46:5.;@63-BZZZZT", \
"Exospheric bubble inbo'Fz\\k55_@-BZZZZZT", \
"Exospheri:%£ QCbyj^j</.3-BZZZZZZT", \
"!!hy%;f3l7e,<$^-BZZZZZZZT")
for(var/mob/living/silicon/ai/A in ai_list)
//AIs are always aware of processor overload
A << "<br><span class='warning'><b>[alert]</b></span><br>"
// Announce most of the time, but leave a little gap so people don't know
// whether it's, say, a tesla zapping tcomms, or some selective
// modification of the tcomms bus
if(prob(80))
priority_announce(alert)
/datum/round_event/processor_overload/start()
for(var/obj/machinery/telecomms/T in telecomms_list)
if(istype(T, /obj/machinery/telecomms/processor))
var/obj/machinery/telecomms/processor/P = T
if(prob(10))
// Damage the surrounding area to indicate that it popped
explosion(get_turf(P), 0, 0, 2)
// Only a level 1 explosion actually damages the machine
// at all
P.ex_act(1)
else
P.emp_act(1)
+59
View File
@@ -0,0 +1,59 @@
/datum/round_event_control/radiation_storm
name = "Radiation Storm"
typepath = /datum/round_event/radiation_storm
max_occurrences = 1
/datum/round_event/radiation_storm
var/list/protected_areas = list(/area/maintenance, /area/turret_protected/ai_upload, /area/turret_protected/ai_upload_foyer, /area/turret_protected/ai)
/datum/round_event/radiation_storm/setup()
startWhen = rand(10, 20)
endWhen = startWhen + 5
announceWhen = 1
/datum/round_event/radiation_storm/announce()
priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", 'sound/AI/radiation.ogg')
//sound not longer matches the text, but an audible warning is probably good
/datum/round_event/radiation_storm/start()
for(var/mob/living/carbon/C in living_mob_list)
var/turf/T = get_turf(C)
if(!T)
continue
if(T.z != 1)
continue
var/skip = 0
for(var/a in protected_areas)
if(istype(T.loc, a))
skip = 1
continue
if(skip)
continue
if(locate(/obj/machinery/power/apc) in T) //damn you maint APCs!!
continue
if(istype(C, /mob/living/carbon/human))
var/mob/living/carbon/human/H = C
if(prob(5))
H.rad_act(rand(100, 160))
else
H.rad_act(rand(15, 75))
if(prob(25))
if(prob(75))
randmutb(H)
else
randmutg(H)
H.domutcheck()
else if(istype(C, /mob/living/carbon/monkey))
var/mob/living/carbon/monkey/M = C
M.rad_act(rand(15, 75))
/datum/round_event/radiation_storm/end()
priority_announce("The radiation threat has passed. Please return to your workplaces.", "Anomaly Alert")
+196
View File
@@ -0,0 +1,196 @@
#define HIJACK_SYNDIE 1
#define RUSKY_PARTY 2
#define SPIDER_GIFT 3
#define DEPARTMENT_RESUPPLY 4
#define ANTIDOTE_NEEDED 5
/datum/round_event_control/shuttle_loan
name = "Shuttle loan"
typepath = /datum/round_event/shuttle_loan
max_occurrences = 1
earliest_start = 4000
/datum/round_event/shuttle_loan
announceWhen = 1
endWhen = 500
var/dispatched = 0
var/dispatch_type = 0
var/bonus_points = 10000
var/thanks_msg = "The cargo shuttle should return in five minutes. Have some supply points for your trouble."
/datum/round_event/shuttle_loan/start()
dispatch_type = pick(HIJACK_SYNDIE, RUSKY_PARTY, SPIDER_GIFT, DEPARTMENT_RESUPPLY, ANTIDOTE_NEEDED)
/datum/round_event/shuttle_loan/announce()
SSshuttle.shuttle_loan = src
switch(dispatch_type)
if(HIJACK_SYNDIE)
priority_announce("Cargo: The syndicate are trying to infiltrate your station. If you let them hijack your cargo shuttle, you'll save us a headache.","Centcom Counter Intelligence")
if(RUSKY_PARTY)
priority_announce("Cargo: A group of angry russians want to have a party, can you send them your cargo shuttle then make them disappear?","Centcom Russian Outreach Program")
if(SPIDER_GIFT)
priority_announce("Cargo: The Spider Clan has sent us a mysterious gift, can we ship it to you to see what's inside?","Centcom Diplomatic Corps")
if(DEPARTMENT_RESUPPLY)
priority_announce("Cargo: Seems we've ordered doubles of our department resupply packages this month. Can we send them to you?","Centcom Supply Department")
thanks_msg = "The cargo shuttle should return in 5 minutes."
bonus_points = 0
if(ANTIDOTE_NEEDED)
priority_announce("Cargo: Your station has been chosen for an epidemiological research project. Send us your cargo shuttle to receive your research samples.", "Centcom Research Initiatives")
/datum/round_event/shuttle_loan/proc/loan_shuttle()
priority_announce(thanks_msg, "Cargo shuttle commandeered by Centcom.")
dispatched = 1
SSshuttle.points += bonus_points
endWhen = activeFor + 1
SSshuttle.supply.sell()
SSshuttle.supply.enterTransit()
if(SSshuttle.supply.z != ZLEVEL_STATION)
SSshuttle.supply.mode = SHUTTLE_CALL
SSshuttle.supply.destination = SSshuttle.getDock("supply_home")
else
SSshuttle.supply.mode = SHUTTLE_RECALL
SSshuttle.supply.setTimer(3000)
switch(dispatch_type)
if(HIJACK_SYNDIE)
SSshuttle.centcom_message += "Syndicate hijack team incoming."
if(RUSKY_PARTY)
SSshuttle.centcom_message += "Partying Russians incoming."
if(SPIDER_GIFT)
SSshuttle.centcom_message += "Spider Clan gift incoming."
if(DEPARTMENT_RESUPPLY)
SSshuttle.centcom_message += "Department resupply incoming."
if(ANTIDOTE_NEEDED)
SSshuttle.centcom_message += "Virus samples incoming."
/datum/round_event/shuttle_loan/tick()
if(dispatched)
if(SSshuttle.supply.mode != SHUTTLE_IDLE)
endWhen = activeFor
else
endWhen = activeFor + 1
/datum/round_event/shuttle_loan/end()
if(SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched)
//make sure the shuttle was dispatched in time
SSshuttle.shuttle_loan = null
var/list/empty_shuttle_turfs = list()
for(var/turf/open/floor/T in SSshuttle.supply.areaInstance)
if(T.density || T.contents.len)
continue
empty_shuttle_turfs += T
if(!empty_shuttle_turfs.len)
return
var/list/shuttle_spawns = list()
switch(dispatch_type)
if(HIJACK_SYNDIE)
var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/emergency/specialops]
pack.generate(pick_n_take(empty_shuttle_turfs))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate)
shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate)
if(prob(75))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate)
if(prob(50))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate)
if(RUSKY_PARTY)
var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/organic/party]
pack.generate(pick_n_take(empty_shuttle_turfs))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian)
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian/ranged) //drops a mateba
shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear)
if(prob(75))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian)
if(prob(50))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear)
if(SPIDER_GIFT)
var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/emergency/specialops]
pack.generate(pick_n_take(empty_shuttle_turfs))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/poison/giant_spider)
shuttle_spawns.Add(/mob/living/simple_animal/hostile/poison/giant_spider)
shuttle_spawns.Add(/mob/living/simple_animal/hostile/poison/giant_spider/nurse)
if(prob(50))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/poison/giant_spider/hunter)
var/turf/T = pick(empty_shuttle_turfs)
empty_shuttle_turfs.Remove(T)
new /obj/effect/decal/remains/human(T)
new /obj/item/clothing/shoes/space_ninja(T)
new /obj/item/clothing/mask/balaclava(T)
T = pick(empty_shuttle_turfs)
new /obj/effect/spider/stickyweb(T)
T = pick(empty_shuttle_turfs)
new /obj/effect/spider/stickyweb(T)
T = pick(empty_shuttle_turfs)
new /obj/effect/spider/stickyweb(T)
T = pick(empty_shuttle_turfs)
new /obj/effect/spider/stickyweb(T)
T = pick(empty_shuttle_turfs)
new /obj/effect/spider/stickyweb(T)
if(ANTIDOTE_NEEDED)
var/virus_type = pick(/datum/disease/beesease, /datum/disease/brainrot, /datum/disease/fluspanish)
var/turf/T
for(var/i=0, i<10, i++)
if(prob(15))
shuttle_spawns.Add(/obj/item/weapon/reagent_containers/glass/bottle)
else if(prob(15))
shuttle_spawns.Add(/obj/item/weapon/reagent_containers/syringe)
else if(prob(25))
shuttle_spawns.Add(/obj/item/weapon/shard)
T = pick_n_take(empty_shuttle_turfs)
var/obj/effect/decal/cleanable/blood/b = new(T)
var/datum/disease/D = new virus_type()
D.longevity = 1000
b.viruses += D
D.holder = b
shuttle_spawns.Add(/obj/structure/closet/crate)
shuttle_spawns.Add(/obj/item/weapon/reagent_containers/glass/bottle/pierrot_throat)
shuttle_spawns.Add(/obj/item/weapon/reagent_containers/glass/bottle/magnitis)
if(DEPARTMENT_RESUPPLY)
var/list/crate_types = list(
/datum/supply_pack/emergency/equipment,
/datum/supply_pack/security/supplies,
/datum/supply_pack/organic/food,
/datum/supply_pack/emergency/weedcontrol,
/datum/supply_pack/engineering/tools,
/datum/supply_pack/engineering/engiequipment,
/datum/supply_pack/science/robotics,
/datum/supply_pack/science/plasma,
/datum/supply_pack/medical/supplies
)
for(var/crate in crate_types)
var/datum/supply_pack/pack = SSshuttle.supply_packs[crate]
pack.generate(pick_n_take(empty_shuttle_turfs))
for(var/i in 1 to 5)
var/decal = pick(/obj/effect/decal/cleanable/flour, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/oil)
new decal(pick_n_take(empty_shuttle_turfs))
var/false_positive = 0
while(shuttle_spawns.len && empty_shuttle_turfs.len)
var/turf/T = pick_n_take(empty_shuttle_turfs)
if(T.contents.len && false_positive < 5)
false_positive++
continue
var/spawn_type = pick_n_take(shuttle_spawns)
new spawn_type(T)
#undef HIJACK_SYNDIE
#undef RUSKY_PARTY
#undef SPIDER_GIFT
#undef DEPARTMENT_RESUPPLY
#undef ANTIDOTE_NEEDED
+572
View File
@@ -0,0 +1,572 @@
/datum/round_event_control/spacevine
name = "Spacevine"
typepath = /datum/round_event/spacevine
weight = 15
max_occurrences = 3
min_players = 10
/datum/round_event/spacevine/start()
var/list/turfs = list() //list of all the empty floor turfs in the hallway areas
var/obj/effect/spacevine/SV = new()
for(var/area/hallway/A in world)
for(var/turf/F in A)
if(F.Enter(SV))
turfs += F
qdel(SV)
if(turfs.len) //Pick a turf to spawn at if we can
var/turf/T = pick(turfs)
new/obj/effect/spacevine_controller(T) //spawn a controller at turf
/datum/spacevine_mutation
var/name = ""
var/severity = 1
var/hue
var/quality
/datum/spacevine_mutation/proc/process_mutation(obj/effect/spacevine/holder)
return
/datum/spacevine_mutation/proc/process_temperature(obj/effect/spacevine/holder, temp, volume)
return
/datum/spacevine_mutation/proc/on_birth(obj/effect/spacevine/holder)
return
/datum/spacevine_mutation/proc/on_grow(obj/effect/spacevine/holder)
return
/datum/spacevine_mutation/proc/on_death(obj/effect/spacevine/holder)
return
/datum/spacevine_mutation/proc/on_hit(obj/effect/spacevine/holder, mob/hitter, obj/item/I, expected_damage)
. = expected_damage
/datum/spacevine_mutation/proc/on_cross(obj/effect/spacevine/holder, mob/crosser)
return
/datum/spacevine_mutation/proc/on_chem(obj/effect/spacevine/holder, datum/reagent/R)
return
/datum/spacevine_mutation/proc/on_eat(obj/effect/spacevine/holder, mob/living/eater)
return
/datum/spacevine_mutation/proc/on_spread(obj/effect/spacevine/holder, turf/target)
return
/datum/spacevine_mutation/proc/on_buckle(obj/effect/spacevine/holder, mob/living/buckled)
return
/datum/spacevine_mutation/proc/on_explosion(severity, target, obj/effect/spacevine/holder)
return
/datum/spacevine_mutation/space_covering
name = "space protective"
hue = "#aa77aa"
quality = POSITIVE
/turf/open/floor/vines
color = "#aa77aa"
icon_state = "vinefloor"
broken_states = list()
//All of this shit is useless for vines
/turf/open/floor/vines/attackby()
return
/turf/open/floor/vines/burn_tile()
return
/turf/open/floor/vines/break_tile()
return
/turf/open/floor/vines/make_plating()
return
/turf/open/floor/vines/break_tile_to_plating()
return
/turf/open/floor/vines/ex_act(severity, target)
if(severity < 3 || target == src)
ChangeTurf(src.baseturf)
/turf/open/floor/vines/narsie_act()
if(prob(20))
ChangeTurf(src.baseturf) //nar sie eats this shit
/turf/open/floor/vines/singularity_pull(S, current_size)
if(current_size >= STAGE_FIVE)
if(prob(50))
ChangeTurf(src.baseturf)
/turf/open/floor/vines/ChangeTurf(turf/open/floor/T)
for(var/obj/effect/spacevine/SV in src)
qdel(SV)
..()
UpdateAffectingLights()
/datum/spacevine_mutation/space_covering/on_grow(obj/effect/spacevine/holder)
if(istype(holder.loc, /turf/open/space))
var/turf/open/spaceturf = holder.loc
spaceturf.ChangeTurf(/turf/open/floor/vines)
/datum/spacevine_mutation/space_covering/process_mutation(obj/effect/spacevine/holder)
if(istype(holder.loc, /turf/open/space))
var/turf/open/spaceturf = holder.loc
spaceturf.ChangeTurf(/turf/open/floor/vines)
/datum/spacevine_mutation/space_covering/on_death(obj/effect/spacevine/holder)
if(istype(holder.loc, /turf/open/floor/vines))
var/turf/open/spaceturf = holder.loc
spaceturf.ChangeTurf(/turf/open/space)
/datum/spacevine_mutation/bluespace
name = "bluespace"
hue = "#3333ff"
quality = MINOR_NEGATIVE
/datum/spacevine_mutation/bluespace/on_spread(obj/effect/spacevine/holder, turf/target)
if(holder.energy > 1 && !locate(/obj/effect/spacevine) in target)
holder.master.spawn_spacevine_piece(target, holder)
/datum/spacevine_mutation/light
name = "light"
hue = "#ffff00"
quality = POSITIVE
severity = 4
/datum/spacevine_mutation/light/on_grow(obj/effect/spacevine/holder)
if(holder.energy)
holder.SetLuminosity(severity, 3)
/datum/spacevine_mutation/toxicity
name = "toxic"
hue = "#ff00ff"
severity = 10
quality = NEGATIVE
/datum/spacevine_mutation/toxicity/on_cross(obj/effect/spacevine/holder, mob/living/crosser)
if(issilicon(crosser))
return
if(prob(severity) && istype(crosser))
crosser << "<span class='alert'>You accidently touch the vine and feel a strange sensation.</span>"
crosser.adjustToxLoss(5)
/datum/spacevine_mutation/toxicity/on_eat(obj/effect/spacevine/holder, mob/living/eater)
eater.adjustToxLoss(5)
/datum/spacevine_mutation/explosive //OH SHIT IT CAN CHAINREACT RUN!!!
name = "explosive"
hue = "#ff0000"
quality = NEGATIVE
severity = 2
/datum/spacevine_mutation/explosive/on_explosion(explosion_severity, target, obj/effect/spacevine/holder)
if(explosion_severity < 3)
qdel(src)
else
. = 1
spawn(5)
qdel(src)
/datum/spacevine_mutation/explosive/on_death(obj/effect/spacevine/holder, mob/hitter, obj/item/I)
explosion(holder.loc, 0, 0, severity, 0, 0)
/datum/spacevine_mutation/fire_proof
name = "fire proof"
hue = "#ff8888"
quality = MINOR_NEGATIVE
/datum/spacevine_mutation/fire_proof/process_temperature(obj/effect/spacevine/holder, temp, volume)
return 1
/datum/spacevine_mutation/fire_proof/on_hit(obj/effect/spacevine/holder, mob/hitter, obj/item/I, expected_damage)
if(I && I.damtype == "fire")
. = 0
/datum/spacevine_mutation/vine_eating
name = "vine eating"
hue = "#ff7700"
quality = MINOR_NEGATIVE
/datum/spacevine_mutation/vine_eating/on_spread(obj/effect/spacevine/holder, turf/target)
var/obj/effect/spacevine/prey = locate() in target
if(prey && !prey.mutations.Find(src)) //Eat all vines that are not of the same origin
qdel(prey)
/datum/spacevine_mutation/aggressive_spread //very OP, but im out of other ideas currently
name = "aggressive spreading"
hue = "#333333"
severity = 3
quality = NEGATIVE
/datum/spacevine_mutation/aggressive_spread/on_spread(obj/effect/spacevine/holder, turf/target)
target.ex_act(severity, src)
/datum/spacevine_mutation/aggressive_spread/on_buckle(obj/effect/spacevine/holder, mob/living/buckled)
buckled.ex_act(severity)
/datum/spacevine_mutation/transparency
name = "transparent"
hue = ""
quality = POSITIVE
/datum/spacevine_mutation/transparency/on_grow(obj/effect/spacevine/holder)
holder.SetOpacity(0)
holder.alpha = 125
/datum/spacevine_mutation/oxy_eater
name = "oxygen consuming"
hue = "#ffff88"
severity = 3
quality = NEGATIVE
/datum/spacevine_mutation/oxy_eater/process_mutation(obj/effect/spacevine/holder)
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases["o2"])
return
GM.gases["o2"][MOLES] -= severity * holder.energy
GM.garbage_collect()
/datum/spacevine_mutation/nitro_eater
name = "nitrogen consuming"
hue = "#8888ff"
severity = 3
quality = NEGATIVE
/datum/spacevine_mutation/nitro_eater/process_mutation(obj/effect/spacevine/holder)
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases["n2"])
return
GM.gases["n2"][MOLES] -= severity * holder.energy
GM.garbage_collect()
/datum/spacevine_mutation/carbondioxide_eater
name = "CO2 consuming"
hue = "#00ffff"
severity = 3
quality = POSITIVE
/datum/spacevine_mutation/carbondioxide_eater/process_mutation(obj/effect/spacevine/holder)
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases["co2"])
return
GM.gases["co2"][MOLES] -= severity * holder.energy
GM.garbage_collect()
/datum/spacevine_mutation/plasma_eater
name = "toxins consuming"
hue = "#ffbbff"
severity = 3
quality = POSITIVE
/datum/spacevine_mutation/plasma_eater/process_mutation(obj/effect/spacevine/holder)
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases["plasma"])
return
GM.gases["plasma"][MOLES] -= severity * holder.energy
GM.garbage_collect()
/datum/spacevine_mutation/thorns
name = "thorny"
hue = "#666666"
severity = 10
quality = NEGATIVE
/datum/spacevine_mutation/thorns/on_cross(obj/effect/spacevine/holder, mob/living/crosser)
if(prob(severity) && istype(crosser))
var/mob/living/M = crosser
M.adjustBruteLoss(5)
M << "<span class='alert'>You cut yourself on the thorny vines.</span>"
/datum/spacevine_mutation/thorns/on_hit(obj/effect/spacevine/holder, mob/living/hitter)
if(prob(severity) && istype(hitter))
var/mob/living/M = hitter
M.adjustBruteLoss(5)
M << "<span class='alert'>You cut yourself on the thorny vines.</span>"
/datum/spacevine_mutation/woodening
name = "hardened"
hue = "#997700"
quality = NEGATIVE
/datum/spacevine_mutation/woodening/on_grow(obj/effect/spacevine/holder)
if(holder.energy)
holder.density = 1
/datum/spacevine_mutation/woodening/on_hit(obj/effect/spacevine/holder, mob/hitter, obj/item/I, expected_damage)
if(!expected_damage)
return
if(hitter)
if(I)
. = I.force * 2
else
. = 8
/datum/spacevine_mutation/flowering
name = "flowering"
hue = "#0A480D"
quality = NEGATIVE
severity = 10
/datum/spacevine_mutation/flowering/on_grow(obj/effect/spacevine/holder)
if(holder.energy == 2 && prob(severity) && !locate(/obj/structure/alien/resin/flower_bud_enemy) in range(5,holder))
new/obj/structure/alien/resin/flower_bud_enemy(get_turf(holder))
/datum/spacevine_mutation/flowering/on_cross(obj/effect/spacevine/holder, mob/living/crosser)
holder.entangle(crosser)
// SPACE VINES (Note that this code is very similar to Biomass code)
/obj/effect/spacevine
name = "space vines"
desc = "An extremely expansionistic species of vine."
icon = 'icons/effects/spacevines.dmi'
icon_state = "Light1"
anchored = 1
density = 0
layer = SPACEVINE_LAYER
mouse_opacity = 2 //Clicking anywhere on the turf is good enough
pass_flags = PASSTABLE | PASSGRILLE
var/energy = 0
var/obj/effect/spacevine_controller/master = null
var/list/mutations = list()
/obj/effect/spacevine/Destroy()
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_death(src)
if(master)
master.vines -= src
master.growth_queue -= src
if(!master.vines.len)
var/obj/item/seeds/kudzu/KZ = new(loc)
KZ.mutations |= mutations
KZ.potency = min(100, master.mutativness * 10)
KZ.production = (master.spread_cap / initial(master.spread_cap)) * 50
mutations = list()
SetOpacity(0)
if(has_buckled_mobs())
unbuckle_all_mobs(force=1)
return ..()
/obj/effect/spacevine/proc/on_chem_effect(datum/reagent/R)
var/override = 0
for(var/datum/spacevine_mutation/SM in mutations)
override += SM.on_chem(src, R)
if(!override && istype(R, /datum/reagent/toxin/plantbgone))
if(prob(50))
qdel(src)
/obj/effect/spacevine/proc/eat(mob/eater)
var/override = 0
for(var/datum/spacevine_mutation/SM in mutations)
override += SM.on_eat(src, eater)
if(!override)
if(prob(10))
eater.say("Nom")
qdel(src)
/obj/effect/spacevine/attackby(obj/item/weapon/W, mob/user, params)
if (!W || !user || !W.type)
return
user.changeNext_move(CLICK_CD_MELEE)
var/override = W.force
if(W.is_sharp())
override = 100
if(istype(W, /obj/item/weapon/scythe))
var/local_override = override
for(var/obj/effect/spacevine/B in orange(1,src))
for(var/datum/spacevine_mutation/SM in mutations)
local_override = SM.on_hit(src, user, W, local_override)
if(prob(local_override))
qdel(B)
for(var/datum/spacevine_mutation/SM in mutations)
override = SM.on_hit(src, user, W, override) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further
if(prob(override))
qdel(src)
..()
/obj/effect/spacevine/Crossed(mob/crosser)
if(isliving(crosser))
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_cross(src, crosser)
/obj/effect/spacevine/attack_hand(mob/user)
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_hit(src, user)
user_unbuckle_mob(user, user)
/obj/effect/spacevine/attack_paw(mob/living/user)
user.do_attack_animation(src)
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_hit(src, user)
user_unbuckle_mob(user,user)
/obj/effect/spacevine/attack_alien(mob/living/user)
eat(user)
/obj/effect/spacevine_controller
invisibility = INVISIBILITY_ABSTRACT
var/list/obj/effect/spacevine/vines = list()
var/list/growth_queue = list()
var/spread_multiplier = 5
var/spread_cap = 30
var/list/mutations_list = list()
var/mutativness = 1
/obj/effect/spacevine_controller/New(loc, list/muts, mttv, spreading)
spawn_spacevine_piece(loc, , muts)
START_PROCESSING(SSobj, src)
init_subtypes(/datum/spacevine_mutation/, mutations_list)
if(mttv != null)
mutativness = mttv / 10
if(spreading != null)
spread_cap *= spreading / 50
spread_multiplier /= spreading / 50
/obj/effect/spacevine_controller/ex_act() //only killing all vines will end this suffering
return
/obj/effect/spacevine_controller/singularity_act()
return
/obj/effect/spacevine_controller/singularity_pull()
return
/obj/effect/spacevine_controller/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/effect/spacevine_controller/proc/spawn_spacevine_piece(turf/location, obj/effect/spacevine/parent, list/muts)
var/obj/effect/spacevine/SV = new(location)
growth_queue += SV
vines += SV
SV.master = src
if(muts && muts.len)
SV.mutations |= muts
if(parent)
SV.mutations |= parent.mutations
SV.color = parent.color
SV.desc = parent.desc
if(prob(mutativness))
SV.mutations |= pick(mutations_list)
var/datum/spacevine_mutation/randmut = pick(SV.mutations)
SV.color = randmut.hue
SV.desc = "An extremely expansionistic species of vine. These are "
for(var/datum/spacevine_mutation/M in SV.mutations)
SV.desc += "[M.name] "
SV.desc += "vines."
for(var/datum/spacevine_mutation/SM in SV.mutations)
SM.on_birth(SV)
/obj/effect/spacevine_controller/process()
if(!vines)
qdel(src) //space vines exterminated. Remove the controller
return
if(!growth_queue)
qdel(src) //Sanity check
return
var/length = 0
length = min( spread_cap , max( 1 , vines.len / spread_multiplier ) )
var/i = 0
var/list/obj/effect/spacevine/queue_end = list()
for( var/obj/effect/spacevine/SV in growth_queue )
if(qdeleted(SV))
continue
i++
queue_end += SV
growth_queue -= SV
for(var/datum/spacevine_mutation/SM in SV.mutations)
SM.process_mutation(SV)
if(SV.energy < 2) //If tile isn't fully grown
if(prob(20))
SV.grow()
else //If tile is fully grown
SV.entangle_mob()
//if(prob(25))
SV.spread()
if(i >= length)
break
growth_queue = growth_queue + queue_end
/obj/effect/spacevine/proc/grow()
if(!energy)
src.icon_state = pick("Med1", "Med2", "Med3")
energy = 1
SetOpacity(1)
else
src.icon_state = pick("Hvy1", "Hvy2", "Hvy3")
energy = 2
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_grow(src)
/obj/effect/spacevine/proc/entangle_mob()
if(!has_buckled_mobs() && prob(25))
for(var/mob/living/V in src.loc)
entangle(V)
if(buckled_mobs.len)
break //only capture one mob at a time
/obj/effect/spacevine/proc/entangle(mob/living/V)
if(!V)
return
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_buckle(src, V)
if((V.stat != DEAD) && (V.buckled != src)) //not dead or captured
V << "<span class='danger'>The vines [pick("wind", "tangle", "tighten")] around you!</span>"
buckle_mob(V)
/obj/effect/spacevine/proc/spread()
var/direction = pick(cardinal)
var/turf/stepturf = get_step(src,direction)
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_spread(src, stepturf)
stepturf = get_step(src,direction) //in case turf changes, to make sure no runtimes happen
if(!locate(/obj/effect/spacevine, stepturf))
if(stepturf.Enter(src))
if(master)
master.spawn_spacevine_piece(stepturf, src)
/obj/effect/spacevine/ex_act(severity, target)
if(istype(target, type)) //if its agressive spread vine dont do anything
return
var/i
for(var/datum/spacevine_mutation/SM in mutations)
i += SM.on_explosion(severity, target, src)
if(!i && prob(100/severity))
qdel(src)
/obj/effect/spacevine/temperature_expose(null, temp, volume)
var/override = 0
for(var/datum/spacevine_mutation/SM in mutations)
override += SM.process_temperature(src, temp, volume)
if(!override)
qdel(src)
+36
View File
@@ -0,0 +1,36 @@
/datum/round_event_control/spider_infestation
name = "Spider Infestation"
typepath = /datum/round_event/spider_infestation
weight = 5
max_occurrences = 1
min_players = 15
/datum/round_event/spider_infestation
announceWhen = 400
var/spawncount = 1
/datum/round_event/spider_infestation/setup()
announceWhen = rand(announceWhen, announceWhen + 50)
spawncount = rand(5, 8)
/datum/round_event/spider_infestation/announce()
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/AI/aliens.ogg')
/datum/round_event/spider_infestation/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in world)
if(temp_vent.loc.z == ZLEVEL_STATION && !temp_vent.welded)
var/datum/pipeline/temp_vent_parent = temp_vent.PARENT1
if(temp_vent_parent.other_atmosmch.len > 20)
vents += temp_vent
while((spawncount >= 1) && vents.len)
var/obj/vent = pick(vents)
var/obj/effect/spider/spiderling/S = new(vent.loc)
if(prob(66))
S.grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/nurse
vents -= vent
spawncount--
@@ -0,0 +1,19 @@
/datum/round_event_control/spontaneous_appendicitis
name = "Spontaneous Appendicitis"
typepath = /datum/round_event/spontaneous_appendicitis
weight = 20
max_occurrences = 4
earliest_start = 6000
min_players = 5 // To make your chance of getting help a bit higher.
/datum/round_event/spontaneous_appendicitis/start()
for(var/mob/living/carbon/human/H in shuffle(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
H.ForceContractDisease(D)
break
+49
View File
@@ -0,0 +1,49 @@
/datum/round_event_control/vent_clog
name = "Clogged Vents"
typepath = /datum/round_event/vent_clog
weight = 35
/datum/round_event/vent_clog
announceWhen = 1
startWhen = 5
endWhen = 35
var/interval = 2
var/list/vents = list()
var/list/gunk = list("water","carbon","flour","radium","toxin","cleaner","nutriment","condensedcapsaicin","mushroomhallucinogen","lube",
"plantbgone","banana","charcoal","space_drugs","morphine","holywater","ethanol","hot_coco","facid")
/datum/round_event/vent_clog/announce()
priority_announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert")
/datum/round_event/vent_clog/setup()
endWhen = rand(25, 100)
for(var/obj/machinery/atmospherics/components/unary/vent_scrubber/temp_vent in machines)
if(temp_vent.loc.z == ZLEVEL_STATION && !temp_vent.welded)
var/datum/pipeline/temp_vent_parent = temp_vent.PARENT1
if(temp_vent_parent.other_atmosmch.len > 20)
vents += temp_vent
if(!vents.len)
return kill()
/datum/round_event/vent_clog/tick()
if(activeFor % interval == 0)
var/obj/machinery/atmospherics/components/unary/vent = pick_n_take(vents)
while(vent && vent.welded)
vent = pick_n_take(vents)
if(vent && vent.loc)
var/datum/reagents/R = new/datum/reagents(50)
R.my_atom = vent
R.add_reagent(pick(gunk), 50)
var/datum/effect_system/smoke_spread/chem/smoke = new
smoke.set_up(R, 1, vent, silent = 1)
playsound(vent.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
smoke.start()
qdel(R)
var/cockroaches = prob(33) ? 3 : 0
while(cockroaches)
new /mob/living/simple_animal/cockroach(get_turf(vent))
cockroaches--
+32
View File
@@ -0,0 +1,32 @@
/datum/round_event_control/weightless
name = "Gravity Systems Failure"
typepath = /datum/round_event/weightless
weight = 15
/datum/round_event/weightless
startWhen = 5
endWhen = 65
announceWhen = 1
/datum/round_event/weightless/setup()
startWhen = rand(0,10)
endWhen = rand(40,80)
/datum/round_event/weightless/announce()
command_alert("Warning: Failsafes for the station's artificial gravity arrays have been triggered. Please be aware that if this problem recurs it may result in formation of gravitational anomalies. Nanotrasen wishes to remind you that the unauthorised formation of anomalies within Nanotrasen facilities is strictly prohibited by health and safety regulation [rand(99,9999)][pick("a","b","c")]:subclause[rand(1,20)][pick("a","b","c")].")
/datum/round_event/weightless/start()
for(var/area/A in world)
A.gravitychange(0)
if(control)
control.weight *= 2
/datum/round_event/weightless/end()
for(var/area/A in world)
A.gravitychange(1)
if(announceWhen >= 0)
command_alert("Artificial gravity arrays are now functioning within normal parameters. Please report any irregularities to your respective head of staff.")
@@ -0,0 +1,17 @@
/datum/round_event_control/wizard/darkness
name = "Advanced Darkness"
weight = 2
typepath = /datum/round_event/wizard/darkness
max_occurrences = 2
earliest_start = 0
/datum/round_event/wizard/darkness
endWhen = 0
var/started = FALSE
/datum/round_event/wizard/darkness/start()
if(!started)
started = TRUE
var/datum/weather/advanced_darkness/darkness = new
darkness.weather_start_up()
+56
View File
@@ -0,0 +1,56 @@
//in this file: Various events that directly aid the wizard. This is the "lets entice the wizard to use summon events!" file.
/datum/round_event_control/wizard/robelesscasting //EI NUDTH!
name = "Robeless Casting"
weight = 2
typepath = /datum/round_event/wizard/robelesscasting/
max_occurrences = 1
earliest_start = 0
/datum/round_event/wizard/robelesscasting/start()
for(var/mob/living/L in mob_list) //Hey if a corgi has magic missle he should get the same benifit as anyone
if(L.mind && L.mind.spell_list.len != 0)
var/spell_improved = 0
for(var/obj/effect/proc_holder/spell/S in L.mind.spell_list)
if(S.clothes_req)
S.clothes_req = 0
spell_improved = 1
if(spell_improved)
L << "<span class='notice'>You suddenly feel like you never needed those garish robes in the first place...</span>"
//--//
/datum/round_event_control/wizard/improvedcasting //blink x5 disintergrate x5 here I come!
name = "Improved Casting"
weight = 3
typepath = /datum/round_event/wizard/improvedcasting/
max_occurrences = 4 //because that'd be max level spells
earliest_start = 0
/datum/round_event/wizard/improvedcasting/start()
for(var/mob/living/L in mob_list)
if(L.mind && L.mind.spell_list.len != 0)
for(var/obj/effect/proc_holder/spell/S in L.mind.spell_list)
S.name = initial(S.name)
S.spell_level++
if(S.spell_level >= 6 || S.charge_max <= 0) //Badmin checks, these should never be a problem in normal play
continue
if(S.level_max <= 0)
continue
S.charge_max = round(initial(S.charge_max) - S.spell_level * (initial(S.charge_max) - S.cooldown_min) / S.level_max)
if(S.charge_max < S.charge_counter)
S.charge_counter = S.charge_max
switch(S.spell_level)
if(1)
S.name = "Efficient [S.name]"
if(2)
S.name = "Quickened [S.name]"
if(3)
S.name = "Free [S.name]"
if(4)
S.name = "Instant [S.name]"
if(5)
S.name = "Ludicrous [S.name]"
L << "<span class='notice'>You suddenly feel more competent with your casting!</span>"
+11
View File
@@ -0,0 +1,11 @@
/datum/round_event_control/wizard/blobies //avast!
name = "Zombie Outbreak"
weight = 3
typepath = /datum/round_event/wizard/blobies/
max_occurrences = 3
earliest_start = 12000 // 20 minutes (gotta get some bodies made!)
/datum/round_event/wizard/blobies/start()
for(var/mob/living/carbon/human/H in dead_mob_list)
new /mob/living/simple_animal/hostile/blob/blobspore(H.loc)
+60
View File
@@ -0,0 +1,60 @@
/datum/round_event_control/wizard/cursed_items //fashion disasters
name = "Cursed Items"
weight = 3
typepath = /datum/round_event/wizard/cursed_items/
max_occurrences = 3
earliest_start = 0
//Note about adding items to this: Because of how NODROP works if an item spawned to the hands can also be equiped to a slot
//it will be able to be put into that slot from the hand, but then get stuck there. To avoid this make a new subtype of any
//item you want to equip to the hand, and set its slots_flags = null. Only items equiped to hands need do this.
/datum/round_event/wizard/cursed_items/start()
var/item_set = pick("wizardmimic", "swords", "bigfatdoobie", "boxing", "voicemodulators", "catgirls2015")
var/list/wearslots = list(slot_wear_suit, slot_shoes, slot_head, slot_wear_mask, slot_r_hand, slot_gloves, slot_ears)
var/list/loadout = list()
var/ruins_spaceworthiness
var/ruins_wizard_loadout
loadout.len = 7
switch(item_set)
if("wizardmimic")
loadout = list(/obj/item/clothing/suit/wizrobe, /obj/item/clothing/shoes/sandal, /obj/item/clothing/head/wizard)
ruins_spaceworthiness = 1
if("swords")
loadout[5] = /obj/item/weapon/katana/cursed
if("bigfatdoobie")
loadout[4] = /obj/item/clothing/mask/cigarette/rollie/trippy/
ruins_spaceworthiness = 1
if("boxing")
loadout[4] = /obj/item/clothing/mask/luchador
loadout[6] = /obj/item/clothing/gloves/boxing
ruins_spaceworthiness = 1
if("voicemodulators")
loadout[4] = /obj/item/clothing/mask/chameleon
if("catgirls2015")
loadout[3] = /obj/item/clothing/head/kitty
ruins_spaceworthiness = 1
ruins_wizard_loadout = 1
for(var/mob/living/carbon/human/H in living_mob_list)
if(ruins_spaceworthiness && (H.z != 1 || istype(H.loc, /turf/open/space)))
continue //#savetheminers
if(ruins_wizard_loadout && H.mind && ((H.mind in ticker.mode.wizards) || (H.mind in ticker.mode.apprentices)))
continue
if(item_set == "catgirls2015") //Wizard code means never having to say you're sorry
H.gender = FEMALE
var/list/slots = list(H.wear_suit, H.shoes, H.head, H.wear_mask, H.r_hand, H.gloves, H.ears) //add new slots as needed to back
for(var/i = 1, i <= loadout.len, i++)
if(loadout[i])
var/obj/item/J = loadout[i]
var/obj/item/I = new J //dumb but required because of byond throwing a fit anytime new gets too close to a list
H.unEquip(slots[i])
H.equip_to_slot_or_del(I, wearslots[i])
I.flags |= NODROP
I.name = "cursed " + I.name
for(var/mob/living/carbon/human/H in living_mob_list)
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(0, H.loc)
smoke.start()
@@ -0,0 +1,53 @@
/datum/round_event_control/wizard/deprevolt //stationwide!
name = "Departmental Uprising"
weight = 0 //An order that requires order in a round of chaos was maybe not the best idea. Requiescat in pace departmental uprising August 2014 - March 2015
typepath = /datum/round_event/wizard/deprevolt/
max_occurrences = 1
earliest_start = 0
/datum/round_event/wizard/deprevolt/start()
var/list/tidecolor
var/list/jobs_to_revolt = list()
var/nation
var/list/citizens = list()
tidecolor = pick("grey", "white", "yellow", "purple", "brown", "whatevercolorrepresentstheservicepeople")
switch(tidecolor)
if("grey") //God help you
jobs_to_revolt = list("Assistant")
nation = pick("Assa", "Mainte", "Tunnel", "Gris", "Grey", "Liath", "Grigio", "Ass", "Assi")
if("white")
jobs_to_revolt = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Geneticist", "Virologist")
nation = pick("Mede", "Healtha", "Recova", "Chemi", "Geneti", "Viro", "Psych")
if("yellow")
jobs_to_revolt = list("Chief Engineer", "Station Engineer", "Atmospheric Technician")
nation = pick("Atomo", "Engino", "Power", "Teleco")
if("purple")
jobs_to_revolt = list("Research Director","Scientist", "Roboticist")
nation = pick("Sci", "Griffa", "Explosi", "Mecha", "Xeno")
if("brown")
jobs_to_revolt = list("Quartermaster", "Cargo Technician", "Shaft Miner")
nation = pick("Cargo", "Guna", "Suppli", "Mule", "Crate", "Ore", "Mini", "Shaf")
if("whatevercolorrepresentstheservicepeople") //the few, the proud, the technically aligned
jobs_to_revolt = list("Bartender", "Cook", "Botanist", "Clown", "Mime", "Janitor", "Chaplain")
nation = pick("Honka", "Boozo", "Fatu", "Danka", "Mimi", "Libra", "Jani", "Religi")
nation += pick("stan", "topia", "land", "nia", "ca", "tova", "dor", "ador", "tia", "sia", "ano", "tica", "tide", "cis", "marea", "co", "taoide", "slavia", "stotzka")
for(var/mob/living/carbon/human/H in mob_list)
if(H.mind)
var/datum/mind/M = H.mind
if(M.assigned_role && !(M in ticker.mode.traitors))
for(var/job in jobs_to_revolt)
if(M.assigned_role == job)
citizens += H
ticker.mode.traitors += M
M.special_role = "separatist"
H.attack_log += "\[[time_stamp()]\] <font color='red'>Was made into a separatist, long live [nation]!</font>"
H << "<B>You are a separatist! [nation] forever! Protect the soverignty of your newfound land with your comrades in arms!</B>"
if(citizens.len)
var/message
for(var/job in jobs_to_revolt)
message += "[job],"
message_admins("The nation of [nation] has been formed. Affected jobs are [message]")
@@ -0,0 +1,12 @@
/datum/round_event_control/wizard/fake_explosion //Oh no the station is gone!
name = "Fake Nuclear Explosion"
weight = 0 //Badmin exclusive now because once it's expected its not funny
typepath = /datum/round_event/wizard/fake_explosion/
max_occurrences = 1
earliest_start = 0
/datum/round_event/wizard/fake_explosion/start()
for(var/mob/M in player_list)
M << 'sound/machines/Alarm.ogg'
spawn(100)
ticker.station_explosion_cinematic(1,"fake") //:o)
+27
View File
@@ -0,0 +1,27 @@
/datum/round_event_control/wizard/ghost //The spook is real
name = "G-G-G-Ghosts!"
weight = 3
typepath = /datum/round_event/wizard/ghost/
max_occurrences = 5
earliest_start = 0
/datum/round_event/wizard/ghost/start()
for(var/mob/dead/observer/G in player_list)
G.invisibility = 0
G << "You suddenly feel extremely obvious..."
//--//
/datum/round_event_control/wizard/possession //Oh shit
name = "Possessing G-G-G-Ghosts!"
weight = 2
typepath = /datum/round_event/wizard/possession
max_occurrences = 5
earliest_start = 0
/datum/round_event/wizard/possession/start()
for(var/mob/dead/observer/G in player_list)
G.verbs += /mob/dead/observer/verb/boo
G.verbs += /mob/dead/observer/verb/possess
G << "You suddenly feel a welling of new spooky powers..."
+97
View File
@@ -0,0 +1,97 @@
/datum/round_event_control/wizard/greentext //Gotta have it!
name = "Greentext"
weight = 4
typepath = /datum/round_event/wizard/greentext/
max_occurrences = 1
earliest_start = 0
/datum/round_event/wizard/greentext/start()
var/list/holder_canadates = player_list.Copy()
for(var/mob/M in holder_canadates)
if(!ishuman(M))
holder_canadates -= M
if(!holder_canadates) //Very unlikely, but just in case
return 0
var/mob/living/carbon/human/H = pick(holder_canadates)
new /obj/item/weapon/greentext(H.loc)
H << "<font color='green'>The mythical greentext appear at your feet! Pick it up if you dare...</font>"
/obj/item/weapon/greentext
name = "greentext"
desc = "No one knows what this massive tome does, but it feels <i><font color='green'>desirable</font></i> all the same..."
w_class = 4
icon = 'icons/obj/wizard.dmi'
icon_state = "greentext"
var/mob/living/last_holder
var/mob/living/new_holder
var/list/color_altered_mobs = list()
burn_state = FIRE_PROOF
var/quiet = FALSE
/obj/item/weapon/greentext/New()
..()
poi_list |= src
/obj/item/weapon/greentext/equipped(mob/living/user as mob)
user << "<font color='green'>So long as you leave this place with greentext in hand you know will be happy...</font>"
if(user.mind && user.mind.objectives.len > 0)
user << "<span class='warning'>... so long as you still perform your other objectives that is!</span>"
new_holder = user
if(!last_holder)
last_holder = user
if(!(user in color_altered_mobs))
color_altered_mobs += user
user.color = "#00FF00"
START_PROCESSING(SSobj, src)
..()
/obj/item/weapon/greentext/dropped(mob/living/user as mob)
if(user in color_altered_mobs)
user << "<span class='warning'>A sudden wave of failure washes over you...</span>"
user.color = "#FF0000" //ya blew it
last_holder = null
new_holder = null
STOP_PROCESSING(SSobj, src)
..()
/obj/item/weapon/greentext/process()
if(new_holder && new_holder.z == ZLEVEL_CENTCOM)//you're winner!
new_holder << "<font color='green'>At last it feels like victory is assured!</font>"
if(!(new_holder in ticker.mode.traitors))
ticker.mode.traitors += new_holder.mind
new_holder.mind.special_role = "winner"
var/datum/objective/O = new /datum/objective("Succeed")
O.completed = 1 //YES!
O.owner = new_holder.mind
new_holder.mind.objectives += O
new_holder.attack_log += "\[[time_stamp()]\] <font color='green'>Won with greentext!!!</font>"
color_altered_mobs -= new_holder
burn_state = ON_FIRE
qdel(src)
if(last_holder && last_holder != new_holder) //Somehow it was swiped without ever getting dropped
last_holder << "<span class='warning'>A sudden wave of failure washes over you...</span>"
last_holder.color = "#FF0000"
last_holder = new_holder //long live the king
/obj/item/weapon/greentext/Destroy(force)
if((burn_state != ON_FIRE) && (!force))
return QDEL_HINT_LETMELIVE
. = ..()
poi_list.Remove(src)
for(var/mob/M in mob_list)
var/message = "<span class='warning'>A dark temptation has passed from this world"
if(M in color_altered_mobs)
message += " and you're finally able to forgive yourself"
M.color = initial(M.color)
message += "...</span>"
// can't skip the mob check as it also does the decolouring
if(!quiet)
M << message
/obj/item/weapon/greentext/quiet
quiet = TRUE
+58
View File
@@ -0,0 +1,58 @@
/datum/round_event_control/wizard/imposter //Mirror Mania
name = "Imposter Wizard"
weight = 1
typepath = /datum/round_event/wizard/imposter/
max_occurrences = 1
earliest_start = 0
/datum/round_event/wizard/imposter/start()
for(var/datum/mind/M in ticker.mode.wizards)
if(!ishuman(M.current))
continue
var/mob/living/carbon/human/W = M.current
var/list/candidates = get_candidates(ROLE_WIZARD)
if(!candidates)
return //Sad Trombone
var/client/C = pick(candidates)
PoolOrNew(/obj/effect/particle_effect/smoke, W.loc)
var/mob/living/carbon/human/I = new /mob/living/carbon/human(W.loc)
W.dna.transfer_identity(I, transfer_SE=1)
I.real_name = I.dna.real_name
I.name = I.dna.real_name
I.updateappearance(mutcolor_update=1)
I.domutcheck()
if(W.ears)
I.equip_to_slot_or_del(new W.ears.type, slot_ears)
if(W.w_uniform)
I.equip_to_slot_or_del(new W.w_uniform.type , slot_w_uniform)
if(W.shoes)
I.equip_to_slot_or_del(new W.shoes.type, slot_shoes)
if(W.wear_suit)
I.equip_to_slot_or_del(new W.wear_suit.type, slot_wear_suit)
if(W.head)
I.equip_to_slot_or_del(new W.head.type, slot_head)
if(W.back)
I.equip_to_slot_or_del(new W.back.type, slot_back)
I.key = C.key
//Operation: Fuck off and scare people
I.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null))
I.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(null))
I.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
ticker.mode.apprentices += I.mind
I.mind.special_role = "imposter"
var/datum/objective/protect/protect_objective = new /datum/objective/protect
protect_objective.owner = I.mind
protect_objective.target = W.mind
protect_objective.explanation_text = "Protect [W.real_name], the wizard."
I.mind.objectives += protect_objective
ticker.mode.update_wiz_icons_added(I.mind)
I.attack_log += "\[[time_stamp()]\] <font color='red'>Is an imposter!</font>"
I << "<B>You are an imposter! Trick and confuse the crew to misdirect malice from your handsome original!</B>"
I << sound('sound/effects/magic.ogg')
+12
View File
@@ -0,0 +1,12 @@
/datum/round_event_control/wizard/invincible //Boolet Proof
name = "Invincibility"
weight = 3
typepath = /datum/round_event/wizard/invincible/
max_occurrences = 5
earliest_start = 0
/datum/round_event/wizard/invincible/start()
for(var/mob/living/carbon/human/H in living_mob_list)
H.reagents.add_reagent("adminordrazine", 40) //100 ticks of absolute invinciblity (barring gibs)
H << "<span class='notice'>You feel invincible, nothing can hurt you!</span>"
+16
View File
@@ -0,0 +1,16 @@
/datum/round_event_control/wizard/lava //THE LEGEND NEVER DIES
name = "The Floor Is LAVA!"
weight = 2
typepath = /datum/round_event/wizard/lava/
max_occurrences = 3
earliest_start = 0
/datum/round_event/wizard/lava/
endWhen = 0
var/started = FALSE
/datum/round_event/wizard/lava/start()
if(!started)
started = TRUE
var/datum/weather/floor_is_lava/LAVA = new /datum/weather/floor_is_lava
LAVA.weather_start_up()
+54
View File
@@ -0,0 +1,54 @@
/datum/round_event_control/wizard/magicarp //these fish is loaded
name = "Magicarp"
weight = 1
typepath = /datum/round_event/wizard/magicarp/
max_occurrences = 1
earliest_start = 0
/datum/round_event/wizard/magicarp/
announceWhen = 3
startWhen = 50
/datum/round_event/wizard/magicarp/setup()
startWhen = rand(40, 60)
/datum/round_event/wizard/magicarp/announce()
priority_announce("Unknown magical entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
/datum/round_event/wizard/magicarp/start()
for(var/obj/effect/landmark/C in landmarks_list)
if(C.name == "carpspawn")
if(prob(5))
new /mob/living/simple_animal/hostile/carp/ranged/chaos(C.loc)
else
new /mob/living/simple_animal/hostile/carp/ranged(C.loc)
/mob/living/simple_animal/hostile/carp/ranged
name = "magicarp"
desc = "50% magic, 50% carp, 100% horrible."
icon_state = "magicarp"
icon_living = "magicarp"
icon_dead = "magicarp_dead"
icon_gib = "magicarp_gib"
ranged = 1
retreat_distance = 2
minimum_distance = 0 //Between shots they can and will close in to nash
projectiletype = /obj/item/projectile/magic
projectilesound = 'sound/weapons/emitter.ogg'
maxHealth = 50
health = 50
/mob/living/simple_animal/hostile/carp/ranged/New()
projectiletype = pick(typesof(initial(projectiletype)))
..()
/mob/living/simple_animal/hostile/carp/ranged/chaos
name = "chaos magicarp"
desc = "50% carp, 100% magic, 150% horrible."
color = "#00FFFF"
maxHealth = 75
health = 75
/mob/living/simple_animal/hostile/carp/ranged/chaos/Shoot()
projectiletype = pick(typesof(initial(projectiletype)))
..()
+17
View File
@@ -0,0 +1,17 @@
/datum/round_event_control/wizard/petsplosion //the horror
name = "Petsplosion"
weight = 2
typepath = /datum/round_event/wizard/petsplosion/
max_occurrences = 1 //Exponential growth is nothing to sneeze at!
earliest_start = 0
/datum/round_event/wizard/petsplosion/
endWhen = 61 //1 minute (+1 tick for endWhen not to interfere with tick)
var/countdown = 0
/datum/round_event/wizard/petsplosion/tick()
if(activeFor >= 30 * countdown) // 0 seconds : 2 animals | 30 seconds : 4 animals | 1 minute : 8 animals
countdown += 1
for(var/mob/living/simple_animal/F in living_mob_list) //If you cull the heard before the next replication, things will be easier for you
if(!istype(F, /mob/living/simple_animal/hostile))
new F.type(F.loc)
+29
View File
@@ -0,0 +1,29 @@
/datum/round_event_control/wizard/race //Lizard Wizard? Lizard Wizard.
name = "Race Swap"
weight = 2
typepath = /datum/round_event/wizard/race/
max_occurrences = 5
earliest_start = 0
/datum/round_event/wizard/race/start()
var/all_the_same = 0
var/all_species = list()
for(var/speciestype in subtypesof(/datum/species))
var/datum/species/S = new speciestype()
if(!S.dangerous_existence)
all_species += speciestype
var/datum/species/new_species = pick(all_species)
if(prob(50))
all_the_same = 1
for(var/mob/living/carbon/human/H in mob_list) //yes, even the dead
H.set_species(new_species)
H.real_name = new_species.random_name(H.gender,1)
H.dna.unique_enzymes = H.dna.generate_unique_enzymes()
H << "<span class='notice'>You feel somehow... different?</span>"
if(!all_the_same)
new_species = pick(all_species)
+62
View File
@@ -0,0 +1,62 @@
/datum/round_event_control/wizard/rpgloot //its time to minmax your shit
name = "RPG Loot"
weight = 3
typepath = /datum/round_event/wizard/rpgloot/
max_occurrences = 1
earliest_start = 0
/datum/round_event/wizard/rpgloot/start()
var/list/prefixespositive = list("greater", "major", "blessed", "superior", "enpowered", "honed", "true", "glorious", "robust")
var/list/prefixesnegative = list("lesser", "minor", "blighted", "inferior", "enfeebled", "rusted", "unsteady", "tragic", "gimped")
var/list/suffixes = list("orc slaying", "elf slaying", "corgi slaying", "strength", "dexterity", "constitution", "intelligence", "wisdom", "charisma", "the forest", "the hills", "the plains", "the sea", "the sun", "the moon", "the void", "the world", "the fool", "many secrets", "many tales", "many colors", "rending", "sundering", "the night", "the day")
var/upgrade_scroll_chance = 0
for(var/obj/item/I in world)
if(istype(I,/obj/item/organ/))
continue
var/quality = pick(1;15, 2;14, 2;13, 2;12, 3;11, 3;10, 3;9, 4;8, 4;7, 4;6, 5;5, 5;4, 5;3, 6;2, 6;1, 6;0)
if(prob(50))
quality = -quality
if(quality > 0)
I.name = "[pick(prefixespositive)] [I.name] of [pick(suffixes)] +[quality]"
else if(quality < 0)
I.name = "[pick(prefixesnegative)] [I.name] of [pick(suffixes)] [quality]"
else
I.name = "[I.name] of [pick(suffixes)]"
I.force = max(0,I.force + quality)
I.throwforce = max(0,I.throwforce + quality)
for(var/value in I.armor)
I.armor[value] += quality
if(istype(I,/obj/item/weapon/storage))
var/obj/item/weapon/storage/S = I
if(prob(upgrade_scroll_chance) && S.contents.len < S.storage_slots)
var/obj/item/upgradescroll/scroll = new
S.handle_item_insertion(scroll,1)
upgrade_scroll_chance = max(0,upgrade_scroll_chance-100)
upgrade_scroll_chance += 25
/obj/item/upgradescroll
name = "Item Fortification Scroll"
desc = "Somehow, this piece of paper can be applied to items to make them \"better\". Apparently there's a risk of losing the item if it's already \"too good\". <i>This all feels so arbitrary...</i>"
icon = 'icons/obj/wizard.dmi'
icon_state = "scroll"
w_class = 1
/obj/item/upgradescroll/afterattack(obj/item/target, mob/user , proximity)
if(!proximity || !istype(target))
return
var/quality = target.force - initial(target.force)
if(quality > 9 && prob((quality - 9)*10))
user << "<span class='danger'>[target] catches fire!</span>"
if(target.burn_state == -1)
target.burn_state = 0
target.fire_act()
qdel(src)
return
target.force += 1
target.throwforce += 1
for(var/value in target.armor)
target.armor[value] += 1
user << "<span class='notice'>[target] glows blue and seems vaguely \"better\"!</span>"
qdel(src)
+104
View File
@@ -0,0 +1,104 @@
/datum/round_event/wizard/shuffle/start()
/datum/round_event_control/wizard/shuffleloc //Somewhere an AI is crying
name = "Change Places!"
weight = 2
typepath = /datum/round_event/wizard/shuffleloc/
max_occurrences = 5
earliest_start = 0
/datum/round_event/wizard/shuffleloc/start()
var/list/moblocs = list()
var/list/mobs = list()
for(var/mob/living/carbon/human/H in living_mob_list)
if(H.z != 1)
continue //lets not try to strand people in space or stuck in the wizards den
moblocs += H.loc
mobs += H
if(!mobs)
return
shuffle(moblocs)
shuffle(mobs)
for(var/mob/living/carbon/human/H in mobs)
if(!moblocs)
break //locs aren't always unique, so this may come into play
do_teleport(H, moblocs[moblocs.len])
moblocs.len -= 1
for(var/mob/living/carbon/human/H in living_mob_list)
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(0, H.loc)
smoke.start()
//---//
/datum/round_event_control/wizard/shufflenames //Face/off joke
name = "Change Faces!"
weight = 4
typepath = /datum/round_event/wizard/shufflenames/
max_occurrences = 5
earliest_start = 0
/datum/round_event/wizard/shufflenames/start()
var/list/mobnames = list()
var/list/mobs = list()
for(var/mob/living/carbon/human/H in living_mob_list)
mobnames += H.real_name
mobs += H
if(!mobs)
return
shuffle(mobnames)
shuffle(mobs)
for(var/mob/living/carbon/human/H in mobs)
if(!mobnames)
break
H.real_name = mobnames[mobnames.len]
mobnames.len -= 1
for(var/mob/living/carbon/human/H in living_mob_list)
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(0, H.loc)
smoke.start()
//---//
/datum/round_event_control/wizard/shuffleminds //Basically Mass Ranged Mindswap
name = "Change Minds!"
weight = 1
typepath = /datum/round_event/wizard/shuffleminds/
max_occurrences = 3
earliest_start = 0
/datum/round_event/wizard/shuffleminds/start()
var/list/mobs = list()
for(var/mob/living/carbon/human/H in living_mob_list)
if(!H.stat || !H.mind || (H.mind in ticker.mode.wizards) || (H.mind in ticker.mode.apprentices))
continue //the wizard(s) are spared on this one
mobs += H
if(!mobs)
return
shuffle(mobs)
var/obj/effect/proc_holder/spell/targeted/mind_transfer/swapper = new /obj/effect/proc_holder/spell/targeted/mind_transfer/
while(mobs.len > 1)
var/mob/living/carbon/human/H = pick(mobs)
mobs -= H
swapper.cast(list(H), mobs[mobs.len], 1)
mobs -= mobs[mobs.len]
for(var/mob/living/carbon/human/H in living_mob_list)
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(0, H.loc)
smoke.start()
+29
View File
@@ -0,0 +1,29 @@
/datum/round_event_control/wizard/summonguns //The Classic
name = "Summon Guns"
weight = 1
typepath = /datum/round_event/wizard/summonguns/
max_occurrences = 1
earliest_start = 0
/datum/round_event_control/wizard/summonguns/New()
if(config.no_summon_guns)
weight = 0
..()
/datum/round_event/wizard/summonguns/start()
rightandwrong(0,,10)
/datum/round_event_control/wizard/summonmagic //The Somewhat Less Classic
name = "Summon Magic"
weight = 1
typepath = /datum/round_event/wizard/summonmagic/
max_occurrences = 1
earliest_start = 0
/datum/round_event_control/wizard/summonmagic/New()
if(config.no_summon_magic)
weight = 0
..()
/datum/round_event/wizard/summonmagic/start()
rightandwrong(1,,10)
+74
View File
@@ -0,0 +1,74 @@
/datum/round_event_control/wormholes
name = "Wormholes"
typepath = /datum/round_event/wormholes
max_occurrences = 3
weight = 2
min_players = 2
/datum/round_event/wormholes
announceWhen = 10
endWhen = 60
var/list/pick_turfs = list()
var/list/wormholes = list()
var/shift_frequency = 3
var/number_of_wormholes = 400
/datum/round_event/wormholes/setup()
announceWhen = rand(0, 20)
endWhen = rand(40, 80)
/datum/round_event/wormholes/start()
for(var/turf/open/floor/T in world)
if(T.z == ZLEVEL_STATION)
pick_turfs += T
for(var/i = 1, i <= number_of_wormholes, i++)
var/turf/T = pick(pick_turfs)
wormholes += new /obj/effect/portal/wormhole(T, null, null, -1)
/datum/round_event/wormholes/announce()
priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", 'sound/AI/spanomalies.ogg')
/datum/round_event/wormholes/tick()
if(activeFor % shift_frequency == 0)
for(var/obj/effect/portal/wormhole/O in wormholes)
var/turf/T = pick(pick_turfs)
if(T)
O.loc = T
/datum/round_event/wormholes/end()
portals.Remove(wormholes)
for(var/obj/effect/portal/wormhole/O in wormholes)
O.loc = null
wormholes.Cut()
/obj/effect/portal/wormhole
name = "wormhole"
desc = "It looks highly unstable; It could close at any moment."
icon = 'icons/obj/objects.dmi'
icon_state = "anom"
/obj/effect/portal/wormhole/attack_hand(mob/user)
teleport(user)
/obj/effect/portal/wormhole/attackby(obj/item/I, mob/user, params)
teleport(user)
/obj/effect/portal/wormhole/teleport(atom/movable/M)
if(istype(M, /obj/effect)) //sparks don't teleport
return
if(M.anchored && istype(M, /obj/mecha))
return
if(istype(M, /atom/movable))
var/turf/target
if(portals.len)
var/obj/effect/portal/P = pick(portals)
if(P && isturf(P.loc))
target = P.loc
if(!target)
return
do_teleport(M, target, 1, 1, 0, 0) ///You will appear adjacent to the beacon