@@ -17,9 +17,9 @@
|
||||
|
||||
var/holidayID = "" //string which should be in the SSeventss.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
|
||||
var/wizardevent = FALSE
|
||||
var/random = FALSE //If the event has occured randomly, or if it was forced by an admin or in-game occurance
|
||||
var/alert_observers = TRUE //should we let the ghosts and 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
|
||||
@@ -33,7 +33,7 @@
|
||||
min_players = CEILING(min_players * CONFIG_GET(number/events_min_players_mul), 1)
|
||||
|
||||
/datum/round_event_control/wizard
|
||||
wizardevent = 1
|
||||
wizardevent = TRUE
|
||||
var/can_be_midround_wizard = TRUE
|
||||
|
||||
// Checks if the event can be spawned. Used by event controller and "false alarm" event.
|
||||
@@ -67,7 +67,7 @@
|
||||
return EVENT_CANT_RUN
|
||||
|
||||
triggering = TRUE
|
||||
if (alertadmins)
|
||||
if (alert_observers)
|
||||
message_admins("Random Event triggering in 10 seconds: [name] (<a href='?src=[REF(src)];cancel=1'>CANCEL</a>)")
|
||||
sleep(100)
|
||||
var/gamemode = SSticker.mode.config_tag
|
||||
@@ -92,7 +92,7 @@
|
||||
log_admin_private("[key_name(usr)] cancelled event [name].")
|
||||
SSblackbox.record_feedback("tally", "event_admin_cancelled", 1, typepath)
|
||||
|
||||
/datum/round_event_control/proc/runEvent(random)
|
||||
/datum/round_event_control/proc/runEvent()
|
||||
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
|
||||
@@ -101,10 +101,9 @@
|
||||
|
||||
testing("[time2text(world.time, "hh:mm:ss")] [E.type]")
|
||||
if(random)
|
||||
if(alertadmins)
|
||||
deadchat_broadcast("<span class='deadsay'><b>[name]</b> has just been randomly triggered!</span>") //STOP ASSUMING IT'S BADMINS!
|
||||
log_game("Random Event triggering: [name] ([typepath])")
|
||||
|
||||
if (alert_observers)
|
||||
deadchat_broadcast("<span class='deadsay'><b>[name]</b> has just been[random ? " randomly" : ""] triggered!</span>") //STOP ASSUMING IT'S BADMINS!
|
||||
return E
|
||||
|
||||
//Special admins setup
|
||||
@@ -140,6 +139,17 @@
|
||||
/datum/round_event/proc/start()
|
||||
return
|
||||
|
||||
/**
|
||||
* Called after something followable has been spawned by an event
|
||||
* Provides ghosts a follow link to an atom if possible
|
||||
* Only called once.
|
||||
*/
|
||||
/datum/round_event/proc/announce_to_ghosts(atom/atom_of_interest)
|
||||
if(control.alert_observers)
|
||||
if (atom_of_interest)
|
||||
notify_ghosts("[control.name] has an object of interest: [atom_of_interest]!", source=atom_of_interest, action=NOTIFY_ORBIT, header="Something's Interesting!")
|
||||
return
|
||||
|
||||
//Called when the tick is equal to the announceWhen variable.
|
||||
//Allows you to announce before starting or vice versa.
|
||||
//Only called once.
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
/datum/round_event/anomaly
|
||||
var/area/impact_area
|
||||
var/obj/effect/anomaly/newAnomaly
|
||||
var/obj/effect/anomaly/anomaly_path = /obj/effect/anomaly/flux
|
||||
announceWhen = 1
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
//Subtypes from the above that actually should explode.
|
||||
var/list/unsafe_area_subtypes = typecacheof(list(/area/engine/break_room))
|
||||
|
||||
|
||||
allowed_areas = make_associative(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
|
||||
|
||||
return safepick(typecache_filter_list(GLOB.sortedAreas,allowed_areas))
|
||||
@@ -44,6 +44,9 @@
|
||||
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))
|
||||
var/turf/T = pick(get_area_turfs(impact_area))
|
||||
var/newAnomaly
|
||||
if(T)
|
||||
newAnomaly = new /obj/effect/anomaly/flux(T)
|
||||
newAnomaly = new anomaly_path(T)
|
||||
if (newAnomaly)
|
||||
announce_to_ghosts(newAnomaly)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/round_event_control/anomaly/anomaly_bluespace
|
||||
name = "Anomaly: Bluespace"
|
||||
typepath = /datum/round_event/anomaly/anomaly_bluespace
|
||||
|
||||
max_occurrences = 1
|
||||
weight = 5
|
||||
gamemode_blacklist = list("dynamic")
|
||||
@@ -8,15 +9,10 @@
|
||||
/datum/round_event/anomaly/anomaly_bluespace
|
||||
startWhen = 3
|
||||
announceWhen = 10
|
||||
|
||||
anomaly_path = /obj/effect/anomaly/bluespace
|
||||
|
||||
/datum/round_event/anomaly/anomaly_bluespace/announce(fake)
|
||||
if(prob(90))
|
||||
priority_announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
else
|
||||
print_command_report("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Unstable bluespace anomaly")
|
||||
|
||||
/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)
|
||||
|
||||
@@ -10,14 +10,10 @@
|
||||
/datum/round_event/anomaly/anomaly_flux
|
||||
startWhen = 10
|
||||
announceWhen = 3
|
||||
anomaly_path = /obj/effect/anomaly/flux
|
||||
|
||||
/datum/round_event/anomaly/anomaly_flux/announce(fake)
|
||||
if(prob(90))
|
||||
priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
else
|
||||
print_command_report("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].","Localized hyper-energetic flux wave")
|
||||
|
||||
/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)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/round_event_control/anomaly/anomaly_grav
|
||||
name = "Anomaly: Gravitational"
|
||||
typepath = /datum/round_event/anomaly/anomaly_grav
|
||||
|
||||
max_occurrences = 5
|
||||
weight = 20
|
||||
gamemode_blacklist = list("dynamic")
|
||||
@@ -9,14 +10,10 @@
|
||||
/datum/round_event/anomaly/anomaly_grav
|
||||
startWhen = 3
|
||||
announceWhen = 20
|
||||
anomaly_path = /obj/effect/anomaly/grav
|
||||
|
||||
/datum/round_event/anomaly/anomaly_grav/announce(fake)
|
||||
if(prob(90))
|
||||
priority_announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
else
|
||||
print_command_report("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Gravitational anomaly")
|
||||
|
||||
/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)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/round_event_control/anomaly/anomaly_pyro
|
||||
name = "Anomaly: Pyroclastic"
|
||||
typepath = /datum/round_event/anomaly/anomaly_pyro
|
||||
|
||||
max_occurrences = 5
|
||||
weight = 20
|
||||
gamemode_blacklist = list("dynamic")
|
||||
@@ -8,14 +9,10 @@
|
||||
/datum/round_event/anomaly/anomaly_pyro
|
||||
startWhen = 3
|
||||
announceWhen = 10
|
||||
anomaly_path = /obj/effect/anomaly/pyro
|
||||
|
||||
/datum/round_event/anomaly/anomaly_pyro/announce(fake)
|
||||
if(prob(90))
|
||||
priority_announce("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
|
||||
else
|
||||
print_command_report("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Pyroclastic anomaly")
|
||||
|
||||
/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)
|
||||
|
||||
@@ -10,14 +10,10 @@
|
||||
/datum/round_event/anomaly/anomaly_vortex
|
||||
startWhen = 10
|
||||
announceWhen = 3
|
||||
anomaly_path = /obj/effect/anomaly/bhole
|
||||
|
||||
/datum/round_event/anomaly/anomaly_vortex/announce(fake)
|
||||
if(prob(90))
|
||||
priority_announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert")
|
||||
else
|
||||
print_command_report("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name].","Vortex anomaly")
|
||||
|
||||
/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)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/datum/round_event_control/brain_trauma
|
||||
name = "Spontaneous Brain Trauma"
|
||||
typepath = /datum/round_event/brain_trauma
|
||||
weight = 25
|
||||
|
||||
/datum/round_event/brain_trauma
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/brain_trauma/start()
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
|
||||
if(!H.client)
|
||||
continue
|
||||
if(H.stat == DEAD) // What are you doing in this list
|
||||
continue
|
||||
if(!H.getorgan(/obj/item/organ/brain)) // If only I had a brain
|
||||
continue
|
||||
|
||||
traumatize(H)
|
||||
break
|
||||
|
||||
/datum/round_event/brain_trauma/proc/traumatize(mob/living/carbon/human/H)
|
||||
var/resistance = pick(
|
||||
65;TRAUMA_RESILIENCE_BASIC,
|
||||
30;TRAUMA_RESILIENCE_SURGERY,
|
||||
5;TRAUMA_RESILIENCE_LOBOTOMY)
|
||||
|
||||
var/trauma_type = pickweight(list(
|
||||
BRAIN_TRAUMA_MILD = 60,
|
||||
BRAIN_TRAUMA_SEVERE = 30,
|
||||
BRAIN_TRAUMA_SPECIAL = 10
|
||||
))
|
||||
|
||||
H.gain_trauma_type(trauma_type, resistance)
|
||||
@@ -54,6 +54,7 @@
|
||||
vendingMachines.Remove(originMachine)
|
||||
originMachine.shut_up = 0
|
||||
originMachine.shoot_inventory = 1
|
||||
announce_to_ghosts(originMachine)
|
||||
|
||||
|
||||
/datum/round_event/brand_intelligence/tick()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
typepath = /datum/round_event/camera_failure
|
||||
weight = 100
|
||||
max_occurrences = 20
|
||||
alertadmins = 0
|
||||
alert_observers = FALSE
|
||||
|
||||
/datum/round_event/camera_failure
|
||||
fakeable = FALSE
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
/datum/round_event/carp_migration
|
||||
announceWhen = 3
|
||||
startWhen = 50
|
||||
var/hasAnnounced = FALSE
|
||||
|
||||
/datum/round_event/carp_migration/setup()
|
||||
startWhen = rand(40, 60)
|
||||
@@ -22,10 +23,16 @@
|
||||
|
||||
|
||||
/datum/round_event/carp_migration/start()
|
||||
var/mob/living/simple_animal/hostile/carp/fish
|
||||
for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list)
|
||||
if(prob(95))
|
||||
new /mob/living/simple_animal/hostile/carp(C.loc)
|
||||
fish = new (C.loc)
|
||||
else
|
||||
new /mob/living/simple_animal/hostile/carp/megacarp(C.loc)
|
||||
|
||||
fish = new /mob/living/simple_animal/hostile/carp/megacarp(C.loc)
|
||||
fishannounce(fish) //Prefer to announce the megacarps over the regular fishies
|
||||
fishannounce(fish)
|
||||
|
||||
/datum/round_event/carp_migration/proc/fishannounce(atom/fish)
|
||||
if (!hasAnnounced)
|
||||
announce_to_ghosts(fish) //Only anounce the first fish
|
||||
hasAnnounced = TRUE
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
weight = 200
|
||||
max_occurrences = 1000
|
||||
earliest_start = 0 MINUTES
|
||||
alertadmins = 0
|
||||
alert_observers = FALSE
|
||||
gamemode_blacklist = list("dynamic")
|
||||
|
||||
/datum/round_event/space_dust
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
earliest_start = 10 MINUTES
|
||||
min_players = 5
|
||||
weight = 40
|
||||
alertadmins = 0
|
||||
alert_observers = FALSE
|
||||
gamemode_blacklist = list("dynamic")
|
||||
|
||||
/datum/round_event/electrical_storm
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/datum/round_event_control/fake_virus
|
||||
name = "Fake Virus"
|
||||
typepath = /datum/round_event/fake_virus
|
||||
weight = 20
|
||||
|
||||
/datum/round_event/fake_virus/start()
|
||||
var/list/fake_virus_victims = list()
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.player_list))
|
||||
if(!H.client || H.stat == DEAD || H.InCritical())
|
||||
continue
|
||||
fake_virus_victims += H
|
||||
|
||||
//first we do hard status effect victims
|
||||
var/defacto_min = min(3, LAZYLEN(fake_virus_victims))
|
||||
if(defacto_min)// event will hit 1-3 people by default, but will do 1-2 or just 1 if only those many candidates are available
|
||||
for(var/i=1; i<=rand(1,defacto_min); i++)
|
||||
var/mob/living/carbon/human/hypochondriac = pick(fake_virus_victims)
|
||||
hypochondriac.apply_status_effect(STATUS_EFFECT_FAKE_VIRUS)
|
||||
fake_virus_victims -= hypochondriac
|
||||
|
||||
//then we do light one-message victims who simply cough or whatever once (have to repeat the process since the last operation modified our candidates list)
|
||||
defacto_min = min(5, LAZYLEN(fake_virus_victims))
|
||||
if(defacto_min)
|
||||
for(var/i=1; i<=rand(1,defacto_min); i++)
|
||||
var/mob/living/carbon/human/onecoughman = pick(fake_virus_victims)
|
||||
if(prob(25))//1/4 odds to get a spooky message instead of coughing out loud
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, onecoughman, "<span class='warning'>[pick("Your head hurts.", "Your head pounds.")]</span>"), rand(30,150))
|
||||
else
|
||||
addtimer(CALLBACK(onecoughman, .mob/proc/emote, pick("cough", "sniff", "sneeze")), rand(30,150))//deliver the message with a slightly randomized time interval so there arent multiple people coughing at the exact same time
|
||||
fake_virus_victims -= onecoughman
|
||||
@@ -0,0 +1,117 @@
|
||||
/datum/round_event_control/fugitives
|
||||
name = "Spawn Fugitives"
|
||||
typepath = /datum/round_event/ghost_role/fugitives
|
||||
max_occurrences = 1
|
||||
min_players = 20
|
||||
earliest_start = 30 MINUTES //deadchat sink, lets not even consider it early on.
|
||||
gamemode_blacklist = list("nuclear")
|
||||
|
||||
/datum/round_event/ghost_role/fugitives
|
||||
minimum_required = 1
|
||||
role_name = "fugitive"
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/ghost_role/fugitives/spawn_role()
|
||||
var/list/possible_spawns = list()//Some xeno spawns are in some spots that will instantly kill the refugees, like atmos
|
||||
for(var/turf/X in GLOB.xeno_spawn)
|
||||
if(istype(X.loc, /area/maintenance))
|
||||
possible_spawns += X
|
||||
if(!possible_spawns.len)
|
||||
message_admins("No valid spawn locations found, aborting...")
|
||||
return MAP_ERROR
|
||||
var/turf/landing_turf = pick(possible_spawns)
|
||||
var/list/possible_backstories = list()
|
||||
var/list/candidates = get_candidates(ROLE_TRAITOR, null, ROLE_TRAITOR)
|
||||
if(candidates.len >= 1) //solo refugees
|
||||
if(prob(30))
|
||||
possible_backstories.Add("waldo") //less common as it comes with magicks and is kind of immershun shattering
|
||||
else //For accurate deadchat feedback
|
||||
minimum_required = 4
|
||||
if(candidates.len >= 4)//group refugees
|
||||
possible_backstories.Add("prisoner", "cultist", "synth")
|
||||
if(!possible_backstories.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
var/backstory = pick(possible_backstories)
|
||||
var/member_size = 3
|
||||
var/leader
|
||||
switch(backstory)
|
||||
if("synth")
|
||||
leader = pick_n_take(candidates)
|
||||
if("waldo")
|
||||
member_size = 0 //solo refugees have no leader so the member_size gets bumped to one a bit later
|
||||
var/list/members = list()
|
||||
var/list/spawned_mobs = list()
|
||||
if(isnull(leader))
|
||||
member_size++ //if there is no leader role, then the would be leader is a normal member of the team.
|
||||
|
||||
for(var/i in 1 to member_size)
|
||||
members += pick_n_take(candidates)
|
||||
|
||||
for(var/mob/dead/selected in members)
|
||||
var/mob/living/carbon/human/S = gear_fugitive(selected, landing_turf, backstory)
|
||||
spawned_mobs += S
|
||||
if(!isnull(leader))
|
||||
gear_fugitive_leader(leader, landing_turf, backstory)
|
||||
|
||||
//after spawning
|
||||
playsound(src, 'sound/weapons/emitter.ogg', 50, TRUE)
|
||||
new /obj/item/storage/toolbox/mechanical(landing_turf) //so they can actually escape maint
|
||||
addtimer(CALLBACK(src, .proc/spawn_hunters), 10 MINUTES)
|
||||
role_name = "fugitive hunter"
|
||||
return SUCCESSFUL_SPAWN
|
||||
|
||||
/datum/round_event/ghost_role/fugitives/proc/gear_fugitive(mob/dead/selected, turf/landing_turf, backstory) //spawns normal fugitive
|
||||
var/datum/mind/player_mind = new /datum/mind(selected.key)
|
||||
player_mind.active = TRUE
|
||||
var/mob/living/carbon/human/S = new(landing_turf)
|
||||
player_mind.transfer_to(S)
|
||||
player_mind.assigned_role = "Fugitive"
|
||||
player_mind.special_role = "Fugitive"
|
||||
player_mind.add_antag_datum(/datum/antagonist/fugitive)
|
||||
var/datum/antagonist/fugitive/fugitiveantag = player_mind.has_antag_datum(/datum/antagonist/fugitive)
|
||||
INVOKE_ASYNC(fugitiveantag, /datum/antagonist/fugitive.proc/greet, backstory) //some fugitives have a sleep on their greet, so we don't want to stop the entire antag granting proc with fluff
|
||||
|
||||
switch(backstory)
|
||||
if("prisoner")
|
||||
S.equipOutfit(/datum/outfit/prisoner)
|
||||
if("cultist")
|
||||
S.equipOutfit(/datum/outfit/yalp_cultist)
|
||||
if("waldo")
|
||||
S.equipOutfit(/datum/outfit/waldo)
|
||||
if("synth")
|
||||
S.equipOutfit(/datum/outfit/synthetic)
|
||||
message_admins("[ADMIN_LOOKUPFLW(S)] has been made into a Fugitive by an event.")
|
||||
log_game("[key_name(S)] was spawned as a Fugitive by an event.")
|
||||
spawned_mobs += S
|
||||
return S
|
||||
|
||||
//special spawn for one member. it can be used for a special mob or simply to give one normal member special items.
|
||||
/datum/round_event/ghost_role/fugitives/proc/gear_fugitive_leader(mob/dead/leader, turf/landing_turf, backstory)
|
||||
var/datum/mind/player_mind = new /datum/mind(leader.key)
|
||||
player_mind.active = TRUE
|
||||
//if you want to add a fugitive with a special leader in the future, make this switch with the backstory
|
||||
var/mob/living/carbon/human/S = gear_fugitive(leader, landing_turf, backstory)
|
||||
var/obj/item/choice_beacon/augments/A = new(S)
|
||||
S.put_in_hands(A)
|
||||
new /obj/item/autosurgeon(landing_turf)
|
||||
|
||||
//security team gets called in after 10 minutes of prep to find the refugees
|
||||
/datum/round_event/ghost_role/fugitives/proc/spawn_hunters()
|
||||
var/backstory = pick("space cop", "russian", "bounty hunter")
|
||||
var/datum/map_template/shuttle/ship
|
||||
if(backstory == "space cop")
|
||||
ship = new /datum/map_template/shuttle/hunter/space_cop
|
||||
else if (backstory == "russian")
|
||||
ship = new /datum/map_template/shuttle/hunter/russian
|
||||
else
|
||||
ship = new /datum/map_template/shuttle/hunter/bounty
|
||||
var/x = rand(TRANSITIONEDGE,world.maxx - TRANSITIONEDGE - ship.width)
|
||||
var/y = rand(TRANSITIONEDGE,world.maxy - TRANSITIONEDGE - ship.height)
|
||||
var/z = SSmapping.empty_space.z_value
|
||||
var/turf/T = locate(x,y,z)
|
||||
if(!T)
|
||||
CRASH("Fugitive Hunters (Created from fugitive event) found no turf to load in")
|
||||
if(!ship.load(T))
|
||||
CRASH("Loading [backstory] ship failed!")
|
||||
priority_announce("Unidentified ship detected near the station.")
|
||||
@@ -37,7 +37,10 @@
|
||||
signing up.")
|
||||
else if(status == SUCCESSFUL_SPAWN)
|
||||
message_admins("[role_name] spawned successfully.")
|
||||
if(!spawned_mobs.len)
|
||||
if(spawned_mobs.len)
|
||||
for(var/mob/M in spawned_mobs)
|
||||
announce_to_ghosts(M)
|
||||
else
|
||||
message_admins("No mobs found in the `spawned_mobs` list, this is \
|
||||
a bug.")
|
||||
else
|
||||
|
||||
@@ -20,4 +20,4 @@
|
||||
var/mob/living/carbon/human/winner = pickweight(heart_attack_contestants)
|
||||
var/datum/disease/D = new /datum/disease/heart_failure()
|
||||
winner.ForceContractDisease(D, FALSE, TRUE)
|
||||
notify_ghosts("[winner] is beginning to have a heart attack!", enter_link="<a href=?src=[REF(src)];orbit=1>(Click to orbit)</a>", source=winner, action=NOTIFY_ORBIT)
|
||||
announce_to_ghosts(winner)
|
||||
@@ -35,7 +35,8 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
var/z = pick(SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
var/turf/startT = spaceDebrisStartLoc(startside, z)
|
||||
var/turf/endT = spaceDebrisFinishLoc(startside, z)
|
||||
new /obj/effect/immovablerod(startT, endT, C.special_target)
|
||||
var/atom/rod = new /obj/effect/immovablerod(startT, endT, C.special_target)
|
||||
announce_to_ghosts(rod)
|
||||
|
||||
/obj/effect/immovablerod
|
||||
name = "immovable rod"
|
||||
@@ -61,10 +62,6 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
z_original = z
|
||||
destination = end
|
||||
special_target = aimed_at
|
||||
if(notify)
|
||||
notify_ghosts("\A [src] is inbound!",
|
||||
enter_link="<a href=?src=[REF(src)];orbit=1>(Click to orbit)</a>",
|
||||
source=src, action=NOTIFY_ORBIT)
|
||||
GLOB.poi_list += src
|
||||
|
||||
var/special_target_valid = FALSE
|
||||
|
||||
@@ -80,8 +80,9 @@
|
||||
var/mob/M = candidates[1]
|
||||
spawner.create(M.ckey)
|
||||
candidates -= M
|
||||
announce_to_ghosts(M)
|
||||
else
|
||||
notify_ghosts("Space pirates are waking up!", source = spawner, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE)
|
||||
announce_to_ghosts(spawner)
|
||||
|
||||
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") //CITADEL EDIT also metabreak here too
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
/datum/round_event/processor_overload/start()
|
||||
for(var/obj/machinery/telecomms/processor/P in GLOB.telecomms_list)
|
||||
if(prob(10))
|
||||
announce_to_ghosts(P)
|
||||
// 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
|
||||
|
||||
@@ -330,8 +330,8 @@
|
||||
if(!override)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/spacevine/attacked_by(obj/item/I, mob/living/user)
|
||||
var/damage_dealt = I.force
|
||||
/obj/structure/spacevine/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
var/damage_dealt = I.force * damage_multiplier
|
||||
if(I.get_sharpness())
|
||||
damage_dealt *= 4
|
||||
if(I.damtype == BURN)
|
||||
@@ -383,7 +383,9 @@
|
||||
/datum/spacevine_controller/New(turf/location, list/muts, potency, production, datum/round_event/event = null)
|
||||
vines = list()
|
||||
growth_queue = list()
|
||||
spawn_spacevine_piece(location, null, muts)
|
||||
var/obj/structure/spacevine/SV = spawn_spacevine_piece(location, null, muts)
|
||||
if (event)
|
||||
event.announce_to_ghosts(SV)
|
||||
START_PROCESSING(SSobj, src)
|
||||
vine_mutations_list = list()
|
||||
init_subtypes(/datum/spacevine_mutation/, vine_mutations_list)
|
||||
|
||||
@@ -35,6 +35,6 @@
|
||||
var/spawn_type = /obj/structure/spider/spiderling
|
||||
if(prob(66))
|
||||
spawn_type = /obj/structure/spider/spiderling/nurse
|
||||
spawn_atom_to_turf(spawn_type, vent, 1, FALSE)
|
||||
announce_to_ghosts(spawn_atom_to_turf(spawn_type, vent, 1, FALSE))
|
||||
vents -= vent
|
||||
spawncount--
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
///Spawns a cargo pod containing a random cargo supply pack on a random area of the station
|
||||
/datum/round_event_control/stray_cargo
|
||||
name = "Stray Cargo Pod"
|
||||
typepath = /datum/round_event/stray_cargo
|
||||
weight = 20
|
||||
max_occurrences = 4
|
||||
earliest_start = 10 MINUTES
|
||||
|
||||
///Spawns a cargo pod containing a random cargo supply pack on a random area of the station
|
||||
/datum/round_event/stray_cargo
|
||||
var/area/impact_area ///Randomly picked area
|
||||
var/list/possible_pack_types = list() ///List of possible supply packs dropped in the pod, if empty picks from the cargo list
|
||||
var/static/list/stray_spawnable_supply_packs = list() ///List of default spawnable supply packs, filtered from the cargo list
|
||||
|
||||
/datum/round_event/stray_cargo/announce(fake)
|
||||
priority_announce("Stray cargo pod detected on long-range scanners. Expected location of impact: [impact_area.name].", "Collision Alert")
|
||||
|
||||
/**
|
||||
* Tries to find a valid area, throws an error if none are found
|
||||
* Also randomizes the start timer
|
||||
*/
|
||||
/datum/round_event/stray_cargo/setup()
|
||||
startWhen = rand(20, 40)
|
||||
impact_area = find_event_area()
|
||||
if(!impact_area)
|
||||
CRASH("No valid areas for cargo pod found.")
|
||||
var/list/turf_test = get_area_turfs(impact_area)
|
||||
if(!turf_test.len)
|
||||
CRASH("Stray Cargo Pod : No valid turfs found for [impact_area] - [impact_area.type]")
|
||||
|
||||
if(!stray_spawnable_supply_packs.len)
|
||||
stray_spawnable_supply_packs = SSshuttle.supply_packs.Copy()
|
||||
for(var/pack in stray_spawnable_supply_packs)
|
||||
var/datum/supply_pack/pack_type = pack
|
||||
if(initial(pack_type.special))
|
||||
stray_spawnable_supply_packs -= pack
|
||||
|
||||
///Spawns a random supply pack, puts it in a pod, and spawns it on a random tile of the selected area
|
||||
/datum/round_event/stray_cargo/start()
|
||||
var/list/turf/valid_turfs = get_area_turfs(impact_area)
|
||||
//Only target non-dense turfs to prevent wall-embedded pods
|
||||
for(var/i in valid_turfs)
|
||||
var/turf/T = i
|
||||
if(T.density)
|
||||
valid_turfs -= T
|
||||
var/turf/LZ = pick(valid_turfs)
|
||||
var/pack_type
|
||||
if(possible_pack_types.len)
|
||||
pack_type = pick(possible_pack_types)
|
||||
else
|
||||
pack_type = pick(stray_spawnable_supply_packs)
|
||||
var/datum/supply_pack/SP = new pack_type
|
||||
var/obj/structure/closet/crate/crate = SP.generate(null)
|
||||
crate.locked = FALSE //Unlock secure crates
|
||||
crate.update_icon()
|
||||
var/obj/structure/closet/supplypod/pod = make_pod()
|
||||
crate.forceMove(pod)
|
||||
new /obj/effect/abstract/DPtarget(LZ, pod)
|
||||
|
||||
///Handles the creation of the pod, in case it needs to be modified beforehand
|
||||
/datum/round_event/stray_cargo/proc/make_pod()
|
||||
var/obj/structure/closet/supplypod/S = new
|
||||
return S
|
||||
|
||||
///Picks an area that wouldn't risk critical damage if hit by a pod explosion
|
||||
/datum/round_event/stray_cargo/proc/find_event_area()
|
||||
var/static/list/allowed_areas
|
||||
if(!allowed_areas)
|
||||
///Places that shouldn't explode
|
||||
var/list/safe_area_types = typecacheof(list(
|
||||
/area/ai_monitored/turret_protected/ai,
|
||||
/area/ai_monitored/turret_protected/ai_upload,
|
||||
/area/engine,
|
||||
/area/shuttle)
|
||||
)
|
||||
|
||||
///Subtypes from the above that actually should explode.
|
||||
var/list/unsafe_area_subtypes = typecacheof(list(/area/engine/break_room))
|
||||
allowed_areas = make_associative(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
|
||||
var/list/possible_areas = typecache_filter_list(GLOB.sortedAreas,allowed_areas)
|
||||
if (length(possible_areas))
|
||||
return pick(possible_areas)
|
||||
|
||||
///A rare variant that drops a crate containing syndicate uplink items
|
||||
/datum/round_event_control/stray_cargo/syndicate
|
||||
name = "Stray Syndicate Cargo Pod"
|
||||
typepath = /datum/round_event/stray_cargo/syndicate
|
||||
weight = 0
|
||||
max_occurrences = 0
|
||||
earliest_start = 30 MINUTES
|
||||
|
||||
/datum/round_event/stray_cargo/syndicate
|
||||
possible_pack_types = list(/datum/supply_pack/misc/syndicate)
|
||||
|
||||
///Apply the syndicate pod skin
|
||||
/datum/round_event/stray_cargo/syndicate/make_pod()
|
||||
var/obj/structure/closet/supplypod/S = new
|
||||
S.setStyle(STYLE_SYNDICATE)
|
||||
return S
|
||||
@@ -140,22 +140,6 @@
|
||||
typepath = /datum/round_event/vent_clog/plasma_decon
|
||||
max_occurrences = 0
|
||||
|
||||
/datum/round_event_control/vent_clog/female
|
||||
name = "Clogged Vents; Girlcum"
|
||||
typepath = /datum/round_event/vent_clog/female
|
||||
max_occurrences = 0
|
||||
|
||||
/datum/round_event/vent_clog/female
|
||||
reagentsAmount = 100
|
||||
|
||||
/datum/round_event_control/vent_clog/male
|
||||
name = "Clogged Vents: Semen"
|
||||
typepath = /datum/round_event/vent_clog/male
|
||||
max_occurrences = 0
|
||||
|
||||
/datum/round_event/vent_clog/male
|
||||
reagentsAmount = 100
|
||||
|
||||
/datum/round_event/vent_clog/beer/announce()
|
||||
priority_announce("The scrubbers network is experiencing an unexpected surge of pressurized beer. Some ejection of contents may occur.", "Atmospherics alert")
|
||||
|
||||
@@ -171,36 +155,6 @@
|
||||
foam.start()
|
||||
CHECK_TICK
|
||||
|
||||
/datum/round_event/vent_clog/male/announce()
|
||||
priority_announce("The scrubbers network is experiencing a backpressure surge. Some ejaculation of contents may occur.", "Atmospherics alert")
|
||||
|
||||
/datum/round_event/vent_clog/male/start()
|
||||
for(var/obj/machinery/atmospherics/components/unary/vent in vents)
|
||||
if(vent && vent.loc && !vent.welded)
|
||||
var/datum/reagents/R = new/datum/reagents(1000)
|
||||
R.my_atom = vent
|
||||
R.add_reagent(/datum/reagent/consumable/semen, reagentsAmount)
|
||||
|
||||
var/datum/effect_system/foam_spread/foam = new
|
||||
foam.set_up(200, get_turf(vent), R)
|
||||
foam.start()
|
||||
CHECK_TICK
|
||||
|
||||
/datum/round_event/vent_clog/female/announce()
|
||||
priority_announce("The scrubbers network is experiencing a backpressure squirt. Some ejection of contents may occur.", "Atmospherics alert")
|
||||
|
||||
/datum/round_event/vent_clog/female/start()
|
||||
for(var/obj/machinery/atmospherics/components/unary/vent in vents)
|
||||
if(vent && vent.loc && !vent.welded)
|
||||
var/datum/reagents/R = new/datum/reagents(1000)
|
||||
R.my_atom = vent
|
||||
R.add_reagent(/datum/reagent/consumable/femcum, reagentsAmount)
|
||||
|
||||
var/datum/effect_system/foam_spread/foam = new
|
||||
foam.set_up(200, get_turf(vent), R)
|
||||
foam.start()
|
||||
CHECK_TICK
|
||||
|
||||
/datum/round_event/vent_clog/plasma_decon/announce()
|
||||
priority_announce("We are deploying an experimental plasma decontamination system. Please stand away from the vents and do not breathe the smoke that comes out.", "Central Command Update")
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/datum/round_event_control/wisdomcow
|
||||
name = "Wisdom cow"
|
||||
typepath = /datum/round_event/wisdomcow
|
||||
max_occurrences = 1
|
||||
weight = 20
|
||||
|
||||
/datum/round_event/wisdomcow/announce(fake)
|
||||
priority_announce("A wise cow has been spotted in the area. Be sure to ask for her advice.", "Nanotrasen Cow Ranching Agency")
|
||||
|
||||
/datum/round_event/wisdomcow/start()
|
||||
var/turf/targetloc = get_random_station_turf()
|
||||
new /mob/living/simple_animal/cow/wisdom(targetloc)
|
||||
var/datum/effect_system/smoke_spread/smoke = new
|
||||
smoke.set_up(1, targetloc)
|
||||
smoke.start()
|
||||
@@ -0,0 +1,46 @@
|
||||
/datum/round_event_control/wizard/embedpocalypse
|
||||
name = "Make Everything Embeddable"
|
||||
weight = 2
|
||||
typepath = /datum/round_event/wizard/embedpocalypse
|
||||
max_occurrences = 1
|
||||
earliest_start = 0 MINUTES
|
||||
|
||||
/datum/round_event/wizard/embedpocalypse/start()
|
||||
for(var/obj/item/I in world)
|
||||
CHECK_TICK
|
||||
|
||||
if(!(I.flags_1 & INITIALIZED_1))
|
||||
continue
|
||||
|
||||
if(!I.embedding || I.embedding == EMBED_HARMLESS)
|
||||
I.embedding = EMBED_POINTY
|
||||
I.updateEmbedding()
|
||||
I.name = "pointy [I.name]"
|
||||
|
||||
GLOB.embedpocalypse = TRUE
|
||||
GLOB.stickpocalypse = FALSE // embedpocalypse takes precedence over stickpocalypse
|
||||
|
||||
/datum/round_event_control/wizard/embedpocalypse/sticky
|
||||
name = "Make Everything Sticky"
|
||||
weight = 6
|
||||
typepath = /datum/round_event/wizard/embedpocalypse/sticky
|
||||
max_occurrences = 1
|
||||
earliest_start = 0 MINUTES
|
||||
|
||||
/datum/round_event_control/wizard/embedpocalypse/sticky/canSpawnEvent(players_amt, gamemode)
|
||||
if(GLOB.embedpocalypse)
|
||||
return FALSE
|
||||
|
||||
/datum/round_event/wizard/embedpocalypse/sticky/start()
|
||||
for(var/obj/item/I in world)
|
||||
CHECK_TICK
|
||||
|
||||
if(!(I.flags_1 & INITIALIZED_1))
|
||||
continue
|
||||
|
||||
if(!I.embedding)
|
||||
I.embedding = EMBED_HARMLESS
|
||||
I.updateEmbedding()
|
||||
I.name = "sticky [I.name]"
|
||||
|
||||
GLOB.stickpocalypse = TRUE
|
||||
@@ -0,0 +1,28 @@
|
||||
/datum/round_event_control/wizard/madness
|
||||
name = "Curse of Madness"
|
||||
weight = 1
|
||||
typepath = /datum/round_event/wizard/madness
|
||||
earliest_start = 0 MINUTES
|
||||
|
||||
var/forced_secret
|
||||
|
||||
/datum/round_event_control/wizard/madness/admin_setup()
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/suggested = pick(strings(REDPILL_FILE, "redpill_questions"))
|
||||
|
||||
forced_secret = (input(usr, "What horrifying truth will you reveal?", "Curse of Madness", sortList(suggested)) as text|null) || suggested
|
||||
|
||||
/datum/round_event/wizard/madness/start()
|
||||
var/datum/round_event_control/wizard/madness/C = control
|
||||
|
||||
var/horrifying_truth
|
||||
|
||||
if(C.forced_secret)
|
||||
horrifying_truth = C.forced_secret
|
||||
C.forced_secret = null
|
||||
else
|
||||
horrifying_truth = pick(strings(REDPILL_FILE, "redpill_questions"))
|
||||
|
||||
curse_of_madness(null, horrifying_truth)
|
||||
Reference in New Issue
Block a user