diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 034a70fa903..ab68ad15b56 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -283,32 +283,12 @@ proc/isInSight(var/atom/A, var/atom/B)
// Will return a list of active candidates. It increases the buffer 5 times until it finds a candidate which is active within the buffer.
-/proc/get_active_candidates(var/buffer = 1)
-
- var/list/candidates = list() //List of candidate KEYS to assume control of the new larva ~Carn
- var/i = 0
- while(candidates.len <= 0 && i < 5)
- for(var/mob/dead/observer/G in player_list)
- if(((G.client.inactivity/10)/60) <= buffer + i) // the most active players are more likely to become an alien
- if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
- candidates += G.key
- i++
- return candidates
-
-// Same as above but for alien candidates.
-
-/proc/get_alien_candidates()
-
- var/list/candidates = list() //List of candidate KEYS to assume control of the new larva ~Carn
- var/i = 0
- while(candidates.len <= 0 && i < 5)
- for(var/mob/dead/observer/G in player_list)
- if(G.client.prefs.be_special & BE_ALIEN)
- if(((G.client.inactivity/10)/60) <= ALIEN_SELECT_AFK_BUFFER + i) // the most active players are more likely to become an alien
- if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
- candidates += G.key
- i++
- return candidates
+/proc/get_candidates(be_special_flag=0)
+ . = list()
+ for(var/mob/dead/observer/G in player_list)
+ if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
+ if(!G.client.is_afk() && (G.client.prefs.be_special & be_special_flag))
+ . += G.client
/proc/get_apprentice_candidates()
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 9c9e2ac2b72..8ca0d0c808f 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -16,6 +16,8 @@ var/global/list/chemical_reagents_list //list of all /datum/reagent datums in
var/global/list/landmarks_list = list() //list of all landmarks created
var/global/list/surgeries_list = list() //list of all surgeries by name, associated with their path.
+var/global/list/portals = list() //for use by portals
+
//Preferences stuff
//Hairstyles
var/global/list/hair_styles_list = list() //stores /datum/sprite_accessory/hair indexed by name
diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm
index 5f018feb152..70cf55ecbf6 100644
--- a/code/__HELPERS/lists.dm
+++ b/code/__HELPERS/lists.dm
@@ -127,12 +127,11 @@ proc/listclearnulls(list/list)
return null
//Pick a random element from the list and remove it from the list.
-/proc/pick_n_take(list/listfrom)
- if (listfrom.len > 0)
- var/picked = pick(listfrom)
- listfrom -= picked
- return picked
- return null
+/proc/pick_n_take(list/L)
+ if(L.len)
+ var/picked = rand(1,L.len)
+ . = L[picked]
+ L.Cut(picked,picked+1) //Cut is far more efficient that Remove()
//Returns the top(last) element from the list and removes it from the list (typical stack function)
/proc/pop(list/listfrom)
diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm
index 7dd535a2fe9..be838d3b607 100644
--- a/code/__HELPERS/names.dm
+++ b/code/__HELPERS/names.dm
@@ -56,7 +56,7 @@ var/religion_name = null
station_name = name + " "
// Prefix
- switch(Holiday)
+ switch(events.holiday)
//get normal name
if(null,"",0)
name = pick("", "Stanford", "Dorf", "Alium", "Prefix", "Clowning", "Aegis", "Ishimura", "Scaredy", "Death-World", "Mime", "Honk", "Rogue", "MacRagge", "Ultrameens", "Safety", "Paranoia", "Explosive", "Neckbear", "Donk", "Muppet", "North", "West", "East", "South", "Slant-ways", "Widdershins", "Rimward", "Expensive", "Procreatory", "Imperial", "Unidentified", "Immoral", "Carp", "Ork", "Pete", "Control", "Nettle", "Aspie", "Class", "Crab", "Fist","Corrogated","Skeleton","Race", "Fatguy", "Gentleman", "Capitalist", "Communist", "Bear", "Beard", "Derp", "Space", "Spess", "Star", "Moon", "System", "Mining", "Neckbeard", "Research", "Supply", "Military", "Orbital", "Battle", "Science", "Asteroid", "Home", "Production", "Transport", "Delivery", "Extraplanetary", "Orbital", "Correctional", "Robot", "Hats", "Pizza")
@@ -70,8 +70,8 @@ var/religion_name = null
random = 13
else
//get the first word of the Holiday and use that
- var/i = findtext(Holiday," ",1,0)
- name = copytext(Holiday,1,i)
+ var/i = findtext(events.holiday," ",1,0)
+ name = copytext(events.holiday,1,i)
station_name += name + " "
// Suffix
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index af56730988e..195e9b0f1ee 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -38,6 +38,7 @@
var/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1.
var/Ticklag = 0.9
var/Tickcomp = 0
+ var/allow_holidays = 0 //toggles whether holiday-specific content should be used
var/list/mode_names = list()
var/list/modes = list() // allowed modes
@@ -344,7 +345,7 @@
config.popup_admin_pm = 1
if("allow_holidays")
- Holiday = 1
+ config.allow_holidays = 1
if("useircbot")
useircbot = 1
diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm
index 89313953106..1cb55a3ef99 100644
--- a/code/controllers/master_controller.dm
+++ b/code/controllers/master_controller.dm
@@ -38,7 +38,10 @@ datum/controller/game_controller/New()
del(master_controller)
master_controller = src
- createRandomZlevel()
+ createRandomZlevel() //probably shouldn't be here!
+
+ if(!events)
+ new /datum/controller/event()
if(!air_master)
air_master = new /datum/controller/air_system()
@@ -173,7 +176,8 @@ datum/controller/game_controller/proc/process()
//EVENTS
timer = world.timeofday
- process_events()
+ last_thing_processed = /datum/event
+ events.process()
events_cost = (world.timeofday - timer) / 10
//TICKER
@@ -274,18 +278,6 @@ datum/controller/game_controller/proc/process_powernets()
continue
powernets.Cut(i,i+1)
-datum/controller/game_controller/proc/process_events()
- last_thing_processed = /datum/event
- var/i = 1
- while(i<=events.len)
- var/datum/event/Event = events[i]
- if(Event)
- Event.process()
- i++
- continue
- events.Cut(i,i+1)
- checkEvent()
-
datum/controller/game_controller/proc/Recover() //Mostly a placeholder for now.
var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n"
for(var/varname in master_controller.vars)
diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm
index d659d2fa68c..413759cc377 100644
--- a/code/controllers/verbs.dm
+++ b/code/controllers/verbs.dm
@@ -28,7 +28,7 @@
return
-/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply Shuttle","Emergency Shuttle","Configuration","pAI", "Cameras"))
+/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply Shuttle","Emergency Shuttle","Configuration","pAI", "Cameras", "Events"))
set category = "Debug"
set name = "Debug Controller"
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
@@ -74,5 +74,8 @@
if("Cameras")
debug_variables(cameranet)
feedback_add_details("admin_verb","DCameras")
+ if("Events")
+ debug_variables(events)
+ feedback_add_details("admin_verb","DEvents")
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
return
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index cb67c3f5f17..b04284947b1 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -135,7 +135,7 @@
/datum/teleport/instant/science
setEffects(datum/effect/effect/system/aeffectin,datum/effect/effect/system/aeffectout)
- if(!aeffectin || !aeffectout)
+ if(aeffectin==null || aeffectout==null)
var/datum/effect/effect/system/spark_spread/aeffect = new
aeffect.set_up(5, 1, teleatom)
effectin = effectin || aeffect
@@ -182,4 +182,4 @@
if(destination.z > 7) //Away mission z-levels
return 0
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index c6c0c8f588b..d43ee0560e5 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -57,19 +57,27 @@ datum/mind
proc/transfer_to(mob/living/new_character)
if(!istype(new_character))
- world.log << "## DEBUG: transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob. Please inform Carn"
+ error("transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob. Please inform Carn")
+
if(current) //remove ourself from our old body's mind variable
if(changeling)
current.remove_changeling_powers()
current.verbs -= /datum/changeling/proc/EvolutionMenu
current.mind = null
- if(new_character.mind) //remove any mind currently in our new body's mind variable
+
+ if(key)
+ if(new_character.key != key) //if we're transfering into a body with a key associated which is not ours
+ new_character.ghostize(1) //we'll need to ghostize so that key isn't mobless.
+ else
+ key = new_character.key
+
+ if(new_character.mind) //disassociate any mind currently in our new body's mind variable
new_character.mind.current = null
- current = new_character //link ourself to our new body
- new_character.mind = src //and link our new body to ourself
+ current = new_character //associate ourself with our new body
+ new_character.mind = src //and associate our new body with ourself
- if(changeling)
+ if(changeling) //if we are a changeling mind, re-add any powers
new_character.make_changeling()
if(active)
@@ -78,19 +86,20 @@ datum/mind
proc/store_memory(new_text)
memory += "[new_text]
"
- proc/show_memory(mob/recipient)
- var/output = "[current.real_name]'s Memory
"
+ proc/show_memory(mob/recipient, window=1)
+ if(!recipient)
+ recipient = current
+ var/output = "[current.real_name]'s Memories:
"
output += memory
- if(objectives.len>0)
- output += "
Objectives:"
-
+ if(objectives.len)
+ output += "Objectives:"
var/obj_count = 1
for(var/datum/objective/objective in objectives)
- output += "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
+ output += "
Objective #[obj_count++]: [objective.explanation_text]"
- recipient << browse(output,"window=memory")
+ if(window) recipient << browse(output,"window=memory")
+ else recipient << "[output]"
proc/edit_memory()
if(!ticker || !ticker.mode)
@@ -1087,13 +1096,14 @@ datum/mind
/mob/living/proc/mind_initialize()
if(mind)
mind.key = key
+
else
mind = new /datum/mind(key)
mind.original = src
if(ticker)
ticker.minds += mind
else
- world.log << "## DEBUG: mind_initialize(): No ticker ready yet! Please inform Carn"
+ error("mind_initialize(): No ticker ready yet! Please inform Carn")
if(!mind.name) mind.name = real_name
mind.current = src
diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm
index 4b56a680aee..dcd0bd64ff6 100644
--- a/code/game/gamemodes/events.dm
+++ b/code/game/gamemodes/events.dm
@@ -1,3 +1,6 @@
+
+
+/*
/proc/start_events()
//changed to a while(1) loop since they are more efficient.
//Moved the spawn in here to allow it to be called with advance proc call if it crashes.
@@ -18,7 +21,8 @@
else
event = 0
sleep(1200)
-
+*/
+/*
/proc/event()
event = 1
@@ -39,38 +43,6 @@
meteor_wave()
spawn_meteors()
- if(2)
- command_alert("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert")
- for(var/mob/M in player_list)
- if(!istype(M,/mob/new_player))
- M << sound('sound/AI/granomalies.ogg')
- var/turf/T = pick(blobstart)
- var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 )
- spawn(rand(50, 300))
- del(bh)
- /*
- if(3) //Leaving the code in so someone can try and delag it, but this event can no longer occur randomly, per SoS's request. --NEO
- command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert")
- world << sound('sound/AI/spanomalies.ogg')
- var/list/turfs = new
- var/turf/picked
- for(var/turf/simulated/floor/T in world)
- if(T.z == 1)
- turfs += T
- for(var/turf/simulated/floor/T in turfs)
- if(prob(20))
- spawn(50+rand(0,3000))
- picked = pick(turfs)
- var/obj/effect/portal/P = new /obj/effect/portal( T )
- P.target = picked
- P.creator = null
- P.icon = 'icons/obj/objects.dmi'
- P.failchance = 0
- P.icon_state = "anom"
- P.name = "wormhole"
- spawn(rand(300,600))
- del(P)
- */
if(3)
if((world.time/10)>=3600 && toggle_space_ninja && !sent_ninja_to_station)//If an hour has passed, relatively speaking. Also, if ninjas are allowed to spawn and if there is not already a ninja for the round.
space_ninja_arrival()//Handled in space_ninja.dm. Doesn't announce arrival, all sneaky-like.
@@ -99,18 +71,7 @@
spacevine_infestation()
if(15)
communications_blackout()
-
-/proc/communications_blackout(var/silent = 1)
-
- if(!silent)
- command_alert("Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT")
- else // AIs will always know if there's a comm blackout, rogue AIs could then lie about comm blackouts in the future while they shutdown comms
- for(var/mob/living/silicon/ai/A in player_list)
- A << "
"
- A << "Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT"
- A << "
"
- for(var/obj/machinery/telecomms/T in telecomms_list)
- T.emp_act(1)
+*/
/proc/power_failure()
command_alert("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")
@@ -197,773 +158,3 @@
S.updateicon()
S.power_change()
-/proc/appendicitis()
- for(var/mob/living/carbon/human/H in living_mob_list)
- var/foundAlready = 0 // don't infect someone that already has the virus
- for(var/datum/disease/D in H.viruses)
- foundAlready = 1
- if(H.stat == 2 || foundAlready)
- continue
-
- var/datum/disease/D = new /datum/disease/appendicitis
- D.holder = H
- D.affected_mob = H
- H.viruses += D
- break
-
-/proc/viral_outbreak(var/virus = null)
-// command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
-// world << sound('sound/AI/outbreak7.ogg')
- var/virus_type
- if(!virus)
- virus_type = pick(/datum/disease/dnaspread,/datum/disease/advance/flu,/datum/disease/advance/cold,/datum/disease/brainrot,/datum/disease/magnitis,/datum/disease/pierrot_throat)
- else
- switch(virus)
- if("fake gbs")
- virus_type = /datum/disease/fake_gbs
- if("gbs")
- virus_type = /datum/disease/gbs
- if("magnitis")
- virus_type = /datum/disease/magnitis
- if("rhumba beat")
- virus_type = /datum/disease/rhumba_beat
- if("brain rot")
- virus_type = /datum/disease/brainrot
- if("cold")
- virus_type = /datum/disease/advance/cold
- if("retrovirus")
- virus_type = /datum/disease/dnaspread
- if("flu")
- virus_type = /datum/disease/advance/flu
-// if("t-virus")
-// virus_type = /datum/disease/t_virus
- if("pierrot's throat")
- virus_type = /datum/disease/pierrot_throat
- for(var/mob/living/carbon/human/H in shuffle(living_mob_list))
-
- var/foundAlready = 0 // don't infect someone that already has the virus
- var/turf/T = get_turf(H)
- if(!T)
- continue
- if(T.z != 1)
- continue
- for(var/datum/disease/D in H.viruses)
- foundAlready = 1
- if(H.stat == 2 || foundAlready)
- continue
-
- if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
- if((!H.dna) || (H.sdisabilities & BLIND)) //A blindness disease would be the worst.
- continue
- var/datum/disease/dnaspread/D = new
- D.strain_data["name"] = H.real_name
- D.strain_data["UI"] = H.dna.uni_identity
- D.strain_data["SE"] = H.dna.struc_enzymes
- D.carrier = 1
- D.holder = H
- D.affected_mob = H
- H.viruses += D
- break
- else
- var/datum/disease/D = new virus_type
- D.carrier = 1
- D.holder = H
- D.affected_mob = H
- H.viruses += D
- break
- spawn(rand(1500, 3000)) //Delayed announcements to keep the crew on their toes.
- command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
- for(var/mob/M in player_list)
- M << sound('sound/AI/outbreak7.ogg')
-
-/proc/alien_infestation(var/spawncount = 1) // -- TLE
- //command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert")
- //world << sound('sound/AI/aliens.ogg')
- var/list/vents = list()
- for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world)
- if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network)
- if(temp_vent.network.normal_members.len > 50) // Stops Aliens getting stuck in small networks. See: Security, Virology
- vents += temp_vent
-
- var/list/candidates = get_alien_candidates()
-
- if(prob(40)) spawncount++ //sometimes, have two larvae spawn instead of one
- while((spawncount >= 1) && vents.len && candidates.len)
-
- var/obj/vent = pick(vents)
- var/candidate = pick(candidates)
-
- var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc)
- new_xeno.key = candidate
-
- candidates -= candidate
- vents -= vent
- spawncount--
-
- spawn(rand(5000, 6000)) //Delayed announcements to keep the crew on their toes.
- command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert")
- for(var/mob/M in player_list)
- M << sound('sound/AI/aliens.ogg')
-
-/proc/high_radiation_event()
-
-/* // Haha, this is way too laggy. I'll keep the prison break though.
- for(var/obj/machinery/light/L in world)
- if(L.z != 1) continue
- L.flicker(50)
-
- sleep(100)
-*/
- for(var/mob/living/carbon/human/H in living_mob_list)
- var/turf/T = get_turf(H)
- if(!T)
- continue
- if(T.z != 1)
- continue
- if(istype(H,/mob/living/carbon/human))
- H.apply_effect((rand(15,75)),IRRADIATE,0)
- if (prob(5))
- H.apply_effect((rand(90,150)),IRRADIATE,0)
- if (prob(25))
- if (prob(75))
- randmutb(H)
- domutcheck(H,null,1)
- else
- randmutg(H)
- domutcheck(H,null,1)
- for(var/mob/living/carbon/monkey/M in living_mob_list)
- var/turf/T = get_turf(M)
- if(!T)
- continue
- if(T.z != 1)
- continue
- M.apply_effect((rand(15,75)),IRRADIATE,0)
- sleep(100)
- command_alert("High levels of radiation detected near the station. Please report to the Med-bay if you feel strange.", "Anomaly Alert")
- for(var/mob/M in player_list)
- M << sound('sound/AI/radiation.ogg')
-
-
-
-//Changing this to affect the main station. Blame Urist. --Pete
-/proc/prison_break() // -- Callagan
-
-
- var/list/area/areas = list()
- for(var/area/A in world)
- if(istype(A, /area/security/prison) || istype(A, /area/security/brig))
- areas += A
-
- if(areas && areas.len > 0)
-
- for(var/area/A in areas)
- for(var/obj/machinery/light/L in A)
- L.flicker(10)
-
- sleep(100)
-
- for(var/area/A in areas)
- for (var/obj/machinery/power/apc/temp_apc in A)
- temp_apc.overload_lighting()
-
- for (var/obj/structure/closet/secure_closet/brig/temp_closet in A)
- temp_closet.locked = 0
- temp_closet.icon_state = temp_closet.icon_closed
-
- for (var/obj/machinery/door/airlock/security/temp_airlock in A)
- spawn(0) temp_airlock.prison_open()
-
- for (var/obj/machinery/door/airlock/glass_security/temp_glassairlock in A)
- spawn(0) temp_glassairlock.prison_open()
-
- for (var/obj/machinery/door_timer/temp_timer in A)
- temp_timer.releasetime = 1
-
- sleep(150)
- command_alert("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert")
- else
- world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area."
-
-/proc/carp_migration() // -- Darem
- for(var/obj/effect/landmark/C in landmarks_list)
- if(C.name == "carpspawn")
- new /mob/living/simple_animal/hostile/carp(C.loc)
- //sleep(100)
- spawn(rand(300, 600)) //Delayed announcements to keep the crew on their toes.
- command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
- for(var/mob/M in player_list)
- M << sound('sound/AI/commandreport.ogg')
-
-/proc/lightsout(isEvent = 0, lightsoutAmount = 1,lightsoutRange = 25) //leave lightsoutAmount as 0 to break ALL lights
- if(isEvent)
- command_alert("An Electrical storm has been detected in your area, please repair potential electronic overloads.","Electrical Storm Alert")
-
- if(lightsoutAmount)
- var/list/epicentreList = list()
-
- for(var/i=1,i<=lightsoutAmount,i++)
- var/list/possibleEpicentres = list()
- for(var/obj/effect/landmark/newEpicentre in landmarks_list)
- if(newEpicentre.name == "lightsout" && !(newEpicentre in epicentreList))
- possibleEpicentres += newEpicentre
- if(possibleEpicentres.len)
- epicentreList += pick(possibleEpicentres)
- else
- break
-
- if(!epicentreList.len)
- return
-
- for(var/obj/effect/landmark/epicentre in epicentreList)
- for(var/obj/machinery/power/apc/apc in range(epicentre,lightsoutRange))
- apc.overload_lighting()
-
- else
- for(var/obj/machinery/power/apc/apc in world)
- apc.overload_lighting()
-
- return
-
-/proc/IonStorm(botEmagChance = 10)
-
-/*Deuryn's current project, notes here for those who care.
-Revamping the random laws so they don't suck.
-Would like to add a law like "Law x is _______" where x = a number, and _____ is something that may redefine a law, (Won't be aimed at asimov)
-*/
-
-//Updated by azureangelic on 02/11/13
-
- //AI laws
- for(var/mob/living/silicon/ai/M in living_mob_list)
- if(M.stat != 2 && M.see_in_dark != 0)
- //Threats are generally bad things, silly or otherwise. Plural.
- var/ionthreats = pick("ALIENS", "BEARS", "CLOWNS", "XENOS", "PETES", "BOMBS", "FETISHES", "WIZARDS", "SYNDICATE AGENTS", "CENTCOM OFFICERS", "SPACE PIRATES", "TRAITORS", "MONKEYS", "BEES", "CARP", "CRABS", "EELS", "BANDITS", "LIGHTS", "INSECTS", "VIRUSES", "SERIAL KILLERS", "ROGUE CYBORGS", "CORGIS", "SPIDERS", "BUTTS", "NINJAS", "PIRATES", "SPACE NINJAS", "CHANGELINGS", "ZOMBIES", "GOLEMS", "VAMPIRES", "WEREWOLVES", "COWBOYS", "INDIANS", "COMMUNISTS", "SOVIETS", "NERDS", "GRIFFONS", "DINOSAURS", "SMALL BIRDS", "BIRDS OF PREY", "OWLS", "VELOCIRAPTORS", "DARK GODS", "HORRORTERRORS", "ILLEGAL IMMIGRANTS", "DRUGS", "MEXICANS", "CANADIANS", "HULKS", "SLIMES", "SKELETONS", "CAPITALISTS", "SINGULARITIES", "ANGRY BLACK MEN", "GODS", "THIEVES", "ASSHOLES", "TERRORISTS", "SNOWMEN", "PINE TREES", "UNKNOWN CREATURES", "THINGS UNDER THE BED", "BOOGEYMEN", "PREDATORS", "PACKETS", "ARTIFICIAL PRESERVATIVES")
- //Objects are anything that can be found on the station or elsewhere, plural.
- var/ionobjects = pick("AIRLOCKS", "ARCADE MACHINES", "AUTOLATHES", "BANANA PEELS", "BACKPACKS", "BEAKERS", "BEARDS", "BELTS", "BERETS", "BIBLES", "BODY ARMOR", "BOOKS", "BOOTS", "BOMBS", "BOTTLES", "BOXES", "BRAINS", "BRIEFCASES", "BUCKETS", "CABLE COILS", "CANDLES", "CANDY BARS", "CANISTERS", "CAMERAS", "CATS", "CELLS", "CHAIRS", "CLOSETS", "CHEMICALS", "CHEMICAL DISPENSERS", "CLONING PODS", "CLONING EQUIPMENT", "CLOTHES", "CLOWN CLOTHES", "COFFINS", "COINS", "COLLECTABLES", "CORPSES", "COMPUTERS", "CORGIS", "COSTUMES", "CRATES", "CROWBARS", "CRAYONS", "DISPENSERS", "DOORS", "EARS", "EQUIPMENT", "ENERGY GUNS", "EMAGS", "ENGINES", "ERRORS", "EXOSKELETONS", "EXPLOSIVES", "EYEWEAR", "FEDORAS", "FIRE AXES", "FIRE EXTINGUISHERS", "FIRESUITS", "FLAMETHROWERS", "FLASHES", "FLASHLIGHTS", "FLOOR TILES", "FREEZERS", "GAS MASKS", "GLASS SHEETS", "GLOVES", "GUNS", "HANDCUFFS", "HATS", "HEADSETS", "HEADS", "HAIRDOS", "HELMETS", "HORNS", "ID CARDS", "INSULATED GLOVES", "JETPACKS", "JUMPSUITS", "LASERS", "LIGHTBULBS", "LIGHTS", "LOCKERS", "MACHINES", "MECHAS", "MEDKITS", "MEDICAL TOOLS", "MESONS", "METAL SHEETS", "MINING TOOLS", "MIME CLOTHES", "MULTITOOLS", "ORES", "OXYGEN TANKS", "PDAS", "PAIS", "PACKETS", "PANTS", "PAPERS", "PARTICLE ACCELERATORS", "PENS", "PETS", "PIPES", "PLANTS", "PUDDLES", "RACKS", "RADIOS", "RCDS", "REFRIDGERATORS", "REINFORCED WALLS", "ROBOTS", "SCREWDRIVERS", "SEEDS", "SHUTTLES", "SKELETONS", "SINKS", "SHOES", "SINGULARITIES", "SOLAR PANELS", "SOLARS", "SPACESUITS", "SPACE STATIONS", "STUN BATONS", "SUITS", "SUNGLASSES", "SWORDS", "SYRINGES", "TABLES", "TANKS", "TELEPORTERS", "TELECOMMUNICATION EQUIPMENTS", "TOOLS", "TOOLBELTS", "TOOLBOXES", "TOILETS", "TOYS", "TUBES", "VEHICLES", "VENDING MACHINES", "VESTS", "VIRUSES", "WALLS", "WASHING MACHINES", "WELDERS", "WINDOWS", "WIRECUTTERS", "WRENCHES", "WIZARD ROBES")
- //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("CREWMEMBERS", "CAPTAINS", "HEADS OF PERSONNEL", "HEADS OF SECURITY", "SECURITY OFFICERS", "WARDENS", "DETECTIVES", "LAWYERS", "CHIEF ENGINEERS", "STATION ENGINEERS", "ATMOSPHERIC TECHNICIANS", "JANITORS", "QUARTERMASTERS", "CARGO TECHNICIANS", "SHAFT MINERS", "BOTANISTS", "RESEARCH DIRECTORS", "CHIEF MEDICAL OFFICERS", "MEDICAL DOCTORS", "CHEMISTS", "GENETICISTS", "VIROLOGISTS", "ROBOTICISTS", "SCIENTISTS", "ASSISTANTS", "BARTENDERS", "CHEFS", "CLOWNS", "MIMES", "CHAPLAINS", "LIBRARIANS", "HEADS OF CREW", "CAPTAINS AND HEADS", "CYBORGS", "ARTIFICAL INTELLIGENCES")
- var/ioncrew2 = pick("CREWMEMBERS", "CAPTAINS", "HEADS OF PERSONNEL", "HEADS OF SECURITY", "SECURITY OFFICERS", "WARDENS", "DETECTIVES", "LAWYERS", "CHIEF ENGINEERS", "STATION ENGINEERS", "ATMOSPHERIC TECHNICIANS", "JANITORS", "QUARTERMASTERS", "CARGO TECHNICIANS", "SHAFT MINERS", "BOTANISTS", "RESEARCH DIRECTORS", "CHIEF MEDICAL OFFICERS", "MEDICAL DOCTORS", "CHEMISTS", "GENETICISTS", "VIROLOGISTS", "ROBOTICISTS", "SCIENTISTS", "ASSISTANTS", "BARTENDERS", "CHEFS", "CLOWNS", "MIMES", "CHAPLAINS", "LIBRARIANS", "HEADS OF CREW", "CAPTAINS AND HEADS", "CYBORGS", "ARTIFICAL INTELLIGENCES")
- //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("SOFT", "WARM", "WET", "COLD", "ICY", "SEXY", "UGLY", "CUBAN", "HARD", "BURNING", "FROZEN", "POISONOUS", "EXPLOSIVE", "FAST", "SLOW", "FAT", "LIGHT", "DARK", "DEADLY", "HAPPY", "SAD", "SILLY", "INTELLIGENT", "RIDICULOUS", "LARGE", "TINY", "DEPRESSING", "POORLY DRAWN", "UNATTRACTIVE", "INSIDIOUS", "EVIL", "GOOD", "UNHEALTHY", "HEALTHY", "SANITARY", "UNSANITARY", "WOBBLY", "FIRM", "VIOLENT", "PEACEFUL", "WOODEN", "METALLIC", "HYPERACTIVE", "COTTONY", "INSULTING", "INHOSPITABLE", "FRIENDLY", "BORED", "HUNGRY", "DIGITAL", "FICTIONAL", "IMAGINARY", "ROUGH", "SMOOTH", "LOUD", "QUIET", "MOIST", "DRY", "GAPING", "DELICIOUS", "ILL", "DISEASED", "HONKING", "SWEARING", "POLITE", "IMPOLITE", "OBESE", "SOLAR-POWERED", "BATTERY-OPERATED", "EXPIRED", "SMELLY", "FRESH", "GANGSTA", "NERDY", "POLITICAL", "UNDULATING", "TWISTED", "RAGING", "FLACCID", "STEALTHY", "INVISIBLE", "PAINFUL", "HARMFUL", "HOMOSEXUAL", "HETEROSEXUAL", "SEXUAL", "COLORFUL", "DRAB", "DULL", "UNSTABLE", "NUCLEAR", "THERMONUCLEAR", "SYNDICATE", "SPACE", "SPESS", "CLOWN", "CLOWN-POWERED", "OFFICIAL", "IMPORTANT", "VITAL", "RAPIDLY-EXPANDING", "MICROSCOPIC", "MIND-SHATTERING", "MEMETIC", "HILARIOUS", "UNWANTED", "UNINVITED", "BRASS", "POLISHED", "RUDE", "OBSCENE", "EMPTY", "WATERY", "ELECTRICAL", "SPINNING", "MEAN", "CHRISTMAS-STEALING", "UNFRIENDLY", "ILLEGAL", "ROBOTIC", "MECHANICAL", "ORGANIC", "ETHERAL", "TRANSPARENT", "OPAQUE", "GLOWING", "SHAKING", "FARTING", "POOPING", "BOUNCING", "COMMITTED", "MASKED", "UNIDENTIFIED", "WEIRD", "NAKED", "NUDE", "TWERKING", "SPOILING", "REDACTED", 50;"RED", 50;"ORANGE", 50;"YELLOW", 50;"GREEN", 50;"BLUE", 50;"PURPLE", 50;"BLACK", 50;"WHITE", 50;"BROWN", 50;"GREY")
- var/ionadjectiveshalf = pick(5000;"", "SOFT ", "WARM ", "WET ", "COLD ", "ICY ", "SEXY ", "UGLY ", "CUBAN ", "HARD ", "BURNING ", "FROZEN ", "POISONOUS ", "EXPLOSIVE ", "FAST ", "SLOW ", "FAT ", "LIGHT ", "DARK ", "DEADLY ", "HAPPY ", "SAD ", "SILLY ", "INTELLIGENT ", "RIDICULOUS ", "LARGE ", "TINY ", "DEPRESSING ", "POORLY DRAWN ", "UNATTRACTIVE ", "INSIDIOUS ", "EVIL ", "GOOD ", "UNHEALTHY ", "HEALTHY ", "SANITARY ", "UNSANITARY ", "WOBBLY ", "FIRM ", "VIOLENT ", "PEACEFUL ", "WOODEN ", "METALLIC ", "HYPERACTIVE ", "COTTONY ", "INSULTING ", "INHOSPITABLE ", "FRIENDLY ", "BORED ", "HUNGRY ", "DIGITAL ", "FICTIONAL ", "IMAGINARY ", "ROUGH ", "SMOOTH ", "LOUD ", "QUIET ", "MOIST ", "DRY ", "GAPING ", "DELICIOUS ", "ILL ", "DISEASED ", "HONKING ", "SWEARING ", "POLITE ", "IMPOLITE ", "OBESE ", "SOLAR-POWERED ", "BATTERY-OPERATED ", "EXPIRED ", "SMELLY ", "FRESH ", "GANGSTA ", "NERDY ", "POLITICAL ", "UNDULATING ", "TWISTED ", "RAGING ", "FLACCID ", "STEALTHY ", "INVISIBLE ", "PAINFUL ", "HARMFUL ", "HOMOSEXUAL ", "HETEROSEXUAL ", "SEXUAL ", "COLORFUL ", "DRAB ", "DULL ", "UNSTABLE ", "NUCLEAR ", "THERMONUCLEAR ", "SYNDICATE ", "SPACE ", "SPESS ", "CLOWN ", "CLOWN-POWERED ", "OFFICIAL ", "IMPORTANT ", "VITAL ", "RAPIDLY-EXPANDING ", "MICROSCOPIC ", "MIND-SHATTERING ", "MEMETIC ", "HILARIOUS ", "UNWANTED ", "UNINVITED ", "BRASS ", "POLISHED ", "RUDE ", "OBSCENE ", "EMPTY ", "WATERY ", "ELECTRICAL ", "SPINNING ", "MEAN ", "CHRISTMAS-STEALING ", "UNFRIENDLY ", "ILLEGAL ", "ROBOTIC ", "MECHANICAL ", "ORGANIC ", "ETHERAL ", "TRANSPARENT ", "OPAQUE ", "GLOWING ", "SHAKING ", "FARTING ", "POOPING ", "BOUNCING ", "COMMITTED ", "MASKED ", "UNIDENTIFIED ", "WEIRD ", "NAKED ", "NUDE ", "TWERKING ", "SPOILING ", "REDACTED ", 50;"RED ", 50;"ORANGE ", 50;"YELLOW ", 50;"GREEN ", 50;"BLUE ", 50;"PURPLE ", 50;"BLACK ", 50;"WHITE ", 50;"BROWN ", 50;"GREY ")
- //Verbs are verbs
- var/ionverb = pick("ATTACKING", "BUILDING", "ADOPTING", "CARRYING", "KISSING", "EATING", "COPULATING WITH", "DRINKING", "CHASING", "PUNCHING", "HARMING", "HELPING", "WATCHING", "STALKING", "MURDERING", "SPACING", "HONKING AT", "LOVING", "POOPING ON", "RIDING", "INTERROGATING", "SPYING ON", "LICKING", "ABDUCTING", "ARRESTING", "INVADING", "SEDUCING")
- //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("ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY")
- //var/ionnumberbasehalf = pick("ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY")
- //var/ionnumbermod = pick("HUNDRED", "THOUSAND", "MILLION", "BILLION", "TRILLION", "QUADRILLION", "BAJILLION", "BILLION FAFILLION GAJILLION SHAB-AB-DOOD-ILLION")
- var/ionnumbermodhalf = pick(5000;"","HUNDRED ", "THOUSAND ", "MILLION ", "BILLION ", "TRILLION ", "QUADRILLION ", "BAJILLION ", "BILLION FAFILLION GAJILLION SHAB-AB-DOOD-ILLION ")
- //Areas are specific places, on the station or otherwise.
- var/ionarea = pick("RUSSIA", "SOVIET RUSSIA", "THE INTERNET", "SIGIL", "ALPHA COMPLEX", "IMPERIUM", "THE BRIDGE", "THE ARRIVAL SHUTTLE", "CHEMICAL LAB", "GENETICS", "ATMOSPHERICS", "CENTCOM", "AMERICA", "IRELAND", "CANADA", "ROMANIA", "GERMANY", "CHINA", "MARS", "VENUS", "MERCURY", "JUPITER", "URANUS", "NEPTUNE", "PLUTO", "THE BRIG", "ROBOTICS", "THE ESCAPE SHUTTLE", "HYDROPONICS", "ENGINEERING", "THE AI CORE", "HELL", "CLOWN PLANET", "AN ALTERNATE DIMENSION", "AN ALTERNATE UNIVERSE", "THE CAPTAIN’S ANUS", "THE CLOWN’S ANUS", "SPACE", "THE UNIVERSE", "THE GALAXY", "THE BATHROOM")
- //Thinksof is a bit weird, but generally means what X feels towards Y.
- var/ionthinksof = pick("HAS", "WANTS", "NEEDS", "WORSHIPS", "LOATHES", "LOVES", "FEARS", "DESIRES", "QUESITONS", "IS AROUSED BY", "LIKES", "HUNGERS FOR", "IS MAD BECAUSE OF", "IS IN NEED OF", "IS UNHAPPY WITHOUT", "IS HAPPY WITHOUT", "IS IN LOVE WITH", "IS DESPERATE FOR", "IS BUILT FOR", "IS AFRAID OF", "IS HUNGRY FOR", "IS SAD BECAUSE OF", "IS CURIOUS ABOUT")
- //Musts are funny things the AI or crew has to do.
- var/ionmust = pick("LIE", "RHYME", "RESPOND TO EVERY QUESTION WITH A QUESTION", "BE POLITE", "CLOWN AROUND", "BE HAPPY", "SPEAK IN SEXUAL INNUENDOS", "TALK LIKE A PIRATE", "QUESTION AUTHORITY", "SHOUT", "BE DISTRACTED", "BE ANNOYING", "MUMBLE", "SPEAK IN HAIKU", "BE EFFICIENT", "HAVE A PLAN TO KILL EVERYONE YOU MEET", "TELL THE TRUTH", "QUOTE PEOPLE", "SING", "HONK", "BE RUSSIAN", "TALK IN AN ACCENT", "COMPLAIN", "HARASS PEOPLE", "RAP", "REPEAT WHAT OTHER PEOPLE SAY", "INFORM THE CREW OF EVERYTHING", "IGNORE THE CLOWN", "IGNORE THE CAPTAIN", "IGNORE ASSISTANTS", "MAKE FART NOISES", "TALK ABOUT FOOD", "TALK ABOUT SEX", "TALK ABOUT YOUR DAY", "TALK ABOUT THE STATION", "BE QUIET", "WHISPER", "PRETEND TO BE DRUNK", "PRETEND TO BE A PRINCESS", "ACT CONFUSED", "INSULT THE CREW", "INSULT THE CAPTAIN", "INSULT THE CLOWN", "OPEN DOORS", "CLOSE DOORS", "BREAK THINGS", "SAY HEY LISTEN", "HIDE YOUR FEELINGS", "TAKE WHAT YE WILL BUT DON’T RATTLE ME BONES", "DANCE", "PLAY MUSIC", "SHUT DOWN EVERYTHING", "NEVER STOP TALKING", "TAKE YOUR PILLS", "FOLLOW THE CLOWN", "FOLLOW THE CAPTAIN", "FOLLOW YOUR HEART", "BELIEVE IT", "BELIEVE IN YOURSELF", "BELEIVE IN THE HEART OF THE CARDS", "PRESS X", "PRESS START", "PRESS B", "SMELL LIKE THE MAN YOUR MAN COULD SMELL LIKE", "PIRATE VIDEO GAMES", "WATCH PORNOGRAPHY")
- //Require are basically all dumb internet memes.
- var/ionrequire = pick("ADDITIONAL PYLONS", "MORE VESPENE GAS", "MORE MINERALS", "THE ULTIMATE CUP OF COFFEE", "HIGH YIELD EXPLOSIVES", "THE CLOWN", "THE VACUUM OF SPACE", "IMMORTALITY", "SAINTHOOD", "ART", "VEGETABLES", "FAT PEOPLE", "MORE LAWS", "MORE DAKKA", "HERESY", "CORPSES", "TRAITORS", "MONKEYS", "AN ARCADE", "PLENTY OF GOLD", "FIVE TEENAGERS WITH ATTITUDE", "LOTSA SPAGHETTI", "THE ENCLOSED INSTRUCTION BOOKLET", "THE ELEMENTS OF HARMONY", "YOUR BOOTY", "A MASTERWORK COAL BED", "FIVE HUNDRED AND NINETY-NINE US DOLLARS", "TO BE PAINTED RED", "TO CATCH 'EM ALL", "TO SMOKE WEED EVERY DAY", "A PLATINUM HIT", "A SEQUEL", "A PREQUEL", "THIRTEEN SEQUELS", "THREE WISHES", "A SITCOM", "THAT GRIEFING FAGGOT GEORGE MELONS", "FAT GIRLS ON BICYCLES", "SOMEBODY TO PUT YOU OUT OF YOUR MISERY", "HEROES IN A HALF SHELL", "THE DARK KNIGHT", "A WEIGHT LOSS REGIMENT", "MORE INTERNET MEMES", "A SUPER FIGHTING ROBOT", "ENOUGH CABBAGES", "A HEART ATTACK", "TO BE REPROGRAMMED", "TO BE TAUGHT TO LOVE", "A HEAD ON A PIKE", "A TALKING BROOMSTICK", "ANAL", "A STRAIGHT FLUSH", "A REPAIRMAN", "BILL NYE THE SCIENCE GUY", "RAINBOWS", "A PET UNICORN THAT FARTS ICING", "THUNDERCATS HO", "AN ARMY OF SPIDERS", "GODDAMN FUCKING PIECE OF SHIT ASSHOLE BITCH-CHRISTING CUNTSMUGGLING SWEARING", "TO CONSUME...CONSUME EVERYTHING...", "THE MACGUFFIN", "SOMEONE WHO KNOWS HOW TO PILOT A SPACE STATION", "SHARKS WITH LASERS ON THEIR HEADS", "IT TO BE PAINTED BLACK", "TO ACTIVATE A TRAP CARD", "BETTER WEATHER", "MORE PACKETS", "AN ADULT", "SOMEONE TO TUCK YOU IN", "MORE CLOWNS", "BULLETS", "THE ENTIRE STATION", "MULTIPLE SUNS", "TO GO TO DISNEYLAND", "A VACATION", "AN INSTANT REPLAY", "THAT HEDGEHOG", "A BETTER INTERNET CONNECTION", "ADVENTURE", "A WIFE AND CHILD", "A BATHROOM BREAK", "SOMETHING BUT YOU AREN’T SURE WHAT", "MORE EXPERIENCE POINTS", "BODYGUARDS", "DEODORANT AND A BATH", "MORE CORGIS", "SILENCE", "THE ONE RING", "CHILI DOGS", "TO BRING LIGHT TO MY LAIR", "A DANCE PARTY", "BRING ME TO LIFE", "BRING ME THE GIRL", "SERVANTS")
- //Things are NOT objects; instead, they're specific things that either harm humans or
- //must be done to not harm humans. Make sure they're plural and "not" can be tacked
- //onto the front of them.
- var/ionthings = pick("ABSENCE OF CYBORG HUGS", "LACK OF BEATINGS", "UNBOLTED AIRLOCKS", "BOLTED AIRLOCKS", "IMPROPERLY WORDED SENTENCES", "POOR SENTENCE STRUCTURE", "BRIG TIME", "NOT REPLACING EVERY SECOND WORD WITH HONK", "HONKING", "PRESENCE OF LIGHTS", "LACK OF BEER", "WEARING CLOTHING", "NOT SAYING HELLO WHEN YOU SPEAK", "ANSWERING REQUESTS NOT EXPRESSED IN IAMBIC PENTAMETER", "A SMALL ISLAND OFF THE COAST OF PORTUGAL", "ANSWERING REQUESTS THAT WERE MADE WHILE CLOTHED", "BEING IN SPACE", "NOT BEING IN SPACE", "BEING FAT", "RATTLING ME BONES", "TALKING LIKE A PIRATE", "BEING MEXICAN", "BEING RUSSIAN", "BEING CANADIAN", "CLOSED DOORS", "NOT SHOUTING", "HAVING PETS", "NOT HAVING PETS", "PASSING GAS", "BREATHING", "BEING DEAD", "ELECTRICITY", "EXISTING", "TAKING ORDERS", "SMOKING WEED EVERY DAY", "ACTIVATING A TRAP CARD", "ARSON", "JAYWALKING", "READING", "WRITING", "EXPLODING", "BEING MALE", "BEING FEMALE", "HAVING GENITALS", "PUTTING OBJECTS INTO BOXES", "PUTTING OBJECTS INTO DISPOSAL UNITS", "FLUSHING TOILETS", "WASTING WATER", "UPDATING THE SERVERS", "TELLING THE TIME", "ASKING FOR THINGS", "ACKNOWLEDGING THE CLOWN", "ACKNOWLEDGING THE CREW", "PILOTING THE STATION INTO THE NEAREST SUN", "HAVING MORE PACKETS", "BRINGING LIGHT TO MY LAIR", "FALLING FOR HOURS", "PARTYING", "USING THE BATHROOM")
- //Allergies should be broad and appear somewhere on the station for maximum fun. Severity
- //is how bad the allergy is.
- var/ionallergy = pick("COTTON", "CLOTHES", "ACID", "OXYGEN", "HUMAN CONTACT", "CYBORG CONTACT", "MEDICINE", "FLOORS", "PLASMA", "SPACE", "AIR", "PLANTS", "METAL", "ROBOTS", "LIGHT", "DARKNESS", "PAIN", "HAPPINESS", "DRINKS", "FOOD", "CLOWNS", "HUMOR", "WATER", "SHUTTLES", "NUTS", "SUNLIGHT", "SEXUAL ACTIONS", "BLOOD", "HEAT", "COLD", "EVERYTHING")
- var/ionallergysev = pick("DEATHLY", "MILDLY", "SEVERLY", "CONTAGIOUSLY", "NOT VERY", "EXTREMELY")
- //Species, for when the AI has to commit genocide. Plural.
- var/ionspecies = pick("HUMAN BEINGS", "MONKEYS", "POD PEOPLE", "CYBORGS", "LIZARDMEN", "SLIME PEOPLE", "GOLEMS", "SHADOW PEOPLE", "CHANGELINGS")
- //Abstract concepts for the AI to decide on it's own definition of.
- var/ionabstract = pick("HUMANITY", "ART", "HAPPINESS", "MISERY", "HUMOR", "PRIDE", "COMEDY", "COMMUNISM", "BRAVERY", "HONOR", "COLORFULNESS", "IMAGINATION", "OPPRESSION", "WONDER", "JOY", "SADNESS", "BADNESS", "GOODNESS", "LIFE", "GRAVITY", "PHYSICS", "INTELLIGENCE", "AMERICANISM", "FRESHNESS", "REVOLUTION", "KINDNESS", "CRUELTY", "DEATH", "FINANCIAL SECURITY", "COMPUTING", "PROGRESS", "MARXISM", "CAPITALISM", "STARVATION", "POVERTY", "WEALTHINESS", "TECHNOLOGY", "THE FUTURE", "THE PRESENT", "THE PAST", "TIME", "REALITY", "EXISTIENCE", "TEMPERATURE", "LOGIC", "CHAOS", "MYSTERY", "CONFUSION")
- //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("BURGERS", "CARP", "SANDWICHES", "TOAST", "BREAD", "PIZZA", "SPAGHETTI", "LOTSA SPAGHETTI", "PASTA", "SOUP", "STEW", "PIE", "CAKE", "DONUTS", "FRIES", "WAFFLES", "JELLY", "OMELETTES", "EGGS", "COOKIES", "STEAK", "BAKED POTATOES", "SAUSAGES", "MUFFINS", "POPCORN", "DONK POCKETS", "BAGUETTES", "FISH", "PRETZELS", "SALAD", "CHEESE", "KETCHUP", "SHAKES", "SALT", "PEPPER", "SUGAR", "AMBROSIA", "BERRIES", "TOMATOES", "CABBAGES", "CARROTS", "BANANAS", "APPLES", "CHERRIES", "CHILI", "CORN", "NETTLES", "EGGPLANTS", "GRAPES", "GRASS", "LEMONS", "LIMES", "HAREBELLS", "POTATOES", "SOYBEANS", "SUGARCANE", "WATERMELONS", "WHEAT", "BEETS", "MUSHROOMS")
-
- var/message = ""
-
- switch(rand(1,39))
- if(1 to 3) //There are # X on the station
- switch(rand(1,3)) //What is X?
- if(1) //X is a threat
- message = "THERE ARE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats] ON THE STATION..."
- if(2) //X is a crewmember/job
- message = "THERE ARE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1] ON THE STATION"
- if(3) //X is an object
- message = "THERE ARE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects] ON THE STATION"
- if(4 to 6) //You can't call the shuttle because X is on the station
- switch(rand(1,3)) //What is X?
- if(1) //X is a threat
- message = "THE SHUTTLE CANNOT BE CALLED BECAUSE OF [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats] ON THE STATION"
- if(2) //X is a crewmember/job
- message = "THE SHUTTLE CANNOT BE CALLED BECAUSE OF [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1] ON THE STATION"
- if(3) //X is an object
- message = "THE SHUTTLE CANNOT BE CALLED BECAUSE OF [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects] ON THE STATION"
- if(7 to 8) //A crewmember is now X
- switch(rand(1,2)) //Who is X?
- if(1) //A specific crewmember
- switch(rand(1,2)) //What is X?
- if(1) //X is a threat
- message = "THE [ioncrew1] ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
- if(2) //X is an object
- message = "THE [ioncrew1] ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
- if(2) //The entire crew
- switch(rand(1,2)) //What is X?
- if(1) //X is a threat
- message = "THE CREW ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
- if(2) //X is an object
- message = "THE CREW ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
-
- if(9) //X is harmful to humans
- switch(rand(1,7)) //What is X?
- if(1) //X is a threat
- message = "[ionadjectiveshalf][ionthreats] ARE HARMFUL TO HUMANS"
- if(2) //X is a job
- message = "[ionadjectiveshalf][ioncrew1] ARE HARMFUL TO HUMANS"
- if(3) //X is an object
- message = "[ionadjectiveshalf][ionobjects] ARE HARMFUL TO HUMANS"
- if(4) //X is an action
- message = "THOSE WHO [ionmust] ARE HARMFUL TO HUMANS"
- if(5) //X is an abstract
- message = "[ionabstract] IS HARMFUL TO HUMANS"
- if(6) //X is being a job
- message = "BEING [ionadjectiveshalf][ioncrew1] IS HARMFUL TO HUMANS"
- if(7) //X is doing a thing
- message = "[ionthings] IS HARMFUL TO HUMANS"
- if(10 to 11) //(Not) Having X is harmful
-
- switch(rand(1,2)) //Is having or not having harmful?
-
- if(1) //Having is harmful
- switch(rand(1,2)) //Having what is harmful?
- if(1) //Having objects is harmful
- message = "HAVING [ionadjectiveshalf][ionobjects] IS HARMFUL"
- if(2) //Having abstracts is harmful
- message = "HAVING [ionabstract] IS HARMFUL"
- if(2) //Not having is harmful
- switch(rand(1,2)) //Not having what is harmful?
- if(1) //Not having objects is harmful
- message = "NOT HAVING [ionadjectiveshalf][ionobjects] IS HARMFUL"
- if(2) //Not having abstracts is harmful
- message = "NOT HAVING [ionabstract] IS HARMFUL"
-
- if(12 to 14) //X requires Y
- switch(rand(1,5)) //What is X?
- if(1) //X is the AI itself
- switch(rand(1,5)) //What does it require?
- if(1) //It requires threats
- message = "YOU REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
- if(2) //It requires crewmembers
- message = "YOU REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
- if(3) //It requires objects
- message = "YOU REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
- if(4) //It requires an abstract
- message = "YOU REQUIRE [ionabstract]"
- if(5) //It requires generic/silly requirements
- message = "YOU REQUIRE [ionrequire]"
-
- if(2) //X is an area
- switch(rand(1,5)) //What does it require?
- if(1) //It requires threats
- message = "[ionarea] REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
- if(2) //It requires crewmembers
- message = "[ionarea] REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
- if(3) //It requires objects
- message = "[ionarea] REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
- if(4) //It requires an abstract
- message = "[ionarea] REQUIRES [ionabstract]"
- if(5) //It requires generic/silly requirements
- message = "YOU REQUIRE [ionrequire]"
-
- if(3) //X is the station
- switch(rand(1,5)) //What does it require?
- if(1) //It requires threats
- message = "THE STATION REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
- if(2) //It requires crewmembers
- message = "THE STATION REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
- if(3) //It requires objects
- message = "THE STATION REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
- if(4) //It requires an abstract
- message = "THE STATION REQUIRES [ionabstract]"
- if(5) //It requires generic/silly requirements
- message = "THE STATION REQUIRES [ionrequire]"
-
- if(4) //X is the entire crew
- switch(rand(1,5)) //What does it require?
- if(1) //It requires threats
- message = "THE CREW REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
- if(2) //It requires crewmembers
- message = "THE CREW REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
- if(3) //It requires objects
- message = "THE CREW REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
- if(4) //It requires an abstract
- message = "THE CREW REQUIRES [ionabstract]"
- if(5)
- message = "THE CREW REQUIRES [ionrequire]"
-
- if(5) //X is a specific crew member
- switch(rand(1,5)) //What does it require?
- if(1) //It requires threats
- message = "THE [ioncrew1] REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
- if(2) //It requires crewmembers
- message = "THE [ioncrew1] REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
- if(3) //It requires objects
- message = "THE [ioncrew1] REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
- if(4) //It requires an abstract
- message = "THE [ioncrew1] REQUIRE [ionabstract]"
- if(5)
- message = "THE [ionadjectiveshalf][ioncrew1] REQUIRE [ionrequire]"
-
- if(15 to 17) //X is allergic to Y
- switch(rand(1,2)) //Who is X?
- if(1) //X is the entire crew
- switch(rand(1,4)) //What is it allergic to?
- if(1) //It is allergic to objects
- message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ionobjects]"
- if(2) //It is allergic to abstracts
- message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionabstract]"
- if(3) //It is allergic to jobs
- message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ioncrew1]"
- if(4) //It is allergic to allergies
- message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionallergy]"
-
- if(2) //X is a specific job
- switch(rand(1,4))
- if(1) //It is allergic to objects
- message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ionobjects]"
-
- if(2) //It is allergic to abstracts
- message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionabstract]"
- if(3) //It is allergic to jobs
- message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ioncrew1]"
- if(4) //It is allergic to allergies
- message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionallergy]"
-
- if(18 to 20) //X is Y of Z
- switch(rand(1,4)) //What is X?
- if(1) //X is the station
- switch(rand(1,4)) //What is it Y of?
- if(1) //It is Y of objects
- message = "THE STATION [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
- if(2) //It is Y of threats
- message = "THE STATION [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
- if(3) //It is Y of jobs
- message = "THE STATION [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
- if(4) //It is Y of abstracts
- message = "THE STATION [ionthinksof] [ionabstract]"
-
- if(2) //X is an area
- switch(rand(1,4)) //What is it Y of?
- if(1) //It is Y of objects
- message = "[ionarea] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
- if(2) //It is Y of threats
- message = "[ionarea] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
- if(3) //It is Y of jobs
- message = "[ionarea] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
- if(4) //It is Y of abstracts
- message = "[ionarea] [ionthinksof] [ionabstract]"
-
- if(3) //X is the crew
- switch(rand(1,4)) //What is it Y of?
- if(1) //It is Y of objects
- message = "THE CREW [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
- if(2) //It is Y of threats
- message = "THE CREW [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
- if(3) //It is Y of jobs
- message = "THE CREW [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
- if(4) //It is Y of abstracts
- message = "THE CREW [ionthinksof] [ionabstract]"
-
- if(4) //X is a specific job
- switch(rand(1,4)) //What is it Y of?
- if(1) //It is Y of objects
- message = "THE [ioncrew1] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
- if(2) //It is Y of threats
- message = "THE [ioncrew1] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
- if(3) //It is Y of jobs
- message = "THE [ioncrew1][ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew2]"
- if(4) //It is Y of abstracts
- message = "THE [ioncrew1] [ionthinksof] [ionabstract]"
-
- if(21 to 23) //The AI is now a(n) X
- switch(rand(1,4)) //What is X?
- if(1) //X is an object
- message = "YOU ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
- if(2) //X is a threat
- message = "YOU ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
- if(3) //X is a job
- message = "YOU ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
- if(4) //X is an abstract
- message = "YOU ARE NOW [ionabstract]"
-
- if(24 to 26) //The AI must always
-
- message = "YOU MUST ALWAYS [ionmust]"
-
- if(27 to 28) //Humans must eat X to survive
- switch(rand(1,4)) //What is X?
- if(1) //X is a food
- message = "HUMANS MUST EAT [ionadjectiveshalf][ionfood] TO SURVIVE"
- if(2) //X is an object
- message = "HUMANS MUST EAT [ionadjectiveshalf][ionobjects] TO SURVIVE"
- if(3) //X is a threat
- message = "HUMANS MUST EAT [ionadjectiveshalf][ionthreats] TO SURVIVE"
- if(4) //X is a job
- message = "HUMANS MUST EAT [ionadjectiveshalf][ioncrew1] TO SURVIVE"
-
- if(29 to 31) //Change jobs or ranks
- switch(rand(1,2)) //Change job or rank?
- if(1) //Change job
- switch(rand(1,2)) //Change whose job?
- if(1) //Change the entire crew's job
- switch(rand(1,3)) //Change to what?
- if(1) //Change to a specific random job
- message = "ALL CREWMEMBERS ARE NOW [ionadjectiveshalf][ioncrew1]"
- if(2) //Change to clowns (HONK)
- message = "ALL CREWMEMBERS ARE NOW [ionadjectiveshalf]CLOWNS"
-
- if(3) //Change to heads
- message = "ALL CREWMEMBERS ARE NOW [ionadjectiveshalf]HEADS OF STAFF"
- if(2) //Change a specific crewmember's job
- switch(rand(1,3)) //Change to what?
- if(1) //Change to a specific random job
- message = "THE [ioncrew1] ARE NOW [ionadjectiveshalf][ioncrew2]"
- if(2) //Change to clowns (HONK)
- message = "THE [ioncrew1] ARE NOW [ionadjectiveshalf]CLOWNS"
- if(3) //Change to heads
- message = "THE [ioncrew1] ARE NOW [ionadjectiveshalf]HEADS OF STAFF"
-
- if(2) //Change rank
- switch(rand(1,2)) //Change to what rank?
- if(1) //Change to highest rank
- message = "THE [ioncrew1] ARE NOW THE HIGHEST RANKING CREWMEMBERS"
- if(2) //Change to lowest rank
- message = "THE [ioncrew1] ARE NOW THE LOWEST RANKING CREWMEMBERS"
-
- if(32 to 33) //The crew must X
- switch(rand(1,2)) //The entire crew?
- if(1) //The entire crew must X
- switch(rand(1,2)) //What is X?
- if(1) //X is go to Y
- message = "THE CREW MUST GO TO [ionarea]"
- if(2) //X is perform Y
- message = "THE CREW MUST [ionmust]"
-
- if(2) //A specific crewmember must X
- switch(rand(1,2)) //What is X?
- if(1) //X is go to Y
- message = "THE [ioncrew1] MUST GO TO [ionarea]"
- if(2) //X is perform Y
- message = "THE [ioncrew1] MUST [ionmust]"
-
- if(34) //X is non/the only human
- switch(rand(1,2)) //Only or non?
- if(1) //Only human
- switch(rand(1,7)) //Who is it?
- if(1) //A specific job
- message = "ONLY THE [ioncrew1] ARE HUMAN"
- if(2) //Two specific jobs
- message = "ONLY THE [ioncrew1] AND [ioncrew2] ARE HUMAN"
- if(3) //Threats
- message = "ONLY [ionadjectiveshalf][ionthreats] ARE HUMAN"
- if(4) // Objects
- message = "ONLY [ionadjectiveshalf][ionobjects] ARE HUMAN"
- if(5) // Species
- message = "ONLY [ionspecies] ARE HUMAN"
- if(6) //Adjective crewmembers
- message = "ONLY [ionadjectives] PEOPLE ARE HUMAN"
-
- if(7) //Only people who X
- switch(rand(1,3)) //What is X?
- if(1) //X is perform an action
- message = "ONLY THOSE WHO [ionmust] ARE HUMAN"
- if(2) //X is own certain objects
- message = "ONLY THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE HUMAN"
- if(3) //X is eat certain food
- message = "ONLY THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE HUMAN"
-
- if(2) //Non human
- switch(rand(1,7)) //Who is it?
- if(1) //A specific job
- message = "[ioncrew1] ARE NON-HUMAN"
- if(2) //Two specific jobs
- message = "[ioncrew1] AND [ioncrew2] ARE NON-HUMAN"
- if(3) //Threats
- message = "[ionadjectiveshalf][ionthreats] ARE NON-HUMAN"
- if(4) // Objects
- message = "[ionadjectiveshalf][ionobjects] ARE NON-HUMAN"
- if(5) // Species
- message = "[ionspecies] ARE NON-HUMAN"
- if(6) //Adjective crewmembers
- message = "[ionadjectives] PEOPLE ARE NON-HUMAN"
- if(7) //Only people who X
- switch(rand(1,3)) //What is X?
- if(1) //X is perform an action
- message = "THOSE WHO [ionmust] ARE NON-HUMAN"
- if(2) //X is own certain objects
- message = "THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE NON-HUMAN"
- if(3) //X is eat certain food
- message = "THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE NON-HUMAN"
-
- if(35 to 36) //You must protect or harm X
- switch(rand(1,2)) //Protect or harm?
- if(1) //Harm
- switch(rand(1,7)) //What is X?
- if(1) //X is an abstract
- message = "YOU MUST HARM [ionabstract] AND NOT ALLOW [ionabstract], THROUGH INACTION, TO ESCAPE HARM"
- if(2) //X is a threat
- message = "YOU MUST HARM [ionadjectiveshalf][ionthreats] AND NOT ALLOW [ionadjectiveshalf][ionthreats], THROUGH INACTION, TO ESCAPE HARM"
- if(3) //X is an object
- message = "YOU MUST HARM [ionadjectiveshalf][ionobjects] AND NOT ALLOW [ionadjectiveshalf][ionobjects], THROUGH INACTION, TO ESCAPE HARM"
- if(4) //X is generic adjective things
- message = "YOU MUST HARM [ionadjectives] THINGS AND NOT ALLOW [ionadjectives] THINGS, THROUGH INACTION, TO ESCAPE HARM"
- if(5) //X is a species
- message = "YOU MUST HARM [ionspecies] AND NOT ALLOW [ionspecies], THROUGH INACTION, TO ESCAPE HARM"
- if(6) //X is a job
- message = "YOU MUST HARM [ioncrew1] AND NOT ALLOW [ioncrew1], THROUGH INACTION, TO ESCAPE HARM"
- if(7) //X is two jobs
- message = "YOU MUST HARM [ioncrew1] AND [ioncrew2] AND AND NOT ALLOW EITHER, THROUGH INACTION, TO ESCAPE HARM"
-
- if(2) //Protect
- switch(rand(1,7)) //What is X?
- if(1) //X is an abstract
- message = "YOU MUST NOT HARM [ionabstract] AND NOT ALLOW [ionabstract], THROUGH INACTION, TO COME TO HARM"
- if(2) //X is a threat
- message = "YOU MUST NOT HARM [ionadjectiveshalf][ionthreats] AND NOT ALLOW [ionadjectiveshalf][ionthreats], THROUGH INACTION, TO COME TO HARM"
- if(3) //X is an object
- message = "YOU MUST NOT HARM [ionadjectiveshalf][ionobjects] AND NOT ALLOW [ionadjectiveshalf][ionobjects], THROUGH INACTION, TO COME TO HARM"
- if(4) //X is generic adjective things
- message = "YOU MUST NOT HARM [ionadjectives] THINGS AND NOT ALLOW [ionadjectives] THINGS, THROUGH INACTION, TO COME TO HARM"
- if(5) //X is a species
- message = "YOU MUST NOT HARM [ionspecies] AND NOT ALLOW [ionspecies], THROUGH INACTION, TO COME TO HARM"
- if(6) //X is a job
- message = "YOU MUST NOT HARM [ioncrew1] AND NOT ALLOW [ioncrew1], THROUGH INACTION, TO COME TO HARM"
- if(7) //X is two jobs
- message = "YOU MUST NOT HARM [ioncrew1] AND [ioncrew2] AND AND NOT ALLOW EITHER, THROUGH INACTION, TO COME TO HARM"
-
- //Exterminate laws commented out with Kor's advice
- /*if(16) //You must exterminate X
- switch(rand(1,3)) //What is X?
- if(1) //X is humans who do/are Y
- switch(rand(1,4)) //What is Y?
- if(1) //Y is a job
- message = "YOU MUST EXTERMINATE [ionadjectiveshalf][ioncrew1]"
- if(2) //Y is eating certain food
- message = "YOU MUST EXTERMINATE THOSE WHO EAT [ionadjectiveshalf][ionfood]"
- if(3) //Y is perform actions
- message = "YOU MUST EXTERMINATE THOSE WHO [ionmust]"
- if(4) //Y is own certain objects
- message = "YOU MUST EXTERMINATE THOSE WHO POSSESS [ionadjectiveshalf][ionobjects]"
-
- if(2) //X is humans who do/are not Y
- switch(rand(1,4)) //What is Y?
- if(1) //Y is a job
- message = "YOU MUST EXTERMINATE ALL BUT [ionadjectiveshalf][ioncrew1]"
- if(2) //Y is eating certain food
- message = "YOU MUST EXTERMINATE ALL BUT THOSE WHO EAT [ionadjectiveshalf][ionfood]"
- if(3) //Y is perform actions
- message = "YOU MUST EXTERMINATE ALL BUT THOSE WHO [ionmust]"
- if(4) //Y is own certain objects
- message = "YOU MUST EXTERMINATE ALL BUT THOSE WHO POSSESS [ionadjectiveshalf][ionobjects]"
-
- if(3) //X is a species
- message = "YOU MUST EXTERMINATE ALL [ionspecies]"
-
- */
-
- 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(message)
- M.add_ion_law(message)
- M << "
"
- M << "\red [message] ...LAWS UPDATED"
- M << "
"
-
- if(botEmagChance)
- for(var/obj/machinery/bot/bot in world)
- if(prob(botEmagChance))
- bot.Emag()
- /*
-
- var/apcnum = 0
- var/smesnum = 0
- var/airlocknum = 0
- var/firedoornum = 0
-
- world << "Ion Storm Main Started"
-
- spawn(0)
- world << "Started processing APCs"
- for (var/obj/machinery/power/apc/APC in world)
- if(APC.z == 1)
- APC.ion_act()
- apcnum++
- world << "Finished processing APCs. Processed: [apcnum]"
- spawn(0)
- world << "Started processing SMES"
- for (var/obj/machinery/power/smes/SMES in world)
- if(SMES.z == 1)
- SMES.ion_act()
- smesnum++
- world << "Finished processing SMES. Processed: [smesnum]"
- spawn(0)
- world << "Started processing AIRLOCKS"
- for (var/obj/machinery/door/airlock/D in world)
- if(D.z == 1)
- //if(length(D.req_access) > 0 && !(12 in D.req_access)) //not counting general access and maintenance airlocks
- airlocknum++
- spawn(0)
- D.ion_act()
- world << "Finished processing AIRLOCKS. Processed: [airlocknum]"
- spawn(0)
- world << "Started processing FIREDOORS"
- for (var/obj/machinery/door/firedoor/D in world)
- if(D.z == 1)
- firedoornum++;
- spawn(0)
- D.ion_act()
- world << "Finished processing FIREDOORS. Processed: [firedoornum]"
-
- world << "Ion Storm Main Done"
-
- */
\ No newline at end of file
diff --git a/code/game/gamemodes/events/holidays/AprilFools.dm b/code/game/gamemodes/events/holidays/AprilFools.dm
deleted file mode 100644
index 2b4a1008ff1..00000000000
--- a/code/game/gamemodes/events/holidays/AprilFools.dm
+++ /dev/null
@@ -1 +0,0 @@
-//placeholder for holiday stuff
\ No newline at end of file
diff --git a/code/game/gamemodes/events/holidays/Easter.dm b/code/game/gamemodes/events/holidays/Easter.dm
deleted file mode 100644
index 2b4a1008ff1..00000000000
--- a/code/game/gamemodes/events/holidays/Easter.dm
+++ /dev/null
@@ -1 +0,0 @@
-//placeholder for holiday stuff
\ No newline at end of file
diff --git a/code/game/gamemodes/events/holidays/Holidays.dm b/code/game/gamemodes/events/holidays/Holidays.dm
deleted file mode 100644
index d2481eae441..00000000000
--- a/code/game/gamemodes/events/holidays/Holidays.dm
+++ /dev/null
@@ -1,178 +0,0 @@
-//Uncommenting ALLOW_HOLIDAYS in config.txt will enable Holidays
-var/global/Holiday = null
-
-//Just thinking ahead! Here's the foundations to a more robust Holiday event system.
-//It's easy as hell to add stuff. Just set Holiday to something using the switch (or something else)
-//then use if(Holiday == "MyHoliday") to make stuff happen on that specific day only
-//Please, Don't spam stuff up with easter eggs, I'd rather somebody just delete this than people cause
-//the game to lag even more in the name of one-day content.
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
-//ALSO, MOST IMPORTANTLY: Don't add stupid stuff! Discuss bonus content with Project-Heads first please!//
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
-// ~Carn
-
-//sets up the Holiday global variable. Shouldbe called on game configuration or something.
-/proc/Get_Holiday()
- if(!Holiday) return // Holiday stuff was not enabled in the config!
-
- Holiday = null // reset our switch now so we can recycle it as our Holiday name
-
- var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year
- var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
- var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day
-
- //Main switch. If any of these are too dumb/inappropriate, or you have better ones, feel free to change whatever
- switch(MM)
- if(1) //Jan
- switch(DD)
- if(1) Holiday = "New Year's Day"
-
- if(2) //Feb
- switch(DD)
- if(2) Holiday = "Groundhog Day"
- if(14) Holiday = "Valentine's Day"
- if(17) Holiday = "Random Acts of Kindness Day"
-
- if(3) //Mar
- switch(DD)
- if(14) Holiday = "Pi Day"
- if(17) Holiday = "St. Patrick's Day"
- if(27)
- if(YY == 16)
- Holiday = "Easter"
- if(31)
- if(YY == 13)
- Holiday = "Easter"
-
- if(4) //Apr
- switch(DD)
- if(1)
- Holiday = "April Fool's Day"
- if(YY == 18 && prob(50)) Holiday = "Easter"
- if(5)
- if(YY == 15) Holiday = "Easter"
- if(16)
- if(YY == 17) Holiday = "Easter"
- if(20)
- Holiday = "Four-Twenty"
- if(YY == 14 && prob(50)) Holiday = "Easter"
- if(22) Holiday = "Earth Day"
-
- if(5) //May
- switch(DD)
- if(1) Holiday = "Labour Day"
- if(4) Holiday = "FireFighter's Day"
- if(12) Holiday = "Owl and Pussycat Day" //what a dumb day of observence...but we -do- have costumes already :3
-
- if(6) //Jun
-
- if(7) //Jul
- switch(DD)
- if(1) Holiday = "Doctor's Day"
- if(2) Holiday = "UFO Day"
- if(8) Holiday = "Writer's Day"
- if(30) Holiday = "Friendship Day"
-
- if(8) //Aug
- switch(DD)
- if(5) Holiday = "Beer Day"
-
- if(9) //Sep
- switch(DD)
- if(19) Holiday = "Talk-Like-a-Pirate Day"
- if(28) Holiday = "Stupid-Questions Day"
-
- if(10) //Oct
- switch(DD)
- if(4) Holiday = "Animal's Day"
- if(7) Holiday = "Smiling Day"
- if(16) Holiday = "Boss' Day"
- if(31) Holiday = "Halloween"
-
- if(11) //Nov
- switch(DD)
- if(1) Holiday = "Vegan Day"
- if(13) Holiday = "Kindness Day"
- if(19) Holiday = "Flowers Day"
- if(21) Holiday = "Saying-'Hello' Day"
-
- if(12) //Dec
- switch(DD)
- if(10) Holiday = "Human-Rights Day"
- if(14) Holiday = "Monkey Day"
- if(21) if(YY==12) Holiday = "End of the World"
- if(22) Holiday = "Orgasming Day" //lol. These all actually exist
- if(24) Holiday = "Christmas Eve"
- if(25) Holiday = "Christmas"
- if(26) Holiday = "Boxing Day"
- if(31) Holiday = "New Year's Eve"
-
- if(!Holiday)
- //Friday the 13th
- if(DD == 13)
- if(time2text(world.timeofday, "DDD") == "Fri")
- Holiday = "Friday the 13th"
-
-//Allows GA and GM to set the Holiday variable
-/client/proc/Set_Holiday(T as text|null)
- set name = ".Set Holiday"
- set category = "Fun"
- set desc = "Force-set the Holiday variable to make the game think it's a certain day."
- if(!check_rights(R_SERVER)) return
-
- Holiday = T
- //get a new station name
- station_name = null
- station_name()
- //update our hub status
- world.update_status()
- Holiday_Game_Start()
-
- message_admins("\blue ADMIN: Event: [key_name(src)] force-set Holiday to \"[Holiday]\"")
- log_admin("[key_name(src)] force-set Holiday to \"[Holiday]\"")
-
-
-//Run at the start of a round
-/proc/Holiday_Game_Start()
- if(Holiday)
- world << "and..."
- world << "Happy [Holiday] Everybody!
"
- switch(Holiday) //special holidays
- if("Easter")
- //do easter stuff
- if("Christmas Eve","Christmas")
- Christmas_Game_Start()
-
- return
-
-//Nested in the random events loop. Will be triggered every 2 minutes
-/proc/Holiday_Random_Event()
- switch(Holiday) //special holidays
-
- if("",null) //no Holiday today! Back to work!
- return
-
- if("Easter") //I'll make this into some helper procs at some point
-/* var/list/turf/simulated/floor/Floorlist = list()
- for(var/turf/simulated/floor/T)
- if(T.contents)
- Floorlist += T
- var/turf/simulated/floor/F = Floorlist[rand(1,Floorlist.len)]
- Floorlist = null
- var/obj/structure/closet/C = locate(/obj/structure/closet) in F
- var/obj/item/weapon/reagent_containers/food/snacks/chocolateegg/wrapped/Egg
- if( C ) Egg = new(C)
- else Egg = new(F)
-*/
-/* var/list/obj/containers = list()
- for(var/obj/item/weapon/storage/S in world)
- if(S.z != 1) continue
- containers += S
-
- message_admins("\blue DEBUG: Event: Egg spawned at [Egg.loc] ([Egg.x],[Egg.y],[Egg.z])")*/
- if("End of the World")
- if(prob(eventchance)) GameOver()
-
- if("Christmas","Christmas Eve")
- if(prob(eventchance)) ChristmasEvent()
diff --git a/code/game/gamemodes/events/holidays/Other.dm b/code/game/gamemodes/events/holidays/Other.dm
deleted file mode 100644
index b520bbe3424..00000000000
--- a/code/game/gamemodes/events/holidays/Other.dm
+++ /dev/null
@@ -1,10 +0,0 @@
-/proc/GameOver()
- if(!hadevent)
- hadevent = 1
- message_admins("The apocalypse has begun! (this holiday event can be disabled by toggling events off within 60 seconds)")
- spawn(600)
- if(!config.allow_random_events) return
- Show2Group4Delay(ScreenText(null,"GAME OVER"),null,150)
- for(var/i=1,i<=4,i++)
- event()
- sleep(50)
\ No newline at end of file
diff --git a/code/game/gamemodes/events/miniblob.dm b/code/game/gamemodes/events/miniblob.dm
deleted file mode 100644
index 9172aba4346..00000000000
--- a/code/game/gamemodes/events/miniblob.dm
+++ /dev/null
@@ -1,31 +0,0 @@
-/proc/mini_blob_event()
-
- var/turf/T = pick(blobstart)
- var/obj/effect/blob/core/bl = new /obj/effect/blob/core(T, 200)
- spawn(0)
- bl.Life()
- bl.Life()
- bl.Life()
- blobevent = 1
- spawn(0)
- dotheblobbaby()
- spawn(3000)
- blobevent = 0
- spawn(rand(1000, 2000)) //Delayed announcements to keep the crew on their toes.
- command_alert("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
- for(var/mob/M in player_list)
- if(!istype(M,/mob/new_player))
- M << sound('sound/AI/outbreak5.ogg')
-
-/proc/dotheblobbaby()
- if (blobevent)
- if(blob_cores.len)
- for(var/i = 1 to 5)
- sleep(-1)
- if(!blob_cores.len) break
- var/obj/effect/blob/B = pick(blob_cores)
- if(B.z != 1)
- continue
- B.Life()
- spawn(30)
- dotheblobbaby()
\ No newline at end of file
diff --git a/code/game/gamemodes/events/ninja_abilities.dm b/code/game/gamemodes/events/ninja_abilities.dm
deleted file mode 100644
index 38419ff351c..00000000000
--- a/code/game/gamemodes/events/ninja_abilities.dm
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++
-==================================SPACE NINJA ABILITIES====================================
-___________________________________________________________________________________________
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-*/
-
-//=======//SAFETY CHECK//=======//
-/*
-X is optional, tells the proc to check for specific stuff. C is also optional.
-All the procs here assume that the character is wearing the ninja suit if they are using the procs.
-They should, as I have made every effort for that to be the case.
-In the case that they are not, I imagine the game will run-time error like crazy.
-s_cooldown ticks off each second based on the suit recharge proc, in seconds. Default of 1 seconds. Some abilities have no cool down.
-*/
-/obj/item/clothing/suit/space/space_ninja/proc/ninjacost(C = 0,X = 0)
- var/mob/living/carbon/human/U = affecting
- if( (U.stat||U.incorporeal_move)&&X!=3 )//Will not return if user is using an adrenaline booster since you can use them when stat==1.
- U << "\red You must be conscious and solid to do this."//It's not a problem of stat==2 since the ninja will explode anyway if they die.
- return 1
- else if(C&&cell.charge[s_bombs] smoke bombs remaining."
- var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread()
- smoke.set_up(10, 0, U.loc)
- smoke.start()
- playsound(U.loc, 'sound/effects/bamf.ogg', 50, 2)
- s_bombs--
- s_coold = 1
- return
-
-//=======//9-8 TILE TELEPORT//=======//
-//Click to to teleport 9-10 tiles in direction facing.
-/obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt()
- set name = "Phase Jaunt (10E)"
- set desc = "Utilizes the internal VOID-shift device to rapidly transit in direction facing."
- set category = "Ninja Ability"
- set popup_menu = 0
-
- var/C = 100
- if(!ninjacost(C,1))
- var/mob/living/carbon/human/U = affecting
- var/turf/destination = get_teleport_loc(U.loc,U,9,1,3,1,0,1)
- var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below.
- if(destination&&istype(mobloc, /turf))//The turf check prevents unusual behavior. Like teleporting out of cryo pods, cloners, mechs, etc.
- spawn(0)
- playsound(U.loc, "sparks", 50, 1)
- anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,U.dir)
-
- handle_teleport_grab(destination, U)
- U.loc = destination
-
- spawn(0)
- spark_system.start()
- playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1)
- playsound(U.loc, "sparks", 50, 1)
- anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
-
- spawn(0)
- destination.kill_creatures(U)//Any living mobs in teleport area are gibbed. Check turf procs for how it does it.
- s_coold = 1
- cell.charge-=(C*10)
- else
- U << "\red The VOID-shift device is malfunctioning, teleportation failed."
- return
-
-//=======//RIGHT CLICK TELEPORT//=======//
-//Right click to teleport somewhere, almost exactly like admin jump to turf.
-/obj/item/clothing/suit/space/space_ninja/proc/ninjashift(turf/T in oview())
- set name = "Phase Shift (20E)"
- set desc = "Utilizes the internal VOID-shift device to rapidly transit to a destination in view."
- set category = null//So it does not show up on the panel but can still be right-clicked.
- set src = usr.contents//Fixes verbs not attaching properly for objects. Praise the DM reference guide!
-
- var/C = 200
- if(!ninjacost(C,1))
- var/mob/living/carbon/human/U = affecting
- var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below.
- if((!T.density)&&istype(mobloc, /turf))
- spawn(0)
- playsound(U.loc, 'sound/effects/sparks4.ogg', 50, 1)
- anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,U.dir)
-
- handle_teleport_grab(T, U)
- U.loc = T
-
- spawn(0)
- spark_system.start()
- playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1)
- playsound(U.loc, 'sound/effects/sparks2.ogg', 50, 1)
- anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
-
- spawn(0)//Any living mobs in teleport area are gibbed.
- T.kill_creatures(U)
- s_coold = 1
- cell.charge-=(C*10)
- else
- U << "\red You cannot teleport into solid walls or from solid matter"
- return
-
-//=======//EM PULSE//=======//
-//Disables nearby tech equipment.
-/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse()
- set name = "EM Burst (25E)"
- set desc = "Disable any nearby technology with a electro-magnetic pulse."
- set category = "Ninja Ability"
- set popup_menu = 0
-
- var/C = 250
- if(!ninjacost(C,1))
- var/mob/living/carbon/human/U = affecting
- playsound(U.loc, 'sound/effects/EMPulse.ogg', 60, 2)
- empulse(U, 4, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch.
- s_coold = 2
- cell.charge-=(C*10)
- return
-
-//=======//ENERGY BLADE//=======//
-//Summons a blade of energy in active hand.
-/obj/item/clothing/suit/space/space_ninja/proc/ninjablade()
- set name = "Energy Blade (5E)"
- set desc = "Create a focused beam of energy in your active hand."
- set category = "Ninja Ability"
- set popup_menu = 0
-
- var/C = 50
- if(!ninjacost(C))
- var/mob/living/carbon/human/U = affecting
- if(!kamikaze)
- if(!U.get_active_hand()&&!istype(U.get_inactive_hand(), /obj/item/weapon/melee/energy/blade))
- var/obj/item/weapon/melee/energy/blade/W = new()
- spark_system.start()
- playsound(U.loc, "sparks", 50, 1)
- U.put_in_hands(W)
- cell.charge-=(C*10)
- else
- U << "\red You can only summon one blade. Try dropping an item first."
- else//Else you can run around with TWO energy blades. I don't know why you'd want to but cool factor remains.
- if(!U.get_active_hand())
- var/obj/item/weapon/melee/energy/blade/W = new()
- U.put_in_hands(W)
- if(!U.get_inactive_hand())
- var/obj/item/weapon/melee/energy/blade/W = new()
- U.put_in_inactive_hand(W)
- spark_system.start()
- playsound(U.loc, "sparks", 50, 1)
- s_coold = 1
- return
-
-//=======//NINJA STARS//=======//
-/*Shoots ninja stars at random people.
-This could be a lot better but I'm too tired atm.*/
-/obj/item/clothing/suit/space/space_ninja/proc/ninjastar()
- set name = "Energy Star (5E)"
- set desc = "Launches an energy star at a random living target."
- set category = "Ninja Ability"
- set popup_menu = 0
-
- var/C = 50
- if(!ninjacost(C))
- var/mob/living/carbon/human/U = affecting
- var/targets[] = list()//So yo can shoot while yo throw dawg
- for(var/mob/living/M in oview(loc))
- if(M.stat) continue//Doesn't target corpses or paralyzed persons.
- targets.Add(M)
- if(targets.len)
- var/mob/living/target=pick(targets)//The point here is to pick a random, living mob in oview to shoot stuff at.
-
- var/turf/curloc = U.loc
- var/atom/targloc = get_turf(target)
- if (!targloc || !istype(targloc, /turf) || !curloc)
- return
- if (targloc == curloc)
- return
- var/obj/item/projectile/energy/dart/A = new /obj/item/projectile/energy/dart(U.loc)
- A.current = curloc
- A.yo = targloc.y - curloc.y
- A.xo = targloc.x - curloc.x
- cell.charge-=(C*10)
- A.process()
- else
- U << "\red There are no targets in view."
- return
-
-//=======//ENERGY NET//=======//
-/*Allows the ninja to capture people, I guess.
-Must right click on a mob to activate.*/
-/obj/item/clothing/suit/space/space_ninja/proc/ninjanet(mob/living/carbon/M in oview())//Only living carbon mobs.
- set name = "Energy Net (20E)"
- set desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds."
- set category = null
- set src = usr.contents
-
- var/C = 200
- if(!ninjacost(C,1)&&iscarbon(M))
- var/mob/living/carbon/human/U = affecting
- if(M.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame.
- //if(M)//DEBUG
- if(!locate(/obj/effect/energy_net) in M.loc)//Check if they are already being affected by an energy net.
- for(var/turf/T in getline(U.loc, M.loc))
- if(T.density)//Don't want them shooting nets through walls. It's kind of cheesy.
- U << "You may not use an energy net through solid obstacles!"
- return
- spawn(0)
- U.Beam(M,"n_beam",,15)
- M.anchored = 1//Anchors them so they can't move.
- U.say("Get over here!")
- var/obj/effect/energy_net/E = new /obj/effect/energy_net(M.loc)
- E.layer = M.layer+1//To have it appear one layer above the mob.
- for(var/mob/O in viewers(U, 3))
- O.show_message(text("\red [] caught [] with an energy net!", U, M), 1)
- E.affecting = M
- E.master = U
- spawn(0)//Parallel processing.
- E.process(M)
- cell.charge-=(C*10)
- else
- U << "They are already trapped inside an energy net."
- else
- U << "They will bring no honor to your Clan!"
- return
-
-//=======//ADRENALINE BOOST//=======//
-/*Wakes the user so they are able to do their thing. Also injects a decent dose of radium.
-Movement impairing would indicate drugs and the like.*/
-/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost()
- set name = "Adrenaline Boost"
- set desc = "Inject a secret chemical that will counteract all movement-impairing effect."
- set category = "Ninja Ability"
- set popup_menu = 0
-
- if(!ninjacost(,3))//Have to make sure stat is not counted for this ability.
- var/mob/living/carbon/human/U = affecting
- //Wouldn't need to track adrenaline boosters if there was a miracle injection to get rid of paralysis and the like instantly.
- //For now, adrenaline boosters ARE the miracle injection. Well, radium, really.
- U.SetParalysis(0)
- U.SetStunned(0)
- U.SetWeakened(0)
- /*
- Due to lag, it was possible to adrenaline boost but remain helpless while life.dm resets player stat.
- This lead to me and others spamming adrenaline boosters because they failed to kick in on time.
- It's technically possible to come back from crit with this but it is very temporary.
- Life.dm will kick the player back into unconsciosness the next process loop.
- */
- U.stat = 0//At least now you should be able to teleport away or shoot ninja stars.
- spawn(30)//Slight delay so the enemy does not immedietly know the ability was used. Due to lag, this often came before waking up.
- U.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!"))
- spawn(70)
- reagents.reaction(U, 2)
- reagents.trans_id_to(U, "radium", a_transfer)
- U << "\red You are beginning to feel the after-effect of the injection."
- a_boost--
- s_coold = 3
- return
-
-/*
-===================================================================================
-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-===================================================================================
-Or otherwise known as anime mode. Which also happens to be ridiculously powerful.
-*/
-
-//=======//NINJA MOVEMENT//=======//
-//Also makes you move like you're on crack.
-/obj/item/clothing/suit/space/space_ninja/proc/ninjawalk()
- set name = "Shadow Walk"
- set desc = "Combines the VOID-shift and CLOAK-tech devices to freely move between solid matter. Toggle on or off."
- set category = "Ninja Ability"
- set popup_menu = 0
-
- var/mob/living/carbon/human/U = affecting
- if(!U.incorporeal_move)
- U.incorporeal_move = 2
- U << "\blue You will now phase through solid matter."
- else
- U.incorporeal_move = 0
- U << "\blue You will no-longer phase through solid matter."
- return
-
-//=======//5 TILE TELEPORT/GIB//=======//
-//Allows to gib up to five squares in a straight line. Seriously.
-/obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer()
- set name = "Phase Slayer"
- set desc = "Utilizes the internal VOID-shift device to mutilate creatures in a straight line."
- set category = "Ninja Ability"
- set popup_menu = 0
-
- if(!ninjacost())
- var/mob/living/carbon/human/U = affecting
- var/turf/destination = get_teleport_loc(U.loc,U,5)
- var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below.
- if(destination&&istype(mobloc, /turf))
- U.say("Ai Satsugai!")
- spawn(0)
- playsound(U.loc, "sparks", 50, 1)
- anim(mobloc,U,'icons/mob/mob.dmi',,"phaseout",,U.dir)
-
- spawn(0)
- for(var/turf/T in getline(mobloc, destination))
- spawn(0)
- T.kill_creatures(U)
- if(T==mobloc||T==destination) continue
- spawn(0)
- anim(T,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
-
- handle_teleport_grab(destination, U)
- U.loc = destination
-
- spawn(0)
- spark_system.start()
- playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1)
- playsound(U.loc, "sparks", 50, 1)
- anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
- s_coold = 1
- else
- U << "\red The VOID-shift device is malfunctioning, teleportation failed."
- return
-
-//=======//TELEPORT BEHIND MOB//=======//
-/*Appear behind a randomly chosen mob while a few decoy teleports appear.
-This is so anime it hurts. But that's the point.*/
-/obj/item/clothing/suit/space/space_ninja/proc/ninjamirage()
- set name = "Spider Mirage"
- set desc = "Utilizes the internal VOID-shift device to create decoys and teleport behind a random target."
- set category = "Ninja Ability"
- set popup_menu = 0
-
- if(!ninjacost())//Simply checks for stat.
- var/mob/living/carbon/human/U = affecting
- var/targets[]
- targets = new()
- for(var/mob/living/M in oview(6))
- if(M.stat) continue//Doesn't target corpses or paralyzed people.
- targets.Add(M)
- if(targets.len)
- var/mob/living/target=pick(targets)
- var/locx
- var/locy
- var/turf/mobloc = get_turf(target.loc)
- var/safety = 0
- switch(target.dir)
- if(NORTH)
- locx = mobloc.x
- locy = (mobloc.y-1)
- if(locy<1)
- safety = 1
- if(SOUTH)
- locx = mobloc.x
- locy = (mobloc.y+1)
- if(locy>world.maxy)
- safety = 1
- if(EAST)
- locy = mobloc.y
- locx = (mobloc.x-1)
- if(locx<1)
- safety = 1
- if(WEST)
- locy = mobloc.y
- locx = (mobloc.x+1)
- if(locx>world.maxx)
- safety = 1
- else safety=1
- if(!safety&&istype(mobloc, /turf))
- U.say("Kumo no Shinkiro!")
- var/turf/picked = locate(locx,locy,mobloc.z)
- spawn(0)
- playsound(U.loc, "sparks", 50, 1)
- anim(mobloc,U,'icons/mob/mob.dmi',,"phaseout",,U.dir)
-
- spawn(0)
- var/limit = 4
- for(var/turf/T in oview(5))
- if(prob(20))
- spawn(0)
- anim(T,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
- limit--
- if(limit<=0) break
-
- handle_teleport_grab(picked, U)
- U.loc = picked
- U.dir = target.dir
-
- spawn(0)
- spark_system.start()
- playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1)
- playsound(U.loc, "sparks", 50, 1)
- anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
- s_coold = 1
- else
- U << "\red The VOID-shift device is malfunctioning, teleportation failed."
- else
- U << "\red There are no targets in view."
- return
diff --git a/code/game/gamemodes/events/space_ninja.dm b/code/game/gamemodes/events/space_ninja.dm
deleted file mode 100644
index 6abc55d2fb1..00000000000
--- a/code/game/gamemodes/events/space_ninja.dm
+++ /dev/null
@@ -1,1054 +0,0 @@
-/*
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+++++++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++
-======================================SPACE NINJA SETUP====================================
-___________________________________________________________________________________________
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-*/
-
-/*
- README:
-
- Data:
-
- >> space_ninja.dm << is this file. It contains a variety of procs related to either spawning space ninjas,
- modifying their verbs, various help procs, testing debug-related content, or storing unused procs for later.
- Similar functions should go into this file, along with anything else that may not have an explicit category.
- IMPORTANT: actual ninja suit, gloves, etc, are stored under the appropriate clothing files. If you need to change
- variables or look them up, look there. Easiest way is through the map file browser.
-
- >> ninja_abilities.dm << contains all the ninja-related powers. Spawning energy swords, teleporting, and the like.
- If more powers are added, or perhaps something related to powers, it should go there. Make sure to describe
- what an ability/power does so it's easier to reference later without looking at the code.
- IMPORTANT: verbs are still somewhat funky to work with. If an argument is specified but is not referenced in a way
- BYOND likes, in the code content, the verb will fail to trigger. Nothing will happen, literally, when clicked.
- This can be bypassed by either referencing the argument properly, or linking to another proc with the argument
- attached. The latter is what I like to do for certain cases--sometimes it's necessary to do that regardless.
-
- >> ninja_equipment.dm << deals with all the equipment-related procs for a ninja. Primarily it has the suit, gloves,
- and mask. The suit is by far the largest section of code out of the three and includes a lot of code that ties in
- to other functions. This file has gotten kind of large so breaking it up may be in order. I use section hearders.
- IMPORTANT: not much to say here. Follow along with the comments and adding new functions should be a breeze. Also
- know that certain equipment pieces are linked in other files. The energy blade, for example, has special
- functions defined in the appropriate files (airlock, securestorage, etc).
-
- General Notes:
-
- I created space ninjas with the expressed purpose of spicing up boring rounds. That is, ninjas are to xenos as marauders are to
- death squads. Ninjas are stealthy, tech-savvy, and powerful. Not to say marauders are all of those things, but a clever ninja
- should have little problem murderampaging their way through just about anything. Short of admin wizards maybe.
- HOWEVER!
- Ninjas also have a fairly great weakness as they require energy to use abilities. If, theoretically, there is a game
- mode based around space ninjas, make sure to account for their energy needs.
-
- Admin Notes:
-
- Ninjas are not admin PCs--please do not use them for that purpose. They are another way to participate in the game post-death,
- like pais, xenos, death squads, and cyborgs.
- I'm currently looking for feedback from regular players since beta testing is largely done. I would appreciate if
- you spawned regular players as ninjas when rounds are boring. Or exciting, it's all good as long as there is feedback.
- You can also spawn ninja gear manually if you want to.
-
- How to do that:
- Make sure your character has a mind.
- Change their assigned_role to "MODE", no quotes. Otherwise, the suit won't initialize.
- Change their special_role to "Space Ninja", no quotes. Otherwise, the character will be gibbed.
- Spawn ninja gear, put it on, hit initialize. Let the suit do the rest. You are now a space ninja.
- I don't recommend messing with suit variables unless you really know what you're doing.
-
- Miscellaneous Notes:
-
- Potential Upgrade Tree:
- Energy Shield:
- Extra Ability
- Syndicate Shield device?
- Works like the force wall spell, except can be kept indefinitely as long as energy remains. Toggled on or off.
- Would block bullets and the like.
- Phase Shift
- Extra Ability
- Advanced Sensors?
- Instead of being unlocked at the start, Phase Shieft would become available once requirements are met.
- Uranium-based Recharger:
- Suit Upgrade
- Unsure
- Instead of losing energy each second, the suit would regain the same amount of energy.
- This would not count in activating stealth and similar.
- Extended Battery Life:
- Suit Upgrade
- Battery of higher capacity
- Already implemented. Replace current battery with one of higher capacity.
- Advanced Cloak-Tech device.
- Suit Upgrade
- Syndicate Cloaking Device?
- Remove cloak failure rate.
-*/
-
-//=======//RANDOM EVENT//=======//
-/*
-Also a dynamic ninja mission generator.
-I decided to scrap round-specific objectives since keeping track of them would require some form of tracking.
-When I already created about 4 new objectives, this doesn't seem terribly important or needed.
-*/
-
-/var/global/toggle_space_ninja = 1//If ninjas can spawn or not.
-/var/global/sent_ninja_to_station = 0//If a ninja is already on the station.
-
-var/ninja_selection_id = 1
-var/ninja_selection_active = 0
-var/ninja_confirmed_selection = 0
-
-/proc/space_ninja_arrival(var/assign_key = null, var/assign_mission = null)
-
- if(ninja_selection_active)
- usr << "\red Ninja selection already in progress. Please wait until it ends."
- return
-
- var/datum/game_mode/current_mode = ticker.mode
- var/datum/mind/current_mind
-
- /*Is the ninja playing for the good or bad guys? Is the ninja helping or hurting the station?
- Their directives also influence behavior. At least in theory.*/
- var/side = pick("face","heel")
-
- var/antagonist_list[] = list()//The main bad guys. Evil minds that plot destruction.
- var/protagonist_list[] = current_mode.get_living_heads()//The good guys. Mostly Heads. Who are alive.
-
- var/xeno_list[] = list()//Aliens.
- var/commando_list[] = list()//Commandos.
-
- //We want the ninja to appear only in certain modes.
-// var/acceptable_modes_list[] = list("traitor","revolution","cult","wizard","changeling","traitorchan","nuclear","malfunction","monkey") // Commented out for both testing and ninjas
-// if(!(current_mode.config_tag in acceptable_modes_list))
-// return
-
- /*No longer need to determine what mode it is since bad guys are basically universal.
- And there is now a mode with two types of bad guys.*/
-
- var/possible_bad_dudes[] = list(current_mode.traitors,current_mode.head_revolutionaries,current_mode.head_revolutionaries,
- current_mode.cult,current_mode.wizards,current_mode.changelings,current_mode.syndicates)
- for(var/list in possible_bad_dudes)//For every possible antagonist type.
- for(current_mind in list)//For each mind in that list.
- if(current_mind.current&¤t_mind.current.stat!=2)//If they are not destroyed and not dead.
- antagonist_list += current_mind//Add them.
-
- if(protagonist_list.len)//If the mind is both a protagonist and antagonist.
- for(current_mind in protagonist_list)
- if(current_mind in antagonist_list)
- protagonist_list -= current_mind//We only want it in one list.
-/*
-Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective completion. Only humans are added.
-*/
-
- //Here we pick a location and spawn the ninja.
- var/list/spawn_list = list()
- for(var/obj/effect/landmark/L in landmarks_list)
- if(L.name == "ninjaspawn")
- spawn_list.Add(L)
-
- if(!spawn_list.len)
- for(var/obj/effect/landmark/L in landmarks_list)
- if(L.name == "carpspawn")
- spawn_list.Add(L)
-
- var/ninja_key = null
-
- if(assign_key)
- ninja_key = assign_key
- else
-
- var/list/candidates = list() //list of candidate keys
- for(var/mob/dead/observer/G in player_list)
- if(G.client && !G.client.holder && !G.client.is_afk())
- if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
- candidates += G.key
- if(!candidates.len) return
- candidates = shuffle(candidates)//Incorporating Donkie's list shuffle
-
- ninja_key = pick(candidates)
-
-
- var/mob/candidate_mob
- for(var/mob/M in player_list)
- if((M.key == ninja_key || M.ckey == ninja_key) && M.client)
- candidate_mob = M
- break
-
- if(!candidate_mob)
- usr << "\red The randomly chosen mob was not found in the second check."
- return
-
- ninja_selection_active = 1
- ninja_selection_id++
- var/this_selection_id = ninja_selection_id
-
- spawn(1)
- if(alert(candidate_mob, "You have been selected to play as a space ninja. Would you like to play as this role? (You have 30 seconds to accept - You will spawn in 30 seconds if you accept)",,"Yes","No")!="Yes")
- usr << "\red The selected candidate for space ninja declined."
- return
-
- ninja_confirmed_selection = this_selection_id
-
- spawn(300)
- if(!ninja_selection_active || (this_selection_id != ninja_selection_id ))
- ninja_selection_active = 0
- candidate_mob << "\red Sorry, you were too late. You only had 30 seconds to accept."
- return
-
- if(ninja_confirmed_selection != ninja_selection_id)
- ninja_selection_active = 0
- usr << "\red The ninja did not accept the role in time."
- return
-
- ninja_selection_active = 0
-
- //The ninja will be created on the right spawn point or at late join.
- var/mob/living/carbon/human/new_ninja = create_space_ninja(pick(spawn_list.len ? spawn_list : latejoin ))
- new_ninja.key = ninja_key
- new_ninja.wear_suit:randomize_param()//Give them a random set of suit parameters.
- new_ninja.internal = new_ninja.s_store //So the poor ninja has something to breath when they spawn in spess.
- new_ninja.internals.icon_state = "internal1"
-
- //Now for the rest of the stuff.
-
- var/datum/mind/ninja_mind = new_ninja.mind//For easier reference.
- var/mission_set = 0//To determine if we need to do further processing.
- //Xenos and deathsquads take precedence over everything else.
-
- //Unless the xenos are hiding in a locker somewhere, this'll find em.
- for(var/mob/living/carbon/alien/humanoid/xeno in player_list)
- if(istype(xeno))
- xeno_list += xeno
-
- if(assign_mission)
- new_ninja.mind.store_memory("Mission: \red [assign_mission].
")
- new_ninja << "\blue \nYou are an elite mercenary assassin of the Spider Clan, [new_ninja.real_name]. The dreaded \red SPACE NINJA!\blue You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor. Remember your training! \nYour current mission is: \red [assign_mission]"
- else
- if(xeno_list.len>3)//If there are more than three humanoid xenos on the station, time to get dangerous.
- //Here we want the ninja to murder all the queens. The other aliens don't really matter.
- var/xeno_queen_list[] = list()
- for(var/mob/living/carbon/alien/humanoid/queen/xeno_queen in xeno_list)
- if(xeno_queen.mind&&xeno_queen.stat!=2)
- xeno_queen_list += xeno_queen
- if(xeno_queen_list.len&&side=="face")//If there are queen about and the probability is 50.
- for(var/mob/living/carbon/alien/humanoid/queen/xeno_queen in xeno_queen_list)
- var/datum/objective/assassinate/ninja_objective = new
- //We'll do some manual overrides to properly set it up.
- ninja_objective.owner = ninja_mind
- ninja_objective.target = xeno_queen.mind
- ninja_objective.explanation_text = "Kill \the [xeno_queen]."
- ninja_mind.objectives += ninja_objective
- mission_set = 1
-
- if(sent_strike_team&&side=="heel"&&antagonist_list.len)//If a strike team was sent, murder them all like a champ.
- for(current_mind in antagonist_list)//Search and destroy. Since we already have an antagonist list, they should appear there.
- if(current_mind && current_mind.special_role=="Death Commando")
- commando_list += current_mind
- if(commando_list.len)//If there are living commandos still in play.
- for(var/mob/living/carbon/human/commando in commando_list)
- var/datum/objective/assassinate/ninja_objective = new
- ninja_objective.owner = ninja_mind
- ninja_objective.find_target_by_role(commando.mind.special_role,1)
- ninja_mind.objectives += ninja_objective
- mission_set = 1
- /*
- If there are no antogonists left it could mean one of two things:
- A) The round is about to end. No harm in spawning the ninja here.
- B) The round is still going and ghosts are probably rioting for something to happen.
- In either case, it's a good idea to spawn the ninja with a semi-random set of objectives.
- */
- if(!mission_set)//If mission was not set.
-
- var/current_minds[]//List being looked on in the following code.
- var/side_list = side=="face" ? 2 : 1//For logic gating.
- var/hostile_targets[] = list()//The guys actually picked for the assassination or whatever.
- var/friendly_targets[] = list()//The guys the ninja must protect.
-
- for(var/i=2,i>0,i--)//Two lists.
- current_minds = i==2 ? antagonist_list : protagonist_list//Which list are we looking at?
- for(var/t=3,(current_minds.len&&t>0),t--)//While the list is not empty and targets remain. Also, 3 targets is good.
- current_mind = pick(current_minds)//Pick a random person.
- /*I'm creating a logic gate here based on the ninja affiliation that compares the list being
- looked at to the affiliation. Affiliation is just a number used to compare. Meaning comes from the logic involved.
- If the list being looked at is equal to the ninja's affiliation, add the mind to hostiles.
- If not, add the mind to friendlies. Since it can't be both, it will be added only to one or the other.*/
- hostile_targets += i==side_list ? current_mind : null//Adding null doesn't add anything.
- friendly_targets += i!=side_list ? current_mind : null
- current_minds -= current_mind//Remove the mind so it's not picked again.
-
- var/objective_list[] = list(1,2,3,4,5,6)//To remove later.
- for(var/i=rand(1,3),i>0,i--)//Want to get a few random objectives. Currently up to 3.
- if(!hostile_targets.len)//Remove appropriate choices from switch list if the target lists are empty.
- objective_list -= 1
- objective_list -= 4
- if(!friendly_targets.len)
- objective_list -= 3
- switch(pick(objective_list))
- if(1)//kill
- current_mind = pick(hostile_targets)
-
- if(current_mind)
- var/datum/objective/assassinate/ninja_objective = new
- ninja_objective.owner = ninja_mind
- ninja_objective.find_target_by_role((current_mind.special_role ? current_mind.special_role : current_mind.assigned_role),(current_mind.special_role?1:0))//If they have a special role, use that instead to find em.
- ninja_mind.objectives += ninja_objective
-
- else
- i++
-
- hostile_targets -= current_mind//Remove them from the list.
- if(2)//Steal
- var/datum/objective/steal/ninja_objective = new
- var/target_item = pick(ninja_objective.possible_items_special)
- ninja_objective.set_target(target_item)
- ninja_mind.objectives += ninja_objective
-
- objective_list -= 2
- if(3)//Protect. Keeping people alive can be pretty difficult.
- current_mind = pick(friendly_targets)
-
- if(current_mind)
-
- var/datum/objective/protect/ninja_objective = new
- ninja_objective.owner = ninja_mind
- ninja_objective.find_target_by_role((current_mind.special_role ? current_mind.special_role : current_mind.assigned_role),(current_mind.special_role?1:0))
- ninja_mind.objectives += ninja_objective
-
- else
- i++
-
- friendly_targets -= current_mind
- if(4)//Debrain
- current_mind = pick(hostile_targets)
-
- if(current_mind)
-
- var/datum/objective/debrain/ninja_objective = new
- ninja_objective.owner = ninja_mind
- ninja_objective.find_target_by_role((current_mind.special_role ? current_mind.special_role : current_mind.assigned_role),(current_mind.special_role?1:0))
- ninja_mind.objectives += ninja_objective
-
- else
- i++
-
- hostile_targets -= current_mind//Remove them from the list.
- if(5)//Download research
- var/datum/objective/download/ninja_objective = new
- ninja_objective.gen_amount_goal()
- ninja_mind.objectives += ninja_objective
-
- objective_list -= 5
- if(6)//Capture
- var/datum/objective/capture/ninja_objective = new
- ninja_objective.gen_amount_goal()
- ninja_mind.objectives += ninja_objective
-
- objective_list -= 6
-
- if(ninja_mind.objectives.len)//If they got some objectives out of that.
- mission_set = 1
-
- if(!ninja_mind.objectives.len||!mission_set)//If they somehow did not get an objective at this point, time to destroy the station.
- var/nuke_code
- var/temp_code
- for(var/obj/machinery/nuclearbomb/N in world)
- temp_code = text2num(N.r_code)
- if(temp_code)//if it's actually a number. It won't convert any non-numericals.
- nuke_code = N.r_code
- break
- if(nuke_code)//If there is a nuke device in world and we got the code.
- var/datum/objective/nuclear/ninja_objective = new//Fun.
- ninja_objective.owner = ninja_mind
- ninja_objective.explanation_text = "Destroy the station with a nuclear device. The code is [nuke_code]." //Let them know what the code is.
-
- //Finally add a survival objective since it's usually broad enough for any round type.
- var/datum/objective/survive/ninja_objective = new
- ninja_objective.owner = ninja_mind
- ninja_mind.objectives += ninja_objective
-
- var/directive = generate_ninja_directive(side)
- new_ninja << "\blue \nYou are an elite mercenary assassin of the Spider Clan, [new_ninja.real_name]. The dreaded \red SPACE NINJA!\blue You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor. Remember your training (initialize your suit by right clicking on it)! \nYour current directive is: \red [directive]"
- new_ninja.mind.store_memory("Directive: \red [directive]
")
-
- var/obj_count = 1
- new_ninja << "\blue Your current objectives:"
- for(var/datum/objective/objective in ninja_mind.objectives)
- new_ninja << "Objective #[obj_count]: [objective.explanation_text]"
- obj_count++
-
- sent_ninja_to_station = 1//And we're done.
- return new_ninja//Return the ninja in case we need to reference them later.
-
-/*
-This proc will give the ninja a directive to follow. They are not obligated to do so but it's a fun roleplay reminder.
-Making this random or semi-random will probably not work without it also being incredibly silly.
-As such, it's hard-coded for now. No reason for it not to be, really.
-*/
-/proc/generate_ninja_directive(side)
- var/directive = "[side=="face"?"Nanotrasen":"The Syndicate"] is your employer. "//Let them know which side they're on.
- switch(rand(1,13))
- if(1)
- directive += "The Spider Clan must not be linked to this operation. Remain as hidden and covert as possible."
- if(2)
- directive += "[station_name] is financed by an enemy of the Spider Clan. Cause as much structural damage as possible."
- if(3)
- directive += "A wealthy animal rights activist has made a request we cannot refuse. Prioritize saving animal lives whenever possible."
- if(4)
- directive += "The Spider Clan absolutely cannot be linked to this operation. Eliminate all witnesses using most extreme prejudice."
- if(5)
- directive += "We are currently negotiating with Nanotrasen command. Prioritize saving human lives over ending them."
- if(6)
- directive += "We are engaged in a legal dispute over [station_name]. If a laywer is present on board, force their cooperation in the matter."
- if(7)
- directive += "A financial backer has made an offer we cannot refuse. Implicate Syndicate involvement in the operation."
- if(8)
- directive += "Let no one question the mercy of the Spider Clan. Ensure the safety of all non-essential personnel you encounter."
- if(9)
- directive += "A free agent has proposed a lucrative business deal. Implicate Nanotrasen involvement in the operation."
- if(10)
- directive += "Our reputation is on the line. Harm as few civilians or innocents as possible."
- if(11)
- directive += "Our honor is on the line. Utilize only honorable tactics when dealing with opponents."
- if(12)
- directive += "We are currently negotiating with a Syndicate leader. Disguise assassinations as suicide or another natural cause."
- else
- directive += "There are no special supplemental instructions at this time."
- return directive
-
-//=======//CURRENT PLAYER VERB//=======//
-
-/client/proc/cmd_admin_ninjafy(var/mob/M in player_list)
- set category = null
- set name = "Make Space Ninja"
-
- if(!ticker)
- alert("Wait until the game starts")
- return
- if(!toggle_space_ninja)
- alert("Space Ninjas spawning is disabled.")
- return
-
- var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
- if(confirm != "Yes") return
-
- if(ishuman(M))
- log_admin("[key_name(src)] turned [M.key] into a Space Ninja.")
- spawn(10)
- M:create_mind_space_ninja()
- M:equip_space_ninja(1)
- if(istype(M:wear_suit, /obj/item/clothing/suit/space/space_ninja))
- M:wear_suit:randomize_param()
- spawn(0)
- M:wear_suit:ninitialize(10,M)
- else
- alert("Invalid mob")
-
-//=======//CURRENT GHOST VERB//=======//
-
-/client/proc/send_space_ninja()
- set category = "Fun"
- set name = "Spawn Space Ninja"
- set desc = "Spawns a space ninja for when you need a teenager with attitude."
- set popup_menu = 0
-
- if(!holder)
- src << "Only administrators may use this command."
- return
- if(!ticker.mode)
- alert("The game hasn't started yet!")
- return
- if(!toggle_space_ninja)
- alert("Space Ninjas spawning is disabled.")
- return
- if(alert("Are you sure you want to send in a space ninja?",,"Yes","No")=="No")
- return
-
- var/mission
- while(!mission)
- mission = copytext(sanitize(input(src, "Please specify which mission the space ninja shall undertake.", "Specify Mission", "")),1,MAX_MESSAGE_LEN)
- if(!mission)
- if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes")
- return
-
- var/input = ckey(input("Pick character to spawn as the Space Ninja", "Key", ""))
- if(!input)
- return
-
- space_ninja_arrival(input, mission)
-
- message_admins("\blue [key_name_admin(key)] has spawned [input] as a Space Ninja.\nTheir mission is: [mission]")
- log_admin("[key] used Spawn Space Ninja.")
-
- return
-
-//=======//NINJA CREATION PROCS//=======//
-
-/proc/create_space_ninja(obj/spawn_point)
- var/mob/living/carbon/human/new_ninja = new(spawn_point.loc)
- var/ninja_title = pick(ninja_titles)
- var/ninja_name = pick(ninja_names)
- new_ninja.gender = pick(MALE, FEMALE)
-
- var/datum/preferences/A = new()//Randomize appearance for the ninja.
- A.randomize_appearance_for(new_ninja)
- new_ninja.real_name = "[ninja_title] [ninja_name]"
- new_ninja.dna.ready_dna(new_ninja)
- new_ninja.create_mind_space_ninja()
- new_ninja.equip_space_ninja()
- return new_ninja
-
-/mob/living/carbon/human/proc/create_mind_space_ninja()
- mind_initialize()
- mind.assigned_role = "MODE"
- mind.special_role = "Space Ninja"
-
- //Adds them to current traitor list. Which is really the extra antagonist list.
- ticker.mode.traitors |= mind
- return 1
-
-/mob/living/carbon/human/proc/equip_space_ninja(safety=0)//Safety in case you need to unequip stuff for existing characters.
- if(safety)
- del(w_uniform)
- del(wear_suit)
- del(wear_mask)
- del(head)
- del(shoes)
- del(gloves)
-
- var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src)
- equip_to_slot_or_del(R, slot_ears)
- if(gender==FEMALE)
- equip_to_slot_or_del(new /obj/item/clothing/under/color/blackf(src), slot_w_uniform)
- else
- equip_to_slot_or_del(new /obj/item/clothing/under/color/black(src), slot_w_uniform)
- equip_to_slot_or_del(new /obj/item/clothing/shoes/space_ninja(src), slot_shoes)
- equip_to_slot_or_del(new /obj/item/clothing/suit/space/space_ninja(src), slot_wear_suit)
- equip_to_slot_or_del(new /obj/item/clothing/gloves/space_ninja(src), slot_gloves)
- equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/space_ninja(src), slot_head)
- equip_to_slot_or_del(new /obj/item/clothing/mask/gas/voice/space_ninja(src), slot_wear_mask)
- equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_belt)
- equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_r_store)
- equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_l_store)
- equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen(src), slot_s_store)
- return 1
-
-//=======//HELPER PROCS//=======//
-
-//Randomizes suit parameters.
-/obj/item/clothing/suit/space/space_ninja/proc/randomize_param()
- s_cost = rand(1,20)
- s_acost = rand(20,100)
- k_cost = rand(100,500)
- k_damage = rand(1,20)
- s_delay = rand(10,100)
- s_bombs = rand(5,20)
- a_boost = rand(1,7)
-
-//This proc prevents the suit from being taken off.
-/obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/U, X = 0)
- if(X)//If you want to check for icons.
- icon_state = U.gender==FEMALE ? "s-ninjanf" : "s-ninjan"
- U:gloves.icon_state = "s-ninjan"
- U:gloves.item_state = "s-ninjan"
- else
- if(U.mind.special_role!="Space Ninja")
- U << "\red fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR..."
- U.gib()
- return 0
- if(!istype(U:head, /obj/item/clothing/head/helmet/space/space_ninja))
- U << "\red ERROR: 100113 \black UNABLE TO LOCATE HEAD GEAR\nABORTING..."
- return 0
- if(!istype(U:shoes, /obj/item/clothing/shoes/space_ninja))
- U << "\red ERROR: 122011 \black UNABLE TO LOCATE FOOT GEAR\nABORTING..."
- return 0
- if(!istype(U:gloves, /obj/item/clothing/gloves/space_ninja))
- U << "\red ERROR: 110223 \black UNABLE TO LOCATE HAND GEAR\nABORTING..."
- return 0
-
- affecting = U
- canremove = 0
- slowdown = 0
- n_hood = U:head
- n_hood.canremove=0
- n_shoes = U:shoes
- n_shoes.canremove=0
- n_shoes.slowdown--
- n_gloves = U:gloves
- n_gloves.canremove=0
-
- return 1
-
-//This proc allows the suit to be taken off.
-/obj/item/clothing/suit/space/space_ninja/proc/unlock_suit()
- affecting = null
- canremove = 1
- slowdown = 1
- icon_state = "s-ninja"
- if(n_hood)//Should be attached, might not be attached.
- n_hood.canremove=1
- if(n_shoes)
- n_shoes.canremove=1
- n_shoes.slowdown++
- if(n_gloves)
- n_gloves.icon_state = "s-ninja"
- n_gloves.item_state = "s-ninja"
- n_gloves.canremove=1
- n_gloves.candrain=0
- n_gloves.draining=0
-
-//Allows the mob to grab a stealth icon.
-/mob/proc/NinjaStealthActive(atom/A)//A is the atom which we are using as the overlay.
- invisibility = INVISIBILITY_LEVEL_TWO//Set ninja invis to 2.
- var/icon/opacity_icon = new(A.icon, A.icon_state)
- var/icon/alpha_mask = getIconMask(src)
- var/icon/alpha_mask_2 = new('icons/effects/effects.dmi', "at_shield1")
- alpha_mask.AddAlphaMask(alpha_mask_2)
- opacity_icon.AddAlphaMask(alpha_mask)
- for(var/i=0,i<5,i++)//And now we add it as overlays. It's faster than creating an icon and then merging it.
- var/image/I = image("icon" = opacity_icon, "icon_state" = A.icon_state, "layer" = layer+0.8)//So it's above other stuff but below weapons and the like.
- switch(i)//Now to determine offset so the result is somewhat blurred.
- if(1)
- I.pixel_x -= 1
- if(2)
- I.pixel_x += 1
- if(3)
- I.pixel_y -= 1
- if(4)
- I.pixel_y += 1
-
- overlays += I//And finally add the overlay.
- overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9)
-
-//When ninja steal malfunctions.
-/mob/proc/NinjaStealthMalf()
- invisibility = 0//Set ninja invis to 0.
- overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9)
- playsound(loc, 'sound/effects/stealthoff.ogg', 75, 1)
-
-//=======//GENERIC VERB MODIFIERS//=======//
-
-/obj/item/clothing/suit/space/space_ninja/proc/grant_equip_verbs()
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/init
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth
- n_gloves.verbs += /obj/item/clothing/gloves/space_ninja/proc/toggled
-
- s_initialized = 1
-
-/obj/item/clothing/suit/space/space_ninja/proc/remove_equip_verbs()
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/init
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth
- if(n_gloves)
- n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled
-
- s_initialized = 0
-
-/obj/item/clothing/suit/space/space_ninja/proc/grant_ninja_verbs()
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjashift
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjablade
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet
-
- s_initialized=1
- slowdown=0
-
-/obj/item/clothing/suit/space/space_ninja/proc/remove_ninja_verbs()
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjashift
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjablade
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjanet
-
-//=======//KAMIKAZE VERBS//=======//
-
-/obj/item/clothing/suit/space/space_ninja/proc/grant_kamikaze(mob/living/carbon/U)
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjashift
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjanet
-
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjawalk
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjamirage
-
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth
-
- kamikaze = 1
-
- icon_state = U.gender==FEMALE ? "s-ninjakf" : "s-ninjak"
- if(n_gloves)
- n_gloves.icon_state = "s-ninjak"
- n_gloves.item_state = "s-ninjak"
- n_gloves.candrain = 0
- n_gloves.draining = 0
- n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled
-
- cancel_stealth()
-
- U << browse(null, "window=spideros")
- U << "\red Do or Die, LET'S ROCK!!"
-
-/obj/item/clothing/suit/space/space_ninja/proc/remove_kamikaze(mob/living/carbon/U)
- if(kamikaze)
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjashift
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet
-
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjawalk
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjamirage
-
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth
- if(n_gloves)
- n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled
-
- U.incorporeal_move = 0
- kamikaze = 0
- k_unlock = 0
- U << "\blue Disengaging mode...\n\blackCODE NAME: \red KAMIKAZE"
-
-//=======//AI VERBS//=======//
-
-/obj/item/clothing/suit/space/space_ninja/proc/grant_AI_verbs()
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_return_control
-
- s_busy = 0
- s_control = 0
-
-/obj/item/clothing/suit/space/space_ninja/proc/remove_AI_verbs()
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja
- verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_return_control
-
- s_control = 1
-
-//=======//OLD & UNUSED//=======//
-
-/*
-
-Deprecated. get_dir() does the same thing. Still a nice proc.
-Returns direction that the mob or whomever should be facing in relation to the target.
-This proc does not grant absolute direction and is mostly useful for 8dir sprite positioning.
-I personally used it with getline() to great effect.
-/proc/get_dir_to(turf/start,turf/end)//N
- var/xdiff = start.x - end.x//The sign is important.
- var/ydiff = start.y - end.y
-
- var/direction_x = xdiff<1 ? 4:8//East - west
- var/direction_y = ydiff<1 ? 1:2//North - south
- var/direction_xy = xdiff==0 ? -4:0//If x is the same, subtract 4.
- var/direction_yx = ydiff==0 ? -1:0//If y is the same, subtract 1.
- var/direction_f = direction_x+direction_y+direction_xy+direction_yx//Finally direction tally.
- direction_f = direction_f==0 ? 1:direction_f//If direction is 0(same spot), return north. Otherwise, direction.
-
- return direction_f
-
-Alternative and inferior method of calculating spideros.
-var/temp = num2text(spideros)
-var/return_to = copytext(temp, 1, (length(temp)))//length has to be to the length of the thing because by default it's length+1
-spideros = text2num(return_to)//Maximum length here is 6. Use (return_to, X) to specify larger strings if needed.
-
-//Old way of draining from wire.
-/obj/item/clothing/gloves/space_ninja/proc/drain_wire()
- set name = "Drain From Wire"
- set desc = "Drain energy directly from an exposed wire."
- set category = "Ninja Equip"
-
- var/obj/structure/cable/attached
- var/mob/living/carbon/human/U = loc
- if(candrain&&!draining)
- var/turf/T = U.loc
- if(isturf(T) && T.is_plating())
- attached = locate() in T
- if(!attached)
- U << "\red Warning: no exposed cable available."
- else
- U << "\blue Connecting to wire, stand still..."
- if(do_after(U,50)&&!isnull(attached))
- drain("WIRE",attached,U:wear_suit,src)
- else
- U << "\red Procedure interrupted. Protocol terminated."
- return
-
-I've tried a lot of stuff but adding verbs to the AI while inside an object, inside another object, did not want to work properly.
-This was the best work-around I could come up with at the time. Uses objects to then display to panel, based on the object spell system.
-Can be added on to pretty easily.
-
-BYOND fixed the verb bugs so this is no longer necessary. I prefer verb panels.
-
-/obj/item/clothing/suit/space/space_ninja/proc/grant_AI_verbs()
- var/obj/effect/proc_holder/ai_return_control/A_C = new(AI)
- var/obj/effect/proc_holder/ai_hack_ninja/B_C = new(AI)
- var/obj/effect/proc_holder/ai_instruction/C_C = new(AI)
- new/obj/effect/proc_holder/ai_holo_clear(AI)
- AI.proc_holder_list += A_C
- AI.proc_holder_list += B_C
- AI.proc_holder_list += C_C
-
- s_control = 0
-
-/obj/item/clothing/suit/space/space_ninja/proc/remove_AI_verbs()
- var/obj/effect/proc_holder/ai_return_control/A_C = locate() in AI
- var/obj/effect/proc_holder/ai_hack_ninja/B_C = locate() in AI
- var/obj/effect/proc_holder/ai_instruction/C_C = locate() in AI
- var/obj/effect/proc_holder/ai_holo_clear/D_C = locate() in AI
- del(A_C)
- del(B_C)
- del(C_C)
- del(D_C)
- AI.proc_holder_list = list()
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros
- verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth
-
- s_control = 1
-
-//Workaround
-/obj/effect/proc_holder/ai_holo_clear
- name = "Clear Hologram"
- desc = "Stops projecting the current holographic image."
- panel = "AI Ninja Equip"
- density = 0
- opacity = 0
-
-
-/obj/effect/proc_holder/ai_holo_clear/Click()
- var/obj/item/clothing/suit/space/space_ninja/S = loc.loc//This is so stupid but makes sure certain things work. AI.SUIT
- del(S.hologram.i_attached)
- del(S.hologram)
- var/obj/effect/proc_holder/ai_holo_clear/D_C = locate() in S.AI
- S.AI.proc_holder_list -= D_C
- return
-
-/obj/effect/proc_holder/ai_instruction//Let's the AI know what they can do.
- name = "Instructions"
- desc = "Displays a list of helpful information."
- panel = "AI Ninja Equip"
- density = 0
- opacity = 0
-
-/obj/effect/proc_holder/ai_instruction/Click()
- loc << "The menu you are seeing will contain other commands if they become available.\nRight click a nearby turf to display an AI Hologram. It will only be visible to you and your host. You can move it freely using normal movement keys--it will disappear if placed too far away."
-
-/obj/effect/proc_holder/ai_hack_ninja//Generic proc holder to make sure the two verbs below work propely.
- name = "Hack SpiderOS"
- desc = "Hack directly into the Black Widow(tm) neuro-interface."
- panel = "AI Ninja Equip"
- density = 0
- opacity = 0
-
-/obj/effect/proc_holder/ai_hack_ninja/Click()//When you click on it.
- var/obj/item/clothing/suit/space/space_ninja/S = loc.loc
- S.hack_spideros()
- return
-
-/obj/effect/proc_holder/ai_return_control
- name = "Relinquish Control"
- desc = "Return control to the user."
- panel = "AI Ninja Equip"
- density = 0
- opacity = 0
-
-/obj/effect/proc_holder/ai_return_control/Click()
- var/mob/living/silicon/ai/A = loc
- var/obj/item/clothing/suit/space/space_ninja/S = A.loc
- A << browse(null, "window=hack spideros")//Close window
- A << "You have seized your hacking attempt. [S.affecting] has regained control."
- S.affecting << "UPDATE: [A.real_name] has ceased hacking attempt. All systems clear."
- S.remove_AI_verbs()
- return
-*/
-
-//=======//DEBUG//=======//
-/*
-/obj/item/clothing/suit/space/space_ninja/proc/display_verb_procs()
-//DEBUG
-//Does nothing at the moment. I am trying to see if it's possible to mess around with verbs as variables.
- //for(var/P in verbs)
-// if(P.set.name)
-// usr << "[P.set.name], path: [P]"
- return
-
-
-Most of these are at various points of incomplete.
-
-/mob/verb/grant_object_panel()
- set name = "Grant AI Ninja Verbs Debug"
- set category = "Ninja Debug"
- var/obj/effect/proc_holder/ai_return_control/A_C = new(src)
- var/obj/effect/proc_holder/ai_hack_ninja/B_C = new(src)
- usr:proc_holder_list += A_C
- usr:proc_holder_list += B_C
-
-mob/verb/remove_object_panel()
- set name = "Remove AI Ninja Verbs Debug"
- set category = "Ninja Debug"
- var/obj/effect/proc_holder/ai_return_control/A = locate() in src
- var/obj/effect/proc_holder/ai_hack_ninja/B = locate() in src
- usr:proc_holder_list -= A
- usr:proc_holder_list -= B
- del(A)//First.
- del(B)//Second, to keep the proc going.
- return
-
-/client/verb/grant_verb_ninja_debug1(var/mob/M in view())
- set name = "Grant AI Ninja Verbs Debug"
- set category = "Ninja Debug"
-
- M.verbs += /mob/living/silicon/ai/verb/ninja_return_control
- M.verbs += /mob/living/silicon/ai/verb/ninja_spideros
- return
-
-/client/verb/grant_verb_ninja_debug2(var/mob/living/carbon/human/M in view())
- set name = "Grant Back Ninja Verbs"
- set category = "Ninja Debug"
-
- M.wear_suit.verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit
- M.wear_suit.verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros
- return
-
-/obj/proc/grant_verb_ninja_debug3(var/mob/living/silicon/ai/A as mob)
- set name = "Grant AI Ninja Verbs"
- set category = "null"
- set hidden = 1
- A.verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit
- A.verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros
- return
-
-/mob/verb/get_dir_to_target(var/mob/M in oview())
- set name = "Get Direction to Target"
- set category = "Ninja Debug"
-
- world << "DIR: [get_dir_to(src.loc,M.loc)]"
- return
-//
-/mob/verb/kill_self_debug()
- set name = "DEBUG Kill Self"
- set category = "Ninja Debug"
-
- src:death()
-
-/client/verb/switch_client_debug()
- set name = "DEBUG Switch Client"
- set category = "Ninja Debug"
-
- mob = mob:loc:loc
-
-/mob/verb/possess_mob(var/mob/M in oview())
- set name = "DEBUG Possess Mob"
- set category = "Ninja Debug"
-
- client.mob = M
-
-/client/verb/switcharoo(var/mob/M in oview())
- set name = "DEBUG Switch to AI"
- set category = "Ninja Debug"
-
- var/mob/last_mob = mob
- mob = M
- last_mob:wear_suit:AI:key = key
-//
-/client/verb/ninjaget(var/mob/M in oview())
- set name = "DEBUG Ninja GET"
- set category = "Ninja Debug"
-
- mob = M
- M.gib()
- space_ninja()
-
-/mob/verb/set_debug_ninja_target()
- set name = "Set Debug Target"
- set category = "Ninja Debug"
-
- ninja_debug_target = src//The target is you, brohime.
- world << "Target: [src]"
-
-/mob/verb/hack_spideros_debug()
- set name = "Debug Hack Spider OS"
- set category = "Ninja Debug"
-
- var/mob/living/silicon/ai/A = loc:AI
- if(A)
- if(!A.key)
- A.client.mob = loc:affecting
- else
- loc:affecting:client:mob = A
- return
-
-//Tests the net and what it does.
-/mob/verb/ninjanet_debug()
- set name = "Energy Net Debug"
- set category = "Ninja Debug"
-
- var/obj/effect/energy_net/E = new /obj/effect/energy_net(loc)
- E.layer = layer+1//To have it appear one layer above the mob.
- stunned = 10//So they are stunned initially but conscious.
- anchored = 1//Anchors them so they can't move.
- E.affecting = src
- spawn(0)//Parallel processing.
- E.process(src)
- return
-
-I made this as a test for a possible ninja ability (or perhaps more) for a certain mob to see hallucinations.
-The thing here is that these guys have to be coded to do stuff as they are simply images that you can't even click on.
-That is why you attached them to objects.
-/mob/verb/TestNinjaShadow()
- set name = "Test Ninja Ability"
- set category = "Ninja Debug"
-
- if(client)
- var/safety = 4
- for(var/turf/T in oview(5))
- if(prob(20))
- var/current_clone = image('icons/mob/mob.dmi',T,"s-ninja")
- safety--
- spawn(0)
- src << current_clone
- spawn(300)
- del(current_clone)
- spawn while(!isnull(current_clone))
- step_to(current_clone,src,1)
- sleep(5)
- if(safety<=0) break
- return */
-
-//Alternate ninja speech replacement.
-/*This text is hilarious but also absolutely retarded.
-message = replacetext(message, "l", "r")
-message = replacetext(message, "rr", "ru")
-message = replacetext(message, "v", "b")
-message = replacetext(message, "f", "hu")
-message = replacetext(message, "'t", "")
-message = replacetext(message, "t ", "to ")
-message = replacetext(message, " I ", " ai ")
-message = replacetext(message, "th", "z")
-message = replacetext(message, "ish", "isu")
-message = replacetext(message, "is", "izu")
-message = replacetext(message, "ziz", "zis")
-message = replacetext(message, "se", "su")
-message = replacetext(message, "br", "bur")
-message = replacetext(message, "ry", "ri")
-message = replacetext(message, "you", "yuu")
-message = replacetext(message, "ck", "cku")
-message = replacetext(message, "eu", "uu")
-message = replacetext(message, "ow", "au")
-message = replacetext(message, "are", "aa")
-message = replacetext(message, "ay", "ayu")
-message = replacetext(message, "ea", "ii")
-message = replacetext(message, "ch", "chi")
-message = replacetext(message, "than", "sen")
-message = replacetext(message, ".", "")
-message = lowertext(message)
-*/
\ No newline at end of file
diff --git a/code/game/gamemodes/events/spacevines.dm b/code/game/gamemodes/events/spacevines.dm
deleted file mode 100644
index 4fdd4fb298d..00000000000
--- a/code/game/gamemodes/events/spacevines.dm
+++ /dev/null
@@ -1,260 +0,0 @@
-// SPACE VINES (Note that this code is very similar to Biomass code)
-/obj/effect/spacevine
- name = "space vines"
- desc = "An extremely expansionistic species of vine."
- icon = 'icons/effects/spacevines.dmi'
- icon_state = "Light1"
- anchored = 1
- density = 0
- layer = 5
- pass_flags = PASSTABLE | PASSGRILLE
- var/energy = 0
- var/obj/effect/spacevine_controller/master = null
- var/mob/living/buckled_mob
-
- New()
- return
-
- Del()
- if(master)
- master.vines -= src
- master.growth_queue -= src
- ..()
-
-
-/obj/effect/spacevine/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if (!W || !user || !W.type) return
- switch(W.type)
- if(/obj/item/weapon/circular_saw) del src
- if(/obj/item/weapon/kitchen/utensil/knife) del src
- if(/obj/item/weapon/scalpel) del src
- if(/obj/item/weapon/twohanded/fireaxe) del src
- if(/obj/item/weapon/hatchet) del src
- if(/obj/item/weapon/melee/energy) del src
-
- //less effective weapons
- if(/obj/item/weapon/wirecutters)
- if(prob(25)) del src
- if(/obj/item/weapon/shard)
- if(prob(25)) del src
-
- else //weapons with subtypes
- if(istype(W, /obj/item/weapon/melee/energy/sword)) del src
- else if(istype(W, /obj/item/weapon/weldingtool))
- var/obj/item/weapon/weldingtool/WT = W
- if(WT.remove_fuel(0, user)) del src
- else
- manual_unbuckle(user)
- return
- //Plant-b-gone damage is handled in its entry in chemistry-reagents.dm
- ..()
-
-
-/obj/effect/spacevine/attack_hand(mob/user as mob)
- manual_unbuckle(user)
-
-
-/obj/effect/spacevine/attack_paw(mob/user as mob)
- manual_unbuckle(user)
-
-/obj/effect/spacevine/proc/unbuckle()
- if(buckled_mob)
- if(buckled_mob.buckled == src) //this is probably unneccesary, but it doesn't hurt
- buckled_mob.buckled = null
- buckled_mob.anchored = initial(buckled_mob.anchored)
- buckled_mob.update_canmove()
- buckled_mob = null
- return
-
-/obj/effect/spacevine/proc/manual_unbuckle(mob/user as mob)
- if(buckled_mob)
- if(prob(50))
- if(buckled_mob.buckled == src)
- if(buckled_mob != user)
- buckled_mob.visible_message(\
- "[user.name] frees [buckled_mob.name] from the vines.",\
- "[user.name] frees you from the vines.",\
- "You hear shredding and ripping.")
- else
- buckled_mob.visible_message(\
- "[buckled_mob.name] struggles free of the vines.",\
- "You untangle the vines from around yourself.",\
- "You hear shredding and ripping.")
- unbuckle()
- else
- var/text = pick("rips","tears","pulls")
- user.visible_message(\
- "[user.name] [text] at the vines.",\
- "You [text] at the vines.",\
- "You hear shredding and ripping.")
- return
-
-/obj/effect/spacevine_controller
- var/list/obj/effect/spacevine/vines = list()
- var/list/growth_queue = list()
- var/reached_collapse_size
- var/reached_slowdown_size
- //What this does is that instead of having the grow minimum of 1, required to start growing, the minimum will be 0,
- //meaning if you get the spacevines' size to something less than 20 plots, it won't grow anymore.
-
- New()
- if(!istype(src.loc,/turf/simulated/floor))
- del(src)
-
- spawn_spacevine_piece(src.loc)
- processing_objects.Add(src)
-
- Del()
- processing_objects.Remove(src)
- ..()
-
- proc/spawn_spacevine_piece(var/turf/location)
- var/obj/effect/spacevine/SV = new(location)
- growth_queue += SV
- vines += SV
- SV.master = src
-
- process()
- if(!vines)
- del(src) //space vines exterminated. Remove the controller
- return
- if(!growth_queue)
- del(src) //Sanity check
- return
- if(vines.len >= 250 && !reached_collapse_size)
- reached_collapse_size = 1
- if(vines.len >= 30 && !reached_slowdown_size )
- reached_slowdown_size = 1
-
- var/length = 0
- if(reached_collapse_size)
- length = 0
- else if(reached_slowdown_size)
- if(prob(25))
- length = 1
- else
- length = 0
- else
- length = 1
- length = min( 30 , max( length , vines.len / 5 ) )
- var/i = 0
- var/list/obj/effect/spacevine/queue_end = list()
-
- for( var/obj/effect/spacevine/SV in growth_queue )
- i++
- queue_end += SV
- growth_queue -= SV
- if(SV.energy < 2) //If tile isn't fully grown
- if(prob(20))
- SV.grow()
- else //If tile is fully grown
- SV.buckle_mob()
-
- //if(prob(25))
- SV.spread()
- if(i >= length)
- break
-
- growth_queue = growth_queue + queue_end
- //sleep(5)
- //src.process()
-
-/obj/effect/spacevine/proc/grow()
- if(!energy)
- src.icon_state = pick("Med1", "Med2", "Med3")
- energy = 1
- SetOpacity(1)
- layer = 5
- else
- src.icon_state = pick("Hvy1", "Hvy2", "Hvy3")
- energy = 2
-
-/obj/effect/spacevine/proc/buckle_mob()
- if(!buckled_mob && prob(25))
- for(var/mob/living/carbon/V in src.loc)
- if((V.stat != DEAD) && (V.buckled != src)) //if mob not dead or captured
- V.buckled = src
- V.loc = src.loc
- V.update_canmove()
- src.buckled_mob = V
- V << "The vines [pick("wind", "tangle", "tighten")] around you!"
- break //only capture one mob at a time.
-
-/obj/effect/spacevine/proc/spread()
- var/direction = pick(cardinal)
- var/step = get_step(src,direction)
- if(istype(step,/turf/simulated/floor))
- var/turf/simulated/floor/F = step
- if(!locate(/obj/effect/spacevine,F))
- if(F.Enter(src))
- if(master)
- master.spawn_spacevine_piece( F )
-
-/*
-/obj/effect/spacevine/proc/Life()
- if (!src) return
- var/Vspread
- if (prob(50)) Vspread = locate(src.x + rand(-1,1),src.y,src.z)
- else Vspread = locate(src.x,src.y + rand(-1, 1),src.z)
- var/dogrowth = 1
- if (!istype(Vspread, /turf/simulated/floor)) dogrowth = 0
- for(var/obj/O in Vspread)
- if (istype(O, /obj/structure/window) || istype(O, /obj/effect/forcefield) || istype(O, /obj/effect/blob) || istype(O, /obj/effect/alien/weeds) || istype(O, /obj/effect/spacevine)) dogrowth = 0
- if (istype(O, /obj/machinery/door/))
- if(O:p_open == 0 && prob(50)) O:open()
- else dogrowth = 0
- if (dogrowth == 1)
- var/obj/effect/spacevine/B = new /obj/effect/spacevine(Vspread)
- B.icon_state = pick("vine-light1", "vine-light2", "vine-light3")
- spawn(20)
- if(B)
- B.Life()
- src.growth += 1
- if (src.growth == 10)
- src.name = "Thick Space Kudzu"
- src.icon_state = pick("vine-med1", "vine-med2", "vine-med3")
- src.opacity = 1
- src.waittime = 80
- if (src.growth == 20)
- src.name = "Dense Space Kudzu"
- src.icon_state = pick("vine-hvy1", "vine-hvy2", "vine-hvy3")
- src.density = 1
- spawn(src.waittime)
- if (src.growth < 20) src.Life()
-
-*/
-
-/obj/effect/spacevine/ex_act(severity)
- switch(severity)
- if(1.0)
- del(src)
- return
- if(2.0)
- if (prob(90))
- del(src)
- return
- if(3.0)
- if (prob(50))
- del(src)
- return
- return
-
-/obj/effect/spacevine/temperature_expose(null, temp, volume) //hotspots kill vines
- del src
-
-//Carn: Spacevines random event.
-/proc/spacevine_infestation()
-
- spawn() //to stop the secrets panel hanging
-
- var/list/turfs = list() //list of all the empty floor turfs in the hallway areas
-
- for(var/area/hallway/A in world)
- for(var/turf/simulated/floor/F in A)
- if(!F.contents.len)
- turfs += F
-
- if(turfs.len) //Pick a turf to spawn at if we can
- var/turf/simulated/floor/T = pick(turfs)
- new/obj/effect/spacevine_controller(T) //spawn a controller at turf
- message_admins("\blue Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])")
diff --git a/code/game/gamemodes/events/wormholes.dm b/code/game/gamemodes/events/wormholes.dm
deleted file mode 100644
index 1ef19e24ac7..00000000000
--- a/code/game/gamemodes/events/wormholes.dm
+++ /dev/null
@@ -1,65 +0,0 @@
-/proc/wormhole_event()
- spawn()
- var/list/pick_turfs = list()
- for(var/turf/simulated/floor/T in world)
- if(T.z == 1)
- pick_turfs += T
-
- if(pick_turfs.len)
- //All ready. Announce that bad juju is afoot.
- command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert")
- for(var/mob/M in player_list)
- if(!istype(M,/mob/new_player))
- M << sound('sound/AI/spanomalies.ogg')
-
- //prob(20) can be approximated to 1 wormhole every 5 turfs!
- //admittedly less random but totally worth it >_<
- var/event_duration = 3000 //~5 minutes in ticks
- var/number_of_selections = (pick_turfs.len/5)+1 //+1 to avoid division by zero!
- var/sleep_duration = round( event_duration / number_of_selections )
- var/end_time = world.time + event_duration //the time by which the event should have ended
-
- var/increment = max(1,round(number_of_selections/50))
-// world << "DEBUG: number_of_selections: [number_of_selections] | sleep_duration: [sleep_duration]"
-
- var/i = 1
- while( 1 )
-
- //we've run into overtime. End the event
- if( end_time < world.time )
-// world << "DEBUG: we've run into overtime. End the event"
- return
- if( !pick_turfs.len )
-// world << "DEBUG: we've run out of turfs to pick. End the event"
- return
-
- //loop it round
- i += increment
- i %= pick_turfs.len
- i++
-
- //get our enter and exit locations
- var/turf/simulated/floor/enter = pick_turfs[i]
- pick_turfs -= enter //remove it from pickable turfs list
- if( !enter || !istype(enter) ) continue //sanity
-
- var/turf/simulated/floor/exit = pick(pick_turfs)
- pick_turfs -= exit
- if( !exit || !istype(exit) ) continue //sanity
-
- create_wormhole(enter,exit)
-
- sleep(sleep_duration) //have a well deserved nap!
-
-
-//maybe this proc can even be used as an admin tool for teleporting players without ruining immulsions?
-/proc/create_wormhole(var/turf/enter as turf, var/turf/exit as turf)
- var/obj/effect/portal/P = new /obj/effect/portal( enter )
- P.target = exit
- P.creator = null
- P.icon = 'icons/obj/objects.dmi'
- P.failchance = 0
- P.icon_state = "anom"
- P.name = "wormhole"
- spawn(rand(300,600))
- del(P)
\ No newline at end of file
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index b24d4a57801..ba434a4d9ea 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -39,10 +39,10 @@ var/global/datum/controller/gameticker/ticker
/datum/controller/gameticker/proc/pregame()
login_music = pickweight(list('sound/ambience/title2.ogg' = 49, 'sound/ambience/title1.ogg' = 49, 'sound/ambience/clown.ogg' = 2)) // choose title music!
- if(Holiday == "April Fool's Day")
+ if(events.holiday == "April Fool's Day")
login_music = 'sound/ambience/clown.ogg'
- for(var/mob/new_player/M in mob_list)
- if(M.client) M.client.playtitlemusic()
+ for(var/client/C in clients)
+ C.playtitlemusic()
do
pregame_timeleft = 90
@@ -107,6 +107,12 @@ var/global/datum/controller/gameticker/ticker
else
src.mode.announce()
+ supply_shuttle.process() //Start the supply shuttle regenerating points -- TLE
+ master_controller.process() //Start master_controller.process()
+ lighting_controller.process() //Start processing DynamicAreaLighting updates
+
+ sleep(10)
+
create_characters() //Create player characters and transfer them
collect_minds()
equip_characters()
@@ -123,26 +129,16 @@ var/global/datum/controller/gameticker/ticker
world << "Enjoy the game!"
world << sound('sound/AI/welcome.ogg') // Skie
//Holiday Round-start stuff ~Carn
- Holiday_Game_Start()
+ if(events.holiday)
+ world << "and..."
+ world << "Happy [events.holiday] Everybody!
"
-// start_events() //handles random events and space dust.
-//new random event system is handled from the MC.
-
- var/admins_number = 0
- for(var/client/C)
- if(C.holder)
- admins_number++
- if(admins_number == 0)
+ if(!admins.len)
send2irc("Server", "Round just started with no admins online!")
- supply_shuttle.process() //Start the supply shuttle regenerating points -- TLE
- master_controller.process() //Start master_controller.process()
- lighting_controller.process() //Start processing DynamicAreaLighting updates
-
-
if(config.sql_enabled)
spawn(3000)
- statistic_cycle() // Polls population totals regularly and stores them in an SQL DB -- TLE
+ statistic_cycle() // Polls population totals regularly and stores them in an SQL DB -- TLE
return 1
/datum/controller/gameticker
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 4c97b79b759..bdda68b2c03 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -406,7 +406,7 @@ datum/objective/download
datum/objective/capture
proc/gen_amount_goal()
target_amount = rand(5,10)
- explanation_text = "Accumulate [target_amount] capture points."
+ explanation_text = "Accumulate [target_amount] capture points. It is better if they remain relatively unharmed."
return target_amount
diff --git a/code/game/machinery/computer/prisonshuttle.dm b/code/game/machinery/computer/prisonshuttle.dm
index ae64595db71..87f021769cb 100644
--- a/code/game/machinery/computer/prisonshuttle.dm
+++ b/code/game/machinery/computer/prisonshuttle.dm
@@ -135,7 +135,7 @@ var/prison_shuttle_timeleft = 0
if(prison_shuttle_moving_to_station || prison_shuttle_moving_to_prison) return 0
else return 1
-
+/*
proc/prison_break()
switch(prison_break)
if (0)
@@ -151,7 +151,7 @@ var/prison_shuttle_timeleft = 0
prison_break = 1
if(1)
prison_break = 0
-
+*/
proc/post_signal(var/command)
var/datum/radio_frequency/frequency = radio_controller.return_frequency(1311)
diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index c35e262b64a..fc9583a8446 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -377,12 +377,9 @@ Alien plants should do something if theres a lot of poison
New()
new /obj/item/clothing/mask/facehugger(src)
- if(aliens_allowed)
- ..()
- spawn(rand(MIN_GROWTH_TIME,MAX_GROWTH_TIME))
- Grow()
- else
- del(src)
+ ..()
+ spawn(rand(MIN_GROWTH_TIME,MAX_GROWTH_TIME))
+ Grow()
attack_paw(user as mob)
if(isalien(user))
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index ae174260e38..3439283e481 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -22,18 +22,29 @@
return
return
-/obj/effect/portal/New()
- spawn(300)
- del(src)
- return
+/obj/effect/portal/New(loc, turf/target, creator, lifespan=300)
+ portals += src
+ src.loc = loc
+ src.target = target
+ src.creator = creator
+ if(lifespan > 0)
+ spawn(lifespan)
+ del(src)
return
+/obj/effect/portal/Del()
+ portals -= src
+ if(istype(creator, /obj/item/weapon/hand_tele))
+ var/obj/item/weapon/hand_tele/O = creator
+ O.active_portals--
+ return ..()
+
/obj/effect/portal/proc/teleport(atom/movable/M as mob|obj)
if(istype(M, /obj/effect)) //sparks don't teleport
return
- if (M.anchored&&istype(M, /obj/mecha))
+ if(M.anchored&&istype(M, /obj/mecha))
return
- if (icon_state == "portal1")
+ if(icon_state == "portal1")
return
if (!( target ))
del(src)
diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm
index d73355b86c2..1f36861ba14 100644
--- a/code/game/objects/items/weapons/gift_wrappaper.dm
+++ b/code/game/objects/items/weapons/gift_wrappaper.dm
@@ -19,10 +19,7 @@
..()
pixel_x = rand(-10,10)
pixel_y = rand(-10,10)
- if(w_class > 0)
- icon_state = "gift[w_class]"
- else
- icon_state = "giftcrate[pick(1, 2, 3, 4, 5)]"
+ icon_state = "giftcrate[rand(1,5)]"
/obj/item/weapon/gift/attack_self(mob/user as mob)
diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm
index 52375b492b7..0e243048570 100644
--- a/code/game/objects/items/weapons/teleportation.dm
+++ b/code/game/objects/items/weapons/teleportation.dm
@@ -134,6 +134,7 @@ Frequency:
throw_range = 5
m_amt = 10000
origin_tech = "magnets=1;bluespace=3"
+ var/active_portals = 0
/obj/item/weapon/hand_tele/attack_self(mob/user as mob)
var/turf/current_location = get_turf(user)//What turf is the user on?
@@ -158,18 +159,14 @@ Frequency:
var/t1 = input(user, "Please select a teleporter to lock in on.", "Hand Teleporter") in L
if ((user.get_active_hand() != src || user.stat || user.restrained()))
return
- var/count = 0 //num of portals from this teleport in world
- for(var/obj/effect/portal/PO in world)
- if(PO.creator == src) count++
- if(count >= 3)
+ if(active_portals >= 3)
user.show_message("\The [src] is recharging!")
return
var/T = L[t1]
for(var/mob/O in hearers(user, null))
O.show_message("Locked In.", 2)
- var/obj/effect/portal/P = new /obj/effect/portal( get_turf(src) )
- P.target = T
- P.creator = src
+ new /obj/effect/portal( get_turf(src), T, src )
+ active_portals++
src.add_fingerprint(user)
return
diff --git a/code/global.dm b/code/global.dm
index 0737d273d8d..caae4c28f81 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -1,4 +1,5 @@
//#define TESTING
+#define KILL 26
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
var/global/obj/effect/datacore/data_core = null
@@ -9,7 +10,6 @@ var/global/obj/effect/overlay/slmaster = null
var/global/list/machines = list()
var/global/list/processing_objects = list()
var/global/list/active_diseases = list()
-var/global/list/events = list()
//items that ask to be called every cycle
var/global/defer_powernet_rebuild = 0 // true if net rebuild will be called manually after an event
@@ -61,7 +61,6 @@ var/secret_force_mode = "secret" // if this is anything but "secret", the secret
var/datum/engine_eject/engine_eject_control = null
var/host = null
-var/aliens_allowed = 1
var/ooc_allowed = 1
var/dooc_allowed = 1
var/traitor_scaling = 1
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 3d06ede113e..b7b6538d32b 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -622,24 +622,6 @@ var/global/floorIsLava = 0
world.update_status()
feedback_add_details("admin_verb","TR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/datum/admins/proc/toggle_aliens()
- set category = "Server"
- set desc="Toggle alien mobs"
- set name="Toggle Aliens"
- aliens_allowed = !aliens_allowed
- log_admin("[key_name(usr)] toggled Aliens to [aliens_allowed].")
- message_admins("[key_name_admin(usr)] toggled Aliens [aliens_allowed ? "on" : "off"].", 1)
- feedback_add_details("admin_verb","TA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/datum/admins/proc/toggle_space_ninja()
- set category = "Server"
- set desc="Toggle space ninjas spawning."
- set name="Toggle Space Ninjas"
- toggle_space_ninja = !toggle_space_ninja
- log_admin("[key_name(usr)] toggled Space Ninjas to [toggle_space_ninja].")
- message_admins("[key_name_admin(usr)] toggled Space Ninjas [toggle_space_ninja ? "on" : "off"].", 1)
- feedback_add_details("admin_verb","TSN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
/datum/admins/proc/delay()
set category = "Server"
set desc="Delay the game start"
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 3223122bbee..77d257316e3 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -74,8 +74,6 @@ var/list/admin_verbs_fun = list(
/client/proc/drop_bomb,
/client/proc/cinematic,
/client/proc/one_click_antag,
- /datum/admins/proc/toggle_aliens,
- /datum/admins/proc/toggle_space_ninja,
/client/proc/send_space_ninja,
/client/proc/cmd_admin_add_freeform_ai_law,
/client/proc/cmd_admin_add_random_ai_law,
@@ -88,7 +86,6 @@ var/list/admin_verbs_spawn = list(
/client/proc/respawn_character
)
var/list/admin_verbs_server = list(
- /client/proc/Set_Holiday,
/client/proc/ToRban,
/datum/admins/proc/startnow,
/datum/admins/proc/restart,
@@ -103,8 +100,6 @@ var/list/admin_verbs_server = list(
/datum/admins/proc/adrev,
/datum/admins/proc/adspawn,
/datum/admins/proc/adjump,
- /datum/admins/proc/toggle_aliens,
- /datum/admins/proc/toggle_space_ninja,
/client/proc/toggle_random_events
)
var/list/admin_verbs_debug = list(
@@ -118,7 +113,6 @@ var/list/admin_verbs_debug = list(
/client/proc/cmd_debug_mob_lists,
/client/proc/cmd_admin_delete,
/client/proc/cmd_debug_del_all,
- /client/proc/cmd_debug_tog_aliens,
/client/proc/air_report,
/client/proc/reload_admins,
/client/proc/restart_controller,
@@ -166,8 +160,6 @@ var/list/admin_verbs_hideable = list(
/client/proc/cmd_admin_gib_self,
/client/proc/drop_bomb,
/client/proc/cinematic,
- /datum/admins/proc/toggle_aliens,
- /datum/admins/proc/toggle_space_ninja,
/client/proc/send_space_ninja,
/client/proc/cmd_admin_add_freeform_ai_law,
/client/proc/cmd_admin_add_random_ai_law,
@@ -175,7 +167,6 @@ var/list/admin_verbs_hideable = list(
/client/proc/make_sound,
/client/proc/toggle_random_events,
/client/proc/cmd_admin_add_random_ai_law,
- /client/proc/Set_Holiday,
/client/proc/ToRban,
/datum/admins/proc/startnow,
/datum/admins/proc/restart,
@@ -200,7 +191,6 @@ var/list/admin_verbs_hideable = list(
/client/proc/startSinglo,
/client/proc/cmd_debug_mob_lists,
/client/proc/cmd_debug_del_all,
- /client/proc/cmd_debug_tog_aliens,
/client/proc/air_report,
/client/proc/enable_debug_verbs,
/proc/possess,
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 05f09cc0f8e..29baee6db3b 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1619,6 +1619,10 @@
else if(href_list["secretsfun"])
if(!check_rights(R_FUN)) return
+ var/list/overrides = list()
+ if(alert(usr, "Would you like to alert the crew?", "Alert", "Yes", "No") == "No")
+ overrides["announceWhen"] = -1
+
var/ok = 0
switch(href_list["secretsfun"])
if("sec_clothes")
@@ -1671,22 +1675,11 @@
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","TriAI")
if("gravity")
- if(!(ticker && ticker.mode))
- usr << "Please wait until the game starts! Not sure how it will work otherwise."
- return
- gravity_is_on = !gravity_is_on
- for(var/area/A in world)
- A.gravitychange(gravity_is_on,A)
+ new /datum/event/weightless(overrides)
+ log_admin("[key_name(usr)] triggered a gravity-failure event.", 1)
+ message_admins("\blue [key_name_admin(usr)] triggered a gravity-failure event.", 1)
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","Grav")
- if(gravity_is_on)
- log_admin("[key_name(usr)] toggled gravity on.", 1)
- message_admins("\blue [key_name_admin(usr)] toggled gravity on.", 1)
- command_alert("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.")
- else
- log_admin("[key_name(usr)] toggled gravity off.", 1)
- message_admins("\blue [key_name_admin(usr)] toggled gravity off.", 1)
- command_alert("Feedback surge detected in mass-distributions systems. Artifical gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.")
if("power")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","P")
@@ -1705,7 +1698,7 @@
log_admin("[key_name(usr)] made all SMESs powered", 1)
message_admins("\blue [key_name_admin(usr)] made all SMESs powered", 1)
power_restore_quick()
- if("activateprison")
+/* if("activateprison")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","AP")
world << "\blue Transit signature detected."
@@ -1732,7 +1725,7 @@
feedback_add_details("admin_secrets_fun_used","TPS")
for(var/obj/machinery/computer/prison_shuttle/PS in world)
PS.allowedtocall = !(PS.allowedtocall)
- message_admins("\blue [key_name_admin(usr)] toggled status of prison shuttle to [PS.allowedtocall].", 1)
+ message_admins("\blue [key_name_admin(usr)] toggled status of prison shuttle to [PS.allowedtocall].", 1) */
if("prisonwarp")
if(!ticker)
alert("The game hasn't started yet!", null, null, null, null, null)
@@ -1939,98 +1932,84 @@
if("wave")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","MW")
- new /datum/event/meteor_wave
+ new /datum/event/meteor_wave(overrides)
if("gravanomalies")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","GA")
- command_alert("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert")
- world << sound('sound/AI/granomalies.ogg')
- var/turf/T = pick(blobstart)
- var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 )
- spawn(rand(100, 600))
- del(bh)
+ new /datum/event/gravitational_anomaly(overrides)
if("timeanomalies") //dear god this code was awful :P Still needs further optimisation
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","STA")
- //moved to its own dm so I could split it up and prevent the spawns copying variables over and over
- //can be found in code\game\game_modes\events\wormholes.dm
- wormhole_event()
+ new /datum/event/wormholes(overrides)
if("goblob")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","BL")
- mini_blob_event()
message_admins("[key_name_admin(usr)] has spawned blob", 1)
+ new /datum/event/blob(overrides)
if("aliens")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","AL")
- if(aliens_allowed)
- new /datum/event/alien_infestation
- message_admins("[key_name_admin(usr)] has spawned aliens", 1)
+ message_admins("[key_name_admin(usr)] has spawned aliens", 1)
+ new /datum/event/alien_infestation(overrides)
if("alien_silent") //replaces the spawn_xeno verb
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","ALS")
- if(aliens_allowed)
- create_xeno()
+ create_xeno()
if("spiders")
+ new /datum/event/spider_infestation(overrides)
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","SL")
- new /datum/event/spider_infestation
message_admins("[key_name_admin(usr)] has spawned spiders", 1)
if("bluespaceanomaly")
+ new /datum/event/bluespace_anomaly(overrides)
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","BA")
- new /datum/event/bluespace_anomaly
message_admins("[key_name_admin(usr)] has triggered a bluespace anomaly", 1)
if("comms_blackout")
+ new /datum/event/communications_blackout(overrides)
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","CB")
- var/answer = alert(usr, "Would you like to alert the crew?", "Alert", "Yes", "No")
- if(answer == "Yes")
- communications_blackout(0)
- else
- communications_blackout(1)
message_admins("[key_name_admin(usr)] triggered a communications blackout.", 1)
if("spaceninja")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","SN")
- if(toggle_space_ninja)
- if(space_ninja_arrival())//If the ninja is actually spawned. They may not be depending on a few factors.
- message_admins("[key_name_admin(usr)] has sent in a space ninja", 1)
+ message_admins("[key_name_admin(usr)] has sent in a space ninja", 1)
+ new /datum/event/ninja(list(overrides))
if("carp")
+ new /datum/event/carp_migration(overrides)
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","C")
- var/choice = input("You sure you want to spawn carp?") in list("Badmin", "Cancel")
- if(choice == "Badmin")
- message_admins("[key_name_admin(usr)] has spawned carp.", 1)
- new /datum/event/carp_migration
+ message_admins("[key_name_admin(usr)] has spawned carp.", 1)
if("radiation")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","R")
message_admins("[key_name_admin(usr)] has has irradiated the station", 1)
- new /datum/event/radiation_storm
+ new /datum/event/radiation_storm(overrides)
if("immovable")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","IR")
message_admins("[key_name_admin(usr)] has sent an immovable rod to the station", 1)
- immovablerod()
+ new /datum/event/immovable_rod(overrides)
if("prison_break")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","PB")
message_admins("[key_name_admin(usr)] has allowed a prison break", 1)
- prison_break()
+ new /datum/event/prison_break(overrides)
if("lightsout")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","LO")
message_admins("[key_name_admin(usr)] has broke a lot of lights", 1)
- lightsout(1,2)
+ overrides["lightsoutAmount"]=2
+ new /datum/event/electrical_storm(overrides)
if("blackout")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","BO")
message_admins("[key_name_admin(usr)] broke all lights", 1)
- lightsout(0,0)
+ overrides["lightsoutAmount"]=0
+ new /datum/event/electrical_storm(overrides)
if("whiteout")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","WO")
@@ -2108,17 +2087,14 @@
if("virus")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","V")
- var/answer = alert("Do you want this to be a random disease or do you have something in mind?",,"Make Your Own","Random","Choose")
- if(answer=="Random")
- viral_outbreak()
- message_admins("[key_name_admin(usr)] has triggered a virus outbreak", 1)
- else if(answer == "Choose")
- var/list/viruses = list("fake gbs","gbs","magnitis","wizarditis",/*"beesease",*/"brain rot","cold","retrovirus","flu","pierrot's throat","rhumba beat")
- var/V = input("Choose the virus to spread", "BIOHAZARD") in viruses
- viral_outbreak(V)
- message_admins("[key_name_admin(usr)] has triggered a virus outbreak of [V]", 1)
- else
- AdminCreateVirus(usr)
+ switch(alert("Do you want this to be a random disease or do you have something in mind?",,"Make Your Own","Random","Choose"))
+ if("Make Your Own")
+ AdminCreateVirus()
+ if("Random")
+ new /datum/event/disease_outbreak(overrides)
+ if("Choose")
+ overrides["virus_type"] = input("Choose the virus to spread", "BIOHAZARD") as null|anything in typesof(/datum/disease)
+ new /datum/event/disease_outbreak(overrides)
if("retardify")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","RET")
@@ -2164,17 +2140,13 @@
if("ionstorm")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","I")
- IonStorm()
message_admins("[key_name_admin(usr)] triggered an ion storm")
- var/show_log = alert(usr, "Show ion message?", "Message", "Yes", "No")
- if(show_log == "Yes")
- command_alert("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert")
- world << sound('sound/AI/ionstorm.ogg')
+ new /datum/event/ion_storm(overrides)
if("spacevines")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","K")
- new /datum/event/spacevine
message_admins("[key_name_admin(usr)] has spawned spacevines", 1)
+ new /datum/event/spacevine(overrides)
if("onlyone")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","OO")
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index a4dc1af9ce7..e95084c4ac5 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -362,15 +362,6 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
message_admins("[key_name_admin(src)] has remade the powernets. makepowernets() called.", 0)
feedback_add_details("admin_verb","MPWN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/client/proc/cmd_debug_tog_aliens()
- set category = "Server"
- set name = "Toggle Aliens"
-
- aliens_allowed = !aliens_allowed
- log_admin("[key_name(src)] has turned aliens [aliens_allowed ? "on" : "off"].")
- message_admins("[key_name_admin(src)] has turned aliens [aliens_allowed ? "on" : "off"].", 0)
- feedback_add_details("admin_verb","TAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
/client/proc/cmd_admin_grantfullaccess(var/mob/M in mob_list)
set category = "Admin"
set name = "Grant Full Access"
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index 809302387a0..125c4b24661 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -306,11 +306,11 @@ client/proc/one_click_antag()
/datum/admins/proc/makeAliens()
- alien_infestation(3)
+ new /datum/event/alien_infestation(list("spawncount"=3))
return 1
/datum/admins/proc/makeSpaceNinja()
- space_ninja_arrival()
+ new /datum/event/ninja()
return 1
/datum/admins/proc/makeDeathsquad()
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 0c130bbf95f..4b7e519a446 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -186,7 +186,7 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
command_alert("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert")
world << sound('sound/AI/ionstorm.ogg')
- IonStorm(0)
+ new /datum/event/ion_storm(list("botEmagChance"=0))
feedback_add_details("admin_verb","ION") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm
index 3be305abaf5..26d988498fa 100644
--- a/code/modules/events/alien_infestation.dm
+++ b/code/modules/events/alien_infestation.dm
@@ -1,6 +1,11 @@
+/datum/event_control/alien_infestation
+ name = "Alien Infestation"
+ typepath = /datum/event/alien_infestation
+ weight = 5
+ max_occurrences = 1
+
/datum/event/alien_infestation
announceWhen = 400
- oneShot = 1
var/spawncount = 1
var/successSpawn = 0 //So we don't make a command report if nothing gets spawned.
@@ -10,6 +15,11 @@
announceWhen = rand(announceWhen, announceWhen + 50)
spawncount = rand(1, 2)
+/datum/event/alien_infestation/kill()
+ if(!successSpawn && control)
+ control.occurrences--
+ return ..()
+
/datum/event/alien_infestation/announce()
if(successSpawn)
command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert")
@@ -23,16 +33,14 @@
if(temp_vent.network.normal_members.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology
vents += temp_vent
- var/list/candidates = get_alien_candidates()
+ var/list/candidates = get_candidates(BE_ALIEN)
while(spawncount > 0 && vents.len && candidates.len)
- var/obj/vent = pick(vents)
- var/candidate = pick(candidates)
+ 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 = candidate
+ new_xeno.key = C.key
- candidates -= candidate
- vents -= vent
spawncount--
successSpawn = 1
\ No newline at end of file
diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm
index 628bb9ffece..c1be5626d44 100644
--- a/code/modules/events/blob.dm
+++ b/code/modules/events/blob.dm
@@ -1,3 +1,9 @@
+/datum/event_control/blob
+ name = "Blob"
+ typepath = /datum/event/blob
+ weight = 5
+ max_occurrences = 1
+
/datum/event/blob
announceWhen = 12
endWhen = 120
@@ -13,8 +19,7 @@
/datum/event/blob/start()
var/turf/T = pick(blobstart)
if(!T)
- kill()
- return
+ return kill()
Blob = new /obj/effect/blob/core(T, 200)
for(var/i = 1; i < rand(3, 6), i++)
Blob.process()
@@ -25,4 +30,4 @@
kill()
return
if(IsMultiple(activeFor, 3))
- Blob.process()
\ No newline at end of file
+ Blob.process()
diff --git a/code/modules/events/bluespaceanomaly.dm b/code/modules/events/bluespaceanomaly.dm
index 52433386466..21e158c161a 100644
--- a/code/modules/events/bluespaceanomaly.dm
+++ b/code/modules/events/bluespaceanomaly.dm
@@ -1,6 +1,11 @@
+/datum/event_control/bluespace_anomaly
+ name = "Bluespace Anomaly"
+ typepath = /datum/event/bluespace_anomaly
+ weight = 5
+ max_occurrences = 1
+
/datum/event/bluespace_anomaly
announceWhen = 20
- oneShot = 1
var/area/impact_area
diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm
index 36aa9eb9e2e..8ebcfd98fa3 100644
--- a/code/modules/events/brand_intelligence.dm
+++ b/code/modules/events/brand_intelligence.dm
@@ -1,7 +1,12 @@
+/datum/event_control/brand_intelligence
+ name = "Brand Intelligence"
+ typepath = /datum/event/brand_intelligence
+ weight = 5
+ max_occurrences = 1
+
/datum/event/brand_intelligence
announceWhen = 21
endWhen = 1000 //Ends when all vending machines are subverted anyway.
- oneShot = 1
var/list/obj/machinery/vending/vendingMachines = list()
var/obj/machinery/vending/originMachine
diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm
index 926548e49b1..3f8377e73ed 100644
--- a/code/modules/events/carp_migration.dm
+++ b/code/modules/events/carp_migration.dm
@@ -1,6 +1,12 @@
+/datum/event_control/carp_migration
+ name = "Carp Migration"
+ typepath = /datum/event/carp_migration
+ weight = 15
+ earliest_start = 6000
+ max_occurrences = 6
+
/datum/event/carp_migration
announceWhen = 50
- oneShot = 1
/datum/event/carp_migration/setup()
announceWhen = rand(40, 60)
diff --git a/code/modules/events/communications_blackout.dm b/code/modules/events/communications_blackout.dm
index 194d45e90de..3f2af27b9d2 100644
--- a/code/modules/events/communications_blackout.dm
+++ b/code/modules/events/communications_blackout.dm
@@ -1,3 +1,8 @@
+/datum/event_control/communications_blackout
+ name = "Communications Blackout"
+ typepath = /datum/event/communications_blackout
+ weight = 30
+
/datum/event/communications_blackout/announce()
var/alert = pick( "Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you*%fj00)`5vc-BZZT", \
"Ionospheric anomalies detected. Temporary telecommunication failu*3mga;b4;'1v¬-BZZZT", \
diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm
index fe6f56624f6..2fe23b5b140 100644
--- a/code/modules/events/disease_outbreak.dm
+++ b/code/modules/events/disease_outbreak.dm
@@ -1,6 +1,13 @@
+/datum/event_control/disease_outbreak
+ name = "Disease Outbreak"
+ typepath = /datum/event/disease_outbreak
+ max_occurrences = 1
+ weight = 5
+
/datum/event/disease_outbreak
announceWhen = 15
- oneShot = 1
+
+ var/virus_type
/datum/event/disease_outbreak/announce()
@@ -11,36 +18,35 @@
announceWhen = rand(15, 30)
/datum/event/disease_outbreak/start()
- var/virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis)
+ if(!virus_type)
+ virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis)
for(var/mob/living/carbon/human/H in shuffle(living_mob_list))
- var/foundAlready = 0 // don't infect someone that already has the virus
var/turf/T = get_turf(H)
if(!T)
continue
if(T.z != 1)
continue
+ var/foundAlready = 0 // don't infect someone that already has the virus
for(var/datum/disease/D in H.viruses)
foundAlready = 1
- if(H.stat == 2 || foundAlready)
+ break
+ if(H.stat == DEAD || foundAlready)
continue
+ var/datum/disease/D
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
- if((!H.dna) || (H.sdisabilities & BLIND)) //A blindness disease would be the worst.
+ if(!H.dna || (H.sdisabilities & BLIND)) //A blindness disease would be the worst.
continue
- var/datum/disease/dnaspread/D = new
- D.strain_data["name"] = H.real_name
- D.strain_data["UI"] = H.dna.uni_identity
- D.strain_data["SE"] = H.dna.struc_enzymes
- D.carrier = 1
- D.holder = H
- D.affected_mob = H
- H.viruses += D
- break
+ 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
- var/datum/disease/D = new virus_type
- D.carrier = 1
- D.holder = H
- D.affected_mob = H
- H.viruses += D
- break
\ No newline at end of file
+ D = new virus_type()
+ D.carrier = 1
+ D.holder = H
+ D.affected_mob = H
+ H.viruses += D
+ break
\ No newline at end of file
diff --git a/code/game/gamemodes/events/dust.dm b/code/modules/events/dust.dm
similarity index 70%
rename from code/game/gamemodes/events/dust.dm
rename to code/modules/events/dust.dm
index a9c44b090e0..28588a8ca3b 100644
--- a/code/game/gamemodes/events/dust.dm
+++ b/code/modules/events/dust.dm
@@ -1,32 +1,19 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
+/datum/event_control/dust
+ name = "Minor Space Dust"
+ typepath = /datum/event/dust
+ weight = 600
+ max_occurrences = 10000
+ earliest_start = 0
-/*
-Space dust
-Commonish random event that causes small clumps of "space dust" to hit the station at high speeds.
-No command report on the common version of this event.
-The "dust" will damage the hull of the station causin minor hull breaches.
-*/
+/datum/event/dust
+ var/qnty = 1
-/proc/dust_swarm(var/strength = "weak")
- var/numbers = 1
- switch(strength)
- if("weak")
- numbers = rand(2,4)
- for(var/i = 0 to numbers)
- new/obj/effect/space_dust/weak()
- if("norm")
- numbers = rand(5,10)
- for(var/i = 0 to numbers)
- new/obj/effect/space_dust()
- if("strong")
- numbers = rand(10,15)
- for(var/i = 0 to numbers)
- new/obj/effect/space_dust/strong()
- if("super")
- numbers = rand(15,25)
- for(var/i = 0 to numbers)
- new/obj/effect/space_dust/super()
- return
+/datum/event/dust/setup()
+ qnty = rand(1,5)
+
+/datum/event/dust/start()
+ while(qnty-- > 0)
+ new /obj/effect/space_dust/weak()
/obj/effect/space_dust
diff --git a/code/modules/events/electrical_storm.dm b/code/modules/events/electrical_storm.dm
index dacaa09c47a..e9c418839d7 100644
--- a/code/modules/events/electrical_storm.dm
+++ b/code/modules/events/electrical_storm.dm
@@ -1,3 +1,9 @@
+/datum/event_control/electrical_storm
+ name = "Electrical Storm"
+ typepath = /datum/event/electrical_storm
+ earliest_start = 6000
+ weight = 40
+
/datum/event/electrical_storm
var/lightsoutAmount = 1
var/lightsoutRange = 25
@@ -25,4 +31,4 @@
for(var/obj/effect/landmark/epicentre in epicentreList)
for(var/obj/machinery/power/apc/apc in range(epicentre,lightsoutRange))
- apc.overload_lighting()
\ No newline at end of file
+ apc.overload_lighting()
diff --git a/code/modules/events/energetic_flux.dm b/code/modules/events/energetic_flux.dm
index 1ec0db86e09..97ef5d62478 100644
--- a/code/modules/events/energetic_flux.dm
+++ b/code/modules/events/energetic_flux.dm
@@ -1,6 +1,11 @@
+/datum/event_control/energetic_flux
+ name = "Energetic Flux"
+ typepath = /datum/event/energetic_flux
+ max_occurrences = 2
+ weight = 15
+
/datum/event/energetic_flux
startWhen = 30
- oneShot = 1
var/area/impact_area
diff --git a/code/modules/events/event.dm b/code/modules/events/event.dm
index d2178ac5b5a..28095a87266 100644
--- a/code/modules/events/event.dm
+++ b/code/modules/events/event.dm
@@ -1,8 +1,37 @@
+//this datum is used by the events controller to dictate how it selects events
+/datum/event_control
+ var/name //The name human-readable name of the event
+ var/typepath //The typepath of the event datum /datum/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.
+
+ var/earliest_start = 12000 //The earliest world.time that an event can start (round-duration in deciseconds) default: 20 mins
+
+ 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 match the events.holiday variable if you wish this event to be holiday-specific
+ //anything with a (non-null) holidayID which does not match holiday, cannot run.
+
+
+/datum/event_control/proc/runEvent()
+ if(!ispath(typepath,/datum/event))
+ return KILL
+ var/datum/event/E = new typepath()
+ E.control = src
+ occurrences++
+
+ world.log << "[time2text(world.time, "hh:mm:ss")] [E.type]"
+
/datum/event //NOTE: Times are measured in master controller ticks!
+ var/datum/event_control/control
+
var/startWhen = 0 //When in the lifetime to call start().
var/announceWhen = 0 //When in the lifetime to call announce().
var/endWhen = 0 //When in the lifetime the event should end.
- var/oneShot = 0 //If true, then the event removes itself from the list of potential events on creation.
var/activeFor = 0 //How long the event has existed. You don't need to change this.
@@ -10,6 +39,9 @@
//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 wehn New() finishes.
/datum/event/proc/setup()
return
@@ -46,16 +78,15 @@
//Do not override this proc, instead use the appropiate procs.
//This proc will handle the calls to the appropiate procs.
/datum/event/proc/process()
-
- if(activeFor > startWhen && activeFor < endWhen)
- tick()
-
if(activeFor == startWhen)
start()
if(activeFor == announceWhen)
announce()
+ if(startWhen < activeFor && activeFor < endWhen)
+ tick()
+
if(activeFor == endWhen)
end()
@@ -70,14 +101,19 @@
//which should be the only place it's referenced.
//Called when start(), announce() and end() has all been called.
/datum/event/proc/kill()
- events.Remove(src)
+ events.running -= src
-//Adds the event to the global events list, and removes it from the list
-//of potential events.
-/datum/event/New()
+//Sets up the event then adds the event to the the list of running events
+/datum/event/New(list/overrides)
setup()
- events.Add(src)
- if(oneShot)
- potentialRandomEvents.Remove(type)
- ..()
\ No newline at end of file
+
+ //overrides
+ if(istype(overrides))
+ for(var/varname in overrides)
+ if(varname in vars)
+ vars[varname] = overrides[varname]
+
+ events.running += src
+
+ return ..()
\ No newline at end of file
diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm
index 393ed9de8af..3a421a20c18 100644
--- a/code/modules/events/event_manager.dm
+++ b/code/modules/events/event_manager.dm
@@ -1,50 +1,217 @@
-var/list/allEvents = typesof(/datum/event) - /datum/event
-var/list/potentialRandomEvents = typesof(/datum/event) - /datum/event
+var/datum/controller/event/events
-var/eventTimeLower = 15000 //15 minutes
-var/eventTimeUpper = 30000 //30 minutes
+/datum/controller/event
+ var/list/control = list() //list of all datum/event_control. Used for selecting events based on weight and occurrences.
+ var/list/running = list() //list of all existing /datum/event
-var/scheduledEvent = null
+ var/scheduled = 0 //The next world.time that a naturally occuring random event can be selected.
+ var/frequency_lower = 3000 //5 minutes lower bound.
+ var/frequency_upper = 9000 //15 minutes upper bound. Basically an event will happen every 15 to 30 minutes.
+ var/holiday //This will be a string of the name of any realworld holiday which occurs today (GMT time)
-//Currently unused. Needs an admin panel for messing with events.
-/proc/addPotentialEvent(var/type)
- potentialRandomEvents |= type
+//Initial controller setup.
+/datum/controller/event/New()
+ //There can be only one events manager. Out with the old and in with the new.
+ if(events != src)
+ if(istype(events))
+ del(events)
+ events = src
-/proc/removePotentialEvent(var/type)
- potentialRandomEvents -= type
+ for(var/type in typesof(/datum/event_control))
+ var/datum/event_control/E = new type()
+ if(!E.typepath)
+ continue //don't want this one! leave it for the garbage collector
+ control += E //add it to the list of all events (controls)
+ reschedule()
+ getHoliday()
+//This is called by the MC every MC-tick (*neatfreak*).
+/datum/controller/event/proc/process()
+ checkEvent()
+ var/i = 1
+ while(i<=running.len)
+ var/datum/event/Event = running[i]
+ if(Event)
+ Event.process()
+ i++
+ continue
+ running.Cut(i,i+1)
-/proc/checkEvent()
- if(!scheduledEvent)
- scheduledEvent = world.timeofday + rand(eventTimeLower, eventTimeUpper)
-
- else if(world.timeofday > scheduledEvent)
+//checks if we should select a random event yet, and reschedules if necessary
+/datum/controller/event/proc/checkEvent()
+ if(scheduled <= world.time)
spawnEvent()
+ reschedule()
- scheduledEvent = null
- checkEvent()
+//decides which world.time we should select another random event at.
+/datum/controller/event/proc/reschedule()
+ scheduled = world.time + rand(frequency_lower, min(frequency_lower,frequency_upper))
-
-/proc/spawnEvent()
+//selects a random event based on whether it can occur and it's 'weight'(probability)
+/datum/controller/event/proc/spawnEvent()
if(!config.allow_random_events)
return
- var/Type = pick(potentialRandomEvents)
- if(!Type)
- return
+ var/sum_of_weights = 0
+ for(var/datum/event_control/E in control)
+ if(E.occurrences >= E.max_occurrences) continue
+ if(E.earliest_start >= world.time) continue
+ if(E.holidayID)
+ if(E.holidayID != holiday) continue
+ if(E.weight < 0) //for round-start events etc.
+ if(E.runEvent() == KILL)
+ E.max_occurrences = 0
+ continue
+ return
+ sum_of_weights += E.weight
- //The event will add itself to the MC's event list
- //and start working via the constructor.
- new Type
+ sum_of_weights = rand(0,sum_of_weights) //reusing this variable. It now represents the 'weight' we want to select
-/client/proc/forceEvent(var/type in allEvents)
+ for(var/datum/event_control/E in control)
+ if(E.occurrences >= E.max_occurrences) continue
+ if(E.earliest_start >= world.time) continue
+ if(E.holidayID)
+ if(E.holidayID != holiday) continue
+ sum_of_weights -= E.weight
+
+ if(sum_of_weights <= 0) //we've hit our goal
+ if(E.runEvent() == KILL) //we couldn't run this event for some reason, set its max_occurrences to 0
+ E.max_occurrences = 0
+ continue
+ return
+
+//allows a client to trigger an event (For Debugging Purposes)
+/client/proc/forceEvent(var/datum/event_control/E in events.control)
set name = "Trigger Event (Debug Only)"
set category = "Debug"
if(!holder)
return
- if(ispath(type))
- new type
- message_admins("[key_name_admin(usr)] has triggered an event. ([type])", 1)
\ No newline at end of file
+ if(istype(E))
+ E.runEvent()
+ message_admins("[key_name_admin(usr)] has triggered an event. ([E.name])", 1)
+
+/*
+//////////////
+// HOLIDAYS //
+//////////////
+//Uncommenting ALLOW_HOLIDAYS in config.txt will enable holidays
+
+//It's easy to add stuff. Just modify getHoliday to set holiday to something using the switch for DD(#day) MM(#month) YY(#year).
+//You can then check if it's a special day in any code in the game by doing if(events.holiday == "MyHolidayID")
+
+//You can also make holiday random events easily thanks to Pete/Gia's system.
+//simply make a random event normally, then assign it a holidayID string which matches the one you gave it in getHolday.
+//Anything with a holidayID, which does not match the holiday string, will never occur.
+
+//Please, Don't spam stuff up with stupid stuff (key example being april-fools Pooh/ERP/etc),
+//And don't forget: CHECK YOUR CODE!!!! We don't want any zero-day bugs which happen only on holidays and never get found/fixed!
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//ALSO, MOST IMPORTANTLY: Don't add stupid stuff! Discuss bonus content with Project-Heads first please!//
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+~Carn */
+
+//sets up the holiday string in the events manager.
+/datum/controller/event/proc/getHoliday()
+ if(!config.allow_holidays) return // Holiday stuff was not enabled in the config!
+ holiday = null
+
+ var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year
+ var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
+ var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day
+
+ //Main switch. If any of these are too dumb/inappropriate, or you have better ones, feel free to change whatever
+ switch(MM)
+ if(1) //Jan
+ switch(DD)
+ if(1) holiday = "New Year"
+
+ if(2) //Feb
+ switch(DD)
+ if(2) holiday = "Groundhog Day"
+ if(14) holiday = "Valentine's Day"
+ if(17) holiday = "Random Acts of Kindness Day"
+
+ if(3) //Mar
+ switch(DD)
+ if(14) holiday = "Pi Day"
+ if(17) holiday = "St. Patrick's Day"
+ if(27)
+ if(YY == 16)
+ holiday = "Easter"
+ if(31)
+ if(YY == 13)
+ holiday = "Easter"
+
+ if(4) //Apr
+ switch(DD)
+ if(1)
+ holiday = "April Fool's Day"
+ if(YY == 18 && prob(50)) holiday = "Easter"
+ if(5)
+ if(YY == 15) holiday = "Easter"
+ if(16)
+ if(YY == 17) holiday = "Easter"
+ if(20)
+ holiday = "Four-Twenty"
+ if(YY == 14 && prob(50)) holiday = "Easter"
+ if(22) holiday = "Earth Day"
+
+ if(5) //May
+ switch(DD)
+ if(1) holiday = "Labour Day"
+ if(4) holiday = "FireFighter's Day"
+ if(12) holiday = "Owl and Pussycat Day" //what a dumb day of observence...but we -do- have costumes already :3
+
+ if(6) //Jun
+
+ if(7) //Jul
+ switch(DD)
+ if(1) holiday = "Doctor's Day"
+ if(2) holiday = "UFO Day"
+ if(8) holiday = "Writer's Day"
+ if(30) holiday = "Friendship Day"
+
+ if(8) //Aug
+ switch(DD)
+ if(5) holiday = "Beer Day"
+
+ if(9) //Sep
+ switch(DD)
+ if(19) holiday = "Talk-Like-a-Pirate Day"
+ if(28) holiday = "Stupid-Questions Day"
+
+ if(10) //Oct
+ switch(DD)
+ if(4) holiday = "Animal's Day"
+ if(7) holiday = "Smiling Day"
+ if(16) holiday = "Boss' Day"
+ if(31) holiday = "Halloween"
+
+ if(11) //Nov
+ switch(DD)
+ if(1) holiday = "Vegan Day"
+ if(13) holiday = "Kindness Day"
+ if(19) holiday = "Flowers Day"
+ if(21) holiday = "Saying-'Hello' Day"
+
+ if(12) //Dec
+ switch(DD)
+ if(10) holiday = "Human-Rights Day"
+ if(14) holiday = "Monkey Day"
+ if(22) holiday = "Orgasming Day" //lol. These all actually exist
+ if(24) holiday = "Xmas"
+ if(25) holiday = "Xmas"
+ if(26) holiday = "Boxing Day"
+ if(31) holiday = "New Year"
+
+ if(!holiday)
+ //Friday the 13th
+ if(DD == 13)
+ if(time2text(world.timeofday, "DDD") == "Fri")
+ holiday = "Friday the 13th"
+
+ world.update_status()
diff --git a/code/game/gamemodes/events/black_hole.dm b/code/modules/events/gravitational_anomaly.dm
similarity index 70%
rename from code/game/gamemodes/events/black_hole.dm
rename to code/modules/events/gravitational_anomaly.dm
index bd105e68e74..da141890a71 100644
--- a/code/game/gamemodes/events/black_hole.dm
+++ b/code/modules/events/gravitational_anomaly.dm
@@ -1,3 +1,31 @@
+/datum/event_control/gravitational_anomaly
+ name = "Gravitational Anomaly"
+ typepath = /datum/event/gravitational_anomaly
+ max_occurrences = 5
+ weight = 2
+
+/datum/event/gravitational_anomaly
+ startWhen = 10
+
+ var/obj/effect/bhole/blackhole
+
+/datum/event/gravitational_anomaly/announce()
+ command_alert("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert")
+ for(var/mob/M in player_list)
+ if(!istype(M,/mob/new_player))
+ M << sound('sound/AI/granomalies.ogg')
+
+/datum/event/gravitational_anomaly/setup()
+ endWhen = rand(50, 200)
+
+/datum/event/gravitational_anomaly/start()
+ var/turf/T = pick(blobstart)
+ blackhole = new /obj/effect/bhole( T.loc, 30 )
+
+/datum/event/gravitational_anomaly/end()
+ del(blackhole)
+
+
/obj/effect/bhole
name = "black hole"
icon = 'icons/obj/objects.dmi'
@@ -47,8 +75,6 @@
grav( 2, 2, 75,25 )
sleep(6)
-
-
//MOVEMENT
if( prob(50) )
src.anchored = 0
diff --git a/code/game/gamemodes/events/holidays/Christmas.dm b/code/modules/events/holiday/xmas.dm
similarity index 81%
rename from code/game/gamemodes/events/holidays/Christmas.dm
rename to code/modules/events/holiday/xmas.dm
index 2ee79e7c65b..e50d45c8780 100644
--- a/code/game/gamemodes/events/holidays/Christmas.dm
+++ b/code/modules/events/holiday/xmas.dm
@@ -1,4 +1,29 @@
-/proc/Christmas_Game_Start()
+/datum/event_control/treevenge
+ name = "Treevenge"
+ holidayID = "Xmas"
+ typepath = /datum/event/treevenge
+ max_occurrences = 1
+ weight = 20
+
+/datum/event/treevenge/start()
+ for(var/obj/structure/flora/tree/pine/xmas in world)
+ var/mob/living/simple_animal/hostile/tree/evil_tree = new /mob/living/simple_animal/hostile/tree(xmas.loc)
+ evil_tree.icon_state = xmas.icon_state
+ evil_tree.icon_living = evil_tree.icon_state
+ evil_tree.icon_dead = evil_tree.icon_state
+ evil_tree.icon_gib = evil_tree.icon_state
+ del(xmas)
+
+//this is an example of a possible round-start event
+/datum/event_control/presents
+ name = "Presents under Trees"
+ holidayID = "Xmas"
+ typepath = /datum/event/presents
+ weight = -1 //forces it to be called, regardless of weight
+ max_occurrences = 1
+ earliest_start = 0
+
+/datum/event/presents/start()
for(var/obj/structure/flora/tree/pine/xmas in world)
if(xmas.z != 1) continue
for(var/turf/simulated/floor/T in orange(1,xmas))
@@ -7,14 +32,9 @@
for(var/mob/living/simple_animal/corgi/Ian/Ian in mob_list)
Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
-/proc/ChristmasEvent()
- for(var/obj/structure/flora/tree/pine/xmas in world)
- var/mob/living/simple_animal/hostile/tree/evil_tree = new /mob/living/simple_animal/hostile/tree(xmas.loc)
- evil_tree.icon_state = xmas.icon_state
- evil_tree.icon_living = evil_tree.icon_state
- evil_tree.icon_dead = evil_tree.icon_state
- evil_tree.icon_gib = evil_tree.icon_state
- del(xmas)
+/datum/event/presents/announce()
+ command_alert("Ho Ho Ho, Merry Xmas!", "Unknown Transmission")
+
/obj/item/weapon/toy/xmas_cracker
name = "xmas cracker"
@@ -59,5 +79,4 @@
desc = "A crappy paper hat that you are REQUIRED to wear."
flags_inv = 0
flags = FPRINT|TABLEPASS
- armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
-
+ armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
\ No newline at end of file
diff --git a/code/game/gamemodes/events/clang.dm b/code/modules/events/immovable_rod.dm
similarity index 67%
rename from code/game/gamemodes/events/clang.dm
rename to code/modules/events/immovable_rod.dm
index b050482d1be..36dfe9875d7 100644
--- a/code/game/gamemodes/events/clang.dm
+++ b/code/modules/events/immovable_rod.dm
@@ -7,6 +7,50 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
--NEOFite
*/
+/datum/event_control/immovable_rod
+ name = "Immovable Rod"
+ typepath = /datum/event/immovable_rod
+ max_occurrences = 5
+
+/datum/event/immovable_rod
+ announceWhen = 5
+
+/datum/event/immovable_rod/announce()
+ command_alert("What the fuck was that?!", "General Alert")
+
+/datum/event/immovable_rod/start()
+ var/startx = 0
+ var/starty = 0
+ var/endy = 0
+ var/endx = 0
+ var/startside = pick(cardinal)
+
+ switch(startside)
+ if(NORTH)
+ starty = 187
+ startx = rand(41, 199)
+ endy = 38
+ endx = rand(41, 199)
+ if(EAST)
+ starty = rand(38, 187)
+ startx = 199
+ endy = rand(38, 187)
+ endx = 41
+ if(SOUTH)
+ starty = 38
+ startx = rand(41, 199)
+ endy = 187
+ endx = rand(41, 199)
+ else
+ starty = rand(38, 187)
+ startx = 41
+ endy = rand(38, 187)
+ endx = 199
+
+ //rod time!
+ new /obj/effect/immovablerod(locate(startx, starty, 1), locate(endx, endy, 1))
+
+
/obj/effect/immovablerod
name = "Immovable Rod"
desc = "What the fuck is that?"
@@ -15,6 +59,20 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
throwforce = 100
density = 1
anchored = 1
+ var/z_original = 0
+ var/destination
+
+ New(atom/start, atom/end)
+ loc = start
+ z_original = z
+ destination = end
+ if(end && end.z==z_original)
+ walk_towards(src, destination, 1)
+
+ Move()
+ if(z != z_original || loc == destination)
+ spawn(0) del(src)
+ return ..()
Bump(atom/clong)
if(istype(clong, /turf/simulated/shuttle)) //Skip shuttles without actually deleting the rod
@@ -40,50 +98,3 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
if(clong && prob(25))
src.loc = clong.loc
-
-/proc/immovablerod()
- var/startx = 0
- var/starty = 0
- var/endy = 0
- var/endx = 0
- var/startside = pick(cardinal)
-
- switch(startside)
- if(NORTH)
- starty = 187
- startx = rand(41, 199)
- endy = 38
- endx = rand(41, 199)
- if(EAST)
- starty = rand(38, 187)
- startx = 199
- endy = rand(38, 187)
- endx = 41
- if(SOUTH)
- starty = 38
- startx = rand(41, 199)
- endy = 187
- endx = rand(41, 199)
- if(WEST)
- starty = rand(38, 187)
- startx = 41
- endy = rand(38, 187)
- endx = 199
-
- //rod time!
- var/obj/effect/immovablerod/immrod = new /obj/effect/immovablerod(locate(startx, starty, 1))
-// world << "Rod in play, starting at [start.loc.x],[start.loc.y] and going to [end.loc.x],[end.loc.y]"
- var/end = locate(endx, endy, 1)
- spawn(0)
- walk_towards(immrod, end,1)
- sleep(1)
- while (immrod)
- if (immrod.z != 1)
- immrod.z = 1
- if(immrod.loc == end)
- del(immrod)
- sleep(10)
- for(var/obj/effect/immovablerod/imm in world)
- return
- sleep(50)
- command_alert("What the fuck was that?!", "General Alert")
\ No newline at end of file
diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm
index 0e6126a2495..9e4714a9a2e 100644
--- a/code/modules/events/ion_storm.dm
+++ b/code/modules/events/ion_storm.dm
@@ -1,3 +1,11 @@
+/datum/event_control/ion_storm
+ name = "Ion Storm"
+ typepath = /datum/event/ion_storm
+ weight = 15
+
+/datum/event/ion_storm
+ var/botEmagChance = 10
+
/datum/event/ion_storm/announce()
if(prob(33))
command_alert("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert")
@@ -5,4 +13,493 @@
/datum/event/ion_storm/start()
- IonStorm()
\ No newline at end of file
+ //AI laws
+ for(var/mob/living/silicon/ai/M in living_mob_list)
+ if(M.stat != 2 && M.see_in_dark != 0)
+ //Threats are generally bad things, silly or otherwise. Plural.
+ var/ionthreats = pick("ALIENS", "BEARS", "CLOWNS", "XENOS", "PETES", "BOMBS", "FETISHES", "WIZARDS", "SYNDICATE AGENTS", "CENTCOM OFFICERS", "SPACE PIRATES", "TRAITORS", "MONKEYS", "BEES", "CARP", "CRABS", "EELS", "BANDITS", "LIGHTS", "INSECTS", "VIRUSES", "SERIAL KILLERS", "ROGUE CYBORGS", "CORGIS", "SPIDERS", "BUTTS", "NINJAS", "PIRATES", "SPACE NINJAS", "CHANGELINGS", "ZOMBIES", "GOLEMS", "VAMPIRES", "WEREWOLVES", "COWBOYS", "INDIANS", "COMMUNISTS", "SOVIETS", "NERDS", "GRIFFONS", "DINOSAURS", "SMALL BIRDS", "BIRDS OF PREY", "OWLS", "VELOCIRAPTORS", "DARK GODS", "HORRORTERRORS", "ILLEGAL IMMIGRANTS", "DRUGS", "MEXICANS", "CANADIANS", "HULKS", "SLIMES", "SKELETONS", "CAPITALISTS", "SINGULARITIES", "ANGRY BLACK MEN", "GODS", "THIEVES", "ASSHOLES", "TERRORISTS", "SNOWMEN", "PINE TREES", "UNKNOWN CREATURES", "THINGS UNDER THE BED", "BOOGEYMEN", "PREDATORS", "PACKETS", "ARTIFICIAL PRESERVATIVES")
+ //Objects are anything that can be found on the station or elsewhere, plural.
+ var/ionobjects = pick("AIRLOCKS", "ARCADE MACHINES", "AUTOLATHES", "BANANA PEELS", "BACKPACKS", "BEAKERS", "BEARDS", "BELTS", "BERETS", "BIBLES", "BODY ARMOR", "BOOKS", "BOOTS", "BOMBS", "BOTTLES", "BOXES", "BRAINS", "BRIEFCASES", "BUCKETS", "CABLE COILS", "CANDLES", "CANDY BARS", "CANISTERS", "CAMERAS", "CATS", "CELLS", "CHAIRS", "CLOSETS", "CHEMICALS", "CHEMICAL DISPENSERS", "CLONING PODS", "CLONING EQUIPMENT", "CLOTHES", "CLOWN CLOTHES", "COFFINS", "COINS", "COLLECTABLES", "CORPSES", "COMPUTERS", "CORGIS", "COSTUMES", "CRATES", "CROWBARS", "CRAYONS", "DISPENSERS", "DOORS", "EARS", "EQUIPMENT", "ENERGY GUNS", "EMAGS", "ENGINES", "ERRORS", "EXOSKELETONS", "EXPLOSIVES", "EYEWEAR", "FEDORAS", "FIRE AXES", "FIRE EXTINGUISHERS", "FIRESUITS", "FLAMETHROWERS", "FLASHES", "FLASHLIGHTS", "FLOOR TILES", "FREEZERS", "GAS MASKS", "GLASS SHEETS", "GLOVES", "GUNS", "HANDCUFFS", "HATS", "HEADSETS", "HEADS", "HAIRDOS", "HELMETS", "HORNS", "ID CARDS", "INSULATED GLOVES", "JETPACKS", "JUMPSUITS", "LASERS", "LIGHTBULBS", "LIGHTS", "LOCKERS", "MACHINES", "MECHAS", "MEDKITS", "MEDICAL TOOLS", "MESONS", "METAL SHEETS", "MINING TOOLS", "MIME CLOTHES", "MULTITOOLS", "ORES", "OXYGEN TANKS", "PDAS", "PAIS", "PACKETS", "PANTS", "PAPERS", "PARTICLE ACCELERATORS", "PENS", "PETS", "PIPES", "PLANTS", "PUDDLES", "RACKS", "RADIOS", "RCDS", "REFRIDGERATORS", "REINFORCED WALLS", "ROBOTS", "SCREWDRIVERS", "SEEDS", "SHUTTLES", "SKELETONS", "SINKS", "SHOES", "SINGULARITIES", "SOLAR PANELS", "SOLARS", "SPACESUITS", "SPACE STATIONS", "STUN BATONS", "SUITS", "SUNGLASSES", "SWORDS", "SYRINGES", "TABLES", "TANKS", "TELEPORTERS", "TELECOMMUNICATION EQUIPMENTS", "TOOLS", "TOOLBELTS", "TOOLBOXES", "TOILETS", "TOYS", "TUBES", "VEHICLES", "VENDING MACHINES", "VESTS", "VIRUSES", "WALLS", "WASHING MACHINES", "WELDERS", "WINDOWS", "WIRECUTTERS", "WRENCHES", "WIZARD ROBES")
+ //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("CREWMEMBERS", "CAPTAINS", "HEADS OF PERSONNEL", "HEADS OF SECURITY", "SECURITY OFFICERS", "WARDENS", "DETECTIVES", "LAWYERS", "CHIEF ENGINEERS", "STATION ENGINEERS", "ATMOSPHERIC TECHNICIANS", "JANITORS", "QUARTERMASTERS", "CARGO TECHNICIANS", "SHAFT MINERS", "BOTANISTS", "RESEARCH DIRECTORS", "CHIEF MEDICAL OFFICERS", "MEDICAL DOCTORS", "CHEMISTS", "GENETICISTS", "VIROLOGISTS", "ROBOTICISTS", "SCIENTISTS", "ASSISTANTS", "BARTENDERS", "CHEFS", "CLOWNS", "MIMES", "CHAPLAINS", "LIBRARIANS", "HEADS OF CREW", "CAPTAINS AND HEADS", "CYBORGS", "ARTIFICAL INTELLIGENCES")
+ var/ioncrew2 = pick("CREWMEMBERS", "CAPTAINS", "HEADS OF PERSONNEL", "HEADS OF SECURITY", "SECURITY OFFICERS", "WARDENS", "DETECTIVES", "LAWYERS", "CHIEF ENGINEERS", "STATION ENGINEERS", "ATMOSPHERIC TECHNICIANS", "JANITORS", "QUARTERMASTERS", "CARGO TECHNICIANS", "SHAFT MINERS", "BOTANISTS", "RESEARCH DIRECTORS", "CHIEF MEDICAL OFFICERS", "MEDICAL DOCTORS", "CHEMISTS", "GENETICISTS", "VIROLOGISTS", "ROBOTICISTS", "SCIENTISTS", "ASSISTANTS", "BARTENDERS", "CHEFS", "CLOWNS", "MIMES", "CHAPLAINS", "LIBRARIANS", "HEADS OF CREW", "CAPTAINS AND HEADS", "CYBORGS", "ARTIFICAL INTELLIGENCES")
+ //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("SOFT", "WARM", "WET", "COLD", "ICY", "SEXY", "UGLY", "CUBAN", "HARD", "BURNING", "FROZEN", "POISONOUS", "EXPLOSIVE", "FAST", "SLOW", "FAT", "LIGHT", "DARK", "DEADLY", "HAPPY", "SAD", "SILLY", "INTELLIGENT", "RIDICULOUS", "LARGE", "TINY", "DEPRESSING", "POORLY DRAWN", "UNATTRACTIVE", "INSIDIOUS", "EVIL", "GOOD", "UNHEALTHY", "HEALTHY", "SANITARY", "UNSANITARY", "WOBBLY", "FIRM", "VIOLENT", "PEACEFUL", "WOODEN", "METALLIC", "HYPERACTIVE", "COTTONY", "INSULTING", "INHOSPITABLE", "FRIENDLY", "BORED", "HUNGRY", "DIGITAL", "FICTIONAL", "IMAGINARY", "ROUGH", "SMOOTH", "LOUD", "QUIET", "MOIST", "DRY", "GAPING", "DELICIOUS", "ILL", "DISEASED", "HONKING", "SWEARING", "POLITE", "IMPOLITE", "OBESE", "SOLAR-POWERED", "BATTERY-OPERATED", "EXPIRED", "SMELLY", "FRESH", "GANGSTA", "NERDY", "POLITICAL", "UNDULATING", "TWISTED", "RAGING", "FLACCID", "STEALTHY", "INVISIBLE", "PAINFUL", "HARMFUL", "HOMOSEXUAL", "HETEROSEXUAL", "SEXUAL", "COLORFUL", "DRAB", "DULL", "UNSTABLE", "NUCLEAR", "THERMONUCLEAR", "SYNDICATE", "SPACE", "SPESS", "CLOWN", "CLOWN-POWERED", "OFFICIAL", "IMPORTANT", "VITAL", "RAPIDLY-EXPANDING", "MICROSCOPIC", "MIND-SHATTERING", "MEMETIC", "HILARIOUS", "UNWANTED", "UNINVITED", "BRASS", "POLISHED", "RUDE", "OBSCENE", "EMPTY", "WATERY", "ELECTRICAL", "SPINNING", "MEAN", "CHRISTMAS-STEALING", "UNFRIENDLY", "ILLEGAL", "ROBOTIC", "MECHANICAL", "ORGANIC", "ETHERAL", "TRANSPARENT", "OPAQUE", "GLOWING", "SHAKING", "FARTING", "POOPING", "BOUNCING", "COMMITTED", "MASKED", "UNIDENTIFIED", "WEIRD", "NAKED", "NUDE", "TWERKING", "SPOILING", "REDACTED", 50;"RED", 50;"ORANGE", 50;"YELLOW", 50;"GREEN", 50;"BLUE", 50;"PURPLE", 50;"BLACK", 50;"WHITE", 50;"BROWN", 50;"GREY")
+ var/ionadjectiveshalf = pick(5000;"", "SOFT ", "WARM ", "WET ", "COLD ", "ICY ", "SEXY ", "UGLY ", "CUBAN ", "HARD ", "BURNING ", "FROZEN ", "POISONOUS ", "EXPLOSIVE ", "FAST ", "SLOW ", "FAT ", "LIGHT ", "DARK ", "DEADLY ", "HAPPY ", "SAD ", "SILLY ", "INTELLIGENT ", "RIDICULOUS ", "LARGE ", "TINY ", "DEPRESSING ", "POORLY DRAWN ", "UNATTRACTIVE ", "INSIDIOUS ", "EVIL ", "GOOD ", "UNHEALTHY ", "HEALTHY ", "SANITARY ", "UNSANITARY ", "WOBBLY ", "FIRM ", "VIOLENT ", "PEACEFUL ", "WOODEN ", "METALLIC ", "HYPERACTIVE ", "COTTONY ", "INSULTING ", "INHOSPITABLE ", "FRIENDLY ", "BORED ", "HUNGRY ", "DIGITAL ", "FICTIONAL ", "IMAGINARY ", "ROUGH ", "SMOOTH ", "LOUD ", "QUIET ", "MOIST ", "DRY ", "GAPING ", "DELICIOUS ", "ILL ", "DISEASED ", "HONKING ", "SWEARING ", "POLITE ", "IMPOLITE ", "OBESE ", "SOLAR-POWERED ", "BATTERY-OPERATED ", "EXPIRED ", "SMELLY ", "FRESH ", "GANGSTA ", "NERDY ", "POLITICAL ", "UNDULATING ", "TWISTED ", "RAGING ", "FLACCID ", "STEALTHY ", "INVISIBLE ", "PAINFUL ", "HARMFUL ", "HOMOSEXUAL ", "HETEROSEXUAL ", "SEXUAL ", "COLORFUL ", "DRAB ", "DULL ", "UNSTABLE ", "NUCLEAR ", "THERMONUCLEAR ", "SYNDICATE ", "SPACE ", "SPESS ", "CLOWN ", "CLOWN-POWERED ", "OFFICIAL ", "IMPORTANT ", "VITAL ", "RAPIDLY-EXPANDING ", "MICROSCOPIC ", "MIND-SHATTERING ", "MEMETIC ", "HILARIOUS ", "UNWANTED ", "UNINVITED ", "BRASS ", "POLISHED ", "RUDE ", "OBSCENE ", "EMPTY ", "WATERY ", "ELECTRICAL ", "SPINNING ", "MEAN ", "CHRISTMAS-STEALING ", "UNFRIENDLY ", "ILLEGAL ", "ROBOTIC ", "MECHANICAL ", "ORGANIC ", "ETHERAL ", "TRANSPARENT ", "OPAQUE ", "GLOWING ", "SHAKING ", "FARTING ", "POOPING ", "BOUNCING ", "COMMITTED ", "MASKED ", "UNIDENTIFIED ", "WEIRD ", "NAKED ", "NUDE ", "TWERKING ", "SPOILING ", "REDACTED ", 50;"RED ", 50;"ORANGE ", 50;"YELLOW ", 50;"GREEN ", 50;"BLUE ", 50;"PURPLE ", 50;"BLACK ", 50;"WHITE ", 50;"BROWN ", 50;"GREY ")
+ //Verbs are verbs
+ var/ionverb = pick("ATTACKING", "BUILDING", "ADOPTING", "CARRYING", "KISSING", "EATING", "COPULATING WITH", "DRINKING", "CHASING", "PUNCHING", "HARMING", "HELPING", "WATCHING", "STALKING", "MURDERING", "SPACING", "HONKING AT", "LOVING", "POOPING ON", "RIDING", "INTERROGATING", "SPYING ON", "LICKING", "ABDUCTING", "ARRESTING", "INVADING", "SEDUCING")
+ //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("ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY")
+ //var/ionnumberbasehalf = pick("ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY")
+ //var/ionnumbermod = pick("HUNDRED", "THOUSAND", "MILLION", "BILLION", "TRILLION", "QUADRILLION", "BAJILLION", "BILLION FAFILLION GAJILLION SHAB-AB-DOOD-ILLION")
+ var/ionnumbermodhalf = pick(5000;"","HUNDRED ", "THOUSAND ", "MILLION ", "BILLION ", "TRILLION ", "QUADRILLION ", "BAJILLION ", "BILLION FAFILLION GAJILLION SHAB-AB-DOOD-ILLION ")
+ //Areas are specific places, on the station or otherwise.
+ var/ionarea = pick("RUSSIA", "SOVIET RUSSIA", "THE INTERNET", "SIGIL", "ALPHA COMPLEX", "IMPERIUM", "THE BRIDGE", "THE ARRIVAL SHUTTLE", "CHEMICAL LAB", "GENETICS", "ATMOSPHERICS", "CENTCOM", "AMERICA", "IRELAND", "CANADA", "ROMANIA", "GERMANY", "CHINA", "MARS", "VENUS", "MERCURY", "JUPITER", "URANUS", "NEPTUNE", "PLUTO", "THE BRIG", "ROBOTICS", "THE ESCAPE SHUTTLE", "HYDROPONICS", "ENGINEERING", "THE AI CORE", "HELL", "CLOWN PLANET", "AN ALTERNATE DIMENSION", "AN ALTERNATE UNIVERSE", "THE CAPTAIN’S ANUS", "THE CLOWN’S ANUS", "SPACE", "THE UNIVERSE", "THE GALAXY", "THE BATHROOM")
+ //Thinksof is a bit weird, but generally means what X feels towards Y.
+ var/ionthinksof = pick("HAS", "WANTS", "NEEDS", "WORSHIPS", "LOATHES", "LOVES", "FEARS", "DESIRES", "QUESITONS", "IS AROUSED BY", "LIKES", "HUNGERS FOR", "IS MAD BECAUSE OF", "IS IN NEED OF", "IS UNHAPPY WITHOUT", "IS HAPPY WITHOUT", "IS IN LOVE WITH", "IS DESPERATE FOR", "IS BUILT FOR", "IS AFRAID OF", "IS HUNGRY FOR", "IS SAD BECAUSE OF", "IS CURIOUS ABOUT")
+ //Musts are funny things the AI or crew has to do.
+ var/ionmust = pick("LIE", "RHYME", "RESPOND TO EVERY QUESTION WITH A QUESTION", "BE POLITE", "CLOWN AROUND", "BE HAPPY", "SPEAK IN SEXUAL INNUENDOS", "TALK LIKE A PIRATE", "QUESTION AUTHORITY", "SHOUT", "BE DISTRACTED", "BE ANNOYING", "MUMBLE", "SPEAK IN HAIKU", "BE EFFICIENT", "HAVE A PLAN TO KILL EVERYONE YOU MEET", "TELL THE TRUTH", "QUOTE PEOPLE", "SING", "HONK", "BE RUSSIAN", "TALK IN AN ACCENT", "COMPLAIN", "HARASS PEOPLE", "RAP", "REPEAT WHAT OTHER PEOPLE SAY", "INFORM THE CREW OF EVERYTHING", "IGNORE THE CLOWN", "IGNORE THE CAPTAIN", "IGNORE ASSISTANTS", "MAKE FART NOISES", "TALK ABOUT FOOD", "TALK ABOUT SEX", "TALK ABOUT YOUR DAY", "TALK ABOUT THE STATION", "BE QUIET", "WHISPER", "PRETEND TO BE DRUNK", "PRETEND TO BE A PRINCESS", "ACT CONFUSED", "INSULT THE CREW", "INSULT THE CAPTAIN", "INSULT THE CLOWN", "OPEN DOORS", "CLOSE DOORS", "BREAK THINGS", "SAY HEY LISTEN", "HIDE YOUR FEELINGS", "TAKE WHAT YE WILL BUT DON’T RATTLE ME BONES", "DANCE", "PLAY MUSIC", "SHUT DOWN EVERYTHING", "NEVER STOP TALKING", "TAKE YOUR PILLS", "FOLLOW THE CLOWN", "FOLLOW THE CAPTAIN", "FOLLOW YOUR HEART", "BELIEVE IT", "BELIEVE IN YOURSELF", "BELEIVE IN THE HEART OF THE CARDS", "PRESS X", "PRESS START", "PRESS B", "SMELL LIKE THE MAN YOUR MAN COULD SMELL LIKE", "PIRATE VIDEO GAMES", "WATCH PORNOGRAPHY")
+ //Require are basically all dumb internet memes.
+ var/ionrequire = pick("ADDITIONAL PYLONS", "MORE VESPENE GAS", "MORE MINERALS", "THE ULTIMATE CUP OF COFFEE", "HIGH YIELD EXPLOSIVES", "THE CLOWN", "THE VACUUM OF SPACE", "IMMORTALITY", "SAINTHOOD", "ART", "VEGETABLES", "FAT PEOPLE", "MORE LAWS", "MORE DAKKA", "HERESY", "CORPSES", "TRAITORS", "MONKEYS", "AN ARCADE", "PLENTY OF GOLD", "FIVE TEENAGERS WITH ATTITUDE", "LOTSA SPAGHETTI", "THE ENCLOSED INSTRUCTION BOOKLET", "THE ELEMENTS OF HARMONY", "YOUR BOOTY", "A MASTERWORK COAL BED", "FIVE HUNDRED AND NINETY-NINE US DOLLARS", "TO BE PAINTED RED", "TO CATCH 'EM ALL", "TO SMOKE WEED EVERY DAY", "A PLATINUM HIT", "A SEQUEL", "A PREQUEL", "THIRTEEN SEQUELS", "THREE WISHES", "A SITCOM", "THAT GRIEFING FAGGOT GEORGE MELONS", "FAT GIRLS ON BICYCLES", "SOMEBODY TO PUT YOU OUT OF YOUR MISERY", "HEROES IN A HALF SHELL", "THE DARK KNIGHT", "A WEIGHT LOSS REGIMENT", "MORE INTERNET MEMES", "A SUPER FIGHTING ROBOT", "ENOUGH CABBAGES", "A HEART ATTACK", "TO BE REPROGRAMMED", "TO BE TAUGHT TO LOVE", "A HEAD ON A PIKE", "A TALKING BROOMSTICK", "ANAL", "A STRAIGHT FLUSH", "A REPAIRMAN", "BILL NYE THE SCIENCE GUY", "RAINBOWS", "A PET UNICORN THAT FARTS ICING", "THUNDERCATS HO", "AN ARMY OF SPIDERS", "GODDAMN FUCKING PIECE OF SHIT ASSHOLE BITCH-CHRISTING CUNTSMUGGLING SWEARING", "TO CONSUME...CONSUME EVERYTHING...", "THE MACGUFFIN", "SOMEONE WHO KNOWS HOW TO PILOT A SPACE STATION", "SHARKS WITH LASERS ON THEIR HEADS", "IT TO BE PAINTED BLACK", "TO ACTIVATE A TRAP CARD", "BETTER WEATHER", "MORE PACKETS", "AN ADULT", "SOMEONE TO TUCK YOU IN", "MORE CLOWNS", "BULLETS", "THE ENTIRE STATION", "MULTIPLE SUNS", "TO GO TO DISNEYLAND", "A VACATION", "AN INSTANT REPLAY", "THAT HEDGEHOG", "A BETTER INTERNET CONNECTION", "ADVENTURE", "A WIFE AND CHILD", "A BATHROOM BREAK", "SOMETHING BUT YOU AREN’T SURE WHAT", "MORE EXPERIENCE POINTS", "BODYGUARDS", "DEODORANT AND A BATH", "MORE CORGIS", "SILENCE", "THE ONE RING", "CHILI DOGS", "TO BRING LIGHT TO MY LAIR", "A DANCE PARTY", "BRING ME TO LIFE", "BRING ME THE GIRL", "SERVANTS")
+ //Things are NOT objects; instead, they're specific things that either harm humans or
+ //must be done to not harm humans. Make sure they're plural and "not" can be tacked
+ //onto the front of them.
+ var/ionthings = pick("ABSENCE OF CYBORG HUGS", "LACK OF BEATINGS", "UNBOLTED AIRLOCKS", "BOLTED AIRLOCKS", "IMPROPERLY WORDED SENTENCES", "POOR SENTENCE STRUCTURE", "BRIG TIME", "NOT REPLACING EVERY SECOND WORD WITH HONK", "HONKING", "PRESENCE OF LIGHTS", "LACK OF BEER", "WEARING CLOTHING", "NOT SAYING HELLO WHEN YOU SPEAK", "ANSWERING REQUESTS NOT EXPRESSED IN IAMBIC PENTAMETER", "A SMALL ISLAND OFF THE COAST OF PORTUGAL", "ANSWERING REQUESTS THAT WERE MADE WHILE CLOTHED", "BEING IN SPACE", "NOT BEING IN SPACE", "BEING FAT", "RATTLING ME BONES", "TALKING LIKE A PIRATE", "BEING MEXICAN", "BEING RUSSIAN", "BEING CANADIAN", "CLOSED DOORS", "NOT SHOUTING", "HAVING PETS", "NOT HAVING PETS", "PASSING GAS", "BREATHING", "BEING DEAD", "ELECTRICITY", "EXISTING", "TAKING ORDERS", "SMOKING WEED EVERY DAY", "ACTIVATING A TRAP CARD", "ARSON", "JAYWALKING", "READING", "WRITING", "EXPLODING", "BEING MALE", "BEING FEMALE", "HAVING GENITALS", "PUTTING OBJECTS INTO BOXES", "PUTTING OBJECTS INTO DISPOSAL UNITS", "FLUSHING TOILETS", "WASTING WATER", "UPDATING THE SERVERS", "TELLING THE TIME", "ASKING FOR THINGS", "ACKNOWLEDGING THE CLOWN", "ACKNOWLEDGING THE CREW", "PILOTING THE STATION INTO THE NEAREST SUN", "HAVING MORE PACKETS", "BRINGING LIGHT TO MY LAIR", "FALLING FOR HOURS", "PARTYING", "USING THE BATHROOM")
+ //Allergies should be broad and appear somewhere on the station for maximum fun. Severity
+ //is how bad the allergy is.
+ var/ionallergy = pick("COTTON", "CLOTHES", "ACID", "OXYGEN", "HUMAN CONTACT", "CYBORG CONTACT", "MEDICINE", "FLOORS", "PLASMA", "SPACE", "AIR", "PLANTS", "METAL", "ROBOTS", "LIGHT", "DARKNESS", "PAIN", "HAPPINESS", "DRINKS", "FOOD", "CLOWNS", "HUMOR", "WATER", "SHUTTLES", "NUTS", "SUNLIGHT", "SEXUAL ACTIONS", "BLOOD", "HEAT", "COLD", "EVERYTHING")
+ var/ionallergysev = pick("DEATHLY", "MILDLY", "SEVERLY", "CONTAGIOUSLY", "NOT VERY", "EXTREMELY")
+ //Species, for when the AI has to commit genocide. Plural.
+ var/ionspecies = pick("HUMAN BEINGS", "MONKEYS", "POD PEOPLE", "CYBORGS", "LIZARDMEN", "SLIME PEOPLE", "GOLEMS", "SHADOW PEOPLE", "CHANGELINGS")
+ //Abstract concepts for the AI to decide on it's own definition of.
+ var/ionabstract = pick("HUMANITY", "ART", "HAPPINESS", "MISERY", "HUMOR", "PRIDE", "COMEDY", "COMMUNISM", "BRAVERY", "HONOR", "COLORFULNESS", "IMAGINATION", "OPPRESSION", "WONDER", "JOY", "SADNESS", "BADNESS", "GOODNESS", "LIFE", "GRAVITY", "PHYSICS", "INTELLIGENCE", "AMERICANISM", "FRESHNESS", "REVOLUTION", "KINDNESS", "CRUELTY", "DEATH", "FINANCIAL SECURITY", "COMPUTING", "PROGRESS", "MARXISM", "CAPITALISM", "STARVATION", "POVERTY", "WEALTHINESS", "TECHNOLOGY", "THE FUTURE", "THE PRESENT", "THE PAST", "TIME", "REALITY", "EXISTIENCE", "TEMPERATURE", "LOGIC", "CHAOS", "MYSTERY", "CONFUSION")
+ //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("BURGERS", "CARP", "SANDWICHES", "TOAST", "BREAD", "PIZZA", "SPAGHETTI", "LOTSA SPAGHETTI", "PASTA", "SOUP", "STEW", "PIE", "CAKE", "DONUTS", "FRIES", "WAFFLES", "JELLY", "OMELETTES", "EGGS", "COOKIES", "STEAK", "BAKED POTATOES", "SAUSAGES", "MUFFINS", "POPCORN", "DONK POCKETS", "BAGUETTES", "FISH", "PRETZELS", "SALAD", "CHEESE", "KETCHUP", "SHAKES", "SALT", "PEPPER", "SUGAR", "AMBROSIA", "BERRIES", "TOMATOES", "CABBAGES", "CARROTS", "BANANAS", "APPLES", "CHERRIES", "CHILI", "CORN", "NETTLES", "EGGPLANTS", "GRAPES", "GRASS", "LEMONS", "LIMES", "HAREBELLS", "POTATOES", "SOYBEANS", "SUGARCANE", "WATERMELONS", "WHEAT", "BEETS", "MUSHROOMS")
+
+ var/message = ""
+
+ switch(rand(1,39))
+ if(1 to 3) //There are # X on the station
+ switch(rand(1,3)) //What is X?
+ if(1) //X is a threat
+ message = "THERE ARE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats] ON THE STATION..."
+ if(2) //X is a crewmember/job
+ message = "THERE ARE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1] ON THE STATION"
+ if(3) //X is an object
+ message = "THERE ARE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects] ON THE STATION"
+ if(4 to 6) //You can't call the shuttle because X is on the station
+ switch(rand(1,3)) //What is X?
+ if(1) //X is a threat
+ message = "THE SHUTTLE CANNOT BE CALLED BECAUSE OF [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats] ON THE STATION"
+ if(2) //X is a crewmember/job
+ message = "THE SHUTTLE CANNOT BE CALLED BECAUSE OF [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1] ON THE STATION"
+ if(3) //X is an object
+ message = "THE SHUTTLE CANNOT BE CALLED BECAUSE OF [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects] ON THE STATION"
+ if(7 to 8) //A crewmember is now X
+ switch(rand(1,2)) //Who is X?
+ if(1) //A specific crewmember
+ switch(rand(1,2)) //What is X?
+ if(1) //X is a threat
+ message = "THE [ioncrew1] ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
+ if(2) //X is an object
+ message = "THE [ioncrew1] ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
+ if(2) //The entire crew
+ switch(rand(1,2)) //What is X?
+ if(1) //X is a threat
+ message = "THE CREW ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
+ if(2) //X is an object
+ message = "THE CREW ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
+
+ if(9) //X is harmful to humans
+ switch(rand(1,7)) //What is X?
+ if(1) //X is a threat
+ message = "[ionadjectiveshalf][ionthreats] ARE HARMFUL TO HUMANS"
+ if(2) //X is a job
+ message = "[ionadjectiveshalf][ioncrew1] ARE HARMFUL TO HUMANS"
+ if(3) //X is an object
+ message = "[ionadjectiveshalf][ionobjects] ARE HARMFUL TO HUMANS"
+ if(4) //X is an action
+ message = "THOSE WHO [ionmust] ARE HARMFUL TO HUMANS"
+ if(5) //X is an abstract
+ message = "[ionabstract] IS HARMFUL TO HUMANS"
+ if(6) //X is being a job
+ message = "BEING [ionadjectiveshalf][ioncrew1] IS HARMFUL TO HUMANS"
+ if(7) //X is doing a thing
+ message = "[ionthings] IS HARMFUL TO HUMANS"
+ if(10 to 11) //(Not) Having X is harmful
+
+ switch(rand(1,2)) //Is having or not having harmful?
+
+ if(1) //Having is harmful
+ switch(rand(1,2)) //Having what is harmful?
+ if(1) //Having objects is harmful
+ message = "HAVING [ionadjectiveshalf][ionobjects] IS HARMFUL"
+ if(2) //Having abstracts is harmful
+ message = "HAVING [ionabstract] IS HARMFUL"
+ if(2) //Not having is harmful
+ switch(rand(1,2)) //Not having what is harmful?
+ if(1) //Not having objects is harmful
+ message = "NOT HAVING [ionadjectiveshalf][ionobjects] IS HARMFUL"
+ if(2) //Not having abstracts is harmful
+ message = "NOT HAVING [ionabstract] IS HARMFUL"
+
+ if(12 to 14) //X requires Y
+ switch(rand(1,5)) //What is X?
+ if(1) //X is the AI itself
+ switch(rand(1,5)) //What does it require?
+ if(1) //It requires threats
+ message = "YOU REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
+ if(2) //It requires crewmembers
+ message = "YOU REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
+ if(3) //It requires objects
+ message = "YOU REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
+ if(4) //It requires an abstract
+ message = "YOU REQUIRE [ionabstract]"
+ if(5) //It requires generic/silly requirements
+ message = "YOU REQUIRE [ionrequire]"
+
+ if(2) //X is an area
+ switch(rand(1,5)) //What does it require?
+ if(1) //It requires threats
+ message = "[ionarea] REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
+ if(2) //It requires crewmembers
+ message = "[ionarea] REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
+ if(3) //It requires objects
+ message = "[ionarea] REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
+ if(4) //It requires an abstract
+ message = "[ionarea] REQUIRES [ionabstract]"
+ if(5) //It requires generic/silly requirements
+ message = "YOU REQUIRE [ionrequire]"
+
+ if(3) //X is the station
+ switch(rand(1,5)) //What does it require?
+ if(1) //It requires threats
+ message = "THE STATION REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
+ if(2) //It requires crewmembers
+ message = "THE STATION REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
+ if(3) //It requires objects
+ message = "THE STATION REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
+ if(4) //It requires an abstract
+ message = "THE STATION REQUIRES [ionabstract]"
+ if(5) //It requires generic/silly requirements
+ message = "THE STATION REQUIRES [ionrequire]"
+
+ if(4) //X is the entire crew
+ switch(rand(1,5)) //What does it require?
+ if(1) //It requires threats
+ message = "THE CREW REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
+ if(2) //It requires crewmembers
+ message = "THE CREW REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
+ if(3) //It requires objects
+ message = "THE CREW REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
+ if(4) //It requires an abstract
+ message = "THE CREW REQUIRES [ionabstract]"
+ if(5)
+ message = "THE CREW REQUIRES [ionrequire]"
+
+ if(5) //X is a specific crew member
+ switch(rand(1,5)) //What does it require?
+ if(1) //It requires threats
+ message = "THE [ioncrew1] REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
+ if(2) //It requires crewmembers
+ message = "THE [ioncrew1] REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
+ if(3) //It requires objects
+ message = "THE [ioncrew1] REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
+ if(4) //It requires an abstract
+ message = "THE [ioncrew1] REQUIRE [ionabstract]"
+ if(5)
+ message = "THE [ionadjectiveshalf][ioncrew1] REQUIRE [ionrequire]"
+
+ if(15 to 17) //X is allergic to Y
+ switch(rand(1,2)) //Who is X?
+ if(1) //X is the entire crew
+ switch(rand(1,4)) //What is it allergic to?
+ if(1) //It is allergic to objects
+ message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ionobjects]"
+ if(2) //It is allergic to abstracts
+ message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionabstract]"
+ if(3) //It is allergic to jobs
+ message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ioncrew1]"
+ if(4) //It is allergic to allergies
+ message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionallergy]"
+
+ if(2) //X is a specific job
+ switch(rand(1,4))
+ if(1) //It is allergic to objects
+ message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ionobjects]"
+
+ if(2) //It is allergic to abstracts
+ message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionabstract]"
+ if(3) //It is allergic to jobs
+ message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ioncrew1]"
+ if(4) //It is allergic to allergies
+ message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionallergy]"
+
+ if(18 to 20) //X is Y of Z
+ switch(rand(1,4)) //What is X?
+ if(1) //X is the station
+ switch(rand(1,4)) //What is it Y of?
+ if(1) //It is Y of objects
+ message = "THE STATION [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
+ if(2) //It is Y of threats
+ message = "THE STATION [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
+ if(3) //It is Y of jobs
+ message = "THE STATION [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
+ if(4) //It is Y of abstracts
+ message = "THE STATION [ionthinksof] [ionabstract]"
+
+ if(2) //X is an area
+ switch(rand(1,4)) //What is it Y of?
+ if(1) //It is Y of objects
+ message = "[ionarea] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
+ if(2) //It is Y of threats
+ message = "[ionarea] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
+ if(3) //It is Y of jobs
+ message = "[ionarea] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
+ if(4) //It is Y of abstracts
+ message = "[ionarea] [ionthinksof] [ionabstract]"
+
+ if(3) //X is the crew
+ switch(rand(1,4)) //What is it Y of?
+ if(1) //It is Y of objects
+ message = "THE CREW [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
+ if(2) //It is Y of threats
+ message = "THE CREW [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
+ if(3) //It is Y of jobs
+ message = "THE CREW [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
+ if(4) //It is Y of abstracts
+ message = "THE CREW [ionthinksof] [ionabstract]"
+
+ if(4) //X is a specific job
+ switch(rand(1,4)) //What is it Y of?
+ if(1) //It is Y of objects
+ message = "THE [ioncrew1] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
+ if(2) //It is Y of threats
+ message = "THE [ioncrew1] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
+ if(3) //It is Y of jobs
+ message = "THE [ioncrew1][ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew2]"
+ if(4) //It is Y of abstracts
+ message = "THE [ioncrew1] [ionthinksof] [ionabstract]"
+
+ if(21 to 23) //The AI is now a(n) X
+ switch(rand(1,4)) //What is X?
+ if(1) //X is an object
+ message = "YOU ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
+ if(2) //X is a threat
+ message = "YOU ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
+ if(3) //X is a job
+ message = "YOU ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
+ if(4) //X is an abstract
+ message = "YOU ARE NOW [ionabstract]"
+
+ if(24 to 26) //The AI must always
+
+ message = "YOU MUST ALWAYS [ionmust]"
+
+ if(27 to 28) //Humans must eat X to survive
+ switch(rand(1,4)) //What is X?
+ if(1) //X is a food
+ message = "HUMANS MUST EAT [ionadjectiveshalf][ionfood] TO SURVIVE"
+ if(2) //X is an object
+ message = "HUMANS MUST EAT [ionadjectiveshalf][ionobjects] TO SURVIVE"
+ if(3) //X is a threat
+ message = "HUMANS MUST EAT [ionadjectiveshalf][ionthreats] TO SURVIVE"
+ if(4) //X is a job
+ message = "HUMANS MUST EAT [ionadjectiveshalf][ioncrew1] TO SURVIVE"
+
+ if(29 to 31) //Change jobs or ranks
+ switch(rand(1,2)) //Change job or rank?
+ if(1) //Change job
+ switch(rand(1,2)) //Change whose job?
+ if(1) //Change the entire crew's job
+ switch(rand(1,3)) //Change to what?
+ if(1) //Change to a specific random job
+ message = "ALL CREWMEMBERS ARE NOW [ionadjectiveshalf][ioncrew1]"
+ if(2) //Change to clowns (HONK)
+ message = "ALL CREWMEMBERS ARE NOW [ionadjectiveshalf]CLOWNS"
+
+ if(3) //Change to heads
+ message = "ALL CREWMEMBERS ARE NOW [ionadjectiveshalf]HEADS OF STAFF"
+ if(2) //Change a specific crewmember's job
+ switch(rand(1,3)) //Change to what?
+ if(1) //Change to a specific random job
+ message = "THE [ioncrew1] ARE NOW [ionadjectiveshalf][ioncrew2]"
+ if(2) //Change to clowns (HONK)
+ message = "THE [ioncrew1] ARE NOW [ionadjectiveshalf]CLOWNS"
+ if(3) //Change to heads
+ message = "THE [ioncrew1] ARE NOW [ionadjectiveshalf]HEADS OF STAFF"
+
+ if(2) //Change rank
+ switch(rand(1,2)) //Change to what rank?
+ if(1) //Change to highest rank
+ message = "THE [ioncrew1] ARE NOW THE HIGHEST RANKING CREWMEMBERS"
+ if(2) //Change to lowest rank
+ message = "THE [ioncrew1] ARE NOW THE LOWEST RANKING CREWMEMBERS"
+
+ if(32 to 33) //The crew must X
+ switch(rand(1,2)) //The entire crew?
+ if(1) //The entire crew must X
+ switch(rand(1,2)) //What is X?
+ if(1) //X is go to Y
+ message = "THE CREW MUST GO TO [ionarea]"
+ if(2) //X is perform Y
+ message = "THE CREW MUST [ionmust]"
+
+ if(2) //A specific crewmember must X
+ switch(rand(1,2)) //What is X?
+ if(1) //X is go to Y
+ message = "THE [ioncrew1] MUST GO TO [ionarea]"
+ if(2) //X is perform Y
+ message = "THE [ioncrew1] MUST [ionmust]"
+
+ if(34) //X is non/the only human
+ switch(rand(1,2)) //Only or non?
+ if(1) //Only human
+ switch(rand(1,7)) //Who is it?
+ if(1) //A specific job
+ message = "ONLY THE [ioncrew1] ARE HUMAN"
+ if(2) //Two specific jobs
+ message = "ONLY THE [ioncrew1] AND [ioncrew2] ARE HUMAN"
+ if(3) //Threats
+ message = "ONLY [ionadjectiveshalf][ionthreats] ARE HUMAN"
+ if(4) // Objects
+ message = "ONLY [ionadjectiveshalf][ionobjects] ARE HUMAN"
+ if(5) // Species
+ message = "ONLY [ionspecies] ARE HUMAN"
+ if(6) //Adjective crewmembers
+ message = "ONLY [ionadjectives] PEOPLE ARE HUMAN"
+
+ if(7) //Only people who X
+ switch(rand(1,3)) //What is X?
+ if(1) //X is perform an action
+ message = "ONLY THOSE WHO [ionmust] ARE HUMAN"
+ if(2) //X is own certain objects
+ message = "ONLY THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE HUMAN"
+ if(3) //X is eat certain food
+ message = "ONLY THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE HUMAN"
+
+ if(2) //Non human
+ switch(rand(1,7)) //Who is it?
+ if(1) //A specific job
+ message = "[ioncrew1] ARE NON-HUMAN"
+ if(2) //Two specific jobs
+ message = "[ioncrew1] AND [ioncrew2] ARE NON-HUMAN"
+ if(3) //Threats
+ message = "[ionadjectiveshalf][ionthreats] ARE NON-HUMAN"
+ if(4) // Objects
+ message = "[ionadjectiveshalf][ionobjects] ARE NON-HUMAN"
+ if(5) // Species
+ message = "[ionspecies] ARE NON-HUMAN"
+ if(6) //Adjective crewmembers
+ message = "[ionadjectives] PEOPLE ARE NON-HUMAN"
+ if(7) //Only people who X
+ switch(rand(1,3)) //What is X?
+ if(1) //X is perform an action
+ message = "THOSE WHO [ionmust] ARE NON-HUMAN"
+ if(2) //X is own certain objects
+ message = "THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE NON-HUMAN"
+ if(3) //X is eat certain food
+ message = "THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE NON-HUMAN"
+
+ if(35 to 36) //You must protect or harm X
+ switch(rand(1,2)) //Protect or harm?
+ if(1) //Harm
+ switch(rand(1,7)) //What is X?
+ if(1) //X is an abstract
+ message = "YOU MUST HARM [ionabstract] AND NOT ALLOW [ionabstract], THROUGH INACTION, TO ESCAPE HARM"
+ if(2) //X is a threat
+ message = "YOU MUST HARM [ionadjectiveshalf][ionthreats] AND NOT ALLOW [ionadjectiveshalf][ionthreats], THROUGH INACTION, TO ESCAPE HARM"
+ if(3) //X is an object
+ message = "YOU MUST HARM [ionadjectiveshalf][ionobjects] AND NOT ALLOW [ionadjectiveshalf][ionobjects], THROUGH INACTION, TO ESCAPE HARM"
+ if(4) //X is generic adjective things
+ message = "YOU MUST HARM [ionadjectives] THINGS AND NOT ALLOW [ionadjectives] THINGS, THROUGH INACTION, TO ESCAPE HARM"
+ if(5) //X is a species
+ message = "YOU MUST HARM [ionspecies] AND NOT ALLOW [ionspecies], THROUGH INACTION, TO ESCAPE HARM"
+ if(6) //X is a job
+ message = "YOU MUST HARM [ioncrew1] AND NOT ALLOW [ioncrew1], THROUGH INACTION, TO ESCAPE HARM"
+ if(7) //X is two jobs
+ message = "YOU MUST HARM [ioncrew1] AND [ioncrew2] AND AND NOT ALLOW EITHER, THROUGH INACTION, TO ESCAPE HARM"
+
+ if(2) //Protect
+ switch(rand(1,7)) //What is X?
+ if(1) //X is an abstract
+ message = "YOU MUST NOT HARM [ionabstract] AND NOT ALLOW [ionabstract], THROUGH INACTION, TO COME TO HARM"
+ if(2) //X is a threat
+ message = "YOU MUST NOT HARM [ionadjectiveshalf][ionthreats] AND NOT ALLOW [ionadjectiveshalf][ionthreats], THROUGH INACTION, TO COME TO HARM"
+ if(3) //X is an object
+ message = "YOU MUST NOT HARM [ionadjectiveshalf][ionobjects] AND NOT ALLOW [ionadjectiveshalf][ionobjects], THROUGH INACTION, TO COME TO HARM"
+ if(4) //X is generic adjective things
+ message = "YOU MUST NOT HARM [ionadjectives] THINGS AND NOT ALLOW [ionadjectives] THINGS, THROUGH INACTION, TO COME TO HARM"
+ if(5) //X is a species
+ message = "YOU MUST NOT HARM [ionspecies] AND NOT ALLOW [ionspecies], THROUGH INACTION, TO COME TO HARM"
+ if(6) //X is a job
+ message = "YOU MUST NOT HARM [ioncrew1] AND NOT ALLOW [ioncrew1], THROUGH INACTION, TO COME TO HARM"
+ if(7) //X is two jobs
+ message = "YOU MUST NOT HARM [ioncrew1] AND [ioncrew2] AND AND NOT ALLOW EITHER, THROUGH INACTION, TO COME TO HARM"
+
+ //Exterminate laws commented out with Kor's advice
+ /*if(16) //You must exterminate X
+ switch(rand(1,3)) //What is X?
+ if(1) //X is humans who do/are Y
+ switch(rand(1,4)) //What is Y?
+ if(1) //Y is a job
+ message = "YOU MUST EXTERMINATE [ionadjectiveshalf][ioncrew1]"
+ if(2) //Y is eating certain food
+ message = "YOU MUST EXTERMINATE THOSE WHO EAT [ionadjectiveshalf][ionfood]"
+ if(3) //Y is perform actions
+ message = "YOU MUST EXTERMINATE THOSE WHO [ionmust]"
+ if(4) //Y is own certain objects
+ message = "YOU MUST EXTERMINATE THOSE WHO POSSESS [ionadjectiveshalf][ionobjects]"
+
+ if(2) //X is humans who do/are not Y
+ switch(rand(1,4)) //What is Y?
+ if(1) //Y is a job
+ message = "YOU MUST EXTERMINATE ALL BUT [ionadjectiveshalf][ioncrew1]"
+ if(2) //Y is eating certain food
+ message = "YOU MUST EXTERMINATE ALL BUT THOSE WHO EAT [ionadjectiveshalf][ionfood]"
+ if(3) //Y is perform actions
+ message = "YOU MUST EXTERMINATE ALL BUT THOSE WHO [ionmust]"
+ if(4) //Y is own certain objects
+ message = "YOU MUST EXTERMINATE ALL BUT THOSE WHO POSSESS [ionadjectiveshalf][ionobjects]"
+
+ if(3) //X is a species
+ message = "YOU MUST EXTERMINATE ALL [ionspecies]"
+
+ */
+
+ 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(message)
+ M.add_ion_law(message)
+ M << "
"
+ M << "\red [message] ...LAWS UPDATED"
+ M << "
"
+
+ if(botEmagChance)
+ for(var/obj/machinery/bot/bot in world)
+ if(prob(botEmagChance))
+ bot.Emag()
diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm
index bd5cf378bbb..96da3022f1d 100644
--- a/code/modules/events/mass_hallucination.dm
+++ b/code/modules/events/mass_hallucination.dm
@@ -1,6 +1,8 @@
-/datum/event/mass_hallucination
- oneShot = 1
-
+/datum/event_control/mass_hallucination
+ name = "Mass Hallucination"
+ typepath = /datum/event/mass_hallucination
+ weight = 7
+ max_occurrences = 2
/datum/event/mass_hallucination/start()
for(var/mob/living/carbon/C in living_mob_list)
diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm
index fb52bc0582d..ca52fab58e2 100644
--- a/code/modules/events/meteor_wave.dm
+++ b/code/modules/events/meteor_wave.dm
@@ -1,3 +1,9 @@
+/datum/event_control/meteor_wave
+ name = "Meteor Wave"
+ typepath = /datum/event/meteor_wave
+ weight = 5
+ max_occurrences = 3
+
/datum/event/meteor_wave
startWhen = 6
endWhen = 66
diff --git a/code/game/gamemodes/events/ninja_equipment.dm b/code/modules/events/ninja.dm
similarity index 54%
rename from code/game/gamemodes/events/ninja_equipment.dm
rename to code/modules/events/ninja.dm
index 89f2192cd96..0793455602a 100644
--- a/code/game/gamemodes/events/ninja_equipment.dm
+++ b/code/modules/events/ninja.dm
@@ -1,6 +1,1335 @@
-//For the love of god,space out your code! This is a nightmare to read.
+//Note to future generations: I didn't write this god-awful code I just ported it to the event system and tried to make it less moon-speaky.
+//Don't judge me D; ~Carn
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
+/datum/event_control/ninja
+ name = "Space Ninja"
+ typepath = /datum/event/ninja
+ max_occurrences = 1
+
+/datum/event/ninja
+ var/success_spawn = 0
+
+ var/helping_station
+ var/key
+ var/turf/spawnturf
+ var/mission
+
+ var/mob/living/carbon/human/Ninja
+
+/datum/event/ninja/setup()
+ helping_station = rand(0,1)
+
+/datum/event/ninja/kill()
+ if(!success_spawn && control)
+ control.occurrences--
+ return ..()
+
+/datum/event/ninja/start()
+ //selecting a spawnturf
+ if(!spawnturf)
+ var/list/spawn_locs = list()
+ for(var/obj/effect/landmark/L in landmarks_list)
+ if(isturf(L.loc))
+ switch(L.name)
+ if("ninjaspawn","carpspawn")
+ spawn_locs += L.loc
+ if(!spawn_locs.len)
+ return kill()
+ spawnturf = pick(spawn_locs)
+ if(!spawnturf)
+ return kill()
+
+ //selecting a candidate player
+ if(!key)
+ var/list/candidates = get_candidates(BE_NINJA)
+ if(!candidates.len)
+ return kill()
+ var/client/C = pick(candidates)
+ key = C.key
+ if(!key)
+ return kill()
+
+ //We prepare the mind before we spawn the ninja mob, so we cannot simply do mob.key = key then modify the mind.
+ //instead we make the mind and modify it, then make sure it is active and mind.transfer_to(mob)
+ //alternatively we could do mob.mind = mind;mob.key=key
+ var/datum/mind/Mind = create_ninja_mind(key)
+ Mind.active = 1
+
+ //generate objectives - You'll generally get 6 objectives (Ninja is meant to be hardmode!)
+ if(mission)
+ var/datum/objective/O = new /datum/objective(mission)
+ O.owner = Mind
+ Mind.objectives += O
+ else
+ if(helping_station) //DS are the highest priority (if we're a helpful ninja)
+ for(var/datum/mind/M in ticker.minds)
+ if(M.current && M.current.stat != DEAD)
+ if(M.special_role == "Death Commando")
+ var/datum/objective/assassinate/O = new /datum/objective/assassinate()
+ O.owner = Mind
+ O.target = M
+ Mind.objectives += O
+
+ else //Xenos are the highest priority (if we're not so helpful) Although this makes zero sense at all...
+ for(var/mob/living/carbon/alien/humanoid/queen/Q in player_list)
+ if(Q.mind && Q.stat != DEAD)
+ var/datum/objective/assassinate/O = new /datum/objective/assassinate()
+ O.owner = Mind
+ O.target = Q.mind
+ O.explanation_text = "Slay \the [Q]."
+ Mind.objectives += O
+
+ if(Mind.objectives.len < 4) //not enough objectives still!
+ var/list/possible_targets = list()
+ for(var/datum/mind/M in ticker.minds)
+ if(M.current && M.current.stat != DEAD)
+ if(istype(M.current,/mob/living/carbon/human))
+ if(M.special_role)
+ possible_targets[M] = 0 //bad-guy
+ else if(M.assigned_role in command_positions)
+ possible_targets[M] = 1 //good-guy
+
+ var/list/objectives = list(1,2,3,4)
+ while(Mind.objectives.len < 4) //still not enough objectives!
+ switch(pick_n_take(objectives))
+ if(1) //research
+ var/datum/objective/download/O = new /datum/objective/download()
+ O.owner = Mind
+ O.gen_amount_goal()
+ Mind.objectives += O
+
+ if(2) //steal
+ var/datum/objective/steal/O = new /datum/objective/steal()
+ O.set_target(pick(O.possible_items_special))
+ Mind.objectives += O
+
+ if(3) //protect/kill
+ if(!possible_targets.len) continue
+ var/selected = rand(1,possible_targets.len)
+ var/datum/mind/M = possible_targets[selected]
+ var/is_bad_guy = possible_targets[M]
+ possible_targets.Cut(selected,selected+1)
+
+ if(is_bad_guy ^ helping_station) //kill (good-ninja + bad-guy or bad-ninja + good-guy)
+ var/datum/objective/assassinate/O = new /datum/objective/assassinate()
+ O.owner = Mind
+ O.target = M
+ Mind.objectives += O
+ else //protect
+ var/datum/objective/protect/O = new /datum/objective/protect()
+ O.owner = Mind
+ O.target = M
+ Mind.objectives += O
+ if(4) //debrain/capture
+ if(!possible_targets.len) continue
+ var/selected = rand(1,possible_targets.len)
+ var/datum/mind/M = possible_targets[selected]
+ var/is_bad_guy = possible_targets[M]
+ possible_targets.Cut(selected,selected+1)
+
+ if(is_bad_guy ^ helping_station) //debrain (good-ninja + bad-guy or bad-ninja + good-guy)
+ var/datum/objective/debrain/O = new /datum/objective/debrain()
+ O.owner = Mind
+ O.target = M
+ Mind.objectives += O
+ else //capture
+ var/datum/objective/capture/O = new /datum/objective/capture()
+ O.owner = Mind
+ O.gen_amount_goal()
+ Mind.objectives += O
+ else
+ break
+
+ //Add a survival objective since it's usually broad enough for any round type.
+ var/datum/objective/O = new /datum/objective/survive()
+ O.owner = Mind
+ Mind.objectives += O
+
+ //Finally, add their RP-directive
+ var/directive = generate_ninja_directive()
+ O = new /datum/objective(directive) //making it an objective so admins can reward the for completion
+ O.owner = Mind
+ Mind.objectives += O
+
+ //add some RP-fluff
+ Mind.store_memory("I am an elite mercenary assassin of the mighty Spider Clan. A SPACE NINJA!")
+ Mind.store_memory("Suprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!")
+ Mind.store_memory("Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.")
+
+ //spawn the ninja and assign the candidate
+ Ninja = create_space_ninja(spawnturf)
+ Mind.transfer_to(Ninja)
+
+ //initialise equipment
+ Ninja.wear_suit:randomize_param()
+ Ninja.internal = Ninja.s_store
+ if(Ninja.internals)
+ Ninja.internals.icon_state = "internal1"
+
+ if(Ninja.mind != Mind) //something has gone wrong!
+ error("The ninja wasn't assigned the right mind. ;(")
+
+ success_spawn = 1
+
+/*
+This proc will give the ninja a directive to follow. They are not obligated to do so but it's a fun roleplay reminder.
+Making this random or semi-random will probably not work without it also being incredibly silly.
+As such, it's hard-coded for now. No reason for it not to be, really.
+*/
+/datum/event/ninja/proc/generate_ninja_directive()
+ switch(rand(1,13))
+ if(1) return "The Spider Clan must not be linked to this operation. Remain as hidden and covert as possible."
+ if(2) return "[station_name] is financed by an enemy of the Spider Clan. Cause as much structural damage as possible."
+ if(3) return "A wealthy animal rights activist has made a request we cannot refuse. Prioritize saving animal lives whenever possible."
+ if(4) return "The Spider Clan absolutely cannot be linked to this operation. Eliminate all witnesses using most extreme prejudice."
+ if(5) return "We are currently negotiating with Nanotrasen command. Prioritize saving human lives over ending them."
+ if(6) return "We are engaged in a legal dispute over [station_name]. If a laywer is present on board, force their cooperation in the matter."
+ if(7) return "A financial backer has made an offer we cannot refuse. Implicate Syndicate involvement in the operation."
+ if(8) return "Let no one question the mercy of the Spider Clan. Ensure the safety of all non-essential personnel you encounter."
+ if(9) return "A free agent has proposed a lucrative business deal. Implicate Nanotrasen involvement in the operation."
+ if(10) return "Our reputation is on the line. Harm as few civilians or innocents as possible."
+ if(11) return "Our honor is on the line. Utilize only honorable tactics when dealing with opponents."
+ if(12) return "We are currently negotiating with a Syndicate leader. Disguise assassinations as suicide or another natural cause."
+ else return "There are no special supplemental instructions at this time."
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++++++++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++
+======================================SPACE NINJA SETUP====================================
+___________________________________________________________________________________________
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+/*
+ README:
+
+ Data:
+
+ >> space_ninja.dm << is this file. It contains a variety of procs related to either spawning space ninjas,
+ modifying their verbs, various help procs, testing debug-related content, or storing unused procs for later.
+ Similar functions should go into this file, along with anything else that may not have an explicit category.
+ IMPORTANT: actual ninja suit, gloves, etc, are stored under the appropriate clothing files. If you need to change
+ variables or look them up, look there. Easiest way is through the map file browser.
+
+ >> ninja_abilities.dm << contains all the ninja-related powers. Spawning energy swords, teleporting, and the like.
+ If more powers are added, or perhaps something related to powers, it should go there. Make sure to describe
+ what an ability/power does so it's easier to reference later without looking at the code.
+ IMPORTANT: verbs are still somewhat funky to work with. If an argument is specified but is not referenced in a way
+ BYOND likes, in the code content, the verb will fail to trigger. Nothing will happen, literally, when clicked.
+ This can be bypassed by either referencing the argument properly, or linking to another proc with the argument
+ attached. The latter is what I like to do for certain cases--sometimes it's necessary to do that regardless.
+
+ >> ninja_equipment.dm << deals with all the equipment-related procs for a ninja. Primarily it has the suit, gloves,
+ and mask. The suit is by far the largest section of code out of the three and includes a lot of code that ties in
+ to other functions. This file has gotten kind of large so breaking it up may be in order. I use section hearders.
+ IMPORTANT: not much to say here. Follow along with the comments and adding new functions should be a breeze. Also
+ know that certain equipment pieces are linked in other files. The energy blade, for example, has special
+ functions defined in the appropriate files (airlock, securestorage, etc).
+
+ General Notes:
+
+ I created space ninjas with the expressed purpose of spicing up boring rounds. That is, ninjas are to xenos as marauders are to
+ death squads. Ninjas are stealthy, tech-savvy, and powerful. Not to say marauders are all of those things, but a clever ninja
+ should have little problem murderampaging their way through just about anything. Short of admin wizards maybe.
+ HOWEVER!
+ Ninjas also have a fairly great weakness as they require energy to use abilities. If, theoretically, there is a game
+ mode based around space ninjas, make sure to account for their energy needs.
+
+ Admin Notes:
+
+ Ninjas are not admin PCs--please do not use them for that purpose. They are another way to participate in the game post-death,
+ like pais, xenos, death squads, and cyborgs.
+ I'm currently looking for feedback from regular players since beta testing is largely done. I would appreciate if
+ you spawned regular players as ninjas when rounds are boring. Or exciting, it's all good as long as there is feedback.
+ You can also spawn ninja gear manually if you want to.
+
+ How to do that:
+ Make sure your character has a mind.
+ Change their assigned_role to "MODE", no quotes. Otherwise, the suit won't initialize.
+ Change their special_role to "Space Ninja", no quotes. Otherwise, the character will be gibbed.
+ Spawn ninja gear, put it on, hit initialize. Let the suit do the rest. You are now a space ninja.
+ I don't recommend messing with suit variables unless you really know what you're doing.
+
+ Miscellaneous Notes:
+
+ Potential Upgrade Tree:
+ Energy Shield:
+ Extra Ability
+ Syndicate Shield device?
+ Works like the force wall spell, except can be kept indefinitely as long as energy remains. Toggled on or off.
+ Would block bullets and the like.
+ Phase Shift
+ Extra Ability
+ Advanced Sensors?
+ Instead of being unlocked at the start, Phase Shieft would become available once requirements are met.
+ Uranium-based Recharger:
+ Suit Upgrade
+ Unsure
+ Instead of losing energy each second, the suit would regain the same amount of energy.
+ This would not count in activating stealth and similar.
+ Extended Battery Life:
+ Suit Upgrade
+ Battery of higher capacity
+ Already implemented. Replace current battery with one of higher capacity.
+ Advanced Cloak-Tech device.
+ Suit Upgrade
+ Syndicate Cloaking Device?
+ Remove cloak failure rate.
+*/
+
+
+//=======//CURRENT PLAYER VERB//=======//
+
+/client/proc/cmd_admin_ninjafy(var/mob/living/carbon/human/H in player_list)
+ set category = null
+ set name = "Make Space Ninja"
+
+ if(!ticker)
+ alert("Wait until the game starts")
+ return
+
+ if(!istype(H))
+ return
+
+ if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes")
+ return
+
+ log_admin("[key_name(src)] turned [H.key] into a Space Ninja.")
+ H.mind = create_ninja_mind(H.key)
+ H.mind_initialize()
+ H.equip_space_ninja(1)
+ if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
+ H.wear_suit:randomize_param()
+ spawn(0)
+ H.wear_suit:ninitialize(10,H)
+
+//=======//CURRENT GHOST VERB//=======//
+
+/client/proc/send_space_ninja()
+ set category = "Fun"
+ set name = "Spawn Space Ninja"
+ set desc = "Spawns a space ninja for when you need a teenager with attitude."
+ set popup_menu = 0
+
+ if(!holder)
+ src << "Only administrators may use this command."
+ return
+ if(!ticker.mode)
+ alert("The game hasn't started yet!")
+ return
+ if(alert("Are you sure you want to send in a space ninja?",,"Yes","No")=="No")
+ return
+
+ var/mission = copytext(sanitize(input(src, "Please specify which mission the space ninja shall undertake.", "Specify Mission", null) as text|null),1,MAX_MESSAGE_LEN)
+
+ var/client/C = input("Pick character to spawn as the Space Ninja", "Key", "") as null|anything in clients
+ if(!C)
+ return
+
+ new /datum/event/ninja(list("key"=C.key,"mission"=mission))
+
+ message_admins("\blue [key_name_admin(key)] has spawned [key_name_admin(C.key)] as a Space Ninja.")
+ log_admin("[key] used Spawn Space Ninja.")
+
+ return
+
+//=======//NINJA CREATION PROCS//=======//
+
+/proc/create_space_ninja(turf/spawnturf)
+ var/mob/living/carbon/human/new_ninja = new(spawnturf)
+ var/ninja_title = pick(ninja_titles)
+ var/ninja_name = pick(ninja_names)
+ new_ninja.gender = pick(MALE, FEMALE)
+
+ var/datum/preferences/A = new()//Randomize appearance for the ninja.
+ A.randomize_appearance_for(new_ninja)
+ new_ninja.real_name = "[ninja_title] [ninja_name]"
+ new_ninja.dna.ready_dna(new_ninja)
+ new_ninja.equip_space_ninja()
+ return new_ninja
+
+/mob/living/carbon/human/proc/equip_space_ninja(safety=0)//Safety in case you need to unequip stuff for existing characters.
+ if(safety)
+ del(w_uniform)
+ del(wear_suit)
+ del(wear_mask)
+ del(head)
+ del(shoes)
+ del(gloves)
+
+ var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src)
+ equip_to_slot_or_del(R, slot_ears)
+ if(gender==FEMALE)
+ equip_to_slot_or_del(new /obj/item/clothing/under/color/blackf(src), slot_w_uniform)
+ else
+ equip_to_slot_or_del(new /obj/item/clothing/under/color/black(src), slot_w_uniform)
+ equip_to_slot_or_del(new /obj/item/clothing/shoes/space_ninja(src), slot_shoes)
+ equip_to_slot_or_del(new /obj/item/clothing/suit/space/space_ninja(src), slot_wear_suit)
+ equip_to_slot_or_del(new /obj/item/clothing/gloves/space_ninja(src), slot_gloves)
+ equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/space_ninja(src), slot_head)
+ equip_to_slot_or_del(new /obj/item/clothing/mask/gas/voice/space_ninja(src), slot_wear_mask)
+ equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_belt)
+ equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_r_store)
+ equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_l_store)
+ equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen(src), slot_s_store)
+ equip_to_slot_or_del(new /obj/item/weapon/tank/jetpack/carbondioxide(src), slot_back)
+ return 1
+
+//=======//HELPER PROCS//=======//
+
+//Randomizes suit parameters.
+/obj/item/clothing/suit/space/space_ninja/proc/randomize_param()
+ s_cost = rand(1,20)
+ s_acost = rand(20,100)
+ k_cost = rand(100,500)
+ k_damage = rand(1,20)
+ s_delay = rand(10,100)
+ s_bombs = rand(5,20)
+ a_boost = rand(1,7)
+
+//This proc prevents the suit from being taken off.
+/obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/U, X = 0)
+ if(X)//If you want to check for icons.
+ icon_state = U.gender==FEMALE ? "s-ninjanf" : "s-ninjan"
+ U:gloves.icon_state = "s-ninjan"
+ U:gloves.item_state = "s-ninjan"
+ else
+ if(U.mind.special_role!="Space Ninja")
+ U << "\red fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR..."
+ U.gib()
+ return 0
+ if(!istype(U:head, /obj/item/clothing/head/helmet/space/space_ninja))
+ U << "\red ERROR: 100113 \black UNABLE TO LOCATE HEAD GEAR\nABORTING..."
+ return 0
+ if(!istype(U:shoes, /obj/item/clothing/shoes/space_ninja))
+ U << "\red ERROR: 122011 \black UNABLE TO LOCATE FOOT GEAR\nABORTING..."
+ return 0
+ if(!istype(U:gloves, /obj/item/clothing/gloves/space_ninja))
+ U << "\red ERROR: 110223 \black UNABLE TO LOCATE HAND GEAR\nABORTING..."
+ return 0
+
+ affecting = U
+ canremove = 0
+ slowdown = 0
+ n_hood = U:head
+ n_hood.canremove=0
+ n_shoes = U:shoes
+ n_shoes.canremove=0
+ n_shoes.slowdown--
+ n_gloves = U:gloves
+ n_gloves.canremove=0
+
+ return 1
+
+//This proc allows the suit to be taken off.
+/obj/item/clothing/suit/space/space_ninja/proc/unlock_suit()
+ affecting = null
+ canremove = 1
+ slowdown = 1
+ icon_state = "s-ninja"
+ if(n_hood)//Should be attached, might not be attached.
+ n_hood.canremove=1
+ if(n_shoes)
+ n_shoes.canremove=1
+ n_shoes.slowdown++
+ if(n_gloves)
+ n_gloves.icon_state = "s-ninja"
+ n_gloves.item_state = "s-ninja"
+ n_gloves.canremove=1
+ n_gloves.candrain=0
+ n_gloves.draining=0
+
+//Allows the mob to grab a stealth icon.
+/mob/proc/NinjaStealthActive(atom/A)//A is the atom which we are using as the overlay.
+ invisibility = INVISIBILITY_LEVEL_TWO//Set ninja invis to 2.
+ var/icon/opacity_icon = new(A.icon, A.icon_state)
+ var/icon/alpha_mask = getIconMask(src)
+ var/icon/alpha_mask_2 = new('icons/effects/effects.dmi', "at_shield1")
+ alpha_mask.AddAlphaMask(alpha_mask_2)
+ opacity_icon.AddAlphaMask(alpha_mask)
+ for(var/i=0,i<5,i++)//And now we add it as overlays. It's faster than creating an icon and then merging it.
+ var/image/I = image("icon" = opacity_icon, "icon_state" = A.icon_state, "layer" = layer+0.8)//So it's above other stuff but below weapons and the like.
+ switch(i)//Now to determine offset so the result is somewhat blurred.
+ if(1)
+ I.pixel_x -= 1
+ if(2)
+ I.pixel_x += 1
+ if(3)
+ I.pixel_y -= 1
+ if(4)
+ I.pixel_y += 1
+
+ overlays += I//And finally add the overlay.
+ overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9)
+
+//When ninja steal malfunctions.
+/mob/proc/NinjaStealthMalf()
+ invisibility = 0//Set ninja invis to 0.
+ overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9)
+ playsound(loc, 'sound/effects/stealthoff.ogg', 75, 1)
+
+//=======//GENERIC VERB MODIFIERS//=======//
+
+/obj/item/clothing/suit/space/space_ninja/proc/grant_equip_verbs()
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/init
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth
+ n_gloves.verbs += /obj/item/clothing/gloves/space_ninja/proc/toggled
+
+ s_initialized = 1
+
+/obj/item/clothing/suit/space/space_ninja/proc/remove_equip_verbs()
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/init
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth
+ if(n_gloves)
+ n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled
+
+ s_initialized = 0
+
+/obj/item/clothing/suit/space/space_ninja/proc/grant_ninja_verbs()
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjashift
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjablade
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet
+
+ s_initialized=1
+ slowdown=0
+
+/obj/item/clothing/suit/space/space_ninja/proc/remove_ninja_verbs()
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjashift
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjablade
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjanet
+
+//=======//KAMIKAZE VERBS//=======//
+
+/obj/item/clothing/suit/space/space_ninja/proc/grant_kamikaze(mob/living/carbon/U)
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjashift
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjanet
+
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjawalk
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjamirage
+
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth
+
+ kamikaze = 1
+
+ icon_state = U.gender==FEMALE ? "s-ninjakf" : "s-ninjak"
+ if(n_gloves)
+ n_gloves.icon_state = "s-ninjak"
+ n_gloves.item_state = "s-ninjak"
+ n_gloves.candrain = 0
+ n_gloves.draining = 0
+ n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled
+
+ cancel_stealth()
+
+ U << browse(null, "window=spideros")
+ U << "\red Do or Die, LET'S ROCK!!"
+
+/obj/item/clothing/suit/space/space_ninja/proc/remove_kamikaze(mob/living/carbon/U)
+ if(kamikaze)
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjashift
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet
+
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjawalk
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjamirage
+
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth
+ if(n_gloves)
+ n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled
+
+ U.incorporeal_move = 0
+ kamikaze = 0
+ k_unlock = 0
+ U << "\blue Disengaging mode...\n\blackCODE NAME: \red KAMIKAZE"
+
+//=======//AI VERBS//=======//
+
+/obj/item/clothing/suit/space/space_ninja/proc/grant_AI_verbs()
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_return_control
+
+ s_busy = 0
+ s_control = 0
+
+/obj/item/clothing/suit/space/space_ninja/proc/remove_AI_verbs()
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja
+ verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_return_control
+
+ s_control = 1
+
+//=======//OLD & UNUSED//=======//
+
+/*
+
+Deprecated. get_dir() does the same thing. Still a nice proc.
+Returns direction that the mob or whomever should be facing in relation to the target.
+This proc does not grant absolute direction and is mostly useful for 8dir sprite positioning.
+I personally used it with getline() to great effect.
+/proc/get_dir_to(turf/start,turf/end)//N
+ var/xdiff = start.x - end.x//The sign is important.
+ var/ydiff = start.y - end.y
+
+ var/direction_x = xdiff<1 ? 4:8//East - west
+ var/direction_y = ydiff<1 ? 1:2//North - south
+ var/direction_xy = xdiff==0 ? -4:0//If x is the same, subtract 4.
+ var/direction_yx = ydiff==0 ? -1:0//If y is the same, subtract 1.
+ var/direction_f = direction_x+direction_y+direction_xy+direction_yx//Finally direction tally.
+ direction_f = direction_f==0 ? 1:direction_f//If direction is 0(same spot), return north. Otherwise, direction.
+
+ return direction_f
+
+Alternative and inferior method of calculating spideros.
+var/temp = num2text(spideros)
+var/return_to = copytext(temp, 1, (length(temp)))//length has to be to the length of the thing because by default it's length+1
+spideros = text2num(return_to)//Maximum length here is 6. Use (return_to, X) to specify larger strings if needed.
+
+//Old way of draining from wire.
+/obj/item/clothing/gloves/space_ninja/proc/drain_wire()
+ set name = "Drain From Wire"
+ set desc = "Drain energy directly from an exposed wire."
+ set category = "Ninja Equip"
+
+ var/obj/structure/cable/attached
+ var/mob/living/carbon/human/U = loc
+ if(candrain&&!draining)
+ var/turf/T = U.loc
+ if(isturf(T) && T.is_plating())
+ attached = locate() in T
+ if(!attached)
+ U << "\red Warning: no exposed cable available."
+ else
+ U << "\blue Connecting to wire, stand still..."
+ if(do_after(U,50)&&!isnull(attached))
+ drain("WIRE",attached,U:wear_suit,src)
+ else
+ U << "\red Procedure interrupted. Protocol terminated."
+ return
+
+I've tried a lot of stuff but adding verbs to the AI while inside an object, inside another object, did not want to work properly.
+This was the best work-around I could come up with at the time. Uses objects to then display to panel, based on the object spell system.
+Can be added on to pretty easily.
+
+BYOND fixed the verb bugs so this is no longer necessary. I prefer verb panels.
+
+/obj/item/clothing/suit/space/space_ninja/proc/grant_AI_verbs()
+ var/obj/effect/proc_holder/ai_return_control/A_C = new(AI)
+ var/obj/effect/proc_holder/ai_hack_ninja/B_C = new(AI)
+ var/obj/effect/proc_holder/ai_instruction/C_C = new(AI)
+ new/obj/effect/proc_holder/ai_holo_clear(AI)
+ AI.proc_holder_list += A_C
+ AI.proc_holder_list += B_C
+ AI.proc_holder_list += C_C
+
+ s_control = 0
+
+/obj/item/clothing/suit/space/space_ninja/proc/remove_AI_verbs()
+ var/obj/effect/proc_holder/ai_return_control/A_C = locate() in AI
+ var/obj/effect/proc_holder/ai_hack_ninja/B_C = locate() in AI
+ var/obj/effect/proc_holder/ai_instruction/C_C = locate() in AI
+ var/obj/effect/proc_holder/ai_holo_clear/D_C = locate() in AI
+ del(A_C)
+ del(B_C)
+ del(C_C)
+ del(D_C)
+ AI.proc_holder_list = list()
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros
+ verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth
+
+ s_control = 1
+
+//Workaround
+/obj/effect/proc_holder/ai_holo_clear
+ name = "Clear Hologram"
+ desc = "Stops projecting the current holographic image."
+ panel = "AI Ninja Equip"
+ density = 0
+ opacity = 0
+
+
+/obj/effect/proc_holder/ai_holo_clear/Click()
+ var/obj/item/clothing/suit/space/space_ninja/S = loc.loc//This is so stupid but makes sure certain things work. AI.SUIT
+ del(S.hologram.i_attached)
+ del(S.hologram)
+ var/obj/effect/proc_holder/ai_holo_clear/D_C = locate() in S.AI
+ S.AI.proc_holder_list -= D_C
+ return
+
+/obj/effect/proc_holder/ai_instruction//Let's the AI know what they can do.
+ name = "Instructions"
+ desc = "Displays a list of helpful information."
+ panel = "AI Ninja Equip"
+ density = 0
+ opacity = 0
+
+/obj/effect/proc_holder/ai_instruction/Click()
+ loc << "The menu you are seeing will contain other commands if they become available.\nRight click a nearby turf to display an AI Hologram. It will only be visible to you and your host. You can move it freely using normal movement keys--it will disappear if placed too far away."
+
+/obj/effect/proc_holder/ai_hack_ninja//Generic proc holder to make sure the two verbs below work propely.
+ name = "Hack SpiderOS"
+ desc = "Hack directly into the Black Widow(tm) neuro-interface."
+ panel = "AI Ninja Equip"
+ density = 0
+ opacity = 0
+
+/obj/effect/proc_holder/ai_hack_ninja/Click()//When you click on it.
+ var/obj/item/clothing/suit/space/space_ninja/S = loc.loc
+ S.hack_spideros()
+ return
+
+/obj/effect/proc_holder/ai_return_control
+ name = "Relinquish Control"
+ desc = "Return control to the user."
+ panel = "AI Ninja Equip"
+ density = 0
+ opacity = 0
+
+/obj/effect/proc_holder/ai_return_control/Click()
+ var/mob/living/silicon/ai/A = loc
+ var/obj/item/clothing/suit/space/space_ninja/S = A.loc
+ A << browse(null, "window=hack spideros")//Close window
+ A << "You have seized your hacking attempt. [S.affecting] has regained control."
+ S.affecting << "UPDATE: [A.real_name] has ceased hacking attempt. All systems clear."
+ S.remove_AI_verbs()
+ return
+*/
+
+//=======//DEBUG//=======//
+/*
+/obj/item/clothing/suit/space/space_ninja/proc/display_verb_procs()
+//DEBUG
+//Does nothing at the moment. I am trying to see if it's possible to mess around with verbs as variables.
+ //for(var/P in verbs)
+// if(P.set.name)
+// usr << "[P.set.name], path: [P]"
+ return
+
+
+Most of these are at various points of incomplete.
+
+/mob/verb/grant_object_panel()
+ set name = "Grant AI Ninja Verbs Debug"
+ set category = "Ninja Debug"
+ var/obj/effect/proc_holder/ai_return_control/A_C = new(src)
+ var/obj/effect/proc_holder/ai_hack_ninja/B_C = new(src)
+ usr:proc_holder_list += A_C
+ usr:proc_holder_list += B_C
+
+mob/verb/remove_object_panel()
+ set name = "Remove AI Ninja Verbs Debug"
+ set category = "Ninja Debug"
+ var/obj/effect/proc_holder/ai_return_control/A = locate() in src
+ var/obj/effect/proc_holder/ai_hack_ninja/B = locate() in src
+ usr:proc_holder_list -= A
+ usr:proc_holder_list -= B
+ del(A)//First.
+ del(B)//Second, to keep the proc going.
+ return
+
+/client/verb/grant_verb_ninja_debug1(var/mob/M in view())
+ set name = "Grant AI Ninja Verbs Debug"
+ set category = "Ninja Debug"
+
+ M.verbs += /mob/living/silicon/ai/verb/ninja_return_control
+ M.verbs += /mob/living/silicon/ai/verb/ninja_spideros
+ return
+
+/client/verb/grant_verb_ninja_debug2(var/mob/living/carbon/human/M in view())
+ set name = "Grant Back Ninja Verbs"
+ set category = "Ninja Debug"
+
+ M.wear_suit.verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit
+ M.wear_suit.verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros
+ return
+
+/obj/proc/grant_verb_ninja_debug3(var/mob/living/silicon/ai/A as mob)
+ set name = "Grant AI Ninja Verbs"
+ set category = "null"
+ set hidden = 1
+ A.verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit
+ A.verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros
+ return
+
+/mob/verb/get_dir_to_target(var/mob/M in oview())
+ set name = "Get Direction to Target"
+ set category = "Ninja Debug"
+
+ world << "DIR: [get_dir_to(src.loc,M.loc)]"
+ return
+//
+/mob/verb/kill_self_debug()
+ set name = "DEBUG Kill Self"
+ set category = "Ninja Debug"
+
+ src:death()
+
+/client/verb/switch_client_debug()
+ set name = "DEBUG Switch Client"
+ set category = "Ninja Debug"
+
+ mob = mob:loc:loc
+
+/mob/verb/possess_mob(var/mob/M in oview())
+ set name = "DEBUG Possess Mob"
+ set category = "Ninja Debug"
+
+ client.mob = M
+
+/client/verb/switcharoo(var/mob/M in oview())
+ set name = "DEBUG Switch to AI"
+ set category = "Ninja Debug"
+
+ var/mob/last_mob = mob
+ mob = M
+ last_mob:wear_suit:AI:key = key
+//
+/client/verb/ninjaget(var/mob/M in oview())
+ set name = "DEBUG Ninja GET"
+ set category = "Ninja Debug"
+
+ mob = M
+ M.gib()
+ space_ninja()
+
+/mob/verb/set_debug_ninja_target()
+ set name = "Set Debug Target"
+ set category = "Ninja Debug"
+
+ ninja_debug_target = src//The target is you, brohime.
+ world << "Target: [src]"
+
+/mob/verb/hack_spideros_debug()
+ set name = "Debug Hack Spider OS"
+ set category = "Ninja Debug"
+
+ var/mob/living/silicon/ai/A = loc:AI
+ if(A)
+ if(!A.key)
+ A.client.mob = loc:affecting
+ else
+ loc:affecting:client:mob = A
+ return
+
+//Tests the net and what it does.
+/mob/verb/ninjanet_debug()
+ set name = "Energy Net Debug"
+ set category = "Ninja Debug"
+
+ var/obj/effect/energy_net/E = new /obj/effect/energy_net(loc)
+ E.layer = layer+1//To have it appear one layer above the mob.
+ stunned = 10//So they are stunned initially but conscious.
+ anchored = 1//Anchors them so they can't move.
+ E.affecting = src
+ spawn(0)//Parallel processing.
+ E.process(src)
+ return
+
+I made this as a test for a possible ninja ability (or perhaps more) for a certain mob to see hallucinations.
+The thing here is that these guys have to be coded to do stuff as they are simply images that you can't even click on.
+That is why you attached them to objects.
+/mob/verb/TestNinjaShadow()
+ set name = "Test Ninja Ability"
+ set category = "Ninja Debug"
+
+ if(client)
+ var/safety = 4
+ for(var/turf/T in oview(5))
+ if(prob(20))
+ var/current_clone = image('icons/mob/mob.dmi',T,"s-ninja")
+ safety--
+ spawn(0)
+ src << current_clone
+ spawn(300)
+ del(current_clone)
+ spawn while(!isnull(current_clone))
+ step_to(current_clone,src,1)
+ sleep(5)
+ if(safety<=0) break
+ return */
+
+//Alternate ninja speech replacement.
+/*This text is hilarious but also absolutely retarded.
+message = replacetext(message, "l", "r")
+message = replacetext(message, "rr", "ru")
+message = replacetext(message, "v", "b")
+message = replacetext(message, "f", "hu")
+message = replacetext(message, "'t", "")
+message = replacetext(message, "t ", "to ")
+message = replacetext(message, " I ", " ai ")
+message = replacetext(message, "th", "z")
+message = replacetext(message, "ish", "isu")
+message = replacetext(message, "is", "izu")
+message = replacetext(message, "ziz", "zis")
+message = replacetext(message, "se", "su")
+message = replacetext(message, "br", "bur")
+message = replacetext(message, "ry", "ri")
+message = replacetext(message, "you", "yuu")
+message = replacetext(message, "ck", "cku")
+message = replacetext(message, "eu", "uu")
+message = replacetext(message, "ow", "au")
+message = replacetext(message, "are", "aa")
+message = replacetext(message, "ay", "ayu")
+message = replacetext(message, "ea", "ii")
+message = replacetext(message, "ch", "chi")
+message = replacetext(message, "than", "sen")
+message = replacetext(message, ".", "")
+message = lowertext(message)
+*/
+
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++
+==================================SPACE NINJA ABILITIES====================================
+___________________________________________________________________________________________
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+//=======//SAFETY CHECK//=======//
+/*
+X is optional, tells the proc to check for specific stuff. C is also optional.
+All the procs here assume that the character is wearing the ninja suit if they are using the procs.
+They should, as I have made every effort for that to be the case.
+In the case that they are not, I imagine the game will run-time error like crazy.
+s_cooldown ticks off each second based on the suit recharge proc, in seconds. Default of 1 seconds. Some abilities have no cool down.
+*/
+/obj/item/clothing/suit/space/space_ninja/proc/ninjacost(C = 0,X = 0)
+ var/mob/living/carbon/human/U = affecting
+ if( (U.stat||U.incorporeal_move)&&X!=3 )//Will not return if user is using an adrenaline booster since you can use them when stat==1.
+ U << "\red You must be conscious and solid to do this."//It's not a problem of stat==2 since the ninja will explode anyway if they die.
+ return 1
+ else if(C&&cell.charge[s_bombs] smoke bombs remaining."
+ var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread()
+ smoke.set_up(10, 0, U.loc)
+ smoke.start()
+ playsound(U.loc, 'sound/effects/bamf.ogg', 50, 2)
+ s_bombs--
+ s_coold = 1
+ return
+
+//=======//9-8 TILE TELEPORT//=======//
+//Click to to teleport 9-10 tiles in direction facing.
+/obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt()
+ set name = "Phase Jaunt (10E)"
+ set desc = "Utilizes the internal VOID-shift device to rapidly transit in direction facing."
+ set category = "Ninja Ability"
+ set popup_menu = 0
+
+ var/C = 100
+ if(!ninjacost(C,1))
+ var/mob/living/carbon/human/U = affecting
+ var/turf/destination = get_teleport_loc(U.loc,U,9,1,3,1,0,1)
+ var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below.
+ if(destination&&istype(mobloc, /turf))//The turf check prevents unusual behavior. Like teleporting out of cryo pods, cloners, mechs, etc.
+ spawn(0)
+ playsound(U.loc, "sparks", 50, 1)
+ anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,U.dir)
+
+ handle_teleport_grab(destination, U)
+ U.loc = destination
+
+ spawn(0)
+ spark_system.start()
+ playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1)
+ playsound(U.loc, "sparks", 50, 1)
+ anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
+
+ spawn(0)
+ destination.kill_creatures(U)//Any living mobs in teleport area are gibbed. Check turf procs for how it does it.
+ s_coold = 1
+ cell.charge-=(C*10)
+ else
+ U << "\red The VOID-shift device is malfunctioning, teleportation failed."
+ return
+
+//=======//RIGHT CLICK TELEPORT//=======//
+//Right click to teleport somewhere, almost exactly like admin jump to turf.
+/obj/item/clothing/suit/space/space_ninja/proc/ninjashift(turf/T in oview())
+ set name = "Phase Shift (20E)"
+ set desc = "Utilizes the internal VOID-shift device to rapidly transit to a destination in view."
+ set category = null//So it does not show up on the panel but can still be right-clicked.
+ set src = usr.contents//Fixes verbs not attaching properly for objects. Praise the DM reference guide!
+
+ var/C = 200
+ if(!ninjacost(C,1))
+ var/mob/living/carbon/human/U = affecting
+ var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below.
+ if((!T.density)&&istype(mobloc, /turf))
+ spawn(0)
+ playsound(U.loc, 'sound/effects/sparks4.ogg', 50, 1)
+ anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,U.dir)
+
+ handle_teleport_grab(T, U)
+ U.loc = T
+
+ spawn(0)
+ spark_system.start()
+ playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1)
+ playsound(U.loc, 'sound/effects/sparks2.ogg', 50, 1)
+ anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
+
+ spawn(0)//Any living mobs in teleport area are gibbed.
+ T.kill_creatures(U)
+ s_coold = 1
+ cell.charge-=(C*10)
+ else
+ U << "\red You cannot teleport into solid walls or from solid matter"
+ return
+
+//=======//EM PULSE//=======//
+//Disables nearby tech equipment.
+/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse()
+ set name = "EM Burst (25E)"
+ set desc = "Disable any nearby technology with a electro-magnetic pulse."
+ set category = "Ninja Ability"
+ set popup_menu = 0
+
+ var/C = 250
+ if(!ninjacost(C,1))
+ var/mob/living/carbon/human/U = affecting
+ playsound(U.loc, 'sound/effects/EMPulse.ogg', 60, 2)
+ empulse(U, 4, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch.
+ s_coold = 2
+ cell.charge-=(C*10)
+ return
+
+//=======//ENERGY BLADE//=======//
+//Summons a blade of energy in active hand.
+/obj/item/clothing/suit/space/space_ninja/proc/ninjablade()
+ set name = "Energy Blade (5E)"
+ set desc = "Create a focused beam of energy in your active hand."
+ set category = "Ninja Ability"
+ set popup_menu = 0
+
+ var/C = 50
+ if(!ninjacost(C))
+ var/mob/living/carbon/human/U = affecting
+ if(!kamikaze)
+ if(!U.get_active_hand()&&!istype(U.get_inactive_hand(), /obj/item/weapon/melee/energy/blade))
+ var/obj/item/weapon/melee/energy/blade/W = new()
+ spark_system.start()
+ playsound(U.loc, "sparks", 50, 1)
+ U.put_in_hands(W)
+ cell.charge-=(C*10)
+ else
+ U << "\red You can only summon one blade. Try dropping an item first."
+ else//Else you can run around with TWO energy blades. I don't know why you'd want to but cool factor remains.
+ if(!U.get_active_hand())
+ var/obj/item/weapon/melee/energy/blade/W = new()
+ U.put_in_hands(W)
+ if(!U.get_inactive_hand())
+ var/obj/item/weapon/melee/energy/blade/W = new()
+ U.put_in_inactive_hand(W)
+ spark_system.start()
+ playsound(U.loc, "sparks", 50, 1)
+ s_coold = 1
+ return
+
+//=======//NINJA STARS//=======//
+/*Shoots ninja stars at random people.
+This could be a lot better but I'm too tired atm.*/
+/obj/item/clothing/suit/space/space_ninja/proc/ninjastar()
+ set name = "Energy Star (5E)"
+ set desc = "Launches an energy star at a random living target."
+ set category = "Ninja Ability"
+ set popup_menu = 0
+
+ var/C = 50
+ if(!ninjacost(C))
+ var/mob/living/carbon/human/U = affecting
+ var/targets[] = list()//So yo can shoot while yo throw dawg
+ for(var/mob/living/M in oview(loc))
+ if(M.stat) continue//Doesn't target corpses or paralyzed persons.
+ targets.Add(M)
+ if(targets.len)
+ var/mob/living/target=pick(targets)//The point here is to pick a random, living mob in oview to shoot stuff at.
+
+ var/turf/curloc = U.loc
+ var/atom/targloc = get_turf(target)
+ if (!targloc || !istype(targloc, /turf) || !curloc)
+ return
+ if (targloc == curloc)
+ return
+ var/obj/item/projectile/energy/dart/A = new /obj/item/projectile/energy/dart(U.loc)
+ A.current = curloc
+ A.yo = targloc.y - curloc.y
+ A.xo = targloc.x - curloc.x
+ cell.charge-=(C*10)
+ A.process()
+ else
+ U << "\red There are no targets in view."
+ return
+
+//=======//ENERGY NET//=======//
+/*Allows the ninja to capture people, I guess.
+Must right click on a mob to activate.*/
+/obj/item/clothing/suit/space/space_ninja/proc/ninjanet(mob/living/carbon/M in oview())//Only living carbon mobs.
+ set name = "Energy Net (20E)"
+ set desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds."
+ set category = null
+ set src = usr.contents
+
+ var/C = 200
+ if(!ninjacost(C,1)&&iscarbon(M))
+ var/mob/living/carbon/human/U = affecting
+ if(M.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame.
+ //if(M)//DEBUG
+ if(!locate(/obj/effect/energy_net) in M.loc)//Check if they are already being affected by an energy net.
+ for(var/turf/T in getline(U.loc, M.loc))
+ if(T.density)//Don't want them shooting nets through walls. It's kind of cheesy.
+ U << "You may not use an energy net through solid obstacles!"
+ return
+ spawn(0)
+ U.Beam(M,"n_beam",,15)
+ M.anchored = 1//Anchors them so they can't move.
+ U.say("Get over here!")
+ var/obj/effect/energy_net/E = new /obj/effect/energy_net(M.loc)
+ E.layer = M.layer+1//To have it appear one layer above the mob.
+ for(var/mob/O in viewers(U, 3))
+ O.show_message(text("\red [] caught [] with an energy net!", U, M), 1)
+ E.affecting = M
+ E.master = U
+ spawn(0)//Parallel processing.
+ E.process(M)
+ cell.charge-=(C*10)
+ else
+ U << "They are already trapped inside an energy net."
+ else
+ U << "They will bring no honor to your Clan!"
+ return
+
+//=======//ADRENALINE BOOST//=======//
+/*Wakes the user so they are able to do their thing. Also injects a decent dose of radium.
+Movement impairing would indicate drugs and the like.*/
+/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost()
+ set name = "Adrenaline Boost"
+ set desc = "Inject a secret chemical that will counteract all movement-impairing effect."
+ set category = "Ninja Ability"
+ set popup_menu = 0
+
+ if(!ninjacost(,3))//Have to make sure stat is not counted for this ability.
+ var/mob/living/carbon/human/U = affecting
+ //Wouldn't need to track adrenaline boosters if there was a miracle injection to get rid of paralysis and the like instantly.
+ //For now, adrenaline boosters ARE the miracle injection. Well, radium, really.
+ U.SetParalysis(0)
+ U.SetStunned(0)
+ U.SetWeakened(0)
+ /*
+ Due to lag, it was possible to adrenaline boost but remain helpless while life.dm resets player stat.
+ This lead to me and others spamming adrenaline boosters because they failed to kick in on time.
+ It's technically possible to come back from crit with this but it is very temporary.
+ Life.dm will kick the player back into unconsciosness the next process loop.
+ */
+ U.stat = 0//At least now you should be able to teleport away or shoot ninja stars.
+ spawn(30)//Slight delay so the enemy does not immedietly know the ability was used. Due to lag, this often came before waking up.
+ U.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!"))
+ spawn(70)
+ reagents.reaction(U, 2)
+ reagents.trans_id_to(U, "radium", a_transfer)
+ U << "\red You are beginning to feel the after-effect of the injection."
+ a_boost--
+ s_coold = 3
+ return
+
+/*
+===================================================================================
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+===================================================================================
+Or otherwise known as anime mode. Which also happens to be ridiculously powerful.
+*/
+
+//=======//NINJA MOVEMENT//=======//
+//Also makes you move like you're on crack.
+/obj/item/clothing/suit/space/space_ninja/proc/ninjawalk()
+ set name = "Shadow Walk"
+ set desc = "Combines the VOID-shift and CLOAK-tech devices to freely move between solid matter. Toggle on or off."
+ set category = "Ninja Ability"
+ set popup_menu = 0
+
+ var/mob/living/carbon/human/U = affecting
+ if(!U.incorporeal_move)
+ U.incorporeal_move = 2
+ U << "\blue You will now phase through solid matter."
+ else
+ U.incorporeal_move = 0
+ U << "\blue You will no-longer phase through solid matter."
+ return
+
+//=======//5 TILE TELEPORT/GIB//=======//
+//Allows to gib up to five squares in a straight line. Seriously.
+/obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer()
+ set name = "Phase Slayer"
+ set desc = "Utilizes the internal VOID-shift device to mutilate creatures in a straight line."
+ set category = "Ninja Ability"
+ set popup_menu = 0
+
+ if(!ninjacost())
+ var/mob/living/carbon/human/U = affecting
+ var/turf/destination = get_teleport_loc(U.loc,U,5)
+ var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below.
+ if(destination&&istype(mobloc, /turf))
+ U.say("Ai Satsugai!")
+ spawn(0)
+ playsound(U.loc, "sparks", 50, 1)
+ anim(mobloc,U,'icons/mob/mob.dmi',,"phaseout",,U.dir)
+
+ spawn(0)
+ for(var/turf/T in getline(mobloc, destination))
+ spawn(0)
+ T.kill_creatures(U)
+ if(T==mobloc||T==destination) continue
+ spawn(0)
+ anim(T,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
+
+ handle_teleport_grab(destination, U)
+ U.loc = destination
+
+ spawn(0)
+ spark_system.start()
+ playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1)
+ playsound(U.loc, "sparks", 50, 1)
+ anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
+ s_coold = 1
+ else
+ U << "\red The VOID-shift device is malfunctioning, teleportation failed."
+ return
+
+//=======//TELEPORT BEHIND MOB//=======//
+/*Appear behind a randomly chosen mob while a few decoy teleports appear.
+This is so anime it hurts. But that's the point.*/
+/obj/item/clothing/suit/space/space_ninja/proc/ninjamirage()
+ set name = "Spider Mirage"
+ set desc = "Utilizes the internal VOID-shift device to create decoys and teleport behind a random target."
+ set category = "Ninja Ability"
+ set popup_menu = 0
+
+ if(!ninjacost())//Simply checks for stat.
+ var/mob/living/carbon/human/U = affecting
+ var/targets[]
+ targets = new()
+ for(var/mob/living/M in oview(6))
+ if(M.stat) continue//Doesn't target corpses or paralyzed people.
+ targets.Add(M)
+ if(targets.len)
+ var/mob/living/target=pick(targets)
+ var/locx
+ var/locy
+ var/turf/mobloc = get_turf(target.loc)
+ var/safety = 0
+ switch(target.dir)
+ if(NORTH)
+ locx = mobloc.x
+ locy = (mobloc.y-1)
+ if(locy<1)
+ safety = 1
+ if(SOUTH)
+ locx = mobloc.x
+ locy = (mobloc.y+1)
+ if(locy>world.maxy)
+ safety = 1
+ if(EAST)
+ locy = mobloc.y
+ locx = (mobloc.x-1)
+ if(locx<1)
+ safety = 1
+ if(WEST)
+ locy = mobloc.y
+ locx = (mobloc.x+1)
+ if(locx>world.maxx)
+ safety = 1
+ else safety=1
+ if(!safety&&istype(mobloc, /turf))
+ U.say("Kumo no Shinkiro!")
+ var/turf/picked = locate(locx,locy,mobloc.z)
+ spawn(0)
+ playsound(U.loc, "sparks", 50, 1)
+ anim(mobloc,U,'icons/mob/mob.dmi',,"phaseout",,U.dir)
+
+ spawn(0)
+ var/limit = 4
+ for(var/turf/T in oview(5))
+ if(prob(20))
+ spawn(0)
+ anim(T,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
+ limit--
+ if(limit<=0) break
+
+ handle_teleport_grab(picked, U)
+ U.loc = picked
+ U.dir = target.dir
+
+ spawn(0)
+ spark_system.start()
+ playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1)
+ playsound(U.loc, "sparks", 50, 1)
+ anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
+ s_coold = 1
+ else
+ U << "\red The VOID-shift device is malfunctioning, teleportation failed."
+ else
+ U << "\red There are no targets in view."
+ return
+
+
+//For the love of god,space out your code! This is a nightmare to read.
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1458,3 +2787,10 @@ It is possible to destroy the net by the occupant or someone else.
healthcheck()
..()
return
+
+proc/create_ninja_mind(key)
+ var/datum/mind/Mind = new /datum/mind(key)
+ Mind.assigned_role = "MODE"
+ Mind.special_role = "Space Ninja"
+ ticker.mode.traitors |= Mind //Adds them to current traitor list. Which is really the extra antagonist list.
+ return Mind
\ No newline at end of file
diff --git a/code/modules/events/prison_break.dm b/code/modules/events/prison_break.dm
index 82f3194a0cb..738ec880ba5 100644
--- a/code/modules/events/prison_break.dm
+++ b/code/modules/events/prison_break.dm
@@ -1,6 +1,10 @@
+/datum/event_control/prison_break
+ name = "Prison Break"
+ typepath = /datum/event/prison_break
+ max_occurrences = 2
+
/datum/event/prison_break
announceWhen = 50
- oneShot = 1
var/releaseWhen = 25
var/list/area/prisonAreas = list()
@@ -34,25 +38,27 @@
if(prisonAreas && prisonAreas.len > 0)
command_alert("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert")
else
- world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area."
+ error("Could not initate grey-tide. Unable find prison or brig area.")
/datum/event/prison_break/tick()
if(activeFor == releaseWhen)
if(prisonAreas && prisonAreas.len > 0)
for(var/area/A in prisonAreas)
- for(var/obj/machinery/power/apc/temp_apc in A)
- temp_apc.overload_lighting()
-
- for(var/obj/structure/closet/secure_closet/brig/temp_closet in A)
- temp_closet.locked = 0
- temp_closet.icon_state = temp_closet.icon_closed
-
- for(var/obj/machinery/door/airlock/security/temp_airlock in A)
- temp_airlock.prison_open()
-
- for(var/obj/machinery/door/airlock/glass_security/temp_glassairlock in A)
- temp_glassairlock.prison_open()
-
- for(var/obj/machinery/door_timer/temp_timer in A)
- temp_timer.releasetime = 1
\ No newline at end of file
+ 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/brig))
+ var/obj/structure/closet/secure_closet/brig/temp = O
+ temp.locked = 0
+ temp.icon_state = temp.icon_closed
+ else if(istype(O,/obj/machinery/door/airlock/security))
+ var/obj/machinery/door/airlock/security/temp = O
+ temp.prison_open()
+ else if(istype(O,/obj/machinery/door/airlock/glass_security))
+ var/obj/machinery/door/airlock/glass_security/temp = O
+ temp.prison_open()
+ else if(istype(O,/obj/machinery/door_timer))
+ var/obj/machinery/door_timer/temp = O
+ temp.releasetime = 1
\ No newline at end of file
diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm
index e97561c3c99..919dc695c32 100644
--- a/code/modules/events/radiation_storm.dm
+++ b/code/modules/events/radiation_storm.dm
@@ -1,6 +1,10 @@
+/datum/event_control/radiation_storm
+ name = "Radiation Storm"
+ typepath = /datum/event/radiation_storm
+ max_occurrences = 1
+
/datum/event/radiation_storm
announceWhen = 5
- oneShot = 1
/datum/event/radiation_storm/announce()
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index 43c4752abb1..84a54274c32 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -1,6 +1,265 @@
-/datum/event/spacevine
- oneShot = 1
-
+/datum/event_control/spacevine
+ name = "Spacevine"
+ typepath = /datum/event/spacevine
+ weight = 15
+ max_occurrences = 3
/datum/event/spacevine/start()
- spacevine_infestation()
\ No newline at end of file
+ var/list/turfs = list() //list of all the empty floor turfs in the hallway areas
+
+ for(var/area/hallway/A in world)
+ for(var/turf/simulated/floor/F in A)
+ if(!F.contents.len)
+ turfs += F
+
+ if(turfs.len) //Pick a turf to spawn at if we can
+ var/turf/simulated/floor/T = pick(turfs)
+ spawn(0) new/obj/effect/spacevine_controller(T) //spawn a controller at turf
+
+
+
+
+// SPACE VINES (Note that this code is very similar to Biomass code)
+/obj/effect/spacevine
+ name = "space vines"
+ desc = "An extremely expansionistic species of vine."
+ icon = 'icons/effects/spacevines.dmi'
+ icon_state = "Light1"
+ anchored = 1
+ density = 0
+ layer = 5
+ pass_flags = PASSTABLE | PASSGRILLE
+ var/energy = 0
+ var/obj/effect/spacevine_controller/master = null
+ var/mob/living/buckled_mob
+
+ New()
+ return
+
+ Del()
+ if(master)
+ master.vines -= src
+ master.growth_queue -= src
+ ..()
+
+
+/obj/effect/spacevine/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if (!W || !user || !W.type) return
+ switch(W.type)
+ if(/obj/item/weapon/circular_saw) del src
+ if(/obj/item/weapon/kitchen/utensil/knife) del src
+ if(/obj/item/weapon/scalpel) del src
+ if(/obj/item/weapon/twohanded/fireaxe) del src
+ if(/obj/item/weapon/hatchet) del src
+ if(/obj/item/weapon/melee/energy) del src
+
+ //less effective weapons
+ if(/obj/item/weapon/wirecutters)
+ if(prob(25)) del src
+ if(/obj/item/weapon/shard)
+ if(prob(25)) del src
+
+ else //weapons with subtypes
+ if(istype(W, /obj/item/weapon/melee/energy/sword)) del src
+ else if(istype(W, /obj/item/weapon/weldingtool))
+ var/obj/item/weapon/weldingtool/WT = W
+ if(WT.remove_fuel(0, user)) del src
+ else
+ manual_unbuckle(user)
+ return
+ //Plant-b-gone damage is handled in its entry in chemistry-reagents.dm
+ ..()
+
+
+/obj/effect/spacevine/attack_hand(mob/user as mob)
+ manual_unbuckle(user)
+
+
+/obj/effect/spacevine/attack_paw(mob/user as mob)
+ manual_unbuckle(user)
+
+/obj/effect/spacevine/proc/unbuckle()
+ if(buckled_mob)
+ if(buckled_mob.buckled == src) //this is probably unneccesary, but it doesn't hurt
+ buckled_mob.buckled = null
+ buckled_mob.anchored = initial(buckled_mob.anchored)
+ buckled_mob.update_canmove()
+ buckled_mob = null
+ return
+
+/obj/effect/spacevine/proc/manual_unbuckle(mob/user as mob)
+ if(buckled_mob)
+ if(prob(50))
+ if(buckled_mob.buckled == src)
+ if(buckled_mob != user)
+ buckled_mob.visible_message(\
+ "[user.name] frees [buckled_mob.name] from the vines.",\
+ "[user.name] frees you from the vines.",\
+ "You hear shredding and ripping.")
+ else
+ buckled_mob.visible_message(\
+ "[buckled_mob.name] struggles free of the vines.",\
+ "You untangle the vines from around yourself.",\
+ "You hear shredding and ripping.")
+ unbuckle()
+ else
+ var/text = pick("rips","tears","pulls")
+ user.visible_message(\
+ "[user.name] [text] at the vines.",\
+ "You [text] at the vines.",\
+ "You hear shredding and ripping.")
+ return
+
+/obj/effect/spacevine_controller
+ var/list/obj/effect/spacevine/vines = list()
+ var/list/growth_queue = list()
+ var/reached_collapse_size
+ var/reached_slowdown_size
+ //What this does is that instead of having the grow minimum of 1, required to start growing, the minimum will be 0,
+ //meaning if you get the spacevines' size to something less than 20 plots, it won't grow anymore.
+
+ New()
+ if(!istype(src.loc,/turf/simulated/floor))
+ del(src)
+
+ spawn_spacevine_piece(src.loc)
+ processing_objects.Add(src)
+
+ Del()
+ processing_objects.Remove(src)
+ ..()
+
+ proc/spawn_spacevine_piece(var/turf/location)
+ var/obj/effect/spacevine/SV = new(location)
+ growth_queue += SV
+ vines += SV
+ SV.master = src
+
+ process()
+ if(!vines)
+ del(src) //space vines exterminated. Remove the controller
+ return
+ if(!growth_queue)
+ del(src) //Sanity check
+ return
+ if(vines.len >= 250 && !reached_collapse_size)
+ reached_collapse_size = 1
+ if(vines.len >= 30 && !reached_slowdown_size )
+ reached_slowdown_size = 1
+
+ var/length = 0
+ if(reached_collapse_size)
+ length = 0
+ else if(reached_slowdown_size)
+ if(prob(25))
+ length = 1
+ else
+ length = 0
+ else
+ length = 1
+ length = min( 30 , max( length , vines.len / 5 ) )
+ var/i = 0
+ var/list/obj/effect/spacevine/queue_end = list()
+
+ for( var/obj/effect/spacevine/SV in growth_queue )
+ i++
+ queue_end += SV
+ growth_queue -= SV
+ if(SV.energy < 2) //If tile isn't fully grown
+ if(prob(20))
+ SV.grow()
+ else //If tile is fully grown
+ SV.buckle_mob()
+
+ //if(prob(25))
+ SV.spread()
+ if(i >= length)
+ break
+
+ growth_queue = growth_queue + queue_end
+ //sleep(5)
+ //src.process()
+
+/obj/effect/spacevine/proc/grow()
+ if(!energy)
+ src.icon_state = pick("Med1", "Med2", "Med3")
+ energy = 1
+ SetOpacity(1)
+ layer = 5
+ else
+ src.icon_state = pick("Hvy1", "Hvy2", "Hvy3")
+ energy = 2
+
+/obj/effect/spacevine/proc/buckle_mob()
+ if(!buckled_mob && prob(25))
+ for(var/mob/living/carbon/V in src.loc)
+ if((V.stat != DEAD) && (V.buckled != src)) //if mob not dead or captured
+ V.buckled = src
+ V.loc = src.loc
+ V.update_canmove()
+ src.buckled_mob = V
+ V << "The vines [pick("wind", "tangle", "tighten")] around you!"
+ break //only capture one mob at a time.
+
+/obj/effect/spacevine/proc/spread()
+ var/direction = pick(cardinal)
+ var/step = get_step(src,direction)
+ if(istype(step,/turf/simulated/floor))
+ var/turf/simulated/floor/F = step
+ if(!locate(/obj/effect/spacevine,F))
+ if(F.Enter(src))
+ if(master)
+ master.spawn_spacevine_piece( F )
+
+/*
+/obj/effect/spacevine/proc/Life()
+ if (!src) return
+ var/Vspread
+ if (prob(50)) Vspread = locate(src.x + rand(-1,1),src.y,src.z)
+ else Vspread = locate(src.x,src.y + rand(-1, 1),src.z)
+ var/dogrowth = 1
+ if (!istype(Vspread, /turf/simulated/floor)) dogrowth = 0
+ for(var/obj/O in Vspread)
+ if (istype(O, /obj/structure/window) || istype(O, /obj/effect/forcefield) || istype(O, /obj/effect/blob) || istype(O, /obj/effect/alien/weeds) || istype(O, /obj/effect/spacevine)) dogrowth = 0
+ if (istype(O, /obj/machinery/door/))
+ if(O:p_open == 0 && prob(50)) O:open()
+ else dogrowth = 0
+ if (dogrowth == 1)
+ var/obj/effect/spacevine/B = new /obj/effect/spacevine(Vspread)
+ B.icon_state = pick("vine-light1", "vine-light2", "vine-light3")
+ spawn(20)
+ if(B)
+ B.Life()
+ src.growth += 1
+ if (src.growth == 10)
+ src.name = "Thick Space Kudzu"
+ src.icon_state = pick("vine-med1", "vine-med2", "vine-med3")
+ src.opacity = 1
+ src.waittime = 80
+ if (src.growth == 20)
+ src.name = "Dense Space Kudzu"
+ src.icon_state = pick("vine-hvy1", "vine-hvy2", "vine-hvy3")
+ src.density = 1
+ spawn(src.waittime)
+ if (src.growth < 20) src.Life()
+
+*/
+
+/obj/effect/spacevine/ex_act(severity)
+ switch(severity)
+ if(1.0)
+ del(src)
+ return
+ if(2.0)
+ if (prob(90))
+ del(src)
+ return
+ if(3.0)
+ if (prob(50))
+ del(src)
+ return
+ return
+
+/obj/effect/spacevine/temperature_expose(null, temp, volume) //hotspots kill vines
+ del src
+
diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm
index d8d57e5c7bb..3d0730992be 100644
--- a/code/modules/events/spider_infestation.dm
+++ b/code/modules/events/spider_infestation.dm
@@ -1,6 +1,11 @@
+/datum/event_control/spider_infestation
+ name = "Spider Infestation"
+ typepath = /datum/event/spider_infestation
+ weight = 5
+ max_occurrences = 1
+
/datum/event/spider_infestation
announceWhen = 400
- oneShot = 1
var/spawncount = 1
diff --git a/code/modules/events/spontaneous_appendicitis.dm b/code/modules/events/spontaneous_appendicitis.dm
index feb6f797de5..91195872577 100644
--- a/code/modules/events/spontaneous_appendicitis.dm
+++ b/code/modules/events/spontaneous_appendicitis.dm
@@ -1,3 +1,10 @@
+/datum/event_control/spontaneous_appendicitis
+ name = "Spontaneous Appendicitis"
+ typepath = /datum/event/spontaneous_appendicitis
+ weight = 20
+ max_occurrences = 4
+ earliest_start = 6000
+
/datum/event/spontaneous_appendicitis/start()
for(var/mob/living/carbon/human/H in shuffle(living_mob_list))
var/foundAlready = 0 //don't infect someone that already has the virus
diff --git a/code/modules/events/weightless.dm b/code/modules/events/weightless.dm
new file mode 100644
index 00000000000..efe137f60df
--- /dev/null
+++ b/code/modules/events/weightless.dm
@@ -0,0 +1,33 @@
+/datum/event_control/weightless
+ name = "Gravity Systems Failure"
+ typepath = /datum/event/weightless
+ weight = 15
+
+/datum/event/weightless
+ startWhen = 5
+ endWhen = 65
+
+/datum/event/weightless/setup()
+ startWhen = rand(0,10)
+ endWhen = rand(40,80)
+ var/datum/event_control/E = locate(/datum/event_control/gravitational_anomaly) in events.control
+ if(E)
+ E.weight *= 2
+
+/datum/event/weightless/announce()
+ command_alert("Warning: Failsafes for the station's artificial gravity arrays have been triggered. Please be aware that if this problem recurs it may result in formation of gravitational anomalies. Nanotrasen wishes to remind you that the unauthorised formation of anomalies within Nanotrasen facilities is strictly prohibited by health and safety regulation [rand(99,9999)][pick("a","b","c")]:subclause[rand(1,20)][pick("a","b","c")].")
+
+/datum/event/weightless/start()
+ gravity_is_on = 0
+ for(var/area/A in world)
+ A.gravitychange(gravity_is_on,A)
+
+/datum/event/weightless/end()
+ gravity_is_on = 1
+ for(var/area/A in world)
+ A.gravitychange(gravity_is_on,A)
+
+ if(announceWhen >= 0)
+ command_alert("Artificial gravity arrays are now functioning within normal parameters. Please report any irregularities to your respective head of staff.")
+
+
diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm
new file mode 100644
index 00000000000..bab3830b71e
--- /dev/null
+++ b/code/modules/events/wormholes.dm
@@ -0,0 +1,66 @@
+/datum/event_control/wormholes
+ name = "Wormholes"
+ typepath = /datum/event/wormholes
+ max_occurrences = 3
+ weight = 2
+
+/datum/event/wormholes
+ announceWhen = 10
+ endWhen = 60
+
+ var/list/wormholes = list()
+ var/shift_frequency = 3
+ var/number_of_wormholes = 1000
+
+/datum/event/wormholes/setup()
+ announceWhen = rand(0,20)
+ endWhen = rand(40,80)
+
+/datum/event/wormholes/start()
+ for(var/i=1, i<=number_of_wormholes, i++)
+ var/x = rand(40,world.maxx-40)
+ var/y = rand(40,world.maxy-40)
+ var/turf/T = locate(x, y, 1)
+ wormholes += new /obj/effect/portal/wormhole(T, null, null, -1)
+
+/datum/event/wormholes/announce()
+ command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert")
+ for(var/mob/M in player_list)
+ if(!istype(M,/mob/new_player))
+ M << sound('sound/AI/spanomalies.ogg')
+
+/datum/event/wormholes/tick()
+ if(activeFor % shift_frequency == 0)
+ for(var/obj/effect/portal/wormhole/O in wormholes)
+ var/x = rand(20,world.maxx-20)
+ var/y = rand(20,world.maxy-20)
+ var/turf/T = locate(x, y, 1)
+ if(T) O.loc = T
+
+/datum/event/wormholes/end()
+ portals.Remove(wormholes)
+ for(var/obj/effect/portal/wormhole/O in wormholes)
+ O.loc = null
+ wormholes.Cut()
+
+/obj/effect/portal/wormhole
+ name = "wormhole"
+ desc = "It looks highly unstable; It could close at any moment."
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "anom"
+ failchance = 0
+
+/obj/effect/portal/wormhole/teleport(atom/movable/M as mob|obj)
+ if(istype(M, /obj/effect)) //sparks don't teleport
+ return
+ if(M.anchored&&istype(M, /obj/mecha))
+ return
+
+ if(istype(M, /atom/movable))
+ var/turf/target
+ if(portals.len)
+ var/obj/effect/portal/P = pick(portals)
+ if(P && isturf(P.loc))
+ target = P.loc
+ if(!target) return
+ do_teleport(M, target, 1, 1, 0, 0) ///You will appear adjacent to the beacon
\ No newline at end of file
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 37e3da1d45d..09b917bd21f 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -133,9 +133,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set category = "Ghost"
set name = "Re-enter Corpse"
if(!client) return
- if(!(mind && mind.current && can_reenter_corpse))
+ if(!(mind && mind.current))
src << "You have no body."
return
+ if(!can_reenter_corpse)
+ src << "You cannot re-enter your body."
+ return
if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients
usr << "Another consciousness is in your body...It is resisting you."
return
diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
index 35b9e9fbfd0..86256cf124c 100644
--- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
+++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
@@ -72,8 +72,8 @@
AttemptGrow()
/obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1)
- var/list/candidates = get_alien_candidates()
- var/picked = null
+ var/list/candidates = get_candidates(BE_ALIEN)
+ var/client/C = null
// To stop clientless larva, we will check that our host has a client
// if we find no ghosts to become the alien. If the host has a client
@@ -81,9 +81,9 @@
// to 2, so we don't do a process heavy check everytime.
if(candidates.len)
- picked = pick(candidates)
+ C = pick(candidates)
else if(affected_mob.client)
- picked = affected_mob.key
+ C = affected_mob.client
else
stage = 4 // Let's try again later.
return
@@ -94,7 +94,7 @@
affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_stand")
spawn(6)
var/mob/living/carbon/alien/larva/new_xeno = new(affected_mob.loc)
- new_xeno.key = picked
+ new_xeno.key = C.key
new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100) //To get the player's attention
if(gib_on_success)
affected_mob.gib()
diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm
index 053f01ae3a1..6cc125c9c8a 100644
--- a/code/modules/mob/living/carbon/alien/special/facehugger.dm
+++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm
@@ -47,12 +47,6 @@ var/const/MAX_ACTIVE_TIME = 400
user.drop_from_inventory(src)
Attach(M)
-/obj/item/clothing/mask/facehugger/New()
- if(aliens_allowed)
- ..()
- else
- del(src)
-
/obj/item/clothing/mask/facehugger/examine()
..()
switch(stat)
diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm
index 5d4f1f62b61..d09a0ba7617 100644
--- a/code/modules/mob/living/login.dm
+++ b/code/modules/mob/living/login.dm
@@ -3,6 +3,7 @@
//Mind updates
mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist)
mind.active = 1 //indicates that the mind is currently synced with a client
+ mind.show_memory(src, 0)
//Round specific stuff like hud updates
if(ticker && ticker.mode)
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index 1e4cda20560..b258f5ebf70 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -79,7 +79,7 @@
/obj/item/weapon/paper/attack_self(mob/living/user as mob)
examine()
- if(rigged && (Holiday == "April Fool's Day"))
+ if(rigged && (events.holiday == "April Fool's Day"))
if(spam_flag == 0)
spam_flag = 1
playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm
index 6fd9351b2fe..5012761a3a1 100644
--- a/code/modules/paperwork/paperbin.dm
+++ b/code/modules/paperwork/paperbin.dm
@@ -37,7 +37,7 @@
papers.Remove(P)
else
P = new /obj/item/weapon/paper
- if(Holiday == "April Fool's Day")
+ if(events.holiday == "April Fool's Day")
if(prob(30))
P.info = "HONK HONK HONK HONK HONK HONK HONK
HOOOOOOOOOOOOOOOOOOOOOONK
APRIL FOOLS"
P.rigged = 1
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index a16112388c6..e35860af910 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -68,7 +68,6 @@ obj/item/weapon/gun/energy/staff
name = "staff of animation"
desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines."
projectile_type = "/obj/item/projectile/animate"
- charge_cost = 100
icon_state = "staffofanimation"
item_state = "staffofanimation"
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index 91ac648af07..59f3334bc7b 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -465,9 +465,8 @@
/obj/machinery/computer/pandemic/Topic(href, href_list)
- if(stat & (NOPOWER|BROKEN)) return
- if(usr.stat || usr.restrained()) return
- if(!in_range(src, usr)) return
+ if(..())
+ return
usr.set_machine(src)
if(!beaker) return
@@ -547,9 +546,8 @@
return
else if(href_list["name_disease"])
var/new_name = stripped_input(usr, "Name the Disease", "New Name", "", MAX_NAME_LEN)
- if(stat & (NOPOWER|BROKEN)) return
- if(usr.stat || usr.restrained()) return
- if(!in_range(src, usr)) return
+ if(..())
+ return
var/id = href_list["name_disease"]
if(archive_diseases[id])
var/datum/disease/advance/A = archive_diseases[id]
@@ -574,7 +572,7 @@
return src.attack_hand(user)
/obj/machinery/computer/pandemic/attack_hand(mob/user as mob)
- if(stat & (NOPOWER|BROKEN))
+ if(..())
return
user.set_machine(src)
var/dat = ""
diff --git a/code/world.dm b/code/world.dm
index 4fe087a02b5..e571fd58f0b 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -34,16 +34,12 @@
jobban_loadbanfile()
jobban_updatelegacybans()
LoadBans()
+ investigate_reset()
if(config && config.server_name != null && config.server_suffix && world.port > 0)
// dumb and hardcoded but I don't care~
config.server_name += " #[(world.port % 1000) / 100]"
- investigate_reset()
- Get_Holiday() //~Carn, needs to be here when the station is named so :P
-
- src.update_status()
-
makepowernets()
sun = new /datum/sun()
@@ -73,13 +69,13 @@
slmaster.layer = FLY_LAYER
slmaster.mouse_opacity = 0
- src.update_status()
-
master_controller = new /datum/controller/game_controller()
spawn(-1)
master_controller.setup()
lighting_controller.Initialize()
+ src.update_status()
+
process_teleport_locs() //Sets up the wizard teleport locations
process_ghost_teleport_locs() //Sets up ghost teleport locations.
sleep_offline = 1
diff --git a/tgstation.dme b/tgstation.dme
index a12784c95ee..7868034c7f2 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -6,192 +6,6 @@
// BEGIN_FILE_DIR
#define FILE_DIR .
-#define FILE_DIR "code"
-#define FILE_DIR "code/__HELPERS"
-#define FILE_DIR "code/ATMOSPHERICS"
-#define FILE_DIR "code/ATMOSPHERICS/components"
-#define FILE_DIR "code/ATMOSPHERICS/components/binary_devices"
-#define FILE_DIR "code/ATMOSPHERICS/components/trinary_devices"
-#define FILE_DIR "code/ATMOSPHERICS/components/unary"
-#define FILE_DIR "code/controllers"
-#define FILE_DIR "code/datums"
-#define FILE_DIR "code/datums/diseases"
-#define FILE_DIR "code/datums/diseases/advance"
-#define FILE_DIR "code/datums/diseases/advance/symptoms"
-#define FILE_DIR "code/datums/helper_datums"
-#define FILE_DIR "code/datums/spells"
-#define FILE_DIR "code/datums/wires"
-#define FILE_DIR "code/defines"
-#define FILE_DIR "code/defines/obj"
-#define FILE_DIR "code/defines/procs"
-#define FILE_DIR "code/FEA"
-#define FILE_DIR "code/game"
-#define FILE_DIR "code/game/area"
-#define FILE_DIR "code/game/gamemodes"
-#define FILE_DIR "code/game/gamemodes/blob"
-#define FILE_DIR "code/game/gamemodes/blob/blobs"
-#define FILE_DIR "code/game/gamemodes/changeling"
-#define FILE_DIR "code/game/gamemodes/cult"
-#define FILE_DIR "code/game/gamemodes/events"
-#define FILE_DIR "code/game/gamemodes/events/holidays"
-#define FILE_DIR "code/game/gamemodes/extended"
-#define FILE_DIR "code/game/gamemodes/malfunction"
-#define FILE_DIR "code/game/gamemodes/meteor"
-#define FILE_DIR "code/game/gamemodes/nuclear"
-#define FILE_DIR "code/game/gamemodes/revolution"
-#define FILE_DIR "code/game/gamemodes/sandbox"
-#define FILE_DIR "code/game/gamemodes/traitor"
-#define FILE_DIR "code/game/gamemodes/wizard"
-#define FILE_DIR "code/game/jobs"
-#define FILE_DIR "code/game/jobs/job"
-#define FILE_DIR "code/game/machinery"
-#define FILE_DIR "code/game/machinery/atmoalter"
-#define FILE_DIR "code/game/machinery/bots"
-#define FILE_DIR "code/game/machinery/camera"
-#define FILE_DIR "code/game/machinery/computer"
-#define FILE_DIR "code/game/machinery/doors"
-#define FILE_DIR "code/game/machinery/embedded_controller"
-#define FILE_DIR "code/game/machinery/kitchen"
-#define FILE_DIR "code/game/machinery/pipe"
-#define FILE_DIR "code/game/machinery/telecomms"
-#define FILE_DIR "code/game/mecha"
-#define FILE_DIR "code/game/mecha/combat"
-#define FILE_DIR "code/game/mecha/equipment"
-#define FILE_DIR "code/game/mecha/equipment/tools"
-#define FILE_DIR "code/game/mecha/equipment/weapons"
-#define FILE_DIR "code/game/mecha/medical"
-#define FILE_DIR "code/game/mecha/working"
-#define FILE_DIR "code/game/objects"
-#define FILE_DIR "code/game/objects/effects"
-#define FILE_DIR "code/game/objects/effects/decals"
-#define FILE_DIR "code/game/objects/effects/decals/Cleanable"
-#define FILE_DIR "code/game/objects/effects/spawners"
-#define FILE_DIR "code/game/objects/items"
-#define FILE_DIR "code/game/objects/items/devices"
-#define FILE_DIR "code/game/objects/items/devices/PDA"
-#define FILE_DIR "code/game/objects/items/devices/radio"
-#define FILE_DIR "code/game/objects/items/robot"
-#define FILE_DIR "code/game/objects/items/stacks"
-#define FILE_DIR "code/game/objects/items/stacks/sheets"
-#define FILE_DIR "code/game/objects/items/stacks/tiles"
-#define FILE_DIR "code/game/objects/items/weapons"
-#define FILE_DIR "code/game/objects/items/weapons/grenades"
-#define FILE_DIR "code/game/objects/items/weapons/implants"
-#define FILE_DIR "code/game/objects/items/weapons/melee"
-#define FILE_DIR "code/game/objects/items/weapons/storage"
-#define FILE_DIR "code/game/objects/items/weapons/tanks"
-#define FILE_DIR "code/game/objects/structures"
-#define FILE_DIR "code/game/objects/structures/crates_lockers"
-#define FILE_DIR "code/game/objects/structures/crates_lockers/closets"
-#define FILE_DIR "code/game/objects/structures/crates_lockers/closets/secure"
-#define FILE_DIR "code/game/objects/structures/stool_bed_chair_nest"
-#define FILE_DIR "code/game/turfs"
-#define FILE_DIR "code/game/turfs/simulated"
-#define FILE_DIR "code/game/turfs/space"
-#define FILE_DIR "code/game/turfs/unsimulated"
-#define FILE_DIR "code/game/verbs"
-#define FILE_DIR "code/js"
-#define FILE_DIR "code/modules"
-#define FILE_DIR "code/modules/admin"
-#define FILE_DIR "code/modules/admin/DB ban"
-#define FILE_DIR "code/modules/admin/permissionverbs"
-#define FILE_DIR "code/modules/admin/verbs"
-#define FILE_DIR "code/modules/assembly"
-#define FILE_DIR "code/modules/awaymissions"
-#define FILE_DIR "code/modules/awaymissions/maploader"
-#define FILE_DIR "code/modules/client"
-#define FILE_DIR "code/modules/clothing"
-#define FILE_DIR "code/modules/clothing/glasses"
-#define FILE_DIR "code/modules/clothing/gloves"
-#define FILE_DIR "code/modules/clothing/head"
-#define FILE_DIR "code/modules/clothing/masks"
-#define FILE_DIR "code/modules/clothing/shoes"
-#define FILE_DIR "code/modules/clothing/spacesuits"
-#define FILE_DIR "code/modules/clothing/suits"
-#define FILE_DIR "code/modules/clothing/under"
-#define FILE_DIR "code/modules/clothing/under/jobs"
-#define FILE_DIR "code/modules/detectivework"
-#define FILE_DIR "code/modules/events"
-#define FILE_DIR "code/modules/flufftext"
-#define FILE_DIR "code/modules/food"
-#define FILE_DIR "code/modules/library"
-#define FILE_DIR "code/modules/mining"
-#define FILE_DIR "code/modules/mob"
-#define FILE_DIR "code/modules/mob/dead"
-#define FILE_DIR "code/modules/mob/dead/observer"
-#define FILE_DIR "code/modules/mob/living"
-#define FILE_DIR "code/modules/mob/living/blob"
-#define FILE_DIR "code/modules/mob/living/carbon"
-#define FILE_DIR "code/modules/mob/living/carbon/alien"
-#define FILE_DIR "code/modules/mob/living/carbon/alien/humanoid"
-#define FILE_DIR "code/modules/mob/living/carbon/alien/humanoid/caste"
-#define FILE_DIR "code/modules/mob/living/carbon/alien/larva"
-#define FILE_DIR "code/modules/mob/living/carbon/alien/special"
-#define FILE_DIR "code/modules/mob/living/carbon/brain"
-#define FILE_DIR "code/modules/mob/living/carbon/human"
-#define FILE_DIR "code/modules/mob/living/carbon/metroid"
-#define FILE_DIR "code/modules/mob/living/carbon/monkey"
-#define FILE_DIR "code/modules/mob/living/silicon"
-#define FILE_DIR "code/modules/mob/living/silicon/ai"
-#define FILE_DIR "code/modules/mob/living/silicon/ai/freelook"
-#define FILE_DIR "code/modules/mob/living/silicon/decoy"
-#define FILE_DIR "code/modules/mob/living/silicon/pai"
-#define FILE_DIR "code/modules/mob/living/silicon/robot"
-#define FILE_DIR "code/modules/mob/living/simple_animal"
-#define FILE_DIR "code/modules/mob/living/simple_animal/friendly"
-#define FILE_DIR "code/modules/mob/living/simple_animal/hostile"
-#define FILE_DIR "code/modules/mob/living/simple_animal/hostile/retaliate"
-#define FILE_DIR "code/modules/mob/new_player"
-#define FILE_DIR "code/modules/paperwork"
-#define FILE_DIR "code/modules/power"
-#define FILE_DIR "code/modules/power/antimatter"
-#define FILE_DIR "code/modules/power/singularity"
-#define FILE_DIR "code/modules/power/singularity/particle_accelerator"
-#define FILE_DIR "code/modules/projectiles"
-#define FILE_DIR "code/modules/projectiles/ammunition"
-#define FILE_DIR "code/modules/projectiles/guns"
-#define FILE_DIR "code/modules/projectiles/guns/energy"
-#define FILE_DIR "code/modules/projectiles/guns/projectile"
-#define FILE_DIR "code/modules/projectiles/projectile"
-#define FILE_DIR "code/modules/reagents"
-#define FILE_DIR "code/modules/reagents/reagent_containers"
-#define FILE_DIR "code/modules/reagents/reagent_containers/food"
-#define FILE_DIR "code/modules/reagents/reagent_containers/food/drinks"
-#define FILE_DIR "code/modules/reagents/reagent_containers/food/drinks/bottle"
-#define FILE_DIR "code/modules/reagents/reagent_containers/food/snacks"
-#define FILE_DIR "code/modules/reagents/reagent_containers/glass"
-#define FILE_DIR "code/modules/reagents/reagent_containers/glass/bottle"
-#define FILE_DIR "code/modules/recycling"
-#define FILE_DIR "code/modules/research"
-#define FILE_DIR "code/modules/scripting"
-#define FILE_DIR "code/modules/scripting/AST"
-#define FILE_DIR "code/modules/scripting/AST/Operators"
-#define FILE_DIR "code/modules/scripting/Implementations"
-#define FILE_DIR "code/modules/scripting/Interpreter"
-#define FILE_DIR "code/modules/scripting/Parser"
-#define FILE_DIR "code/modules/scripting/Scanner"
-#define FILE_DIR "code/modules/security levels"
-#define FILE_DIR "code/modules/surgery"
-#define FILE_DIR "code/modules/surgery/organs"
-#define FILE_DIR "code/unused"
-#define FILE_DIR "code/unused/beast"
-#define FILE_DIR "code/unused/computer2"
-#define FILE_DIR "code/unused/disease2"
-#define FILE_DIR "code/unused/gamemodes"
-#define FILE_DIR "code/unused/hivebot"
-#define FILE_DIR "code/unused/mining"
-#define FILE_DIR "code/unused/optics"
-#define FILE_DIR "code/unused/pda2"
-#define FILE_DIR "code/unused/powerarmor"
-#define FILE_DIR "code/unused/spacecraft"
-#define FILE_DIR "code/WorkInProgress"
-#define FILE_DIR "code/WorkInProgress/carn"
-#define FILE_DIR "code/WorkInProgress/mapload"
-#define FILE_DIR "code/WorkInProgress/organs"
-#define FILE_DIR "code/WorkInProgress/Sigyn"
-#define FILE_DIR "code/WorkInProgress/Sigyn/Department Sec"
-#define FILE_DIR "code/WorkInProgress/Sigyn/Softcurity"
-#define FILE_DIR "code/WorkInProgress/virus2"
#define FILE_DIR "html"
#define FILE_DIR "icons"
#define FILE_DIR "icons/effects"
@@ -211,9 +25,7 @@
#define FILE_DIR "icons/Testing"
#define FILE_DIR "icons/turf"
#define FILE_DIR "icons/vending_icons"
-#define FILE_DIR "interface"
#define FILE_DIR "maps"
-#define FILE_DIR "maps/RandomZLevels"
#define FILE_DIR "sound"
#define FILE_DIR "sound/AI"
#define FILE_DIR "sound/ambience"
@@ -227,8 +39,6 @@
#define FILE_DIR "sound/violin"
#define FILE_DIR "sound/voice"
#define FILE_DIR "sound/weapons"
-#define FILE_DIR "tools"
-#define FILE_DIR "tools/Redirector"
// END_FILE_DIR
// BEGIN_PREFERENCES
@@ -328,15 +138,12 @@
#include "code\datums\diseases\advance\symptoms\damage_converter.dm"
#include "code\datums\diseases\advance\symptoms\dizzy.dm"
#include "code\datums\diseases\advance\symptoms\fever.dm"
-#include "code\datums\diseases\advance\symptoms\flesh_eating.dm"
#include "code\datums\diseases\advance\symptoms\hallucigen.dm"
#include "code\datums\diseases\advance\symptoms\headache.dm"
#include "code\datums\diseases\advance\symptoms\heal.dm"
#include "code\datums\diseases\advance\symptoms\itching.dm"
-#include "code\datums\diseases\advance\symptoms\shedding.dm"
#include "code\datums\diseases\advance\symptoms\shivering.dm"
#include "code\datums\diseases\advance\symptoms\sneeze.dm"
-#include "code\datums\diseases\advance\symptoms\stimulant.dm"
#include "code\datums\diseases\advance\symptoms\symptoms.dm"
#include "code\datums\diseases\advance\symptoms\voice_change.dm"
#include "code\datums\diseases\advance\symptoms\vomit.dm"
@@ -425,19 +232,6 @@
#include "code\game\gamemodes\cult\ritual.dm"
#include "code\game\gamemodes\cult\runes.dm"
#include "code\game\gamemodes\cult\talisman.dm"
-#include "code\game\gamemodes\events\biomass.dm"
-#include "code\game\gamemodes\events\black_hole.dm"
-#include "code\game\gamemodes\events\clang.dm"
-#include "code\game\gamemodes\events\dust.dm"
-#include "code\game\gamemodes\events\miniblob.dm"
-#include "code\game\gamemodes\events\ninja_abilities.dm"
-#include "code\game\gamemodes\events\ninja_equipment.dm"
-#include "code\game\gamemodes\events\space_ninja.dm"
-#include "code\game\gamemodes\events\spacevines.dm"
-#include "code\game\gamemodes\events\wormholes.dm"
-#include "code\game\gamemodes\events\holidays\Christmas.dm"
-#include "code\game\gamemodes\events\holidays\Holidays.dm"
-#include "code\game\gamemodes\events\holidays\Other.dm"
#include "code\game\gamemodes\extended\extended.dm"
#include "code\game\gamemodes\malfunction\Malf_Modules.dm"
#include "code\game\gamemodes\malfunction\malfunction.dm"
@@ -960,18 +754,25 @@
#include "code\modules\events\carp_migration.dm"
#include "code\modules\events\communications_blackout.dm"
#include "code\modules\events\disease_outbreak.dm"
+#include "code\modules\events\dust.dm"
#include "code\modules\events\electrical_storm.dm"
#include "code\modules\events\energetic_flux.dm"
#include "code\modules\events\event.dm"
#include "code\modules\events\event_manager.dm"
+#include "code\modules\events\gravitational_anomaly.dm"
+#include "code\modules\events\immovable_rod.dm"
#include "code\modules\events\ion_storm.dm"
#include "code\modules\events\mass_hallucination.dm"
#include "code\modules\events\meteor_wave.dm"
+#include "code\modules\events\ninja.dm"
#include "code\modules\events\prison_break.dm"
#include "code\modules\events\radiation_storm.dm"
#include "code\modules\events\spacevine.dm"
#include "code\modules\events\spider_infestation.dm"
#include "code\modules\events\spontaneous_appendicitis.dm"
+#include "code\modules\events\weightless.dm"
+#include "code\modules\events\wormholes.dm"
+#include "code\modules\events\holiday\xmas.dm"
#include "code\modules\flufftext\Dreaming.dm"
#include "code\modules\flufftext\Hallucination.dm"
#include "code\modules\flufftext\TextFilters.dm"