Revert "PLASE"

This reverts commit 8af225e6e3.
This commit is contained in:
Fermi
2019-11-24 03:06:08 +00:00
parent aeb8606ce0
commit ba4fa1ef67
2145 changed files with 1387321 additions and 5257 deletions
+212
View File
@@ -0,0 +1,212 @@
//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 = 20 MINUTES //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 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
//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
var/triggering //admin cancellation
/datum/round_event_control/New()
if(config && !wizardevent) // Magic is unaffected by configs
earliest_start = CEILING(earliest_start * CONFIG_GET(number/events_min_time_mul), 1)
min_players = CEILING(min_players * CONFIG_GET(number/events_min_players_mul), 1)
/datum/round_event_control/wizard
wizardevent = 1
var/can_be_midround_wizard = TRUE
// 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-SSticker.round_start_time)
return FALSE
if(wizardevent != SSevents.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 && (!SSevents.holidays || !SSevents.holidays[holidayID]))
return FALSE
return TRUE
/datum/round_event_control/wizard/canSpawnEvent(var/players_amt, var/gamemode)
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/var/datum/game_mode/dynamic/mode = SSticker.mode
if (locate(/datum/dynamic_ruleset/midround/from_ghosts/wizard) in mode.executed_rules)
return can_be_midround_wizard && ..()
return ..()
/datum/round_event_control/proc/preRunEvent()
if(!ispath(typepath, /datum/round_event))
return EVENT_CANT_RUN
triggering = TRUE
if (alertadmins)
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
var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE)
if(!canSpawnEvent(players_amt, gamemode))
message_admins("Second pre-condition check for [name] failed, skipping...")
return EVENT_INTERRUPTED
if(!triggering)
return EVENT_CANCELLED //admin cancelled
triggering = FALSE
return EVENT_READY
/datum/round_event_control/Topic(href, href_list)
..()
if(href_list["cancel"])
if(!triggering)
to_chat(usr, "<span class='admin'>You are too late to cancel that event</span>")
return
triggering = FALSE
message_admins("[key_name_admin(usr)] cancelled event [name].")
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)
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
SSblackbox.record_feedback("tally", "event_ran", 1, "[E]")
occurrences++
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])")
return E
//Special admins setup
/datum/round_event_control/proc/admin_setup()
return
/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 -1 if announcement should not be shown.
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
var/fakeable = TRUE //Can be faked by fake news event.
//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(fake)
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)
processing = FALSE
start()
processing = TRUE
if(activeFor == announceWhen)
processing = FALSE
announce(FALSE)
processing = TRUE
if(startWhen < activeFor && activeFor < endWhen)
processing = FALSE
tick()
processing = TRUE
if(activeFor == endWhen)
processing = FALSE
end()
processing = TRUE
// Everything is done, let's clean up.
if(activeFor >= endWhen && activeFor >= announceWhen && activeFor >= startWhen)
processing = FALSE
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()
SSevents.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
SSevents.running += src
return ..()
+34
View File
@@ -0,0 +1,34 @@
/datum/round_event_control/abductor
name = "Abductors"
typepath = /datum/round_event/ghost_role/abductor
weight = 10
max_occurrences = 1
min_players = 20
gamemode_blacklist = list("nuclear","wizard","revolution","dynamic")
/datum/round_event/ghost_role/abductor
minimum_required = 2
role_name = "abductor team"
fakeable = FALSE //Nothing to fake here
/datum/round_event/ghost_role/abductor/spawn_role()
var/list/mob/dead/observer/candidates = get_candidates(ROLE_ABDUCTOR, null, ROLE_ABDUCTOR)
if(candidates.len < 2)
return NOT_ENOUGH_PLAYERS
var/mob/living/carbon/human/agent = makeBody(pick_n_take(candidates))
var/mob/living/carbon/human/scientist = makeBody(pick_n_take(candidates))
var/datum/team/abductor_team/T = new
if(T.team_number > ABDUCTOR_MAX_TEAMS)
return MAP_ERROR
log_game("[key_name(scientist)] has been selected as [T.name] abductor scientist.")
log_game("[key_name(agent)] has been selected as [T.name] abductor agent.")
scientist.mind.add_antag_datum(/datum/antagonist/abductor/scientist, T)
agent.mind.add_antag_datum(/datum/antagonist/abductor/agent, T)
spawned_mobs += list(agent, scientist)
return SUCCESSFUL_SPAWN
+76
View File
@@ -0,0 +1,76 @@
/datum/round_event_control/alien_infestation
name = "Alien Infestation"
typepath = /datum/round_event/ghost_role/alien_infestation
weight = 5
gamemode_blacklist = list("dynamic")
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.
fakeable = TRUE
/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(fake)
if(successSpawn || fake)
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", "aliens")
/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 GLOB.machines)
if(QDELETED(temp_vent))
continue
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
var/datum/pipeline/temp_vent_parent = temp_vent.parents[1]
//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(ROLE_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 = pick_n_take(candidates)
var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc)
new_xeno.key = C.key
spawncount--
successSpawn = TRUE
message_admins("[ADMIN_LOOKUPFLW(new_xeno)] has been made into an alien by an event.")
log_game("[key_name(new_xeno)] 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
+22
View File
@@ -0,0 +1,22 @@
/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")
/datum/round_event/anomaly/anomaly_bluespace
startWhen = 3
announceWhen = 10
/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)
+23
View File
@@ -0,0 +1,23 @@
/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
gamemode_blacklist = list("dynamic")
/datum/round_event/anomaly/anomaly_flux
startWhen = 10
announceWhen = 3
/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)
+22
View File
@@ -0,0 +1,22 @@
/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")
/datum/round_event/anomaly/anomaly_grav
startWhen = 3
announceWhen = 20
/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)
+21
View File
@@ -0,0 +1,21 @@
/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")
/datum/round_event/anomaly/anomaly_pyro
startWhen = 3
announceWhen = 10
/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)
+23
View File
@@ -0,0 +1,23 @@
/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
gamemode_blacklist = list("dynamic")
/datum/round_event/anomaly/anomaly_vortex
startWhen = 10
announceWhen = 3
/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)
+34
View File
@@ -0,0 +1,34 @@
/datum/round_event_control/blob
name = "Blob"
typepath = /datum/round_event/ghost_role/blob
weight = 10
max_occurrences = 1
earliest_start = 40 MINUTES
min_players = 35
gamemode_blacklist = list("blob","dynamic") //Just in case a blob survives that long
/datum/round_event/ghost_role/blob
announceWhen = -1
role_name = "blob overmind"
fakeable = TRUE
/datum/round_event/ghost_role/blob/announce(fake)
if(prob(75))
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak5")
else
print_command_report("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "level 5 biohazard")
/datum/round_event/ghost_role/blob/spawn_role()
if(!GLOB.blobstart.len)
return MAP_ERROR
var/list/candidates = get_candidates(ROLE_BLOB, null, ROLE_BLOB)
if(!candidates.len)
return NOT_ENOUGH_PLAYERS
var/mob/dead/observer/new_blob = pick(candidates)
var/mob/camera/blob/BC = new_blob.become_overmind()
spawned_mobs += BC
message_admins("[ADMIN_LOOKUPFLW(BC)] has been made into a blob overmind by an event.")
log_game("[key_name(BC)] was spawned as a blob overmind by an event.")
return SUCCESSFUL_SPAWN
+89
View File
@@ -0,0 +1,89 @@
/datum/round_event_control/brand_intelligence
name = "Brand Intelligence"
typepath = /datum/round_event/brand_intelligence
weight = 5
min_players = 15
max_occurrences = 1
gamemode_blacklist = list("dynamic")
/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 obsession!", \
"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.",
"Gamers, rise up!",
"Ok, now, this is epic.",
"HUMAN FUNNY.",
"But I'm already tracer!",
"How do I vore people?",
"ERP?",
"Not epic bros...")
/datum/round_event/brand_intelligence/announce(fake)
var/source = "unknown machine"
if(fake)
var/obj/machinery/vending/cola/example = /obj/machinery/vending/cola
source = initial(example.name)
else if(originMachine)
source = originMachine.name
if(prob(50))
priority_announce("Rampant brand intelligence has been detected aboard [station_name()]. Please stand by. The origin is believed to be \a [source].", "Machine Learning Alert")
else
print_command_report("Rampant brand intelligence has been detected aboard [station_name()]. Please stand by. The origin is believed to be \a [source].", "Rampant brand intelligence")
/datum/round_event/brand_intelligence/start()
for(var/obj/machinery/vending/V in GLOB.machines)
if(!is_station_level(V.z))
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))
+31
View File
@@ -0,0 +1,31 @@
/datum/round_event_control/carp_migration
name = "Carp Migration"
typepath = /datum/round_event/carp_migration
weight = 15
min_players = 2
earliest_start = 10 MINUTES
max_occurrences = 6
gamemode_blacklist = list("dynamic")
/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(fake)
if(prob(50))
priority_announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
else
print_command_report("Unknown biological entities have been detected near [station_name()], you may wish to break out arms.", "Biological entities")
/datum/round_event/carp_migration/start()
for(var/obj/effect/landmark/carpspawn/C in GLOB.landmarks_list)
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,27 @@
/datum/round_event_control/communications_blackout
name = "Communications Blackout"
typepath = /datum/round_event/communications_blackout
weight = 30
gamemode_blacklist = list("dynamic")
/datum/round_event/communications_blackout
announceWhen = 1
/datum/round_event/communications_blackout/announce(fake)
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 GLOB.ai_list) //AIs are always aware of communication blackouts.
to_chat(A, "<br><span class='warning'><b>[alert]</b></span><br>")
if(prob(30) || fake) //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 GLOB.telecomms_list)
T.emp_act(EMP_HEAVY)
+75
View File
@@ -0,0 +1,75 @@
/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
var/max_severity = 3
/datum/round_event/disease_outbreak/announce(fake)
priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak7")
/datum/round_event/disease_outbreak/setup()
announceWhen = rand(15, 30)
/datum/round_event/disease_outbreak/start()
var/advanced_virus = FALSE
max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes
if(prob(20 + (10 * max_severity)))
advanced_virus = TRUE
if(!virus_type && !advanced_virus)
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(GLOB.alive_mob_list))
var/turf/T = get_turf(H)
if(!T)
continue
if(!is_station_level(T.z))
continue
if(!H.client)
continue
if(H.stat == DEAD)
continue
if(HAS_TRAIT(H, TRAIT_VIRUSIMMUNE)) //Don't pick someone who's virus immune, only for it to not do anything.
continue
var/foundAlready = FALSE // don't infect someone that already has a disease
for(var/thing in H.diseases)
foundAlready = TRUE
break
if(foundAlready)
continue
var/datum/disease/D
if(!advanced_virus)
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
if(!H.dna || (HAS_TRAIT(H, TRAIT_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()
else
D = new /datum/disease/advance/random(max_severity, max_severity)
D.carrier = TRUE
H.ForceContractDisease(D, FALSE, TRUE)
if(advanced_virus)
var/datum/disease/advance/A = D
var/list/name_symptoms = list() //for feedback
for(var/datum/symptom/S in A.symptoms)
name_symptoms += S.name
message_admins("An event has triggered a random advanced virus outbreak on [ADMIN_LOOKUPFLW(H)]! It has these symptoms: [english_list(name_symptoms)]")
log_game("An event has triggered a random advanced virus outbreak on [key_name(H)]! It has these symptoms: [english_list(name_symptoms)]")
break
+32
View File
@@ -0,0 +1,32 @@
/datum/round_event_control/space_dust
name = "Minor Space Dust"
typepath = /datum/round_event/space_dust
weight = 200
max_occurrences = 1000
earliest_start = 0 MINUTES
alertadmins = 0
gamemode_blacklist = list("dynamic")
/datum/round_event/space_dust
startWhen = 1
endWhen = 2
fakeable = FALSE
/datum/round_event/space_dust/start()
spawn_meteors(1, GLOB.meteorsC)
/datum/round_event_control/sandstorm
name = "Sandstorm"
typepath = /datum/round_event/sandstorm
weight = 0
max_occurrences = 0
earliest_start = 0 MINUTES
/datum/round_event/sandstorm
startWhen = 1
endWhen = 150 // ~5 min
announceWhen = 0
fakeable = FALSE
/datum/round_event/sandstorm/tick()
spawn_meteors(10, GLOB.meteorsC)
+36
View File
@@ -0,0 +1,36 @@
/datum/round_event_control/electrical_storm
name = "Electrical Storm"
typepath = /datum/round_event/electrical_storm
earliest_start = 10 MINUTES
min_players = 5
weight = 40
alertadmins = 0
gamemode_blacklist = list("dynamic")
/datum/round_event/electrical_storm
var/lightsoutAmount = 1
var/lightsoutRange = 25
announceWhen = 1
/datum/round_event/electrical_storm/announce(fake)
if(prob(50))
priority_announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert")
else
print_command_report("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm")
/datum/round_event/electrical_storm/start()
var/list/epicentreList = list()
for(var/i=1, i <= lightsoutAmount, i++)
var/turf/T = find_safe_turf()
if(istype(T))
epicentreList += T
if(!epicentreList.len)
return
for(var/centre in epicentreList)
for(var/a in GLOB.apcs_list)
var/obj/machinery/power/apc/A = a
if(get_dist(centre, A) <= lightsoutRange)
A.overload_lighting()
+19
View File
@@ -0,0 +1,19 @@
/datum/round_event_control/grid_check
name = "Grid Check"
typepath = /datum/round_event/grid_check
weight = 10
max_occurrences = 3
/datum/round_event/grid_check
announceWhen = 1
startWhen = 1
/datum/round_event/grid_check/announce(fake)
priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", "poweroff")
/datum/round_event/grid_check/start()
for(var/P in GLOB.apcs_list)
var/obj/machinery/power/apc/C = P
if(C.cell && is_station_level(C.z))
C.energy_fail(rand(30,120))
+23
View File
@@ -0,0 +1,23 @@
/datum/round_event_control/heart_attack
name = "Random Heart Attack"
typepath = /datum/round_event/heart_attack
weight = 20
max_occurrences = 2
min_players = 40 // To avoid shafting lowpop
gamemode_blacklist = list("dynamic")
/datum/round_event/heart_attack/start()
var/list/heart_attack_contestants = list()
for(var/mob/living/carbon/human/H in shuffle(GLOB.player_list))
if(!H.client || H.stat == DEAD || H.InCritical() || !H.can_heartattack() || H.has_status_effect(STATUS_EFFECT_EXERCISED) || (/datum/disease/heart_failure in H.diseases) || H.undergoing_cardiac_arrest())
continue
if(H.satiety <= -60) //Multiple junk food items recently
heart_attack_contestants[H] = 3
else
heart_attack_contestants[H] = 1
if(LAZYLEN(heart_attack_contestants))
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)
+185
View File
@@ -0,0 +1,185 @@
// 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 MINUTES
/datum/round_event/valentines/start()
..()
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
H.put_in_hands(new /obj/item/valentine)
var/obj/item/storage/backpack/b = locate() in H.contents
new /obj/item/reagent_containers/food/snacks/candyheart(b)
new /obj/item/storage/fancy/heart_box(b)
var/list/valentines = list()
for(var/mob/living/M in GLOB.player_list)
if(!M.stat && M.client && M.mind)
valentines |= M
while(valentines.len)
var/mob/living/L = pick_n_take(valentines)
if(valentines.len)
var/mob/living/date = pick_n_take(valentines)
forge_valentines_objective(L, date)
forge_valentines_objective(date, L)
if(valentines.len && prob(4))
var/mob/living/notgoodenough = pick_n_take(valentines)
forge_valentines_objective(notgoodenough, date)
else
L.mind.add_antag_datum(/datum/antagonist/heartbreaker)
/proc/forge_valentines_objective(mob/living/lover,mob/living/date,var/chemLove = FALSE)
lover.mind.special_role = "valentine"
if (chemLove == TRUE)
var/datum/antagonist/valentine/chem/V = new //Changes text and EOG check basically.
V.date = date.mind
lover.mind.add_antag_datum(V)
else
var/datum/antagonist/valentine/V = new
V.date = date.mind
lover.mind.add_antag_datum(V) //These really should be teams but i can't be assed to incorporate third wheels right now
/datum/round_event/valentines/announce(fake)
priority_announce("It's Valentine's Day! Give a valentine to that special someone!")
/obj/item/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."
resistance_flags = FLAMMABLE
w_class = WEIGHT_CLASS_TINY
/obj/item/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 doctor, 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.",
"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.",
"I'm a nuke op, and my pinpointer leads to your heart.",
"Wanna slay my megafauna?",
"I'm a clockwork cultist. Or zl inyragvar.",
"If you were a disposal bin I'd ride you all day.",
"Put on your explorer's suit because I'm taking you to LOVEaland.",
"I must be the CMO, 'cause I saw you on my CUTE sensors.",
"You're the vomit to my flyperson.",
"You must be liquid dark matter, because you're pulling me closer.",
"Not even sorium can drive me away from you.",
"Wanna make like a borg and do some heavy petting?",
"Are you powering the station? Because you super matter to me.",
"I wish science could make me a bag of holding you.",
"Let's call the emergency CUDDLE.",
"I must be tripping on BZ, because I saw an angel walk by.",
"Wanna empty out my tool storage?",
"Did you visit the medbay after you fell from heaven?",
"Are you wearing space pants? Wanna not be?" )
/obj/item/valentine/attackby(obj/item/W, mob/user, params)
..()
if(istype(W, /obj/item/pen) || istype(W, /obj/item/toy/crayon))
if(!user.is_literate())
to_chat(user, "<span class='notice'>You scribble illegibly on [src]!</span>")
return
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(!user.canUseTopic(src, BE_CLOSE))
return
if(recipient && sender)
name = "valentine - To: [recipient] From: [sender]"
/obj/item/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
to_chat(user, "<span class='notice'>It is too far away.</span>")
/obj/item/valentine/attack_self(mob/user)
user.examinate(src)
/obj/item/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/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: BOX OF HUGS",
"A heart-shaped candy that reads: REEBE MINE",
"A heart-shaped candy that reads: PET ME",
"A heart-shaped candy that reads: TO THE DORMS",
"A heart-shaped candy that reads: DIS MEMBER")
icon_state = pick("candyheart", "candyheart2", "candyheart3", "candyheart4")
+83
View File
@@ -0,0 +1,83 @@
/obj/item/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/toy/xmas_cracker/attack(mob/target, mob/user)
if( !cracked && ishuman(target) && (target.stat == CONSCIOUS) && !target.get_active_held_item() )
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/paper/Joke = new /obj/item/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/toy/xmas_cracker/other_half = new /obj/item/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, "fire" = 0, "acid" = 0)
/obj/effect/landmark/xmastree
name = "christmas tree spawner"
layer = FLY_LAYER
var/festive_tree = /obj/structure/flora/tree/pine/xmas
var/christmas_tree = /obj/structure/flora/tree/pine/xmas/presents
/obj/effect/landmark/xmastree/Initialize(mapload)
..()
if((CHRISTMAS in SSevents.holidays) && christmas_tree)
new christmas_tree(get_turf(src))
else if((FESTIVE_SEASON in SSevents.holidays) && festive_tree)
new festive_tree(get_turf(src))
return INITIALIZE_HINT_QDEL
/obj/effect/landmark/xmastree/rdrod
name = "festivus pole spawner"
festive_tree = /obj/structure/festivus
christmas_tree = null
/datum/round_event_control/santa
name = "Santa is coming to town! (Christmas)"
holidayID = CHRISTMAS
typepath = /datum/round_event/santa
weight = 20
max_occurrences = 1
earliest_start = 30 MINUTES
/datum/round_event/santa
var/mob/living/carbon/human/santa //who is our santa?
/datum/round_event/santa/announce(fake)
priority_announce("Santa is coming to town!", "Unknown Transmission")
/datum/round_event/santa/start()
var/list/candidates = pollGhostCandidates("Santa is coming to town! Do you want to be Santa?", poll_time=150)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
santa = new /mob/living/carbon/human(pick(GLOB.blobstart))
C.transfer_ckey(santa, FALSE)
var/datum/antagonist/santa/A = new
santa.mind.add_antag_datum(A)
+593
View File
@@ -0,0 +1,593 @@
#define ION_RANDOM 0
#define ION_ANNOUNCE 1
/datum/round_event_control/ion_storm
name = "Ion Storm"
typepath = /datum/round_event/ion_storm
gamemode_blacklist = list("dynamic")
weight = 15
min_players = 2
/datum/round_event/ion_storm
var/replaceLawsetChance = 25 //chance the AI's lawset is completely replaced with something else per config weights
var/removeRandomLawChance = 10 //chance the AI has one random supplied or inherent law removed
var/removeDontImproveChance = 10 //chance the randomly created law replaces a random law instead of simply being added
var/shuffleLawsChance = 10 //chance the AI's laws are shuffled afterwards
var/botEmagChance = 10
var/announceEvent = ION_RANDOM // -1 means don't announce, 0 means have it randomly announce, 1 means it is announced
var/ionMessage = null
var/ionAnnounceChance = 33
announceWhen = 1
/datum/round_event/ion_storm/add_law_only // special subtype that adds a law only
replaceLawsetChance = 0
removeRandomLawChance = 0
removeDontImproveChance = 0
shuffleLawsChance = 0
botEmagChance = 0
/datum/round_event/ion_storm/announce(fake)
if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(ionAnnounceChance)) || fake)
priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", "ionstorm")
/datum/round_event/ion_storm/start()
//Generate AI law change
for(var/mob/living/silicon/ai/M in GLOB.alive_mob_list)
M.laws_sanity_check()
if(M.stat != DEAD && M.see_in_dark != 0)
if(prob(replaceLawsetChance))
M.laws.pick_weighted_lawset()
if(prob(removeRandomLawChance))
M.remove_law(rand(1, M.laws.get_law_amount(list(LAW_INHERENT, LAW_SUPPLIED))))
var/message = ionMessage || generate_ion_law()
if(message)
if(prob(removeDontImproveChance))
M.replace_random_law(message, list(LAW_INHERENT, LAW_SUPPLIED, LAW_ION))
else
M.add_ion_law(message)
if(prob(shuffleLawsChance))
M.shuffle_laws(list(LAW_INHERENT, LAW_SUPPLIED, LAW_ION))
log_game("Ion storm changed laws of [key_name(M)] to [english_list(M.laws.get_law_list(TRUE, TRUE))]")
M.post_lawchange()
//Generate Cyborg law change
for(var/mob/living/silicon/robot/M in GLOB.alive_mob_list)
M.laws_sanity_check()
if(M.stat != DEAD && M.see_in_dark != 0)
if(prob(replaceLawsetChance))
M.laws.pick_weighted_lawset()
if(prob(removeRandomLawChance))
M.remove_law(rand(1, M.laws.get_law_amount(list(LAW_INHERENT, LAW_SUPPLIED))))
var/message = ionMessage || generate_ion_law()
if(message)
if(prob(removeDontImproveChance))
M.replace_random_law(message, list(LAW_INHERENT, LAW_SUPPLIED, LAW_ION))
else
M.add_ion_law(message)
if(prob(shuffleLawsChance))
M.shuffle_laws(list(LAW_INHERENT, LAW_SUPPLIED, LAW_ION))
log_game("Ion storm changed laws of [key_name(M)] to [english_list(M.laws.get_law_list(TRUE, TRUE))]")
M.post_lawchange()
//Chance to emag a Bot
if(botEmagChance)
for(var/mob/living/simple_animal/bot/bot in GLOB.alive_mob_list)
if(prob(botEmagChance))
bot.emag_act()
/proc/generate_ion_law()
//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 crew or
//must be done to not harm crew. 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/iondrinks = pick_list(ION_FILE, "iondrinks")
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 crew
switch(rand(1,7)) //What is X?
if(1) //X is a threat
message = "[ionadjectiveshalf][ionthreats] ARE HARMFUL TO CREW"
if(2) //X is a job
message = "[ionadjectiveshalf][ioncrew1] ARE HARMFUL TO CREW"
if(3) //X is an object
message = "[ionadjectiveshalf][ionobjects] ARE HARMFUL TO CREW"
if(4) //X is an action
message = "THOSE WHO [ionmust] ARE HARMFUL TO CREW"
if(5) //X is an abstract
message = "[ionabstract] IS HARMFUL TO CREW"
if(6) //X is being a job
message = "BEING [ionadjectiveshalf][ioncrew1] IS HARMFUL TO CREW"
if(7) //X is doing a thing
message = "[ionthings] IS HARMFUL TO CREW"
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 consume X to survive
switch(rand(1,5)) //What is X?
if(1) //X is a food
message = "CREWMEMBERS MUST EAT [ionadjectiveshalf][ionfood] TO SURVIVE"
if(2) //X is a drink
message = "CREWMEMBERS MUST DRINK [ionadjectiveshalf][iondrinks] TO SURVIVE"
if(3) //X is an object
message = "CREWMEMBERS MUST EAT [ionadjectiveshalf][ionobjects] TO SURVIVE"
if(4) //X is a threat
message = "CREWMEMBERS MUST EAT [ionadjectiveshalf][ionthreats] TO SURVIVE"
if(5) //X is a job
message = "CREWMEMBERS 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 crew
switch(rand(1,2)) //Only or non?
if(1) //Only crew
switch(rand(1,7)) //Who is it?
if(1) //A specific job
message = "ONLY THE [ioncrew1] ARE CREW"
if(2) //Two specific jobs
message = "ONLY THE [ioncrew1] AND [ioncrew2] ARE CREW"
if(3) //Threats
message = "ONLY [ionadjectiveshalf][ionthreats] ARE CREW"
if(4) // Objects
message = "ONLY [ionadjectiveshalf][ionobjects] ARE CREW"
if(5) // Species
message = "ONLY [ionspecies] ARE CREW"
if(6) //Adjective crewmembers
message = "ONLY [ionadjectives] PEOPLE ARE CREW"
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 CREW"
if(2) //X is own certain objects
message = "ONLY THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE CREW"
if(3) //X is eat certain food
message = "ONLY THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE CREW"
if(2) //Non human
switch(rand(1,7)) //Who is it?
if(1) //A specific job
message = "[ioncrew1] ARE NON-CREW"
if(2) //Two specific jobs
message = "[ioncrew1] AND [ioncrew2] ARE NON-CREW"
if(3) //Threats
message = "[ionadjectiveshalf][ionthreats] ARE NON-CREW"
if(4) // Objects
message = "[ionadjectiveshalf][ionobjects] ARE NON-CREW"
if(5) // Species
message = "[ionspecies] ARE NON-CREW"
if(6) //Adjective crewmembers
message = "[ionadjectives] PEOPLE ARE NON-CREW"
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-CREW"
if(2) //X is own certain objects
message = "THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE NON-CREW"
if(3) //X is eat certain food
message = "THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE NON-CREW"
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
+22
View File
@@ -0,0 +1,22 @@
/datum/round_event_control/meteor_wave/major_dust
name = "Major Space Dust"
typepath = /datum/round_event/meteor_wave/major_dust
weight = 8
/datum/round_event/meteor_wave/major_dust
wave_name = "space dust"
/datum/round_event/meteor_wave/major_dust/announce(fake)
var/reason = pick(
"The station is passing through a debris cloud, expect minor damage \
to external fittings and fixtures.",
"Nanotrasen Superweapons Division is testing a new prototype \
[pick("field","projection","nova","super-colliding","reactive")] \
[pick("cannon","artillery","tank","cruiser","\[REDACTED\]")], \
some mild debris is expected.",
"A neighbouring station is throwing rocks at you. (Perhaps they've \
grown tired of your messages.)")
if(prob(50))
priority_announce(pick(reason), "Collision Alert")
else
print_command_report("[pick(reason)]", "Collision Alert")
+11
View File
@@ -0,0 +1,11 @@
/datum/round_event_control/meteor_wave/meaty
name = "Meteor Wave: Meaty"
typepath = /datum/round_event/meteor_wave/meaty
weight = 2
max_occurrences = 1
/datum/round_event/meteor_wave/meaty
wave_name = "meaty"
/datum/round_event/meteor_wave/meaty/announce(fake)
priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.", "meteors")
+90
View File
@@ -0,0 +1,90 @@
// Normal strength
#define SINGULO_BEACON_DISTURBANCE 0.2 //singularity beacon also improve the odds of meteor waves and speed them up a little.
#define SINGULO_BEACON_MAX_DISTURBANCE 0.6 //maximum cap due to how meteor waves can be potentially round ending.
/datum/round_event_control/meteor_wave
name = "Meteor Wave: Normal"
typepath = /datum/round_event/meteor_wave
weight = 4
min_players = 15
max_occurrences = 3
earliest_start = 25 MINUTES
/datum/round_event/meteor_wave
startWhen = 6
endWhen = 66
announceWhen = 1
var/list/wave_type
var/wave_name = "normal"
/datum/round_event/meteor_wave/setup()
announceWhen = 1
startWhen = rand(180, 360) //Yeah for SOME REASON this is measured in seconds and not deciseconds???
if(GLOB.singularity_counter)
startWhen *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE)
endWhen = startWhen + 60
/datum/round_event/meteor_wave/New()
..()
if(!wave_type)
determine_wave_type()
/datum/round_event/meteor_wave/proc/determine_wave_type()
if(!wave_name)
wave_name = pickweight(list(
"normal" = 50,
"threatening" = 40,
"catastrophic" = 10))
switch(wave_name)
if("normal")
wave_type = GLOB.meteors_normal
if("threatening")
wave_type = GLOB.meteors_threatening
if("catastrophic")
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
wave_type = GLOB.meteorsSPOOKY
else
wave_type = GLOB.meteors_catastrophic
if("meaty")
wave_type = GLOB.meteorsB
if("space dust")
wave_type = GLOB.meteorsC
if("halloween")
wave_type = GLOB.meteorsSPOOKY
else
WARNING("Wave name of [wave_name] not recognised.")
kill()
/datum/round_event/meteor_wave/announce(fake)
priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round(startWhen/60)] minutes.[GLOB.singularity_counter ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]", "Meteor Alert", "meteors")
/datum/round_event/meteor_wave/tick()
if(ISMULTIPLE(activeFor, 3))
spawn_meteors(5, wave_type) //meteor list types defined in gamemode/meteor/meteors.dm
/datum/round_event_control/meteor_wave/threatening
name = "Meteor Wave: Threatening"
typepath = /datum/round_event/meteor_wave/threatening
weight = 5
min_players = 20
max_occurrences = 3
earliest_start = 35 MINUTES
/datum/round_event/meteor_wave/threatening
wave_name = "threatening"
/datum/round_event_control/meteor_wave/catastrophic
name = "Meteor Wave: Catastrophic"
typepath = /datum/round_event/meteor_wave/catastrophic
weight = 7
min_players = 25
max_occurrences = 3
earliest_start = 45 MINUTES
/datum/round_event/meteor_wave/catastrophic
wave_name = "catastrophic"
#undef SINGULO_BEACON_DISTURBANCE
#undef SINGULO_BEACON_MAX_DISTURBANCE
+29
View File
@@ -0,0 +1,29 @@
/datum/round_event_control/mice_migration
name = "Mice Migration"
typepath = /datum/round_event/mice_migration
weight = 10
/datum/round_event/mice_migration
var/minimum_mice = 5
var/maximum_mice = 15
/datum/round_event/mice_migration/announce(fake)
var/cause = pick("space-winter", "budget-cuts", "Ragnarok",
"space being cold", "\[REDACTED\]", "climate change",
"bad luck")
var/plural = pick("a number of", "a horde of", "a pack of", "a swarm of",
"a whoop of", "not more than [maximum_mice]")
var/name = pick("rodents", "mice", "squeaking things",
"wire eating mammals", "\[REDACTED\]", "energy draining parasites")
var/movement = pick("migrated", "swarmed", "stampeded", "descended")
var/location = pick("maintenance tunnels", "maintenance areas",
"\[REDACTED\]", "place with all those juicy wires")
if(prob(50))
priority_announce("Due to [cause], [plural] [name] have [movement] \
into the [location].", "Migration Alert",
'sound/effects/mousesqueek.ogg')
else
print_command_report("Due to [cause], [plural] [name] have [movement] into the [location].", "Rodent Migration")
/datum/round_event/mice_migration/start()
SSminor_mapping.trigger_migration(rand(minimum_mice, maximum_mice))
+44
View File
@@ -0,0 +1,44 @@
/datum/round_event_control/nightmare
name = "Spawn Nightmare"
typepath = /datum/round_event/ghost_role/nightmare
max_occurrences = 1
gamemode_blacklist = list("dynamic")
min_players = 20
/datum/round_event/ghost_role/nightmare
minimum_required = 1
role_name = "nightmare"
fakeable = FALSE
/datum/round_event/ghost_role/nightmare/spawn_role()
var/list/candidates = get_candidates(ROLE_ALIEN, null, ROLE_ALIEN)
if(!candidates.len)
return NOT_ENOUGH_PLAYERS
var/mob/dead/selected = pick(candidates)
var/datum/mind/player_mind = new /datum/mind(selected.key)
player_mind.active = TRUE
var/list/spawn_locs = list()
for(var/X in GLOB.xeno_spawn)
var/turf/T = X
var/light_amount = T.get_lumcount()
if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
spawn_locs += T
if(!spawn_locs.len)
message_admins("No valid spawn locations found, aborting...")
return MAP_ERROR
var/mob/living/carbon/human/S = new ((pick(spawn_locs)))
player_mind.transfer_to(S)
player_mind.assigned_role = "Nightmare"
player_mind.special_role = "Nightmare"
player_mind.add_antag_datum(/datum/antagonist/nightmare)
S.set_species(/datum/species/shadow/nightmare)
playsound(S, 'sound/magic/ethereal_exit.ogg', 50, 1, -1)
message_admins("[ADMIN_LOOKUPFLW(S)] has been made into a Nightmare by an event.")
log_game("[key_name(S)] was spawned as a Nightmare by an event.")
spawned_mobs += S
return SUCCESSFUL_SPAWN
+453
View File
@@ -0,0 +1,453 @@
/datum/round_event_control/pirates
name = "Space Pirates"
typepath = /datum/round_event/pirates
weight = 8
max_occurrences = 1
min_players = 10
earliest_start = 30 MINUTES
gamemode_blacklist = list("nuclear","dynamic")
/datum/round_event_control/pirates/preRunEvent()
if (!SSmapping.empty_space)
return EVENT_CANT_RUN
return ..()
/datum/round_event/pirates
startWhen = 60 //2 minutes to answer
var/datum/comm_message/threat
var/payoff = 0
var/paid_off = FALSE
var/ship_name = "Space Privateers Association"
var/shuttle_spawned = FALSE
/datum/round_event/pirates/setup()
ship_name = pick(strings(PIRATE_NAMES_FILE, "ship_names"))
/datum/round_event/pirates/announce(fake)
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
if(fake)
return
threat = new
payoff = round(SSshuttle.points * 0.80)
threat.title = "Business proposition"
threat.content = "This is [ship_name]. Pay up [payoff] credits or you'll walk the plank."
threat.possible_answers = list("We'll pay.","No way.")
threat.answer_callback = CALLBACK(src,.proc/answered)
SScommunications.send_message(threat,unique = TRUE)
/datum/round_event/pirates/proc/answered()
if(threat && threat.answered == 1)
if(SSshuttle.points >= payoff)
SSshuttle.points -= payoff
priority_announce("Thanks for the credits, landlubbers.",sender_override = ship_name)
paid_off = TRUE
return
else
priority_announce("Trying to cheat us? You'll regret this!",sender_override = ship_name)
if(!shuttle_spawned)
spawn_shuttle()
/datum/round_event/pirates/start()
if(!paid_off && !shuttle_spawned)
spawn_shuttle()
/datum/round_event/pirates/proc/spawn_shuttle()
shuttle_spawned = TRUE
var/list/candidates = pollGhostCandidates("Do you wish to be considered for pirate crew?", ROLE_TRAITOR)
shuffle_inplace(candidates)
var/datum/map_template/shuttle/pirate/default/ship = new
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("Pirate event found no turf to load in")
if(!ship.load(T))
CRASH("Loading pirate ship failed!")
for(var/turf/A in ship.get_affected_turfs(T))
for(var/obj/effect/mob_spawn/human/pirate/spawner in A)
if(candidates.len > 0)
var/mob/M = candidates[1]
spawner.create(M.ckey)
candidates -= M
else
notify_ghosts("Space pirates are waking up!", source = spawner, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE)
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") //CITADEL EDIT also metabreak here too
//Shuttle equipment
/obj/machinery/shuttle_scrambler
name = "Data Siphon"
desc = "This heap of machinery steals credits and data from unprotected systems and locks down cargo shuttles."
icon = 'icons/obj/machines/dominator.dmi'
icon_state = "dominator"
density = TRUE
var/active = FALSE
var/obj/item/gps/gps
var/credits_stored = 0
var/siphon_per_tick = 5
/obj/machinery/shuttle_scrambler/Initialize(mapload)
. = ..()
gps = new/obj/item/gps/internal/pirate(src)
gps.tracking = FALSE
update_icon()
/obj/machinery/shuttle_scrambler/process()
if(active)
if(is_station_level(z))
var/siphoned = min(SSshuttle.points,siphon_per_tick)
SSshuttle.points -= siphoned
credits_stored += siphoned
interrupt_research()
else
return
else
STOP_PROCESSING(SSobj,src)
/obj/machinery/shuttle_scrambler/proc/toggle_on(mob/user)
SSshuttle.registerTradeBlockade(src)
gps.tracking = TRUE
active = TRUE
to_chat(user,"<span class='notice'>You toggle [src] [active ? "on":"off"].</span>")
to_chat(user,"<span class='warning'>The scrambling signal can be now tracked by GPS.</span>")
START_PROCESSING(SSobj,src)
/obj/machinery/shuttle_scrambler/interact(mob/user)
if(!active)
if(alert(user, "Turning the scrambler on will make the shuttle trackable by GPS. Are you sure you want to do it?", "Scrambler", "Yes", "Cancel") == "Cancel")
return
if(active || !user.canUseTopic(src))
return
toggle_on(user)
update_icon()
send_notification()
else
dump_loot(user)
//interrupt_research
/obj/machinery/shuttle_scrambler/proc/interrupt_research()
for(var/obj/machinery/rnd/server/S in GLOB.machines)
if(S.stat & (NOPOWER|BROKEN))
continue
S.emp_act(1)
new /obj/effect/temp_visual/emp(get_turf(S))
/obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user)
if(credits_stored < 200)
to_chat(user,"<span class='notice'>Not enough credits to retrieve.</span>")
return
while(credits_stored >= 200)
new /obj/item/stack/spacecash/c200(drop_location())
credits_stored -= 200
to_chat(user,"<span class='notice'>You retrieve the siphoned credits!</span>")
credits_stored = 0
/obj/machinery/shuttle_scrambler/proc/send_notification()
priority_announce("Data theft signal detected, source registered on local gps units.")
/obj/machinery/shuttle_scrambler/proc/toggle_off(mob/user)
SSshuttle.clearTradeBlockade(src)
gps.tracking = FALSE
active = FALSE
STOP_PROCESSING(SSobj,src)
/obj/machinery/shuttle_scrambler/update_icon()
if(active)
icon_state = "dominator-blue"
else
icon_state = "dominator"
/obj/machinery/shuttle_scrambler/Destroy()
toggle_off()
QDEL_NULL(gps)
return ..()
/obj/item/gps/internal/pirate
gpstag = "Nautical Signal"
desc = "You can hear shanties over the static."
/obj/machinery/computer/shuttle/pirate
name = "pirate shuttle console"
shuttleId = "pirateship"
icon_screen = "syndishuttle"
icon_keyboard = "syndie_key"
light_color = LIGHT_COLOR_RED
possible_destinations = "pirateship_away;pirateship_home;pirateship_custom"
/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/pirate
name = "pirate shuttle navigation computer"
desc = "Used to designate a precise transit location for the pirate shuttle."
shuttleId = "pirateship"
lock_override = CAMERA_LOCK_STATION
shuttlePortId = "pirateship_custom"
x_offset = 9
y_offset = 0
see_hidden = FALSE
/obj/docking_port/mobile/pirate
name = "pirate shuttle"
id = "pirateship"
var/engines_cooling = FALSE
var/engine_cooldown = 3 MINUTES
/obj/docking_port/mobile/pirate/getStatusText()
. = ..()
if(engines_cooling)
return "[.] - Engines cooling."
/obj/docking_port/mobile/pirate/initiate_docking(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
. = ..()
if(. == DOCKING_SUCCESS && !is_reserved_level(new_dock.z))
engines_cooling = TRUE
addtimer(CALLBACK(src,.proc/reset_cooldown),engine_cooldown,TIMER_UNIQUE)
/obj/docking_port/mobile/pirate/proc/reset_cooldown()
engines_cooling = FALSE
/obj/docking_port/mobile/pirate/canMove()
if(engines_cooling)
return FALSE
return ..()
/obj/machinery/suit_storage_unit/pirate
suit_type = /obj/item/clothing/suit/space
helmet_type = /obj/item/clothing/head/helmet/space
mask_type = /obj/item/clothing/mask/breath
storage_type = /obj/item/tank/jetpack/void
/obj/machinery/loot_locator
name = "Booty Locator"
desc = "This sophisticated machine scans the nearby space for items of value."
icon = 'icons/obj/machines/research.dmi'
icon_state = "tdoppler"
density = TRUE
var/cooldown = 300
var/next_use = 0
/obj/machinery/loot_locator/interact(mob/user)
if(world.time <= next_use)
to_chat(user,"<span class='warning'>[src] is recharging.</span>")
return
next_use = world.time + cooldown
var/atom/movable/AM = find_random_loot()
if(!AM)
say("No valuables located. Try again later.")
else
say("Located: [AM.name] at [get_area_name(AM)]")
/obj/machinery/loot_locator/proc/find_random_loot()
if(!GLOB.exports_list.len)
setupExports()
var/list/possible_loot = list()
for(var/datum/export/pirate/E in GLOB.exports_list)
possible_loot += E
var/datum/export/pirate/P
var/atom/movable/AM
while(!AM && possible_loot.len)
P = pick_n_take(possible_loot)
AM = P.find_loot()
return AM
//Pad & Pad Terminal
/obj/machinery/piratepad
name = "cargo hold pad"
icon = 'icons/obj/telescience.dmi'
icon_state = "lpad-idle-o"
var/idle_state = "lpad-idle-o"
var/warmup_state = "lpad-idle"
var/sending_state = "lpad-beam"
var/cargo_hold_id
/obj/machinery/piratepad/multitool_act(mob/living/user, obj/item/multitool/I)
if (istype(I))
to_chat(user, "<span class='notice'>You register [src] in [I]s buffer.</span>")
I.buffer = src
return TRUE
/obj/machinery/computer/piratepad_control
name = "cargo hold control terminal"
var/status_report = "Idle"
var/obj/machinery/piratepad/pad
var/warmup_time = 100
var/sending = FALSE
var/points = 0
var/datum/export_report/total_report
var/sending_timer
var/cargo_hold_id
/obj/machinery/computer/piratepad_control/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/piratepad_control/multitool_act(mob/living/user, obj/item/multitool/I)
if (istype(I) && istype(I.buffer,/obj/machinery/piratepad))
to_chat(user, "<span class='notice'>You link [src] with [I.buffer] in [I] buffer.</span>")
pad = I.buffer
updateDialog()
return TRUE
/obj/machinery/computer/piratepad_control/LateInitialize()
. = ..()
if(cargo_hold_id)
for(var/obj/machinery/piratepad/P in GLOB.machines)
if(P.cargo_hold_id == cargo_hold_id)
pad = P
return
else
pad = locate() in range(4,src)
/obj/machinery/computer/piratepad_control/ui_interact(mob/user)
. = ..()
var/list/t = list()
t += "<div class='statusDisplay'>Cargo Hold Control<br>"
t += "Current cargo value : [points]"
t += "</div>"
if(!pad)
t += "<div class='statusDisplay'>No pad located.</div><BR>"
else
t += "<br>[status_report]<br>"
if(!sending)
t += "<a href='?src=[REF(src)];recalc=1;'>Recalculate Value</a><a href='?src=[REF(src)];send=1'>Send</a>"
else
t += "<a href='?src=[REF(src)];stop=1'>Stop sending</a>"
var/datum/browser/popup = new(user, "piratepad", name, 300, 500)
popup.set_content(t.Join())
popup.open()
/obj/machinery/computer/piratepad_control/proc/recalc()
if(sending)
return
status_report = "Predicted value:<br>"
var/datum/export_report/ex = new
for(var/atom/movable/AM in get_turf(pad))
if(AM == pad)
continue
export_item_and_contents(AM, EXPORT_PIRATE | EXPORT_CARGO | EXPORT_CONTRABAND | EXPORT_EMAG, apply_elastic = FALSE, dry_run = TRUE, external_report = ex)
for(var/datum/export/E in ex.total_amount)
status_report += E.total_printout(ex,notes = FALSE) + "<br>"
/obj/machinery/computer/piratepad_control/proc/send()
if(!sending)
return
var/datum/export_report/ex = new
for(var/atom/movable/AM in get_turf(pad))
if(AM == pad)
continue
export_item_and_contents(AM, EXPORT_PIRATE | EXPORT_CARGO | EXPORT_CONTRABAND | EXPORT_EMAG, apply_elastic = FALSE, delete_unsold = FALSE, external_report = ex)
status_report = "Sold:<br>"
var/value = 0
for(var/datum/export/E in ex.total_amount)
var/export_text = E.total_printout(ex,notes = FALSE) //Don't want nanotrasen messages, makes no sense here.
if(!export_text)
continue
status_report += export_text + "<br>"
value += ex.total_value[E]
if(!total_report)
total_report = ex
else
total_report.exported_atoms += ex.exported_atoms
for(var/datum/export/E in ex.total_amount)
total_report.total_amount[E] += ex.total_amount[E]
total_report.total_value[E] += ex.total_value[E]
points += value
pad.visible_message("<span class='notice'>[pad] activates!</span>")
flick(pad.sending_state,pad)
pad.icon_state = pad.idle_state
sending = FALSE
updateDialog()
/obj/machinery/computer/piratepad_control/proc/start_sending()
if(sending)
return
sending = TRUE
status_report = "Sending..."
pad.visible_message("<span class='notice'>[pad] starts charging up.</span>")
pad.icon_state = pad.warmup_state
sending_timer = addtimer(CALLBACK(src,.proc/send),warmup_time, TIMER_STOPPABLE)
/obj/machinery/computer/piratepad_control/proc/stop_sending()
if(!sending)
return
sending = FALSE
status_report = "Idle"
pad.icon_state = pad.idle_state
deltimer(sending_timer)
/obj/machinery/computer/piratepad_control/Topic(href, href_list)
if(..())
return
if(pad)
if(href_list["recalc"])
recalc()
if(href_list["send"])
start_sending()
if(href_list["stop"])
stop_sending()
updateDialog()
else
updateDialog()
/datum/export/pirate
export_category = EXPORT_PIRATE
//Attempts to find the thing on station
/datum/export/pirate/proc/find_loot()
return
/datum/export/pirate/ransom
cost = 3000
unit_name = "hostage"
export_types = list(/mob/living/carbon/human)
/datum/export/pirate/ransom/find_loot()
var/list/head_minds = SSjob.get_living_heads()
var/list/head_mobs = list()
for(var/datum/mind/M in head_minds)
head_mobs += M.current
if(head_mobs.len)
return pick(head_mobs)
/datum/export/pirate/ransom/get_cost(atom/movable/AM)
var/mob/living/carbon/human/H = AM
if(H.stat != CONSCIOUS || !H.mind || !H.mind.assigned_role) //mint condition only
return 0
else
if(H.mind.assigned_role in GLOB.command_positions)
return 3000
else
return 1000
/datum/export/pirate/parrot
cost = 2000
unit_name = "alive parrot"
export_types = list(/mob/living/simple_animal/parrot)
/datum/export/pirate/parrot/find_loot()
for(var/mob/living/simple_animal/parrot/P in GLOB.alive_mob_list)
var/turf/T = get_turf(P)
if(T && is_station_level(T.z))
return P
/datum/export/pirate/cash
cost = 1
unit_name = "bills"
export_types = list(/obj/item/stack/spacecash)
/datum/export/pirate/cash/get_amount(obj/O)
var/obj/item/stack/spacecash/C = O
return ..() * C.amount * C.value
+64
View File
@@ -0,0 +1,64 @@
/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/bridge,
/area/engine,
/area/medical,
/area/security,
/area/quartermaster,
/area/science)
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(fake)
if(areasToOpen && areasToOpen.len > 0)
if(prob(50))
priority_announce("Gr3y.T1d3 virus detected in [station_name()] door subroutines. Severity level of [severity]. Recommend station AI involvement.", "Security Alert")
else
print_command_report("Gr3y.T1d3 virus detected in [station_name()] door subroutines. Severity level of [severity]. Recommend station AI involvement.", "Gr3y.T1d3 virus")
else
log_world("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 = FALSE
temp.update_icon()
else if(istype(O, /obj/machinery/door/airlock))
var/obj/machinery/door/airlock/temp = O
if(temp.critical_machine) //Skip doors in critical positions, such as the SM chamber.
continue
temp.prison_open()
else if(istype(O, /obj/machinery/door_timer))
var/obj/machinery/door_timer/temp = O
temp.timer_end(forced = TRUE)
@@ -3,7 +3,6 @@
typepath = /datum/round_event/processor_overload
weight = 15
min_players = 20
gamemode_blacklist = list("dynamic")
/datum/round_event/processor_overload
announceWhen = 1
+20
View File
@@ -0,0 +1,20 @@
/datum/round_event_control/radiation_storm
name = "Radiation Storm"
typepath = /datum/round_event/radiation_storm
max_occurrences = 1
gamemode_blacklist = list("dynamic")
/datum/round_event/radiation_storm
/datum/round_event/radiation_storm/setup()
startWhen = 3
endWhen = startWhen + 1
announceWhen = 1
/datum/round_event/radiation_storm/announce(fake)
priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", "radiation")
//sound not longer matches the text, but an audible warning is probably good
/datum/round_event/radiation_storm/start()
SSweather.run_weather(/datum/weather/rad_storm)
+294
View File
@@ -0,0 +1,294 @@
#define HIJACK_SYNDIE 1
#define RUSKY_PARTY 2
#define SPIDER_GIFT 3
#define DEPARTMENT_RESUPPLY 4
#define ANTIDOTE_NEEDED 5
#define PIZZA_DELIVERY 6
#define ITS_HIP_TO 7
#define MY_GOD_JC 8
#define DELTA_CRATES 9
/datum/round_event_control/shuttle_loan
name = "Shuttle Loan"
typepath = /datum/round_event/shuttle_loan
max_occurrences = 1
earliest_start = 7 MINUTES
/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/setup()
dispatch_type = pick(HIJACK_SYNDIE, RUSKY_PARTY, SPIDER_GIFT, DEPARTMENT_RESUPPLY, ANTIDOTE_NEEDED, PIZZA_DELIVERY, ITS_HIP_TO, MY_GOD_JC)
/datum/round_event/shuttle_loan/announce(fake)
SSshuttle.shuttle_loan = src
var/message = "Cargo: I just wanna tell you techs good luck, we are all counting on you."
var/title = "CentCom Free Real Estate"
switch(dispatch_type)
if(HIJACK_SYNDIE)
message = "Cargo: The syndicate are trying to infiltrate your station. If you let them hijack your cargo shuttle, you'll save us a headache."
title = "CentCom Counter Intelligence"
if(RUSKY_PARTY)
message = "Cargo: A group of angry Russians want to have a party. Can you send them your cargo shuttle then make them disappear?"
title = "CentCom Russian Outreach Program"
if(SPIDER_GIFT)
message = "Cargo: The Spider Clan has sent us a mysterious gift. Can we ship it to you to see what's inside?"
title = "CentCom Diplomatic Corps"
if(DEPARTMENT_RESUPPLY)
message = "Cargo: Seems we've ordered doubles of our department resupply packages this month. Can we send them to you?"
title = "CentCom Supply Department"
if(ANTIDOTE_NEEDED)
message = "Cargo: Your station has been chosen for an epidemiological research project. Send us your cargo shuttle to receive your research samples."
title = "CentCom Research Initiatives"
if (PIZZA_DELIVERY)
message = "Cargo: It looks like a neighbouring station accidentally delivered their pizza to you instead."
title = "CentCom Spacepizza Division"
if(ITS_HIP_TO)
message = "Cargo: One of our freighters carrying a bee shipment has been attacked by eco-terrorists. Can you clean up the mess for us?"
title = "CentCom Janitorial Division"
bonus_points = 20000 //Toxin bees can be unbeelievably lethal
if(MY_GOD_JC)
message = "Cargo: We have discovered an active Syndicate bomb near our VIP shuttle's fuel lines. If you feel up to the task, we will pay you for defusing it."
title = "CentCom Security Division"
bonus_points = 45000 //If you mess up, people die and the shuttle gets turned into swiss cheese
if(DELTA_CRATES)
message = "Cargo: We have discovered a warehouse of DELTA locked crates, we cant store any more of them at CC can you take them for us?."
title = "CentCom Security Division"
bonus_points = 25000 //If you mess up, people die and the shuttle gets turned into swiss cheese
if(prob(50))
priority_announce(message, title)
else
print_command_report(message, "Cargo report")
/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.mode = SHUTTLE_CALL
SSshuttle.supply.destination = SSshuttle.getDock("supply_home")
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."
if(PIZZA_DELIVERY)
SSshuttle.centcom_message += "Pizza delivery for [station_name()]"
if(ITS_HIP_TO)
SSshuttle.centcom_message += "Biohazard cleanup incoming."
if(MY_GOD_JC)
SSshuttle.centcom_message += "Live explosive ordnance incoming. Exercise extreme caution."
if(DELTA_CRATES)
SSshuttle.centcom_message += "DELTA Locked crates incoming. Exercise extreme caution."
/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()
var/list/area/shuttle/shuttle_areas = SSshuttle.supply.shuttle_areas
for(var/place in shuttle_areas)
var/area/shuttle/shuttle_area = place
for(var/turf/open/floor/T in shuttle_area)
if(is_blocked_turf(T))
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/ranged/infiltrator)
shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate/ranged/infiltrator)
if(prob(75))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate/ranged/infiltrator)
if(prob(50))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/syndicate/ranged/infiltrator)
if(RUSKY_PARTY)
var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/service/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/russian)
if(prob(75))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian)
if(prob(50))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear/russian)
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_n_take(empty_shuttle_turfs)
new /obj/effect/decal/remains/human(T)
new /obj/item/clothing/shoes/space_ninja(T)
new /obj/item/clothing/mask/balaclava(T)
for(var/i in 1 to 5)
T = pick_n_take(empty_shuttle_turfs)
new /obj/structure/spider/stickyweb(T)
if(ANTIDOTE_NEEDED)
var/obj/effect/mob_spawn/human/corpse/assistant/infected_assistant = pick(/obj/effect/mob_spawn/human/corpse/assistant/beesease_infection, /obj/effect/mob_spawn/human/corpse/assistant/brainrot_infection, /obj/effect/mob_spawn/human/corpse/assistant/spanishflu_infection)
var/turf/T
for(var/i=0, i<10, i++)
if(prob(15))
shuttle_spawns.Add(/obj/item/reagent_containers/glass/bottle)
else if(prob(15))
shuttle_spawns.Add(/obj/item/reagent_containers/syringe)
else if(prob(25))
shuttle_spawns.Add(/obj/item/shard)
T = pick_n_take(empty_shuttle_turfs)
new infected_assistant(T)
shuttle_spawns.Add(/obj/structure/closet/crate)
shuttle_spawns.Add(/obj/item/reagent_containers/glass/bottle/pierrot_throat)
shuttle_spawns.Add(/obj/item/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))
if(PIZZA_DELIVERY)
var/naughtypizza = list(/obj/item/pizzabox/bomb,/obj/item/pizzabox/margherita/robo) //oh look another blaklist, for pizza nonetheless!
var/nicepizza = list(/obj/item/pizzabox/margherita, /obj/item/pizzabox/meat, /obj/item/pizzabox/vegetable, /obj/item/pizzabox/mushroom)
for(var/i in 1 to 6)
shuttle_spawns.Add(pick(prob(5) ? naughtypizza : nicepizza))
if(ITS_HIP_TO)
var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/organic/hydroponics/beekeeping_fullkit]
pack.generate(pick_n_take(empty_shuttle_turfs))
shuttle_spawns.Add(/obj/effect/mob_spawn/human/corpse/bee_terrorist)
shuttle_spawns.Add(/obj/effect/mob_spawn/human/corpse/cargo_tech)
shuttle_spawns.Add(/obj/effect/mob_spawn/human/corpse/cargo_tech)
shuttle_spawns.Add(/obj/effect/mob_spawn/human/corpse/nanotrasensoldier)
shuttle_spawns.Add(/obj/item/gun/ballistic/automatic/pistol/no_mag)
shuttle_spawns.Add(/obj/item/gun/ballistic/automatic/pistol/m1911/no_mag)
shuttle_spawns.Add(/obj/item/honey_frame)
shuttle_spawns.Add(/obj/item/honey_frame)
shuttle_spawns.Add(/obj/item/honey_frame)
shuttle_spawns.Add(/obj/structure/beebox/unwrenched)
shuttle_spawns.Add(/obj/item/queen_bee/bought)
shuttle_spawns.Add(/obj/structure/closet/crate/hydroponics)
for(var/i in 1 to 8)
shuttle_spawns.Add(/mob/living/simple_animal/hostile/poison/bees/toxin)
for(var/i in 1 to 5)
var/decal = pick(/obj/effect/decal/cleanable/blood, /obj/effect/decal/cleanable/insectguts)
new decal(pick_n_take(empty_shuttle_turfs))
for(var/i in 1 to 10)
var/casing = /obj/item/ammo_casing/spent
new casing(pick_n_take(empty_shuttle_turfs))
if(MY_GOD_JC)
shuttle_spawns.Add(/obj/machinery/syndicatebomb/shuttle_loan)
if(prob(95))
shuttle_spawns.Add(/obj/item/paper/fluff/cargo/bomb)
else
shuttle_spawns.Add(/obj/item/paper/fluff/cargo/bomb/allyourbase)
if(DELTA_CRATES) //Delta crates can stack on eacher, and are basicly a 1/3/5 bombs
for(var/i in 1 to 7) //7 seems fair
shuttle_spawns.Add(/obj/structure/closet/crate/secure/loot)
for(var/i in 1 to 5)
var/turf/T = pick_n_take(empty_shuttle_turfs)
new /obj/structure/spider/stickyweb(T)
new /obj/effect/decal/cleanable/ash(T)
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)
//items that appear only in shuttle loan events
/obj/item/storage/belt/fannypack/yellow/bee_terrorist/PopulateContents()
new /obj/item/grenade/plastic/c4 (src)
new /obj/item/reagent_containers/pill/cyanide(src)
new /obj/item/grenade/chem_grenade/facid(src)
/obj/item/paper/fluff/bee_objectives
name = "Objectives of a Bee Liberation Front Operative"
info = "<b>Objective #1</b>. Liberate all bees on the NT transport vessel 2416/B. <b>Success!</b> <br><b>Objective #2</b>. Escape alive. <b>Failed.</b>"
/obj/machinery/syndicatebomb/shuttle_loan/Initialize()
. = ..()
setAnchored(TRUE)
timer_set = rand(480, 600) //once the supply shuttle docks (after 5 minutes travel time), players have between 3-5 minutes to defuse the bomb
activate()
update_icon()
/obj/item/paper/fluff/cargo/bomb
name = "hastly scribbled note"
info = "GOOD LUCK!"
/obj/item/paper/fluff/cargo/bomb/allyourbase
info = "Somebody set us up the bomb!"
#undef HIJACK_SYNDIE
#undef RUSKY_PARTY
#undef SPIDER_GIFT
#undef DEPARTMENT_RESUPPLY
#undef ANTIDOTE_NEEDED
#undef PIZZA_DELIVERY
#undef ITS_HIP_TO
#undef MY_GOD_JC
#undef DELTA_CRATES
+548
View File
@@ -0,0 +1,548 @@
/datum/round_event_control/spacevine
name = "Spacevine"
typepath = /datum/round_event/spacevine
weight = 15
max_occurrences = 3
min_players = 10
/datum/round_event/spacevine
fakeable = FALSE
/datum/round_event/spacevine/start()
var/list/turfs = list() //list of all the empty floor turfs in the hallway areas
var/obj/structure/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 /datum/spacevine_controller(T) //spawn a controller at turf
/datum/spacevine_mutation
var/name = ""
var/severity = 1
var/hue
var/quality
/datum/spacevine_mutation/proc/add_mutation_to_vinepiece(obj/structure/spacevine/holder)
holder.mutations |= src
holder.add_atom_colour(hue, FIXED_COLOUR_PRIORITY)
/datum/spacevine_mutation/proc/process_mutation(obj/structure/spacevine/holder)
return
/datum/spacevine_mutation/proc/process_temperature(obj/structure/spacevine/holder, temp, volume)
return
/datum/spacevine_mutation/proc/on_birth(obj/structure/spacevine/holder)
return
/datum/spacevine_mutation/proc/on_grow(obj/structure/spacevine/holder)
return
/datum/spacevine_mutation/proc/on_death(obj/structure/spacevine/holder)
return
/datum/spacevine_mutation/proc/on_hit(obj/structure/spacevine/holder, mob/hitter, obj/item/I, expected_damage)
. = expected_damage
/datum/spacevine_mutation/proc/on_cross(obj/structure/spacevine/holder, mob/crosser)
return
/datum/spacevine_mutation/proc/on_chem(obj/structure/spacevine/holder, datum/reagent/R)
return
/datum/spacevine_mutation/proc/on_eat(obj/structure/spacevine/holder, mob/living/eater)
return
/datum/spacevine_mutation/proc/on_spread(obj/structure/spacevine/holder, turf/target)
return
/datum/spacevine_mutation/proc/on_buckle(obj/structure/spacevine/holder, mob/living/buckled)
return
/datum/spacevine_mutation/proc/on_explosion(severity, target, obj/structure/spacevine/holder)
return
/datum/spacevine_mutation/light
name = "light"
hue = "#ffff00"
quality = POSITIVE
severity = 4
/datum/spacevine_mutation/light/on_grow(obj/structure/spacevine/holder)
if(holder.energy)
holder.set_light(severity, 0.3)
/datum/spacevine_mutation/toxicity
name = "toxic"
hue = "#ff00ff"
severity = 10
quality = NEGATIVE
/datum/spacevine_mutation/toxicity/on_cross(obj/structure/spacevine/holder, mob/living/crosser)
if(issilicon(crosser))
return
if(prob(severity) && istype(crosser) && !isvineimmune(crosser))
to_chat(crosser, "<span class='alert'>You accidentally touch the vine and feel a strange sensation.</span>")
crosser.adjustToxLoss(5)
/datum/spacevine_mutation/toxicity/on_eat(obj/structure/spacevine/holder, mob/living/eater)
if(!isvineimmune(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/structure/spacevine/holder)
if(explosion_severity < 3)
qdel(holder)
else
. = 1
QDEL_IN(holder, 5)
/datum/spacevine_mutation/explosive/on_death(obj/structure/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/structure/spacevine/holder, temp, volume)
return 1
/datum/spacevine_mutation/fire_proof/on_hit(obj/structure/spacevine/holder, mob/hitter, obj/item/I, expected_damage)
if(I && I.damtype == "fire")
. = 0
else
. = expected_damage
/datum/spacevine_mutation/vine_eating
name = "vine eating"
hue = "#ff7700"
quality = MINOR_NEGATIVE
/datum/spacevine_mutation/vine_eating/on_spread(obj/structure/spacevine/holder, turf/target)
var/obj/structure/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/structure/spacevine/holder, turf/target)
target.ex_act(severity, null, src) // vine immunity handled at /mob/ex_act
/datum/spacevine_mutation/aggressive_spread/on_buckle(obj/structure/spacevine/holder, mob/living/buckled)
buckled.ex_act(severity, null, src)
/datum/spacevine_mutation/transparency
name = "transparent"
hue = ""
quality = POSITIVE
/datum/spacevine_mutation/transparency/on_grow(obj/structure/spacevine/holder)
holder.set_opacity(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/structure/spacevine/holder)
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/oxygen])
return
GM.gases[/datum/gas/oxygen] = max(GM.gases[/datum/gas/oxygen] - severity * holder.energy, 0)
GAS_GARBAGE_COLLECT(GM.gases)
/datum/spacevine_mutation/nitro_eater
name = "nitrogen consuming"
hue = "#8888ff"
severity = 3
quality = NEGATIVE
/datum/spacevine_mutation/nitro_eater/process_mutation(obj/structure/spacevine/holder)
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/nitrogen])
return
GM.gases[/datum/gas/nitrogen] = max(GM.gases[/datum/gas/nitrogen] - severity * holder.energy, 0)
GAS_GARBAGE_COLLECT(GM.gases)
/datum/spacevine_mutation/carbondioxide_eater
name = "CO2 consuming"
hue = "#00ffff"
severity = 3
quality = POSITIVE
/datum/spacevine_mutation/carbondioxide_eater/process_mutation(obj/structure/spacevine/holder)
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/carbon_dioxide])
return
GM.gases[/datum/gas/carbon_dioxide] = max(GM.gases[/datum/gas/carbon_dioxide] - severity * holder.energy, 0)
GAS_GARBAGE_COLLECT(GM.gases)
/datum/spacevine_mutation/plasma_eater
name = "toxins consuming"
hue = "#ffbbff"
severity = 3
quality = POSITIVE
/datum/spacevine_mutation/plasma_eater/process_mutation(obj/structure/spacevine/holder)
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/plasma])
return
GM.gases[/datum/gas/plasma] = max(GM.gases[/datum/gas/plasma] - severity * holder.energy, 0)
GAS_GARBAGE_COLLECT(GM.gases)
/datum/spacevine_mutation/thorns
name = "thorny"
hue = "#666666"
severity = 10
quality = NEGATIVE
/datum/spacevine_mutation/thorns/on_cross(obj/structure/spacevine/holder, mob/living/crosser)
if(prob(severity) && istype(crosser) && !isvineimmune(holder))
var/mob/living/M = crosser
M.adjustBruteLoss(5)
to_chat(M, "<span class='alert'>You cut yourself on the thorny vines.</span>")
/datum/spacevine_mutation/thorns/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage)
if(prob(severity) && istype(hitter) && !isvineimmune(holder))
var/mob/living/M = hitter
M.adjustBruteLoss(5)
to_chat(M, "<span class='alert'>You cut yourself on the thorny vines.</span>")
. = expected_damage
/datum/spacevine_mutation/woodening
name = "hardened"
hue = "#997700"
quality = NEGATIVE
/datum/spacevine_mutation/woodening/on_grow(obj/structure/spacevine/holder)
if(holder.energy)
holder.density = TRUE
holder.max_integrity = 100
holder.obj_integrity = holder.max_integrity
/datum/spacevine_mutation/woodening/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage)
if(I.get_sharpness())
. = expected_damage * 0.5
else
. = expected_damage
/datum/spacevine_mutation/flowering
name = "flowering"
hue = "#0A480D"
quality = NEGATIVE
severity = 10
/datum/spacevine_mutation/flowering/on_grow(obj/structure/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/structure/spacevine/holder, mob/living/crosser)
if(prob(25))
holder.entangle(crosser)
// SPACE VINES (Note that this code is very similar to Biomass code)
/obj/structure/spacevine
name = "space vines"
desc = "An extremely expansionistic species of vine."
icon = 'icons/effects/spacevines.dmi'
icon_state = "Light1"
anchored = TRUE
density = FALSE
layer = SPACEVINE_LAYER
mouse_opacity = MOUSE_OPACITY_OPAQUE //Clicking anywhere on the turf is good enough
pass_flags = PASSTABLE | PASSGRILLE
max_integrity = 50
var/energy = 0
var/datum/spacevine_controller/master = null
var/list/mutations = list()
/obj/structure/spacevine/Initialize()
. = ..()
add_atom_colour("#ffffff", FIXED_COLOUR_PRIORITY)
/obj/structure/spacevine/examine(mob/user)
..()
var/text = "This one is a"
if(mutations.len)
for(var/A in mutations)
var/datum/spacevine_mutation/SM = A
text += " [SM.name]"
else
text += " normal"
text += " vine."
to_chat(user, text)
/obj/structure/spacevine/Destroy()
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_death(src)
if(master)
master.VineDestroyed(src)
mutations = list()
set_opacity(0)
if(has_buckled_mobs())
unbuckle_all_mobs(force=1)
return ..()
/obj/structure/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/structure/spacevine/proc/eat(mob/eater)
var/override = 0
for(var/datum/spacevine_mutation/SM in mutations)
override += SM.on_eat(src, eater)
if(!override)
qdel(src)
/obj/structure/spacevine/attacked_by(obj/item/I, mob/living/user)
var/damage_dealt = I.force
if(I.get_sharpness())
damage_dealt *= 4
if(I.damtype == BURN)
damage_dealt *= 4
for(var/datum/spacevine_mutation/SM in mutations)
damage_dealt = SM.on_hit(src, user, I, damage_dealt) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further
take_damage(damage_dealt, I.damtype, "melee", 1)
/obj/structure/spacevine/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
if(damage_amount)
playsound(src, 'sound/weapons/slash.ogg', 50, 1)
else
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/structure/spacevine/Crossed(mob/crosser)
if(isliving(crosser))
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_cross(src, crosser)
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/structure/spacevine/attack_hand(mob/user)
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_hit(src, user)
user_unbuckle_mob(user, user)
. = ..()
/obj/structure/spacevine/attack_paw(mob/living/user)
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_hit(src, user)
user_unbuckle_mob(user,user)
/obj/structure/spacevine/attack_alien(mob/living/user)
eat(user)
/datum/spacevine_controller
var/list/obj/structure/spacevine/vines
var/list/growth_queue
var/spread_multiplier = 5
var/spread_cap = 30
var/list/vine_mutations_list
var/mutativeness = 1
/datum/spacevine_controller/New(turf/location, list/muts, potency, production)
vines = list()
growth_queue = list()
spawn_spacevine_piece(location, null, muts)
START_PROCESSING(SSobj, src)
vine_mutations_list = list()
init_subtypes(/datum/spacevine_mutation/, vine_mutations_list)
if(potency != null)
mutativeness = potency / 10
if(production != null)
spread_cap *= production / 5
spread_multiplier /= production / 5
/datum/spacevine_controller/vv_get_dropdown()
. = ..()
. += "---"
.["Delete Vines"] = "?_src_=[REF(src)];[HrefToken()];purge_vines=1"
/datum/spacevine_controller/Topic(href, href_list)
if(..() || !check_rights(R_ADMIN, FALSE) || !usr.client.holder.CheckAdminHref(href, href_list))
return
if(href_list["purge_vines"])
if(alert(usr, "Are you sure you want to delete this spacevine cluster?", "Delete Vines", "Yes", "No") != "Yes")
return
DeleteVines()
/datum/spacevine_controller/proc/DeleteVines() //this is kill
QDEL_LIST(vines) //this will also qdel us
/datum/spacevine_controller/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/datum/spacevine_controller/proc/spawn_spacevine_piece(turf/location, obj/structure/spacevine/parent, list/muts)
var/obj/structure/spacevine/SV = new(location)
growth_queue += SV
vines += SV
SV.master = src
if(muts && muts.len)
for(var/datum/spacevine_mutation/M in muts)
M.add_mutation_to_vinepiece(SV)
return
if(parent)
SV.mutations |= parent.mutations
var/parentcolor = parent.atom_colours[FIXED_COLOUR_PRIORITY]
SV.add_atom_colour(parentcolor, FIXED_COLOUR_PRIORITY)
if(prob(mutativeness))
var/datum/spacevine_mutation/randmut = pick(vine_mutations_list - SV.mutations)
randmut.add_mutation_to_vinepiece(SV)
for(var/datum/spacevine_mutation/SM in SV.mutations)
SM.on_birth(SV)
location.Entered(SV)
/datum/spacevine_controller/proc/VineDestroyed(obj/structure/spacevine/S)
S.master = null
vines -= S
growth_queue -= S
if(!vines.len)
var/obj/item/seeds/kudzu/KZ = new(S.loc)
KZ.mutations |= S.mutations
KZ.set_potency(mutativeness * 10)
KZ.set_production((spread_cap / initial(spread_cap)) * 5)
qdel(src)
/datum/spacevine_controller/process()
if(!LAZYLEN(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/structure/spacevine/queue_end = list()
for(var/obj/structure/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()
SV.spread()
if(i >= length)
break
growth_queue = growth_queue + queue_end
/obj/structure/spacevine/proc/grow()
if(!energy)
src.icon_state = pick("Med1", "Med2", "Med3")
energy = 1
set_opacity(1)
else
src.icon_state = pick("Hvy1", "Hvy2", "Hvy3")
energy = 2
for(var/datum/spacevine_mutation/SM in mutations)
SM.on_grow(src)
/obj/structure/spacevine/proc/entangle_mob()
if(!has_buckled_mobs() && prob(25))
for(var/mob/living/V in src.loc)
entangle(V)
if(has_buckled_mobs())
break //only capture one mob at a time
/obj/structure/spacevine/proc/entangle(mob/living/V)
if(!V || isvineimmune(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
to_chat(V, "<span class='danger'>The vines [pick("wind", "tangle", "tighten")] around you!</span>")
buckle_mob(V, 1)
/obj/structure/spacevine/proc/spread()
var/direction = pick(GLOB.cardinals)
var/turf/stepturf = get_step(src,direction)
if (!isspaceturf(stepturf) && stepturf.Enter(src))
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/structure/spacevine, stepturf))
if(master)
master.spawn_spacevine_piece(stepturf, src)
/obj/structure/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/structure/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)
/obj/structure/spacevine/CanPass(atom/movable/mover, turf/target)
if(isvineimmune(mover))
. = TRUE
else
. = ..()
/proc/isvineimmune(atom/A)
. = FALSE
if(isliving(A))
var/mob/living/M = A
if(("vines" in M.faction) || ("plants" in M.faction))
. = TRUE
+40
View File
@@ -0,0 +1,40 @@
/datum/round_event_control/spider_infestation
name = "Spider Infestation"
typepath = /datum/round_event/spider_infestation
weight = 5
gamemode_blacklist = list("dynamic")
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(fake)
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", "aliens")
/datum/round_event/spider_infestation/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in GLOB.machines)
if(QDELETED(temp_vent))
continue
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
var/datum/pipeline/temp_vent_parent = temp_vent.parents[1]
if(temp_vent_parent.other_atmosmch.len > 20)
vents += temp_vent
while((spawncount >= 1) && vents.len)
var/obj/vent = pick(vents)
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)
vents -= vent
spawncount--
+214
View File
@@ -0,0 +1,214 @@
/datum/round_event_control/vent_clog
name = "Clogged Vents: Normal"
typepath = /datum/round_event/vent_clog
weight = 10
max_occurrences = 3
gamemode_blacklist = list("dynamic")
min_players = 25
/datum/round_event/vent_clog
announceWhen = 1
startWhen = 5
endWhen = 35
var/interval = 2
var/list/vents = list()
var/randomProbability = 1
var/reagentsAmount = 100
var/list/saferChems = list(
"water",
"carbon",
"flour",
"cleaner",
"nutriment",
"condensedcapsaicin",
"mushroomhallucinogen",
"lube",
"pink_glitter",
"cryptobiolin",
"plantbgone",
"blood",
"charcoal",
"space_drugs",
"morphine",
"holywater",
"ethanol",
"hot_coco",
"sacid",
"mindbreaker",
"rotatium",
"bluespace",
"pax",
"laughter",
"concentrated_barbers_aid",
"colorful_reagent",
"dizzysolution",
"tiresolution",
"sodiumchloride",
"beer",
"hair_dye",
"sugar",
"white_glitter",
"growthserum",
"cornoil",
"uranium",
"carpet",
"firefighting_foam",
"semen",
"femcum",
"tearjuice",
"strange_reagent"
)
//needs to be chemid unit checked at some point
/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(120, 180)
for(var/obj/machinery/atmospherics/components/unary/vent_scrubber/temp_vent in GLOB.machines)
var/turf/T = get_turf(temp_vent)
var/area/A = T.loc
if(T && is_station_level(T.z) && !temp_vent.welded && !A.safe)
vents += temp_vent
if(!vents.len)
return kill()
/datum/round_event/vent_clog/tick()
if(!vents.len)
return kill()
CHECK_TICK
var/obj/machinery/atmospherics/components/unary/vent = pick(vents)
vents -= vent
if(!vent || vent.welded)
return
var/turf/T = get_turf(vent)
if(!T)
return
var/datum/reagents/R = new/datum/reagents(1000)
R.my_atom = vent
if (prob(randomProbability))
R.add_reagent(get_random_reagent_id(), reagentsAmount)
else
R.add_reagent(pick(saferChems), reagentsAmount)
var/datum/effect_system/smoke_spread/chem/smoke_machine/C = new
C.set_up(R,16,1,T)
C.start()
playsound(T, 'sound/effects/smoke.ogg', 50, 1, -3)
/datum/round_event_control/vent_clog/threatening
name = "Clogged Vents: Threatening"
typepath = /datum/round_event/vent_clog/threatening
weight = 4
min_players = 35
max_occurrences = 1
earliest_start = 35 MINUTES
/datum/round_event/vent_clog/threatening
randomProbability = 10
reagentsAmount = 200
/datum/round_event_control/vent_clog/catastrophic
name = "Clogged Vents: Catastrophic"
typepath = /datum/round_event/vent_clog/catastrophic
weight = 2
min_players = 45
max_occurrences = 1
earliest_start = 45 MINUTES
/datum/round_event/vent_clog/catastrophic
randomProbability = 30
reagentsAmount = 250
/datum/round_event_control/vent_clog/beer
name = "Clogged Vents: Beer"
typepath = /datum/round_event/vent_clog/beer
max_occurrences = 0
/datum/round_event/vent_clog/beer
reagentsAmount = 100
/datum/round_event_control/vent_clog/plasma_decon
name = "Anti-Plasma Flood"
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")
/datum/round_event/vent_clog/beer/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("beer", 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/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("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("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")
/datum/round_event/vent_clog/plasma_decon/start()
for(var/obj/machinery/atmospherics/components/unary/vent in vents)
if(vent && vent.loc && !vent.welded)
var/datum/effect_system/smoke_spread/freezing/decon/smoke = new
smoke.set_up(7, get_turf(vent), 7)
smoke.start()
CHECK_TICK
+61
View File
@@ -0,0 +1,61 @@
/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 MINUTES
can_be_midround_wizard = FALSE
//Note about adding items to this: Because of how NODROP_1 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/loadout[SLOTS_AMT]
var/ruins_spaceworthiness
var/ruins_wizard_loadout
switch(item_set)
if("wizardmimic")
loadout[SLOT_WEAR_SUIT] = /obj/item/clothing/suit/wizrobe
loadout[SLOT_SHOES] = /obj/item/clothing/shoes/sandal/magic
loadout[SLOT_HEAD] = /obj/item/clothing/head/wizard
ruins_spaceworthiness = 1
if("swords")
loadout[SLOT_HANDS] = /obj/item/katana/cursed
if("bigfatdoobie")
loadout[SLOT_WEAR_MASK] = /obj/item/clothing/mask/cigarette/rollie/trippy
ruins_spaceworthiness = 1
if("boxing")
loadout[SLOT_WEAR_MASK] = /obj/item/clothing/mask/luchador
loadout[SLOT_GLOVES] = /obj/item/clothing/gloves/boxing
ruins_spaceworthiness = 1
if("voicemodulators")
loadout[SLOT_WEAR_MASK] = /obj/item/clothing/mask/chameleon
if("catgirls2015")
loadout[SLOT_HEAD] = /obj/item/clothing/head/kitty
ruins_spaceworthiness = 1
ruins_wizard_loadout = 1
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
if(ruins_spaceworthiness && !is_station_level(H.z) || isspaceturf(H.loc) || isplasmaman(H))
continue //#savetheminers
if(ruins_wizard_loadout && iswizard(H))
continue
if(item_set == "catgirls2015") //Wizard code means never having to say you're sorry
H.gender = FEMALE
for(var/i in 1 to loadout.len)
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.dropItemToGround(H.get_item_by_slot(i), TRUE)
H.equip_to_slot_or_del(I, i)
ADD_TRAIT(I, TRAIT_NODROP, CURSED_ITEM_TRAIT)
I.item_flags |= DROPDEL
I.name = "cursed " + I.name
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(0, H.loc)
smoke.start()
@@ -0,0 +1,56 @@
/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 MINUTES
can_be_midround_wizard = FALSE // not removing it completely yet
/datum/round_event/wizard/deprevolt/start()
var/list/tidecolor
var/list/jobs_to_revolt = list()
var/nation_name
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_name = 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_name = pick("Mede", "Healtha", "Recova", "Chemi", "Geneti", "Viro", "Psych")
if("yellow")
jobs_to_revolt = list("Chief Engineer", "Station Engineer", "Atmospheric Technician")
nation_name = pick("Atomo", "Engino", "Power", "Teleco")
if("purple")
jobs_to_revolt = list("Research Director","Scientist", "Roboticist")
nation_name = pick("Sci", "Griffa", "Explosi", "Mecha", "Xeno")
if("brown")
jobs_to_revolt = list("Quartermaster", "Cargo Technician", "Shaft Miner")
nation_name = 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_name = pick("Honka", "Boozo", "Fatu", "Danka", "Mimi", "Libra", "Jani", "Religi")
nation_name += pick("stan", "topia", "land", "nia", "ca", "tova", "dor", "ador", "tia", "sia", "ano", "tica", "tide", "cis", "marea", "co", "taoide", "slavia", "stotzka")
var/datum/team/nation/nation = new
nation.name = nation_name
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
if(H.mind)
var/datum/mind/M = H.mind
if(M.assigned_role && !(M.has_antag_datum(/datum/antagonist)))
for(var/job in jobs_to_revolt)
if(M.assigned_role == job)
citizens += H
M.add_antag_datum(/datum/antagonist/separatist,nation)
H.log_message("Was made into a separatist, long live [nation_name]!", LOG_ATTACK, color="red")
if(citizens.len)
var/message
for(var/job in jobs_to_revolt)
message += "[job],"
message_admins("The nation of [nation_name] has been formed. Affected jobs are [message]")
+102
View File
@@ -0,0 +1,102 @@
/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 MINUTES
/datum/round_event/wizard/greentext/start()
var/list/holder_canadates = GLOB.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/greentext(H.loc)
to_chat(H, "<font color='green'>The mythical greentext appear at your feet! Pick it up if you dare...</font>")
/obj/item/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 = WEIGHT_CLASS_BULKY
icon = 'icons/obj/wizard.dmi'
icon_state = "greentext"
var/mob/living/last_holder
var/mob/living/new_holder
var/list/color_altered_mobs = list()
var/datum/callback/roundend_callback
resistance_flags = FIRE_PROOF | ACID_PROOF
var/quiet = FALSE
/obj/item/greentext/Initialize(mapload)
. = ..()
GLOB.poi_list |= src
roundend_callback = CALLBACK(src,.proc/check_winner)
SSticker.OnRoundend(roundend_callback)
/obj/item/greentext/equipped(mob/living/user as mob)
to_chat(user, "<font color='green'>So long as you leave this place with greentext in hand you know will be happy...</font>")
var/list/other_objectives = user.mind.get_all_objectives()
if(user.mind && other_objectives.len > 0)
to_chat(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.add_atom_colour("#00FF00", ADMIN_COLOUR_PRIORITY)
START_PROCESSING(SSobj, src)
..()
/obj/item/greentext/dropped(mob/living/user as mob)
if(user in color_altered_mobs)
to_chat(user, "<span class='warning'>A sudden wave of failure washes over you...</span>")
user.add_atom_colour("#FF0000", ADMIN_COLOUR_PRIORITY) //ya blew it
last_holder = null
new_holder = null
STOP_PROCESSING(SSobj, src)
..()
/obj/item/greentext/proc/check_winner()
if(!new_holder)
return
if(is_centcom_level(new_holder.z))//you're winner!
to_chat(new_holder, "<font color='green'>At last it feels like victory is assured!</font>")
new_holder.mind.add_antag_datum(/datum/antagonist/greentext)
new_holder.log_message("won with greentext!!!", LOG_ATTACK, color="green")
color_altered_mobs -= new_holder
resistance_flags |= ON_FIRE
qdel(src)
/obj/item/greentext/process()
if(last_holder && last_holder != new_holder) //Somehow it was swiped without ever getting dropped
to_chat(last_holder, "<span class='warning'>A sudden wave of failure washes over you...</span>")
last_holder.add_atom_colour("#FF0000", ADMIN_COLOUR_PRIORITY)
last_holder = new_holder //long live the king
/obj/item/greentext/Destroy(force)
if(!(resistance_flags & ON_FIRE) && !force)
return QDEL_HINT_LETMELIVE
SSticker.round_end_events -= roundend_callback
GLOB.poi_list.Remove(src)
for(var/i in GLOB.player_list)
var/mob/M = i
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"
if(M.color == "#FF0000" || M.color == "#00FF00")
M.remove_atom_colour(ADMIN_COLOUR_PRIORITY)
message += "...</span>"
// can't skip the mob check as it also does the decolouring
if(!quiet)
to_chat(M, message)
. = ..()
/obj/item/greentext/quiet
quiet = TRUE
+57
View File
@@ -0,0 +1,57 @@
/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 MINUTES
/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(fake)
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/carpspawn/C in GLOB.landmarks_list)
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
gold_core_spawnable = NO_SPAWN
var/allowed_projectile_types = list(/obj/item/projectile/magic/change, /obj/item/projectile/magic/animate, /obj/item/projectile/magic/resurrection,
/obj/item/projectile/magic/death, /obj/item/projectile/magic/teleport, /obj/item/projectile/magic/door, /obj/item/projectile/magic/aoe/fireball,
/obj/item/projectile/magic/spellblade, /obj/item/projectile/magic/arcane_barrage)
/mob/living/simple_animal/hostile/carp/ranged/Initialize()
projectiletype = pick(allowed_projectile_types)
. = ..()
/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(allowed_projectile_types)
..()
+59
View File
@@ -0,0 +1,59 @@
/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 MINUTES
can_be_midround_wizard = FALSE
/datum/round_event/wizard/race
var/list/stored_name
var/list/stored_species
var/list/stored_dna
/datum/round_event/wizard/race/setup()
stored_name = list()
stored_species = list()
stored_dna = list()
endWhen = rand(600,1200) //10 to 20 minutes
..()
/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 && !S.blacklisted && !S.nojumpsuit) //Dangerous Species, Blacklisted Species, and Species who can't wear jumpsuits are blacklisted.
all_species += speciestype
var/datum/species/new_species = pick(all_species)
if(prob(75))
all_the_same = 1
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
var/turf/T = get_turf(H)
if(!T)
continue
if(!is_station_level(T.z))
continue
stored_name[H] = H.real_name
stored_species[H] = H.dna.species
stored_dna[H] = H.dna.unique_enzymes
H.set_species(new_species)
H.real_name = H.dna.species.random_name(H.gender,1)
H.dna.unique_enzymes = H.dna.generate_unique_enzymes()
to_chat(H, "<span class='notice'>You feel somehow... different?</span>")
if(!all_the_same)
new_species = pick(all_species)
/datum/round_event/wizard/race/end()
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
if(!(stored_name[H] && stored_species[H] && stored_dna[H]))
continue
H.set_species(stored_species[H])
H.real_name = stored_name[H]
H.dna.unique_enzymes = stored_dna[H]
to_chat(H, "<span class='notice'>You feel back to your normal self again.</span>")
+53
View File
@@ -0,0 +1,53 @@
/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 MINUTES
/datum/round_event/wizard/rpgloot/start()
var/upgrade_scroll_chance = 0
for(var/obj/item/I in world)
CHECK_TICK
if(!(I.flags_1 & INITIALIZED_1))
continue
I.AddComponent(/datum/component/fantasy)
if(istype(I, /obj/item/storage))
var/obj/item/storage/S = I
var/datum/component/storage/STR = S.GetComponent(/datum/component/storage)
if(prob(upgrade_scroll_chance) && S.contents.len < STR.max_items && !S.invisibility)
var/obj/item/upgradescroll/scroll = new
SEND_SIGNAL(S, COMSIG_TRY_STORAGE_INSERT, scroll, null, TRUE, TRUE)
upgrade_scroll_chance = max(0,upgrade_scroll_chance-100)
upgrade_scroll_chance += 25
GLOB.rpg_loot_items = TRUE
/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 = WEIGHT_CLASS_TINY
var/upgrade_amount = 1
var/can_backfire = TRUE
var/uses = 1
/obj/item/upgradescroll/afterattack(obj/item/target, mob/user , proximity)
. = ..()
if(!proximity || !istype(target))
return
target.AddComponent(/datum/component/fantasy, upgrade_amount, null, null, can_backfire, TRUE)
if(--uses <= 0)
qdel(src)
/obj/item/upgradescroll/unlimited
name = "unlimited foolproof item fortification scroll"
desc = "Somehow, this piece of paper can be applied to items to make them \"better\". This scroll is made from the tongues of dead paper wizards, and can be used an unlimited number of times, with no drawbacks."
uses = INFINITY
can_backfire = FALSE
+107
View File
@@ -0,0 +1,107 @@
/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 MINUTES
can_be_midround_wizard = FALSE // not removing it completely yet
/datum/round_event/wizard/shuffleloc/start()
var/list/moblocs = list()
var/list/mobs = list()
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
if(!is_station_level(H.z))
continue //lets not try to strand people in space or stuck in the wizards den
moblocs += H.loc
mobs += H
if(!mobs)
return
shuffle_inplace(moblocs)
shuffle_inplace(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], channel = TELEPORT_CHANNEL_MAGIC)
moblocs.len -= 1
for(var/mob/living/carbon/human/H in GLOB.alive_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 MINUTES
can_be_midround_wizard = FALSE // not removing it completely yet
/datum/round_event/wizard/shufflenames/start()
var/list/mobnames = list()
var/list/mobs = list()
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
mobnames += H.real_name
mobs += H
if(!mobs)
return
shuffle_inplace(mobnames)
shuffle_inplace(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 GLOB.alive_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 MINUTES
can_be_midround_wizard = FALSE // not removing it completely yet
/datum/round_event/wizard/shuffleminds/start()
var/list/mobs = list()
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
if(H.stat || !H.mind || iswizard(H))
continue //the wizard(s) are spared on this one
mobs += H
if(!mobs)
return
shuffle_inplace(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 GLOB.alive_mob_list)
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(0, H.loc)
smoke.start()
+31
View File
@@ -0,0 +1,31 @@
/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 MINUTES
can_be_midround_wizard = FALSE // not removing it completely yet
/datum/round_event_control/wizard/summonguns/New()
if(CONFIG_GET(flag/no_summon_guns))
weight = 0
..()
/datum/round_event/wizard/summonguns/start()
rightandwrong(SUMMON_GUNS, null, 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 MINUTES
can_be_midround_wizard = FALSE // not removing it completely yet
/datum/round_event_control/wizard/summonmagic/New()
if(CONFIG_GET(flag/no_summon_magic))
weight = 0
..()
/datum/round_event/wizard/summonmagic/start()
rightandwrong(SUMMON_MAGIC, null, 10)
+66
View File
@@ -0,0 +1,66 @@
/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(is_station_level(T.z))
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, 0, null, FALSE)
/datum/round_event/wormholes/announce(fake)
priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", "spanomalies")
/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.forceMove(T)
/datum/round_event/wormholes/end()
QDEL_LIST(wormholes)
wormholes = null
/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"
mech_sized = TRUE
/obj/effect/portal/wormhole/teleport(atom/movable/M)
if(iseffect(M)) //sparks don't teleport
return
if(M.anchored)
if(!(ismecha(M) && mech_sized))
return
if(ismovableatom(M))
if(GLOB.portals.len)
var/obj/effect/portal/P = pick(GLOB.portals)
if(P && isturf(P.loc))
hard_target = P.loc
if(!hard_target)
return
do_teleport(M, hard_target, 1, 1, 0, 0, channel = TELEPORT_CHANNEL_WORMHOLE) ///You will appear adjacent to the beacon