Merge branch 'master' into cargocleanupv2boogaloo
This commit is contained in:
@@ -720,20 +720,44 @@
|
||||
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
var/turf/T = get_turf(usr)
|
||||
|
||||
var/chosen = pick_closest_path(object)
|
||||
if(!chosen)
|
||||
return
|
||||
if(ispath(chosen, /turf))
|
||||
var/turf/T = get_turf(usr.loc)
|
||||
T.ChangeTurf(chosen)
|
||||
else
|
||||
var/atom/A = new chosen(usr.loc)
|
||||
var/atom/A = new chosen(T)
|
||||
A.flags_1 |= ADMIN_SPAWNED_1
|
||||
|
||||
log_admin("[key_name(usr)] spawned [chosen] at [AREACOORD(usr)]")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/datum/admins/proc/podspawn_atom(object as text)
|
||||
set category = "Debug"
|
||||
set desc = "(atom path) Spawn an atom via supply drop"
|
||||
set name = "Podspawn"
|
||||
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/chosen = pick_closest_path(object)
|
||||
if(!chosen)
|
||||
return
|
||||
var/turf/T = get_turf(usr)
|
||||
|
||||
if(ispath(chosen, /turf))
|
||||
T.ChangeTurf(chosen)
|
||||
else
|
||||
var/obj/structure/closet/supplypod/centcompod/pod = new()
|
||||
var/atom/A = new chosen(pod)
|
||||
A.flags_1 |= ADMIN_SPAWNED_1
|
||||
new /obj/effect/abstract/DPtarget(T, pod)
|
||||
|
||||
log_admin("[key_name(usr)] pod-spawned [chosen] at [AREACOORD(usr)]")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Podspawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/datum/admins/proc/spawn_cargo(object as text)
|
||||
set category = "Debug"
|
||||
set desc = "(atom path) Spawn a cargo crate"
|
||||
@@ -875,7 +899,7 @@
|
||||
/datum/admins/proc/dynamic_mode_options(mob/user)
|
||||
var/dat = {"
|
||||
<center><B><h2>Dynamic Mode Options</h2></B></center><hr>
|
||||
<br/>
|
||||
<br/>
|
||||
<h3>Common options</h3>
|
||||
<i>All these options can be changed midround.</i> <br/>
|
||||
<br/>
|
||||
|
||||
@@ -108,7 +108,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list(
|
||||
/client/proc/roll_dices //CIT CHANGE - Adds dice verb
|
||||
))
|
||||
GLOBAL_PROTECT(admin_verbs_fun)
|
||||
GLOBAL_LIST_INIT(admin_verbs_spawn, list(/datum/admins/proc/spawn_atom, /datum/admins/proc/spawn_cargo, /datum/admins/proc/spawn_objasmob, /client/proc/respawn_character))
|
||||
GLOBAL_LIST_INIT(admin_verbs_spawn, list(/datum/admins/proc/spawn_atom, /datum/admins/proc/podspawn_atom, /datum/admins/proc/spawn_cargo, /datum/admins/proc/spawn_objasmob, /client/proc/respawn_character))
|
||||
GLOBAL_PROTECT(admin_verbs_spawn)
|
||||
GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer())
|
||||
/world/proc/AVerbsServer()
|
||||
|
||||
@@ -2355,7 +2355,7 @@
|
||||
|
||||
var/atom/target //Where the object will be spawned
|
||||
var/where = href_list["object_where"]
|
||||
if (!( where in list("onfloor","inhand","inmarked") ))
|
||||
if (!( where in list("onfloor","frompod","inhand","inmarked") ))
|
||||
where = "onfloor"
|
||||
|
||||
|
||||
@@ -2366,7 +2366,7 @@
|
||||
where = "onfloor"
|
||||
target = usr
|
||||
|
||||
if("onfloor")
|
||||
if("onfloor", "frompod")
|
||||
switch(href_list["offset_type"])
|
||||
if ("absolute")
|
||||
target = locate(0 + X,0 + Y,0 + Z)
|
||||
@@ -2382,7 +2382,10 @@
|
||||
else
|
||||
target = marked_datum
|
||||
|
||||
var/obj/structure/closet/supplypod/centcompod/pod
|
||||
if(target)
|
||||
if(where == "frompod")
|
||||
pod = new()
|
||||
for (var/path in paths)
|
||||
for (var/i = 0; i < number; i++)
|
||||
if(path in typesof(/turf))
|
||||
@@ -2391,7 +2394,11 @@
|
||||
if(N && obj_name)
|
||||
N.name = obj_name
|
||||
else
|
||||
var/atom/O = new path(target)
|
||||
var/atom/O
|
||||
if(where == "frompod")
|
||||
O = new path(pod)
|
||||
else
|
||||
O = new path(target)
|
||||
if(!QDELETED(O))
|
||||
O.flags_1 |= ADMIN_SPAWNED_1
|
||||
if(obj_dir)
|
||||
@@ -2411,6 +2418,8 @@
|
||||
R.module.add_module(I, TRUE, TRUE)
|
||||
R.activate_module(I)
|
||||
|
||||
if(pod)
|
||||
new /obj/effect/abstract/DPtarget(target, pod)
|
||||
|
||||
if (number == 1)
|
||||
log_admin("[key_name(usr)] created a [english_list(paths)]")
|
||||
|
||||
@@ -1249,7 +1249,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
if(!check_rights(R_ADMIN) || !check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_SUPPLYPOD, ADMIN_PUNISHMENT_MAZING, ADMIN_PUNISHMENT_ROD)
|
||||
var/list/punishment_list = list(ADMIN_PUNISHMENT_PIE, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_SUPPLYPOD_QUICK, ADMIN_PUNISHMENT_SUPPLYPOD, ADMIN_PUNISHMENT_MAZING, ADMIN_PUNISHMENT_ROD)
|
||||
|
||||
var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
|
||||
|
||||
@@ -1277,6 +1277,22 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
var/turf/startT = spaceDebrisStartLoc(startside, T.z)
|
||||
var/turf/endT = spaceDebrisFinishLoc(startside, T.z)
|
||||
new /obj/effect/immovablerod(startT, endT,target)
|
||||
if(ADMIN_PUNISHMENT_SUPPLYPOD_QUICK)
|
||||
var/target_path = input(usr,"Enter typepath of an atom you'd like to send with the pod (type \"empty\" to send an empty pod):" ,"Typepath","/obj/item/reagent_containers/food/snacks/grown/harebell") as null|text
|
||||
var/obj/structure/closet/supplypod/centcompod/pod = new()
|
||||
pod.damage = 40
|
||||
pod.explosionSize = list(0,0,0,2)
|
||||
pod.effectStun = TRUE
|
||||
if (isnull(target_path)) //The user pressed "Cancel"
|
||||
return
|
||||
if (target_path != "empty")//if you didn't type empty, we want to load the pod with a delivery
|
||||
var/delivery = text2path(target_path)
|
||||
if(!ispath(delivery))
|
||||
delivery = pick_closest_path(target_path)
|
||||
if(!delivery)
|
||||
alert("ERROR: Incorrect / improper path given.")
|
||||
new delivery(pod)
|
||||
new /obj/effect/abstract/DPtarget(get_turf(target), pod)
|
||||
if(ADMIN_PUNISHMENT_SUPPLYPOD)
|
||||
var/datum/centcom_podlauncher/plaunch = new(usr)
|
||||
if(!holder)
|
||||
@@ -1289,6 +1305,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
plaunch.temp_pod.explosionSize = list(0,0,0,2)
|
||||
plaunch.temp_pod.effectStun = TRUE
|
||||
plaunch.ui_interact(usr)
|
||||
return //We return here because punish_log() is handled by the centcom_podlauncher datum
|
||||
|
||||
if(ADMIN_PUNISHMENT_MAZING)
|
||||
if(!puzzle_imprison(target))
|
||||
@@ -1298,11 +1315,13 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/creamy = new(get_turf(target))
|
||||
creamy.splat(target)
|
||||
|
||||
var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]."
|
||||
message_admins(msg)
|
||||
admin_ticket_log(target, msg)
|
||||
log_admin("[key_name(usr)] punished [key_name(target)] with [punishment].")
|
||||
punish_log(target, punishment)
|
||||
|
||||
/client/proc/punish_log(var/whom, var/punishment)
|
||||
var/msg = "[key_name_admin(usr)] punished [key_name_admin(whom)] with [punishment]."
|
||||
message_admins(msg)
|
||||
admin_ticket_log(whom, msg)
|
||||
log_admin("[key_name(usr)] punished [key_name(whom)] with [punishment].")
|
||||
|
||||
/client/proc/trigger_centcom_recall()
|
||||
if(!check_rights(R_ADMIN))
|
||||
|
||||
@@ -244,6 +244,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/structure/blob/proc/chemeffectreport()
|
||||
RETURN_TYPE(/list)
|
||||
. = list()
|
||||
if(overmind)
|
||||
. += "<b>Material: <font color=\"[overmind.blob_reagent_datum.color]\">[overmind.blob_reagent_datum.name]</font><span class='notice'>.</span></b>"
|
||||
@@ -253,6 +254,7 @@
|
||||
. += "<b>No Material Detected!</b><br>"
|
||||
|
||||
/obj/structure/blob/proc/typereport()
|
||||
RETURN_TYPE(/list)
|
||||
. = list("<b>Blob Type:</b> <span class='notice'>[uppertext(initial(name))]</span>")
|
||||
. += "<b>Health:</b> <span class='notice'>[obj_integrity]/[max_integrity]</span>"
|
||||
. += "<b>Effects:</b> <span class='notice'>[scannerreport()]</span>"
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
owner.special_role = special_role
|
||||
if(give_objectives)
|
||||
forge_traitor_objectives()
|
||||
RegisterSignal(owner.current, COMSIG_MOVABLE_HEAR, .proc/handle_hearing)
|
||||
finalize_traitor()
|
||||
..()
|
||||
|
||||
@@ -49,7 +48,6 @@
|
||||
A.verbs -= /mob/living/silicon/ai/proc/choose_modules
|
||||
A.malf_picker.remove_malf_verbs(A)
|
||||
qdel(A.malf_picker)
|
||||
UnregisterSignal(owner.current, COMSIG_MOVABLE_HEAR, .proc/handle_hearing)
|
||||
SSticker.mode.traitors -= owner
|
||||
if(!silent && owner.current)
|
||||
to_chat(owner.current,"<span class='userdanger'> You are no longer the [special_role]! </span>")
|
||||
@@ -57,10 +55,10 @@
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/traitor/proc/handle_hearing(datum/source, list/hearing_args)
|
||||
var/message = hearing_args[HEARING_MESSAGE]
|
||||
var/message = hearing_args[HEARING_RAW_MESSAGE]
|
||||
message = GLOB.syndicate_code_phrase_regex.Replace(message, "<span class='blue'>$1</span>")
|
||||
message = GLOB.syndicate_code_response_regex.Replace(message, "<span class='red'>$1</span>")
|
||||
hearing_args[HEARING_MESSAGE] = message
|
||||
hearing_args[HEARING_RAW_MESSAGE] = message
|
||||
|
||||
/datum/antagonist/traitor/proc/add_objective(datum/objective/O)
|
||||
objectives += O
|
||||
@@ -262,16 +260,20 @@
|
||||
/datum/antagonist/traitor/apply_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
update_traitor_icons_added()
|
||||
var/mob/living/silicon/ai/A = mob_override || owner.current
|
||||
if(istype(A) && traitor_kind == TRAITOR_AI)
|
||||
var/mob/M = mob_override || owner.current
|
||||
if(isAI(M) && traitor_kind == TRAITOR_AI)
|
||||
var/mob/living/silicon/ai/A = M
|
||||
A.hack_software = TRUE
|
||||
RegisterSignal(M, COMSIG_MOVABLE_HEAR, .proc/handle_hearing)
|
||||
|
||||
/datum/antagonist/traitor/remove_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
update_traitor_icons_removed()
|
||||
var/mob/living/silicon/ai/A = mob_override || owner.current
|
||||
if(istype(A) && traitor_kind == TRAITOR_AI)
|
||||
var/mob/M = mob_override || owner.current
|
||||
if(isAI(M) && traitor_kind == TRAITOR_AI)
|
||||
var/mob/living/silicon/ai/A = M
|
||||
A.hack_software = FALSE
|
||||
UnregisterSignal(M, COMSIG_MOVABLE_HEAR)
|
||||
|
||||
/datum/antagonist/traitor/proc/give_codewords()
|
||||
if(!owner.current)
|
||||
|
||||
@@ -72,11 +72,13 @@
|
||||
air.copy_from(copy)
|
||||
|
||||
/turf/return_air()
|
||||
RETURN_TYPE(/datum/gas_mixture)
|
||||
var/datum/gas_mixture/GM = new
|
||||
GM.copy_from_turf(src)
|
||||
return GM
|
||||
|
||||
/turf/open/return_air()
|
||||
RETURN_TYPE(/datum/gas_mixture)
|
||||
return air
|
||||
|
||||
/turf/temperature_expose()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
//Variables declared to change how items in the launch bay are picked and launched. (Almost) all of these are changed in the ui_act proc
|
||||
//Some effect groups are choices, while other are booleans. This is because some effects can stack, while others dont (ex: you can stack explosion and quiet, but you cant stack ordered launch and random launch)
|
||||
/datum/centcom_podlauncher
|
||||
var/static/list/ignored_atoms = typecacheof(list(null, /mob/dead, /obj/effect/landmark, /obj/docking_port, /atom/movable/lighting_object, /obj/effect/particle_effect/sparks, /obj/effect/DPtarget, /obj/effect/supplypod_selector ))
|
||||
var/static/list/ignored_atoms = typecacheof(list(null, /mob/dead, /obj/effect/landmark, /obj/docking_port, /atom/movable/lighting_object, /obj/effect/particle_effect/sparks, /obj/effect/abstract/DPtarget, /obj/effect/supplypod_selector ))
|
||||
var/turf/oldTurf //Keeps track of where the user was at if they use the "teleport to centcom" button, so they can go back
|
||||
var/client/holder //client of whoever is using this datum
|
||||
var/area/bay //What bay we're using to launch shit from.
|
||||
@@ -29,9 +29,10 @@
|
||||
var/damageChoice = 0 //Determines if we do no damage (0), custom amnt of damage (1), or gib + 5000dmg (2)
|
||||
var/launcherActivated = FALSE //check if we've entered "launch mode" (when we click a pod is launched). Used for updating mouse cursor
|
||||
var/effectBurst = FALSE //Effect that launches 5 at once in a 3x3 area centered on the target
|
||||
var/effectAnnounce = TRUE
|
||||
var/numTurfs = 0 //Counts the number of turfs with things we can launch in the chosen bay (in the centcom map)
|
||||
var/launchCounter = 1 //Used with the "Ordered" launch mode (launchChoice = 1) to see what item is launched
|
||||
var/specificTarget //Do we want to target a specific mob instead of where we click? Also used for smiting
|
||||
var/atom/specificTarget //Do we want to target a specific mob instead of where we click? Also used for smiting
|
||||
var/list/orderedArea = list() //Contains an ordered list of turfs in an area (filled in the createOrderedArea() proc), read top-left to bottom-right. Used for the "ordered" launch mode (launchChoice = 1)
|
||||
var/list/turf/acceptableTurfs = list() //Contians a list of turfs (in the "bay" area on centcom) that have items that can be launched. Taken from orderedArea
|
||||
var/list/launchList = list() //Contains whatever is going to be put in the supplypod and fired. Taken from acceptableTurfs
|
||||
@@ -66,12 +67,14 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
data["launchChoice"] = launchChoice //Launch turfs all at once (0), ordered (1), or randomly(1)
|
||||
data["explosionChoice"] = explosionChoice //An explosion that occurs when landing. Can be no explosion (0), custom explosion (1), or maxcap (2)
|
||||
data["damageChoice"] = damageChoice //Damage that occurs to any mob under the pod when it lands. Can be no damage (0), custom damage (1), or gib+5000dmg (2)
|
||||
data["fallDuration"] = temp_pod.fallDuration //How long the pod's falling animation lasts
|
||||
data["landingDelay"] = temp_pod.landingDelay //How long the pod takes to land after launching
|
||||
data["openingDelay"] = temp_pod.openingDelay //How long the pod takes to open after landing
|
||||
data["departureDelay"] = temp_pod.departureDelay //How long the pod takes to leave after opening (if bluespace=true, it deletes. if reversing=true, it flies back to centcom)
|
||||
data["styleChoice"] = temp_pod.style //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the POD_STYLES list in cargo.dm defines to get the proper icon/name/desc for the pod.
|
||||
data["effectStun"] = temp_pod.effectStun //If true, stuns anyone under the pod when it launches until it lands, forcing them to get hit by the pod. Devilish!
|
||||
data["effectLimb"] = temp_pod.effectLimb //If true, pops off a limb (if applicable) from anyone caught under the pod when it lands
|
||||
data["effectOrgans"] = temp_pod.effectOrgans //If true, yeets the organs out of any bodies caught under the pod when it lands
|
||||
data["effectBluespace"] = temp_pod.bluespace //If true, the pod deletes (in a shower of sparks) after landing
|
||||
data["effectStealth"] = temp_pod.effectStealth //If true, a target icon isnt displayed on the turf where the pod will land
|
||||
data["effectQuiet"] = temp_pod.effectQuiet //The female sniper. If true, the pod makes no noise (including related explosions, opening sounds, etc)
|
||||
@@ -81,12 +84,14 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
data["effectReverse"] = temp_pod.reversing //If true, the pod will not send any items. Instead, after opening, it will close again (picking up items/mobs) and fly back to centcom
|
||||
data["effectTarget"] = specificTarget //Launches the pod at the turf of a specific mob target, rather than wherever the user clicked. Useful for smites
|
||||
data["effectName"] = temp_pod.adminNamed //Determines whether or not the pod has been named by an admin. If true, the pod's name will not get overridden when the style of the pod changes (changing the style of the pod normally also changes the name+desc)
|
||||
data["effectAnnounce"] = effectAnnounce
|
||||
data["giveLauncher"] = launcherActivated //If true, the user is in launch mode, and whenever they click a pod will be launched (either at their mouse position or at a specific target)
|
||||
data["numObjects"] = numTurfs //Counts the number of turfs that contain a launchable object in the centcom supplypod bay
|
||||
data["fallingSound"] = temp_pod.fallingSound != initial(temp_pod.fallingSound)//Admin sound to play as the pod falls
|
||||
data["landingSound"] = temp_pod.landingSound //Admin sound to play when the pod lands
|
||||
data["openingSound"] = temp_pod.openingSound //Admin sound to play when the pod opens
|
||||
data["leavingSound"] = temp_pod.leavingSound //Admin sound to play when the pod leaves
|
||||
data["soundVolume"] = temp_pod.soundVolume != 50 //Admin sound to play when the pod leaves
|
||||
data["soundVolume"] = temp_pod.soundVolume != initial(temp_pod.soundVolume) //Admin sound to play when the pod leaves
|
||||
return data
|
||||
|
||||
/datum/centcom_podlauncher/ui_act(action, params)
|
||||
@@ -227,6 +232,9 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if("effectLimb") //Toggle: Anyone carbon mob under the pod loses a limb when it lands
|
||||
temp_pod.effectLimb = !temp_pod.effectLimb
|
||||
. = TRUE
|
||||
if("effectOrgans") //Toggle: Any carbon mob under the pod loses every limb and organ
|
||||
temp_pod.effectOrgans = !temp_pod.effectOrgans
|
||||
. = TRUE
|
||||
if("effectBluespace") //Toggle: Deletes the pod after landing
|
||||
temp_pod.bluespace = !temp_pod.bluespace
|
||||
. = TRUE
|
||||
@@ -245,6 +253,9 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if("effectBurst") //Toggle: Launch 5 pods (with a very slight delay between) in a 3x3 area centered around the target
|
||||
effectBurst = !effectBurst
|
||||
. = TRUE
|
||||
if("effectAnnounce") //Toggle: Sends a ghost announcement.
|
||||
effectAnnounce = !effectAnnounce
|
||||
. = TRUE
|
||||
if("effectReverse") //Toggle: Don't send any items. Instead, after landing, close (taking any objects inside) and go back to the centcom bay it came from
|
||||
temp_pod.reversing = !temp_pod.reversing
|
||||
. = TRUE
|
||||
@@ -261,11 +272,23 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
. = TRUE
|
||||
|
||||
////////////////////////////TIMER DELAYS//////////////////
|
||||
if("fallDuration") //Change the falling animation duration
|
||||
if (temp_pod.fallDuration != initial(temp_pod.fallDuration)) //If the fall duration has already been changed when we push the "change value" button, then set it to default
|
||||
temp_pod.fallDuration = initial(temp_pod.fallDuration)
|
||||
return
|
||||
var/timeInput = input("Enter the duration of the pod's falling animation, in seconds", "Delay Time", initial(temp_pod.fallDuration) * 0.1) as null|num
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput)) //Sanitize input, if it doesnt check out, error and set to default
|
||||
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.fallDuration)*0.1]) instead.")
|
||||
timeInput = initial(temp_pod.fallDuration)
|
||||
temp_pod.fallDuration = 10 * timeInput
|
||||
. = TRUE
|
||||
if("landingDelay") //Change the time it takes the pod to land, after firing
|
||||
if (temp_pod.landingDelay != initial(temp_pod.landingDelay)) //If the landing delay has already been changed when we push the "change value" button, then set it to default
|
||||
temp_pod.landingDelay = initial(temp_pod.landingDelay)
|
||||
return
|
||||
var/timeInput = input("Delay Time", "Enter the time it takes for the pod to land, in seconds", 0.5) as null|num
|
||||
var/timeInput = input("Enter the time it takes for the pod to land, in seconds", "Delay Time", initial(temp_pod.landingDelay) * 0.1) as null|num
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput)) //Sanitize input, if it doesnt check out, error and set to default
|
||||
@@ -277,7 +300,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if (temp_pod.openingDelay != initial(temp_pod.openingDelay)) //If the opening delay has already been changed when we push the "change value" button, then set it to default
|
||||
temp_pod.openingDelay = initial(temp_pod.openingDelay)
|
||||
return
|
||||
var/timeInput = input("Delay Time", "Enter the time it takes for the pod to open after landing, in seconds", 3) as null|num
|
||||
var/timeInput = input("Enter the time it takes for the pod to open after landing, in seconds", "Delay Time", initial(temp_pod.openingDelay) * 0.1) as null|num
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput)) //Sanitize input
|
||||
@@ -289,7 +312,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if (temp_pod.departureDelay != initial(temp_pod.departureDelay)) //If the departure delay has already been changed when we push the "change value" button, then set it to default
|
||||
temp_pod.departureDelay = initial(temp_pod.departureDelay)
|
||||
return
|
||||
var/timeInput = input("Delay Time", "Enter the time it takes for the pod to leave after opening, in seconds", 3) as null|num
|
||||
var/timeInput = input("Enter the time it takes for the pod to leave after opening, in seconds", "Delay Time", initial(temp_pod.departureDelay) * 0.1) as null|num
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput))
|
||||
@@ -299,31 +322,57 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
. = TRUE
|
||||
|
||||
////////////////////////////ADMIN SOUNDS//////////////////
|
||||
if("fallingSound") //Admin sound from a local file that plays when the pod falls
|
||||
if ((temp_pod.fallingSound) != initial(temp_pod.fallingSound))
|
||||
temp_pod.fallingSound = initial(temp_pod.fallingSound)
|
||||
temp_pod.fallingSoundLength = initial(temp_pod.fallingSoundLength)
|
||||
return
|
||||
var/soundInput = input(holder, "Please pick a sound file to play when the pod lands! NOTICE: Take a note of exactly how long the sound is.", "Pick a Sound File") as null|sound
|
||||
if (isnull(soundInput))
|
||||
return
|
||||
var/timeInput = input(holder, "What is the exact length of the sound file, in seconds. This number will be used to line the sound up so that it finishes right as the pod lands!", "Pick a Sound File", 0.3) as null|num
|
||||
if (isnull(timeInput))
|
||||
return
|
||||
if (!isnum(timeInput))
|
||||
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.fallingSoundLength)*0.1]) instead.")
|
||||
temp_pod.fallingSound = soundInput
|
||||
temp_pod.fallingSoundLength = 10 * timeInput
|
||||
. = TRUE
|
||||
if("landingSound") //Admin sound from a local file that plays when the pod lands
|
||||
if (!isnull(temp_pod.landingSound))
|
||||
temp_pod.landingSound = null
|
||||
return
|
||||
temp_pod.landingSound = input(holder, "Please pick a sound file to play when the pod lands! I reccomend a nice \"oh shit, i'm sorry\", incase you hit someone with the pod.", "Pick a Sound File") as null|sound
|
||||
var/soundInput = input(holder, "Please pick a sound file to play when the pod lands! I reccomend a nice \"oh shit, i'm sorry\", incase you hit someone with the pod.", "Pick a Sound File") as null|sound
|
||||
if (isnull(soundInput))
|
||||
return
|
||||
temp_pod.landingSound = soundInput
|
||||
. = TRUE
|
||||
if("openingSound") //Admin sound from a local file that plays when the pod opens
|
||||
if (!isnull(temp_pod.openingSound))
|
||||
temp_pod.openingSound = null
|
||||
return
|
||||
temp_pod.openingSound = input(holder, "Please pick a sound file to play when the pod opens! I reccomend a stock sound effect of kids cheering at a party, incase your pod is full of fun exciting stuff!", "Pick a Sound File") as null|sound
|
||||
var/soundInput = input(holder, "Please pick a sound file to play when the pod opens! I reccomend a stock sound effect of kids cheering at a party, incase your pod is full of fun exciting stuff!", "Pick a Sound File") as null|sound
|
||||
if (isnull(soundInput))
|
||||
return
|
||||
temp_pod.openingSound = soundInput
|
||||
. = TRUE
|
||||
if("leavingSound") //Admin sound from a local file that plays when the pod leaves
|
||||
if (!isnull(temp_pod.leavingSound))
|
||||
temp_pod.leavingSound = null
|
||||
return
|
||||
temp_pod.leavingSound = input(holder, "Please pick a sound file to play when the pod leaves! I reccomend a nice slide whistle sound, especially if you're using the reverse pod effect.", "Pick a Sound File") as null|sound
|
||||
var/soundInput = input(holder, "Please pick a sound file to play when the pod leaves! I reccomend a nice slide whistle sound, especially if you're using the reverse pod effect.", "Pick a Sound File") as null|sound
|
||||
if (isnull(soundInput))
|
||||
return
|
||||
temp_pod.leavingSound = soundInput
|
||||
. = TRUE
|
||||
if("soundVolume") //Admin sound from a local file that plays when the pod leaves
|
||||
if (temp_pod.soundVolume != 50)
|
||||
temp_pod.soundVolume = 50
|
||||
if (temp_pod.soundVolume != initial(temp_pod.soundVolume))
|
||||
temp_pod.soundVolume = initial(temp_pod.soundVolume)
|
||||
return
|
||||
temp_pod.soundVolume = input(holder, "Please pick a volume. Default is between 1 and 100 with 50 being average, but pick whatever. I'm a notification, not a cop. If you still cant hear your sound, consider turning on the Quiet effect. It will silence all pod sounds except for the custom admin ones set by the previous three buttons.", "Pick Admin Sound Volume") as null|num
|
||||
if (isnull(temp_pod.soundVolume))
|
||||
temp_pod.soundVolume = 50
|
||||
var/soundInput = input(holder, "Please pick a volume. Default is between 1 and 100 with 80 being average, but pick whatever. I'm a notification, not a cop. If you still cant hear your sound, consider turning on the Quiet effect. It will silence all pod sounds except for the custom admin ones set by the previous three buttons.", "Pick Admin Sound Volume") as null|num
|
||||
if (isnull(soundInput))
|
||||
return
|
||||
temp_pod.soundVolume = soundInput
|
||||
. = TRUE
|
||||
////////////////////////////STYLE CHANGES//////////////////
|
||||
//Style is a value that is used to keep track of what the pod is supposed to look like. It can be used with the POD_STYLES list (in cargo.dm defines)
|
||||
@@ -364,6 +413,9 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if("styleGondola")
|
||||
temp_pod.setStyle(STYLE_GONDOLA)
|
||||
. = TRUE
|
||||
if("styleSeeThrough")
|
||||
temp_pod.setStyle(STYLE_SEETHROUGH)
|
||||
. = TRUE
|
||||
if("refresh") //Refresh the Pod bay. User should press this if they spawn something new in the centcom bay. Automatically called whenever the user launches a pod
|
||||
refreshBay()
|
||||
. = TRUE
|
||||
@@ -403,12 +455,17 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if(left_click) //When we left click:
|
||||
preLaunch() //Fill the acceptableTurfs list from the orderedArea list. Then, fill up the launchList list with items from the acceptableTurfs list based on the manner of launch (ordered, random, etc)
|
||||
if (!isnull(specificTarget))
|
||||
target = get_turf(specificTarget) //if we have a specific mob target, then always launch the pod at the turf of the mob
|
||||
target = get_turf(specificTarget) //if we have a specific target, then always launch the pod at the turf of the target
|
||||
else if (target)
|
||||
target = get_turf(target) //Make sure we're aiming at a turf rather than an item or effect or something
|
||||
else
|
||||
return //if target is null and we don't have a specific target, cancel
|
||||
|
||||
if (effectAnnounce)
|
||||
deadchat_broadcast("<span class='deadsay'>A special package is being launched at the station!</span>", turf_target = target)
|
||||
var/list/bouttaDie = list()
|
||||
for (var/mob/living/M in target)
|
||||
bouttaDie.Add(M)
|
||||
supplypod_punish_log(bouttaDie)
|
||||
if (!effectBurst) //If we're not using burst mode, just launch normally.
|
||||
launch(target)
|
||||
else
|
||||
@@ -422,7 +479,6 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
else
|
||||
launch(target) //If we couldn't locate an adjacent turf, just launch at the normal target
|
||||
sleep(rand()*2) //looks cooler than them all appearing at once. Gives the impression of burst fire.
|
||||
log_admin("Centcom Supplypod Launch: [key_name(user)] launched a supplypod in [AREACOORD(target)]")
|
||||
|
||||
/datum/centcom_podlauncher/proc/refreshBay() //Called whenever the bay is switched, as well as wheneber a pod is launched
|
||||
orderedArea = createOrderedArea(bay) //Create an ordered list full of turfs form the bay
|
||||
@@ -486,11 +542,11 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
if (launchClone) //We arent launching the actual items from the bay, rather we are creating clones and launching those
|
||||
for (var/atom/movable/O in launchList)
|
||||
DuplicateObject(O).forceMove(toLaunch) //Duplicate each atom/movable in launchList and forceMove them into the supplypod
|
||||
new /obj/effect/DPtarget(A, toLaunch) //Create the DPTarget, which will eventually forceMove the temp_pod to it's location
|
||||
new /obj/effect/abstract/DPtarget(A, toLaunch) //Create the DPTarget, which will eventually forceMove the temp_pod to it's location
|
||||
else
|
||||
for (var/atom/movable/O in launchList) //If we aren't cloning the objects, just go through the launchList
|
||||
O.forceMove(toLaunch) //and forceMove any atom/moveable into the supplypod
|
||||
new /obj/effect/DPtarget(A, toLaunch) //Then, create the DPTarget effect, which will eventually forceMove the temp_pod to it's location
|
||||
new /obj/effect/abstract/DPtarget(A, toLaunch) //Then, create the DPTarget effect, which will eventually forceMove the temp_pod to it's location
|
||||
if (launchClone)
|
||||
launchCounter++ //We only need to increment launchCounter if we are cloning objects.
|
||||
//If we aren't cloning objects, taking and removing the first item each time from the acceptableTurfs list will inherently iterate through the list in order
|
||||
@@ -508,4 +564,26 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
|
||||
updateCursor(FALSE) //Make sure our moues cursor resets to default. False means we are not in launch mode
|
||||
qdel(temp_pod) //Delete the temp_pod
|
||||
qdel(selector) //Delete the selector effect
|
||||
. = ..()
|
||||
. = ..()
|
||||
|
||||
/datum/centcom_podlauncher/proc/supplypod_punish_log(var/list/whoDyin)
|
||||
var/podString = effectBurst ? "5 pods" : "a pod"
|
||||
var/whomString = ""
|
||||
if (LAZYLEN(whoDyin))
|
||||
for (var/mob/living/M in whoDyin)
|
||||
whomString += "[key_name(M)], "
|
||||
|
||||
var/delayString = temp_pod.landingDelay == initial(temp_pod.landingDelay) ? "" : " Delay=[temp_pod.landingDelay*0.1]s"
|
||||
var/damageString = temp_pod.damage == 0 ? "" : " Dmg=[temp_pod.damage]"
|
||||
var/explosionString = ""
|
||||
var/explosion_sum = temp_pod.explosionSize[1] + temp_pod.explosionSize[2] + temp_pod.explosionSize[3] + temp_pod.explosionSize[4]
|
||||
if (explosion_sum != 0)
|
||||
explosionString = " Boom=|"
|
||||
for (var/X in temp_pod.explosionSize)
|
||||
explosionString += "[X]|"
|
||||
|
||||
var/msg = "launched [podString][whomString].[delayString][damageString][explosionString]]"
|
||||
message_admins("[key_name_admin(usr)] [msg] in [AREACOORD(specificTarget)].")
|
||||
if (!isemptylist(whoDyin))
|
||||
for (var/mob/living/M in whoDyin)
|
||||
admin_ticket_log(M, "[key_name_admin(usr)] [msg]")
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
LZ = pick(empty_turfs)
|
||||
if (SO.pack.cost <= SSshuttle.points && LZ)//we need to call the cost check again because of the CHECK_TICK call
|
||||
SSshuttle.points -= SO.pack.cost
|
||||
new /obj/effect/DPtarget(LZ, podType, SO)
|
||||
new /obj/effect/abstract/DPtarget(LZ, podType, SO)
|
||||
. = TRUE
|
||||
update_icon()
|
||||
else
|
||||
@@ -200,7 +200,7 @@
|
||||
for(var/i in 1 to MAX_EMAG_ROCKETS)
|
||||
var/LZ = pick(empty_turfs)
|
||||
LAZYREMOVE(empty_turfs, LZ)
|
||||
new /obj/effect/DPtarget(LZ, podType, SO)
|
||||
new /obj/effect/abstract/DPtarget(LZ, podType, SO)
|
||||
. = TRUE
|
||||
update_icon()
|
||||
CHECK_TICK
|
||||
|
||||
@@ -39,7 +39,14 @@
|
||||
set name = "Release Contents"
|
||||
set category = "Gondola"
|
||||
set desc = "Release any contents stored within your vast belly."
|
||||
linked_pod.open(src)
|
||||
linked_pod.open(src, forced = TRUE)
|
||||
|
||||
/mob/living/simple_animal/pet/gondola/gondolapod/examine(mob/user)
|
||||
..()
|
||||
if (contents.len)
|
||||
to_chat(user, "<span class='notice'>It looks like it hasn't made its delivery yet.</b><span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>It looks like it has already made its delivery.</b><span>")
|
||||
|
||||
/mob/living/simple_animal/pet/gondola/gondolapod/verb/check()
|
||||
set name = "Count Contents"
|
||||
@@ -47,7 +54,7 @@
|
||||
set desc = "Take a deep look inside youself, and count up what's inside"
|
||||
var/total = contents.len
|
||||
if (total)
|
||||
to_chat(src, "<span class='notice'>You detect [total] object[total > 1 ? "s" : ""] within your incredibly vast belly.</span>")
|
||||
to_chat(src, "<span class='notice'>You detect [total] object\s within your incredibly vast belly.</span>")
|
||||
else
|
||||
to_chat(src, "<span class='notice'>A closer look inside yourself reveals... nothing.</span>")
|
||||
|
||||
|
||||
@@ -92,15 +92,11 @@
|
||||
crate_name = "insulated gloves crate"
|
||||
crate_type = /obj/structure/closet/crate/engineering/electrical
|
||||
|
||||
/obj/item/stock_parts/cell/inducer_supply
|
||||
maxcharge = 5000
|
||||
charge = 5000
|
||||
|
||||
/datum/supply_pack/engineering/inducers
|
||||
name = "NT-75 Electromagnetic Power Inducers Crate"
|
||||
desc = "No rechargers? No problem, with the NT-75 EPI, you can recharge any standard cell-based equipment anytime, anywhere. Contains two Inducers."
|
||||
cost = 2300
|
||||
contains = list(/obj/item/inducer/sci {cell_type = /obj/item/stock_parts/cell/inducer_supply; opened = 0}, /obj/item/inducer/sci {cell_type = /obj/item/stock_parts/cell/inducer_supply; opened = 0}) //FALSE doesn't work in modified type paths apparently.
|
||||
contains = list(/obj/item/inducer/sci/supply, /obj/item/inducer/sci/supply)
|
||||
crate_name = "inducer crate"
|
||||
crate_type = /obj/structure/closet/crate/engineering/electrical
|
||||
|
||||
@@ -122,17 +118,6 @@
|
||||
crate_name = "power cell crate"
|
||||
crate_type = /obj/structure/closet/crate/engineering/electrical
|
||||
|
||||
/datum/supply_pack/engineering/siezedpower
|
||||
name = "Siezed Power Cell Crate"
|
||||
desc = "We took the means of power! Contains three high-voltage plus power cells."
|
||||
cost = 1300
|
||||
contraband = TRUE
|
||||
contains = list(/obj/item/stock_parts/cell/high/plus,
|
||||
/obj/item/stock_parts/cell/high/plus,
|
||||
/obj/item/stock_parts/cell/high/plus)
|
||||
crate_name = "siezed crate"
|
||||
crate_type = /obj/structure/closet/crate/engineering/electrical
|
||||
|
||||
/datum/supply_pack/engineering/shuttle_engine
|
||||
name = "Shuttle Engine Crate"
|
||||
desc = "Through advanced bluespace-shenanigans, our engineers have managed to fit an entire shuttle engine into one tiny little crate. Requires CE access to open."
|
||||
@@ -142,22 +127,6 @@
|
||||
crate_name = "shuttle engine crate"
|
||||
crate_type = /obj/structure/closet/crate/secure/engineering
|
||||
|
||||
/datum/supply_pack/engineering/siezedproduction
|
||||
name = "The Means of Production"
|
||||
desc = "We will win for we have taken over the production! Contains an autolate board and all the materials required to assemble it! (High-voltage plus power cell included!)"
|
||||
cost = 1500
|
||||
contraband = TRUE
|
||||
contains = list(/obj/item/stock_parts/cell/high/plus,
|
||||
/obj/item/circuitboard/machine/autolathe,
|
||||
/obj/item/stack/cable_coil/random/five,
|
||||
/obj/item/stack/sheet/metal/five,
|
||||
/obj/item/stock_parts/matter_bin,
|
||||
/obj/item/stock_parts/matter_bin,
|
||||
/obj/item/stock_parts/matter_bin,
|
||||
/obj/item/stock_parts/manipulator,
|
||||
/obj/item/stack/sheet/glass,)
|
||||
crate_name = "siezed crate"
|
||||
|
||||
/datum/supply_pack/engineering/tools
|
||||
name = "Toolbox Crate"
|
||||
desc = "Any robust spaceman is never far from their trusty toolbox. Contains three electrical toolboxes and three mechanical toolboxes."
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
name = "Loom"
|
||||
desc = "A large pre-made loom."
|
||||
cost = 1000
|
||||
contains = list(/obj/structure/loom)
|
||||
contains = list(/obj/structure/loom/unanchored)
|
||||
crate_name = "loom crate"
|
||||
crate_type = /obj/structure/closet/crate/large
|
||||
|
||||
|
||||
@@ -40,9 +40,10 @@
|
||||
|
||||
/datum/supply_pack/medical/bloodpacks
|
||||
name = "Blood Pack Variety Crate"
|
||||
desc = "Contains ten different blood packs for reintroducing blood to patients."
|
||||
desc = "Contains nine different blood packs for reintroducing blood to patients, plus two universal synthetic blood packs."
|
||||
cost = 3000
|
||||
contains = list(/obj/item/reagent_containers/blood/random,
|
||||
contains = list(/obj/item/reagent_containers/blood/synthetics,
|
||||
/obj/item/reagent_containers/blood/synthetics,
|
||||
/obj/item/reagent_containers/blood/random,
|
||||
/obj/item/reagent_containers/blood/APlus,
|
||||
/obj/item/reagent_containers/blood/AMinus,
|
||||
@@ -56,18 +57,6 @@
|
||||
crate_name = "blood freezer"
|
||||
crate_type = /obj/structure/closet/crate/freezer
|
||||
|
||||
/datum/supply_pack/medical/bloodpackssynth
|
||||
name = "Synthetics Blood Pack Crate"
|
||||
desc = "Contains five synthetics blood packs for reintroducing blood to patients."
|
||||
cost = 3000
|
||||
contains = list(/obj/item/reagent_containers/blood/synthetics,
|
||||
/obj/item/reagent_containers/blood/synthetics,
|
||||
/obj/item/reagent_containers/blood/synthetics,
|
||||
/obj/item/reagent_containers/blood/synthetics,
|
||||
/obj/item/reagent_containers/blood/synthetics)
|
||||
crate_name = "blood freezer"
|
||||
crate_type = /obj/structure/closet/crate/freezer
|
||||
|
||||
/datum/supply_pack/medical/defibs
|
||||
name = "Defibrillator Crate"
|
||||
desc = "Contains two defibrillators for bringing the recently deceased back to life."
|
||||
|
||||
@@ -344,15 +344,27 @@
|
||||
crate_name = "deluxe keg"
|
||||
crate_type = /obj/structure/closet/crate
|
||||
|
||||
/datum/supply_pack/misc/randomised/promiscuous
|
||||
name = "Promiscuous Organs"
|
||||
desc = "Do YOU want to have more genitals? Well we have just the thing for you~. This crate has two autosurgeons, that will let you have a new sex organ to impress that hot stud and/or chick."
|
||||
cost = 4000 //Only get 2!
|
||||
contraband = TRUE
|
||||
var/num_contained = 2
|
||||
contains = list(/obj/item/autosurgeon/penis,
|
||||
/obj/item/autosurgeon/testicles,
|
||||
/obj/item/autosurgeon/vagina,
|
||||
/obj/item/autosurgeon/breasts,
|
||||
/obj/item/autosurgeon/womb)
|
||||
crate_name = "promiscuous organs"
|
||||
/datum/supply_pack/misc/religious_supplies
|
||||
name = "Religious Supplies Crate"
|
||||
desc = "Keep your local chaplain happy and well-supplied, lest they call down judgement upon your cargo bay. Contains two bottles of holywater, bibles, chaplain robes, and burial garmets."
|
||||
cost = 4000 // it costs so much because the Space Church is ran by Space Jews
|
||||
contains = list(/obj/item/reagent_containers/food/drinks/bottle/holywater,
|
||||
/obj/item/reagent_containers/food/drinks/bottle/holywater,
|
||||
/obj/item/storage/book/bible/booze,
|
||||
/obj/item/storage/book/bible/booze,
|
||||
/obj/item/clothing/suit/hooded/chaplain_hoodie,
|
||||
/obj/item/clothing/suit/hooded/chaplain_hoodie
|
||||
)
|
||||
crate_name = "religious supplies crate"
|
||||
|
||||
/datum/supply_pack/misc/toner
|
||||
name = "Toner Crate"
|
||||
desc = "Spent too much ink printing butt pictures? Fret not, with these six toner refills, you'll be printing butts 'till the cows come home!'"
|
||||
cost = 1000
|
||||
contains = list(/obj/item/toner,
|
||||
/obj/item/toner,
|
||||
/obj/item/toner,
|
||||
/obj/item/toner,
|
||||
/obj/item/toner,
|
||||
/obj/item/toner)
|
||||
crate_name = "toner crate"
|
||||
|
||||
@@ -15,15 +15,17 @@
|
||||
armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80)
|
||||
anchored = TRUE //So it cant slide around after landing
|
||||
anchorable = FALSE
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
|
||||
//*****NOTE*****: Many of these comments are similarly described in centcom_podlauncher.dm. If you change them here, please consider doing so in the centcom podlauncher code as well!
|
||||
var/adminNamed = FALSE //Determines whether or not the pod has been named by an admin. If true, the pod's name will not get overridden when the style of the pod changes (changing the style of the pod normally also changes the name+desc)
|
||||
var/bluespace = FALSE //If true, the pod deletes (in a shower of sparks) after landing
|
||||
var/landingDelay = 30 //How long the pod takes to land after launching
|
||||
var/openingDelay = 30 //How long the pod takes to open after landing
|
||||
var/departureDelay = 30 //How long the pod takes to leave after opening (if bluespace=true, it deletes. if reversing=true, it flies back to centcom)
|
||||
var/departureDelay = 30 //How long the pod takes to leave after opening. If bluespace = TRUE, it deletes. If reversing = TRUE, it flies back to centcom.
|
||||
var/damage = 0 //Damage that occurs to any mob under the pod when it lands.
|
||||
var/effectStun = FALSE //If true, stuns anyone under the pod when it launches until it lands, forcing them to get hit by the pod. Devilish!
|
||||
var/effectLimb = FALSE //If true, pops off a limb (if applicable) from anyone caught under the pod when it lands
|
||||
var/effectOrgans = FALSE //If true, yeets out every limb and organ from anyone caught under the pod when it lands
|
||||
var/effectGib = FALSE //If true, anyone under the pod will be gibbed when it lands
|
||||
var/effectStealth = FALSE //If true, a target icon isnt displayed on the turf where the pod will land
|
||||
var/effectQuiet = FALSE //The female sniper. If true, the pod makes no noise (including related explosions, opening sounds, etc)
|
||||
@@ -31,10 +33,13 @@
|
||||
var/effectCircle = FALSE //If true, allows the pod to come in at any angle. Bit of a weird feature but whatever its here
|
||||
var/style = STYLE_STANDARD //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the POD_STYLES list in cargo.dm defines to get the proper icon/name/desc for the pod.
|
||||
var/reversing = FALSE //If true, the pod will not send any items. Instead, after opening, it will close again (picking up items/mobs) and fly back to centcom
|
||||
var/fallDuration = 4
|
||||
var/fallingSoundLength = 11
|
||||
var/fallingSound = 'sound/weapons/mortar_long_whistle.ogg'//Admin sound to play before the pod lands
|
||||
var/landingSound //Admin sound to play when the pod lands
|
||||
var/openingSound //Admin sound to play when the pod opens
|
||||
var/leavingSound //Admin sound to play when the pod leaves
|
||||
var/soundVolume = 50 //Volume to play sounds at. Ignores the cap
|
||||
var/soundVolume = 80 //Volume to play sounds at. Ignores the cap
|
||||
var/bay //Used specifically for the centcom_podlauncher datum. Holds the current bay the user is launching objects from. Bays are specific rooms on the centcom map.
|
||||
var/list/explosionSize = list(0,0,2,3)
|
||||
|
||||
@@ -48,16 +53,18 @@
|
||||
style = STYLE_CENTCOM
|
||||
bluespace = TRUE
|
||||
explosionSize = list(0,0,0,0)
|
||||
landingDelay = 5 //Very speedy!
|
||||
landingDelay = 20 //Very speedy!
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/structure/closet/supplypod/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
setStyle(style, TRUE) //Upon initialization, give the supplypod an iconstate, name, and description based on the "style" variable. This system is important for the centcom_podlauncher to function correctly
|
||||
|
||||
/obj/structure/closet/supplypod/update_icon()
|
||||
cut_overlays()
|
||||
if (style != STYLE_INVISIBLE) //If we're invisible, we dont bother adding any overlays
|
||||
if (style == STYLE_SEETHROUGH || style == STYLE_INVISIBLE) //If we're invisible, we dont bother adding any overlays
|
||||
return
|
||||
else
|
||||
if (opened)
|
||||
add_overlay("[icon_state]_open")
|
||||
else
|
||||
@@ -75,7 +82,7 @@
|
||||
update_icon()
|
||||
|
||||
/obj/structure/closet/supplypod/tool_interact(obj/item/W, mob/user)
|
||||
if (bluespace) //We dont want to worry about interacting with bluespace pods, as they are due to delete themselves soon anyways.
|
||||
if(bluespace) //We dont want to worry about interacting with bluespace pods, as they are due to delete themselves soon anyways.
|
||||
return FALSE
|
||||
else
|
||||
..()
|
||||
@@ -86,9 +93,6 @@
|
||||
/obj/structure/closet/supplypod/contents_explosion() //Supplypods also protect their contents from the harmful effects of fucking exploding.
|
||||
return
|
||||
|
||||
/obj/structure/closet/supplypod/prevent_content_explosion() //Useful for preventing epicenter explosions from damaging contents
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/supplypod/toggle(mob/living/user) //Supplypods shouldn't be able to be manually opened under any circumstances, as the open() proc generates supply order datums
|
||||
return
|
||||
|
||||
@@ -101,17 +105,33 @@
|
||||
if (effectLimb && iscarbon(M)) //If effectLimb is true (which means we pop limbs off when we hit people):
|
||||
var/mob/living/carbon/CM = M
|
||||
for (var/obj/item/bodypart/bodypart in CM.bodyparts) //Look at the bodyparts in our poor mob beneath our pod as it lands
|
||||
if(bodypart.body_part != HEAD && bodypart.body_zone != CHEST)//we dont want to kill him, just teach em a lesson!
|
||||
if(bodypart.body_part != HEAD && bodypart.body_part != CHEST)//we dont want to kill him, just teach em a lesson!
|
||||
if (bodypart.dismemberable)
|
||||
bodypart.dismember() //Using the power of flextape i've sawed this man's limb in half!
|
||||
break
|
||||
if (effectOrgans && iscarbon(M)) //effectOrgans means remove every organ in our mob
|
||||
var/mob/living/carbon/CM = M
|
||||
for(var/X in CM.internal_organs)
|
||||
var/destination = get_edge_target_turf(T, pick(GLOB.alldirs)) //Pick a random direction to toss them in
|
||||
var/obj/item/organ/O = X
|
||||
O.Remove(CM) //Note that this isn't the same proc as for lists
|
||||
O.forceMove(T) //Move the organ outta the body
|
||||
O.throw_at(destination, 2, 3) //Thow the organ at a random tile 3 spots away
|
||||
sleep(1)
|
||||
for (var/obj/item/bodypart/bodypart in CM.bodyparts) //Look at the bodyparts in our poor mob beneath our pod as it lands
|
||||
var/destination = get_edge_target_turf(T, pick(GLOB.alldirs))
|
||||
if (bodypart.dismemberable)
|
||||
bodypart.dismember() //Using the power of flextape i've sawed this man's bodypart in half!
|
||||
bodypart.throw_at(destination, 2, 3)
|
||||
sleep(1)
|
||||
|
||||
if (effectGib) //effectGib is on, that means whatever's underneath us better be fucking oof'd on
|
||||
M.adjustBruteLoss(5000) //THATS A LOT OF DAMAGE (called just in case gib() doesnt work on em)
|
||||
M.gib() //After adjusting the fuck outta that brute loss we finish the job with some satisfying gibs
|
||||
M.adjustBruteLoss(damage)
|
||||
|
||||
|
||||
if (B[1] || B[2] || B[3] || B[4]) //If the explosion list isn't all zeroes, call an explosion
|
||||
else
|
||||
M.adjustBruteLoss(damage)
|
||||
var/explosion_sum = B[1] + B[2] + B[3] + B[4]
|
||||
if (explosion_sum != 0) //If the explosion list isn't all zeroes, call an explosion
|
||||
explosion(get_turf(src), B[1], B[2], B[3], flame_range = B[4], silent = effectQuiet, ignorecap = istype(src, /obj/structure/closet/supplypod/centcompod)) //less advanced equipment than bluespace pod, so larger explosion when landing
|
||||
else if (!effectQuiet) //If our explosion list IS all zeroes, we still make a nice explosion sound (unless the effectQuiet var is true)
|
||||
playsound(src, "explosion", landingSound ? 15 : 80, 1)
|
||||
@@ -128,22 +148,31 @@
|
||||
|
||||
/obj/structure/closet/supplypod/open(atom/movable/holder, var/broken = FALSE, var/forced = FALSE) //The holder var represents an atom whose contents we will be working with
|
||||
var/turf/T = get_turf(holder) //Get the turf of whoever's contents we're talking about
|
||||
if (!holder)
|
||||
return
|
||||
if(opened)
|
||||
return
|
||||
opened = TRUE //This is to ensure we don't open something that has already been opened
|
||||
var/mob/M
|
||||
if (istype(holder, /mob)) //Allows mobs to assume the role of the holder, meaning we look at the mob's contents rather than the supplypod's contents. Typically by this point the supplypod's contents have already been moved over to the mob's contents
|
||||
M = holder
|
||||
if (M.key && !forced && !broken) //If we are player controlled, then we shouldnt open unless the opening is manual, or if it is due to being destroyed (represented by the "broken" parameter)
|
||||
return
|
||||
opened = TRUE //This is to ensure we don't open something that has already been opened
|
||||
if (openingSound)
|
||||
playsound(get_turf(holder), openingSound, soundVolume, 0, 0)
|
||||
playsound(get_turf(holder), openingSound, soundVolume, 0, 0) //Special admin sound to play
|
||||
INVOKE_ASYNC(holder, .proc/setOpened) //Use the INVOKE_ASYNC proc to call setOpened() on whatever the holder may be, without giving the atom/movable base class a setOpened() proc definition
|
||||
if (style == STYLE_SEETHROUGH)
|
||||
update_icon()
|
||||
for (var/atom/movable/O in holder.contents) //Go through the contents of the holder
|
||||
O.forceMove(T) //move everything from the contents of the holder to the turf of the holder
|
||||
if (!effectQuiet) //If we aren't being quiet, play an open sound
|
||||
if (!effectQuiet && !openingSound && style != STYLE_SEETHROUGH) //If we aren't being quiet, play the default pod open sound
|
||||
playsound(get_turf(holder), open_sound, 15, 1, -3)
|
||||
if (broken) //If the pod is opening because it's been destroyed, we end here
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/depart, holder), departureDelay) //Finish up the pod's duties after a certain amount of time
|
||||
if (style == STYLE_SEETHROUGH)
|
||||
depart(src)
|
||||
else
|
||||
addtimer(CALLBACK(src, .proc/depart, holder), departureDelay) //Finish up the pod's duties after a certain amount of time
|
||||
|
||||
/obj/structure/closet/supplypod/proc/depart(atom/movable/holder)
|
||||
if (leavingSound)
|
||||
@@ -151,7 +180,7 @@
|
||||
if (reversing) //If we're reversing, we call the close proc. This sends the pod back up to centcom
|
||||
close(holder)
|
||||
else if (bluespace) //If we're a bluespace pod, then delete ourselves (along with our holder, if a seperate holder exists)
|
||||
if (style != STYLE_INVISIBLE)
|
||||
if (!effectQuiet && style != STYLE_INVISIBLE && style != STYLE_SEETHROUGH)
|
||||
do_sparks(5, TRUE, holder) //Create some sparks right before closing
|
||||
qdel(src) //Delete ourselves and the holder
|
||||
if (holder != src)
|
||||
@@ -164,13 +193,14 @@
|
||||
if (ismob(O) && !isliving(O)) //We dont want to take ghosts with us
|
||||
continue
|
||||
O.forceMove(holder) //Put objects inside before we close
|
||||
var/obj/effect/temp_visual/risingPod = new /obj/effect/temp_visual/DPfall(get_turf(holder), src) //Make a nice animation of flying back up
|
||||
var/obj/effect/temp_visual/risingPod = new /obj/effect/abstract/DPfall(get_turf(holder), src) //Make a nice animation of flying back up
|
||||
risingPod.pixel_z = 0 //The initial value of risingPod's pixel_z is 200 because it normally comes down from a high spot
|
||||
holder.forceMove(bay) //Move the pod back to centcom, where it belongs
|
||||
animate(risingPod, pixel_z = 200, time = 10, easing = LINEAR_EASING) //Animate our rising pod
|
||||
QDEL_IN(risingPod, 10)
|
||||
reversing = FALSE //Now that we're done reversing, we set this to false (otherwise we would get stuck in an infinite loop of calling the close proc at the bottom of open() )
|
||||
bluespace = TRUE //Make it so that the pod doesn't stay in centcom forever
|
||||
open(holder, forced = TRUE)
|
||||
return
|
||||
|
||||
/obj/structure/closet/supplypod/proc/setOpened() //Proc exists here, as well as in any atom that can assume the role of a "holder" of a supplypod. Check the open() proc for more details
|
||||
update_icon()
|
||||
@@ -179,12 +209,11 @@
|
||||
update_icon()
|
||||
|
||||
/obj/structure/closet/supplypod/Destroy()
|
||||
if (!opened) //If we havent opened yet, we're opening because we've been destroyed. Lets dump our contents by opening up
|
||||
open(src, broken = TRUE)
|
||||
return ..()
|
||||
open(src, broken = TRUE) //Lets dump our contents by opening up
|
||||
. = ..()
|
||||
|
||||
//------------------------------------FALLING SUPPLY POD-------------------------------------//
|
||||
/obj/effect/temp_visual/DPfall //Falling pod
|
||||
/obj/effect/abstract/DPfall //Falling pod
|
||||
name = ""
|
||||
icon = 'icons/obj/supplypods.dmi'
|
||||
pixel_x = -16
|
||||
@@ -192,17 +221,22 @@
|
||||
pixel_z = 200
|
||||
desc = "Get out of the way!"
|
||||
layer = FLY_LAYER//that wasnt flying, that was falling with style!
|
||||
randomdir = FALSE
|
||||
icon_state = ""
|
||||
|
||||
/obj/effect/temp_visual/DPfall/Initialize(dropLocation, obj/structure/closet/supplypod/pod)
|
||||
if (pod.style != STYLE_INVISIBLE) //Check to ensure the pod isn't invisible
|
||||
/obj/effect/abstract/DPfall/Initialize(dropLocation, obj/structure/closet/supplypod/pod)
|
||||
if (pod.style == STYLE_SEETHROUGH)
|
||||
pixel_x = -16
|
||||
pixel_y = 0
|
||||
for (var/atom/movable/O in pod.contents)
|
||||
var/icon/I = getFlatIcon(O) //im so sorry
|
||||
add_overlay(I)
|
||||
else if (pod.style != STYLE_INVISIBLE) //Check to ensure the pod isn't invisible
|
||||
icon_state = "[pod.icon_state]_falling"
|
||||
name = pod.name
|
||||
. = ..()
|
||||
|
||||
//------------------------------------TEMPORARY_VISUAL-------------------------------------//
|
||||
/obj/effect/DPtarget //This is the object that forceMoves the supplypod to it's location
|
||||
/obj/effect/abstract/DPtarget //This is the object that forceMoves the supplypod to it's location
|
||||
name = "Landing Zone Indicator"
|
||||
desc = "A holographic projection designating the landing zone of something. It's probably best to stand back."
|
||||
icon = 'icons/mob/actions/actions_items.dmi'
|
||||
@@ -212,45 +246,60 @@
|
||||
var/obj/effect/temp_visual/fallingPod //Temporary "falling pod" that we animate
|
||||
var/obj/structure/closet/supplypod/pod //The supplyPod that will be landing ontop of this target
|
||||
|
||||
/obj/effect/ex_act()
|
||||
return
|
||||
|
||||
/obj/effect/DPtarget/Initialize(mapload, podParam, var/datum/supply_order/SO = null)
|
||||
/obj/effect/abstract/DPtarget/Initialize(mapload, podParam, single_order = null)
|
||||
. = ..()
|
||||
if (ispath(podParam)) //We can pass either a path for a pod (as expressconsoles do), or a reference to an instantiated pod (as the centcom_podlauncher does)
|
||||
podParam = new podParam() //If its just a path, instantiate it
|
||||
pod = podParam
|
||||
if (SO)
|
||||
SO.generate(pod)
|
||||
for (var/mob/living/M in podParam) //If there are any mobs in the supplypod, we want to forceMove them into the target. This is so that they can see where they are about to land, AND so that they don't get sent to the nullspace error room (as the pod is currently in nullspace)
|
||||
if (single_order)
|
||||
if (istype(single_order, /datum/supply_order))
|
||||
var/datum/supply_order/SO = single_order
|
||||
SO.generate(pod)
|
||||
else if (istype(single_order, /atom/movable))
|
||||
var/atom/movable/O = single_order
|
||||
O.forceMove(pod)
|
||||
for (var/mob/living/M in pod) //If there are any mobs in the supplypod, we want to forceMove them into the target. This is so that they can see where they are about to land, AND so that they don't get sent to the nullspace error room (as the pod is currently in nullspace)
|
||||
M.forceMove(src)
|
||||
if(pod.effectStun) //If effectStun is true, stun any mobs caught on this target until the pod gets a chance to hit them
|
||||
for (var/mob/living/M in get_turf(src))
|
||||
M.Stun(pod.landingDelay+10, ignore_canstun = TRUE)//you aint goin nowhere, kid.
|
||||
if (pod.effectStealth) //If effectStealth is true we want to be invisible
|
||||
alpha = 255
|
||||
icon_state = ""
|
||||
if (pod.fallDuration == initial(pod.fallDuration) && pod.landingDelay + pod.fallDuration < pod.fallingSoundLength)
|
||||
pod.fallingSoundLength = 3 //The default falling sound is a little long, so if the landing time is shorter than the default falling sound, use a special, shorter default falling sound
|
||||
pod.fallingSound = 'sound/weapons/mortar_whistle.ogg'
|
||||
var/soundStartTime = pod.landingDelay - pod.fallingSoundLength + pod.fallDuration
|
||||
if (soundStartTime < 0)
|
||||
soundStartTime = 1
|
||||
if (!pod.effectQuiet)
|
||||
addtimer(CALLBACK(src, .proc/playFallingSound), soundStartTime)
|
||||
addtimer(CALLBACK(src, .proc/beginLaunch, pod.effectCircle), pod.landingDelay)
|
||||
|
||||
/obj/effect/DPtarget/proc/beginLaunch(effectCircle) //Begin the animation for the pod falling. The effectCircle param determines whether the pod gets to come in from any descent angle
|
||||
fallingPod = new /obj/effect/temp_visual/DPfall(drop_location(), pod)
|
||||
/obj/effect/abstract/DPtarget/proc/playFallingSound()
|
||||
playsound(src, pod.fallingSound, pod.soundVolume, 1, 6)
|
||||
|
||||
/obj/effect/abstract/DPtarget/proc/beginLaunch(effectCircle) //Begin the animation for the pod falling. The effectCircle param determines whether the pod gets to come in from any descent angle
|
||||
fallingPod = new /obj/effect/abstract/DPfall(drop_location(), pod)
|
||||
var/matrix/M = matrix(fallingPod.transform) //Create a new matrix that we can rotate
|
||||
var/angle = effectCircle ? rand(0,360) : rand(70,110) //The angle that we can come in from
|
||||
fallingPod.pixel_x = cos(angle)*200 //Use some ADVANCED MATHEMATICS to set the animated pod's position to somewhere on the edge of a circle with the center being the target
|
||||
fallingPod.pixel_z = sin(angle)*200
|
||||
fallingPod.pixel_x = cos(angle)*400 //Use some ADVANCED MATHEMATICS to set the animated pod's position to somewhere on the edge of a circle with the center being the target
|
||||
fallingPod.pixel_z = sin(angle)*400
|
||||
var/rotation = Get_Pixel_Angle(fallingPod.pixel_z, fallingPod.pixel_x) //CUSTOM HOMEBREWED proc that is just arctan with extra steps
|
||||
M.Turn(rotation) //Turn our matrix accordingly
|
||||
fallingPod.transform = M //Transform the animated pod according to the matrix
|
||||
M = matrix(pod.transform) //Make another matrix based on the pod
|
||||
M.Turn(rotation) //Turn the matrix
|
||||
pod.transform = M //Turn the actual pod (Won't be visible until endLaunch() proc tho)
|
||||
animate(fallingPod, pixel_z = 0, pixel_x = -16, time = 3, , easing = LINEAR_EASING) //Make the pod fall! At an angle!
|
||||
addtimer(CALLBACK(src, .proc/endLaunch), 3, TIMER_CLIENT_TIME) //Go onto the last step after a very short falling animation
|
||||
animate(fallingPod, pixel_z = 0, pixel_x = -16, time = pod.fallDuration, , easing = LINEAR_EASING) //Make the pod fall! At an angle!
|
||||
addtimer(CALLBACK(src, .proc/endLaunch), pod.fallDuration, TIMER_CLIENT_TIME) //Go onto the last step after a very short falling animation
|
||||
|
||||
/obj/effect/DPtarget/proc/endLaunch()
|
||||
/obj/effect/abstract/DPtarget/proc/endLaunch()
|
||||
pod.update_icon()
|
||||
pod.forceMove(drop_location()) //The fallingPod animation is over, now's a good time to forceMove the actual pod into position
|
||||
QDEL_NULL(fallingPod) //Delete the falling pod effect, because at this point its animation is over. We dont use temp_visual because we want to manually delete it as soon as the pod appears
|
||||
for (var/mob/living/M in src) //Remember earlier (initialization) when we moved mobs into the DPTarget so they wouldnt get lost in nullspace? Time to get them out
|
||||
M.forceMove(pod)
|
||||
pod.preOpen() //Begin supplypod open procedures. Here effects like explosions, damage, and other dangerous (and potentially admin-caused, if the centcom_podlauncher datum was used) memes will take place
|
||||
QDEL_NULL(fallingPod) //The fallingPod's (the animated effect, not the actual pod) purpose is complete. It can rest easy now
|
||||
qdel(src) //ditto
|
||||
|
||||
//------------------------------------UPGRADES-------------------------------------//
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
icon_state = "chef"
|
||||
item_state = "chef"
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/chef
|
||||
|
||||
/obj/item/clothing/head/collectable/paper
|
||||
|
||||
@@ -113,10 +113,8 @@
|
||||
desc = "Wearing these makes you look useless, and only good for your sex appeal."
|
||||
icon_state = "bunny"
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/rabbit
|
||||
|
||||
|
||||
/obj/item/clothing/head/flatcap
|
||||
name = "flat cap"
|
||||
desc = "A working man's cap."
|
||||
@@ -205,7 +203,6 @@
|
||||
item_state = "sombrero"
|
||||
desc = "You can practically taste the fiesta."
|
||||
flags_inv = HIDEHAIR
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/sombrero
|
||||
|
||||
/obj/item/clothing/head/sombrero/green
|
||||
@@ -369,3 +366,17 @@
|
||||
item_state = "assu_helmet"
|
||||
desc = "A cheap replica of old riot helmet without visor. It has \"D.A.B.\" written on the front."
|
||||
flags_inv = HIDEHAIR
|
||||
|
||||
/obj/item/clothing/head/hotel
|
||||
name = "Telegram cap"
|
||||
desc = "A bright red cap warn by hotel staff. Or people who want to be a singing telegram"
|
||||
icon_state = "telegramhat"
|
||||
item_color = "telegramhat"
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/colour
|
||||
name = "Singer cap"
|
||||
desc = "A light white hat that has bands of color. Just makes you want to sing and dance!"
|
||||
icon_state = "colour"
|
||||
item_color = "colour"
|
||||
dog_fashion = /datum/dog_fashion/head/colour
|
||||
@@ -139,4 +139,4 @@
|
||||
flags_inv = HIDEEYES|HIDEFACE
|
||||
armor = list("melee" = 35, "bullet" = 35, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 90)
|
||||
strip_delay = 90 //You dont take a Major Leage cap
|
||||
dog_fashion = null
|
||||
dog_fashion = null
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/proc/display_visor_message(var/msg)
|
||||
var/mob/wearer = loc
|
||||
if(msg && ishuman(wearer))
|
||||
wearer.show_message("[icon2html(src, wearer)]<b><span class='robot'>[msg]</span></b>", 1)
|
||||
wearer.show_message("[icon2html(src, wearer)]<b><span class='robot'>[msg]</span></b>", MSG_VISUAL)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/rad_act(severity)
|
||||
. = ..()
|
||||
|
||||
@@ -505,6 +505,21 @@
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
flags_inv = HIDEHAIR|HIDEEARS
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/centcom
|
||||
name = "centcom winter coat"
|
||||
icon_state = "coatcentcom"
|
||||
item_state = "coatcentcom"
|
||||
armor = list("melee" = 40, "bullet" = 45, "laser" = 45, "energy" = 35, "bomb" = 40, "bio" = 25, "rad" = 25, "fire" = 35, "acid" = 50)
|
||||
hoodtype = /obj/item/clothing/head/hooded/winterhood/centcom
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/centcom/Initialize()
|
||||
. = ..()
|
||||
allowed = GLOB.security_wintercoat_allowed
|
||||
|
||||
/obj/item/clothing/head/hooded/winterhood/centcom
|
||||
icon_state = "winterhood_centcom"
|
||||
armor = list("melee" = 40, "bullet" = 45, "laser" = 45, "energy" = 35, "bomb" = 40, "bio" = 25, "rad" = 25, "fire" = 35, "acid" = 50)
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/captain
|
||||
name = "captain's winter coat"
|
||||
icon_state = "coatcaptain"
|
||||
@@ -723,6 +738,15 @@
|
||||
/obj/item/clothing/head/hooded/winterhood/qm
|
||||
icon_state = "winterhood_qm"
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/aformal
|
||||
name = "assistant's formal winter coat"
|
||||
icon_state = "coataformal"
|
||||
item_state = "coataformal"
|
||||
hoodtype = /obj/item/clothing/head/hooded/winterhood/aformal
|
||||
|
||||
/obj/item/clothing/head/hooded/winterhood/aformal
|
||||
icon_state = "winterhood_aformal"
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/miner
|
||||
name = "mining winter coat"
|
||||
icon_state = "coatminer"
|
||||
@@ -734,6 +758,27 @@
|
||||
/obj/item/clothing/head/hooded/winterhood/miner
|
||||
icon_state = "winterhood_miner"
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/ratvar
|
||||
name = "ratvarian winter coat"
|
||||
icon_state = "coatratvar"
|
||||
item_state = "coatratvar"
|
||||
hoodtype = /obj/item/clothing/head/hooded/winterhood/ratvar
|
||||
|
||||
/obj/item/clothing/head/hooded/winterhood/ratvar
|
||||
icon_state = "winterhood_ratvar"
|
||||
light_range = 3
|
||||
light_power = 1
|
||||
light_color = "#B18B25" //clockwork slab background top color
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/narsie
|
||||
name = "narsian winter coat"
|
||||
icon_state = "coatnarsie"
|
||||
item_state = "coatnarsie"
|
||||
hoodtype = /obj/item/clothing/head/hooded/winterhood/narsie
|
||||
|
||||
/obj/item/clothing/head/hooded/winterhood/narsie
|
||||
icon_state = "winterhood_narsie"
|
||||
|
||||
/obj/item/clothing/suit/spookyghost
|
||||
name = "spooky ghost"
|
||||
desc = "This is obviously just a bedsheet, but maybe try it on?"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
item_color = "red_pyjamas"
|
||||
item_state = "w_suit"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/pj/blue
|
||||
name = "blue pj's"
|
||||
desc = "Sleepwear."
|
||||
@@ -12,6 +13,7 @@
|
||||
item_color = "blue_pyjamas"
|
||||
item_state = "w_suit"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/patriotsuit
|
||||
name = "Patriotic Suit"
|
||||
desc = "Motorcycle not included."
|
||||
@@ -19,6 +21,7 @@
|
||||
item_state = "ek"
|
||||
item_color = "ek"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/scratch
|
||||
name = "white suit"
|
||||
desc = "A white suit, suitable for an excellent host."
|
||||
@@ -43,6 +46,7 @@
|
||||
icon_state = "sl_suit"
|
||||
item_color = "sl_suit"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/roman
|
||||
name = "\improper Roman armor"
|
||||
desc = "Ancient Roman armor. Made of metallic and leather straps."
|
||||
@@ -52,6 +56,7 @@
|
||||
can_adjust = FALSE
|
||||
strip_delay = 100
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/clothing/under/waiter
|
||||
name = "waiter's outfit"
|
||||
desc = "It's a very smart uniform with a special pocket for tip."
|
||||
@@ -59,6 +64,7 @@
|
||||
item_state = "waiter"
|
||||
item_color = "waiter"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/rank/prisoner
|
||||
name = "prison jumpsuit"
|
||||
desc = "It's standardised Nanotrasen prisoner-wear. Its suit sensors are stuck in the \"Fully On\" position."
|
||||
@@ -85,12 +91,14 @@
|
||||
icon_state = "mailman"
|
||||
item_state = "b_suit"
|
||||
item_color = "mailman"
|
||||
|
||||
/obj/item/clothing/under/rank/psyche
|
||||
name = "psychedelic jumpsuit"
|
||||
desc = "Groovy!"
|
||||
icon_state = "psyche"
|
||||
item_state = "p_suit"
|
||||
item_color = "psyche"
|
||||
|
||||
/obj/item/clothing/under/rank/clown/sexy
|
||||
name = "sexy-clown suit"
|
||||
desc = "It makes you look HONKable!"
|
||||
@@ -98,6 +106,7 @@
|
||||
item_state = "sexyclown"
|
||||
item_color = "sexyclown"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/jabroni
|
||||
name = "Jabroni Outfit"
|
||||
desc = "The leather club is two sectors down."
|
||||
@@ -105,6 +114,7 @@
|
||||
item_state = "darkholme"
|
||||
item_color = "darkholme"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/rank/vice
|
||||
name = "vice officer's jumpsuit"
|
||||
desc = "It's the standard issue pretty-boy outfit, as seen on Holo-Vision."
|
||||
@@ -112,6 +122,7 @@
|
||||
item_state = "gy_suit"
|
||||
item_color = "vice"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/rank/centcom_officer
|
||||
desc = "It's a jumpsuit worn by CentCom Officers."
|
||||
name = "\improper CentCom officer's jumpsuit"
|
||||
@@ -119,12 +130,14 @@
|
||||
item_state = "g_suit"
|
||||
item_color = "officer"
|
||||
alt_covers_chest = TRUE
|
||||
|
||||
/obj/item/clothing/under/rank/centcom_commander
|
||||
desc = "It's a jumpsuit worn by CentCom's highest-tier Commanders."
|
||||
name = "\improper CentCom officer's jumpsuit"
|
||||
icon_state = "centcom"
|
||||
item_state = "dg_suit"
|
||||
item_color = "centcom"
|
||||
|
||||
/obj/item/clothing/under/space
|
||||
name = "\improper NASA jumpsuit"
|
||||
desc = "It has a NASA logo on it and is made of space-proofed materials."
|
||||
@@ -141,6 +154,7 @@
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
|
||||
can_adjust = FALSE
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/clothing/under/acj
|
||||
name = "administrative cybernetic jumpsuit"
|
||||
icon_state = "syndicate"
|
||||
@@ -157,24 +171,28 @@
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
|
||||
can_adjust = FALSE
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/clothing/under/owl
|
||||
name = "owl uniform"
|
||||
desc = "A soft brown jumpsuit made of synthetic feathers and strong conviction."
|
||||
icon_state = "owl"
|
||||
item_color = "owl"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/griffin
|
||||
name = "griffon uniform"
|
||||
desc = "A soft brown jumpsuit with a white feather collar made of synthetic feathers and a lust for mayhem."
|
||||
icon_state = "griffin"
|
||||
item_color = "griffin"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/cloud
|
||||
name = "cloud"
|
||||
desc = "cloud"
|
||||
icon_state = "cloud"
|
||||
item_color = "cloud"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/gimmick/rank/captain/suit
|
||||
name = "captain's suit"
|
||||
desc = "A green suit and yellow necktie. Exemplifies authority."
|
||||
@@ -218,18 +236,21 @@
|
||||
item_state = "bl_suit"
|
||||
item_color = "black_suit"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/suit_jacket/really_black
|
||||
name = "executive suit"
|
||||
desc = "A formal black suit and red tie, intended for the station's finest."
|
||||
icon_state = "really_black_suit"
|
||||
item_state = "bl_suit"
|
||||
item_color = "really_black_suit"
|
||||
|
||||
/obj/item/clothing/under/suit_jacket/female
|
||||
name = "executive suit"
|
||||
desc = "A formal trouser suit for women, intended for the station's finest."
|
||||
icon_state = "black_suit_fem"
|
||||
item_state = "black_suit_fem"
|
||||
item_color = "black_suit_fem"
|
||||
|
||||
/obj/item/clothing/under/suit_jacket/green
|
||||
name = "green suit"
|
||||
desc = "A green suit and yellow necktie. Baller."
|
||||
@@ -237,48 +258,56 @@
|
||||
item_state = "dg_suit"
|
||||
item_color = "green_suit"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/suit_jacket/red
|
||||
name = "red suit"
|
||||
desc = "A red suit and blue tie. Somewhat formal."
|
||||
icon_state = "red_suit"
|
||||
item_state = "r_suit"
|
||||
item_color = "red_suit"
|
||||
|
||||
/obj/item/clothing/under/suit_jacket/charcoal
|
||||
name = "charcoal suit"
|
||||
desc = "A charcoal suit and red tie. Very professional."
|
||||
icon_state = "charcoal_suit"
|
||||
item_state = "charcoal_suit"
|
||||
item_color = "charcoal_suit"
|
||||
|
||||
/obj/item/clothing/under/suit_jacket/navy
|
||||
name = "navy suit"
|
||||
desc = "A navy suit and red tie, intended for the station's finest."
|
||||
icon_state = "navy_suit"
|
||||
item_state = "navy_suit"
|
||||
item_color = "navy_suit"
|
||||
|
||||
/obj/item/clothing/under/suit_jacket/burgundy
|
||||
name = "burgundy suit"
|
||||
desc = "A burgundy suit and black tie. Somewhat formal."
|
||||
icon_state = "burgundy_suit"
|
||||
item_state = "burgundy_suit"
|
||||
item_color = "burgundy_suit"
|
||||
|
||||
/obj/item/clothing/under/suit_jacket/checkered
|
||||
name = "checkered suit"
|
||||
desc = "That's a very nice suit you have there. Shame if something were to happen to it, eh?"
|
||||
icon_state = "checkered_suit"
|
||||
item_state = "checkered_suit"
|
||||
item_color = "checkered_suit"
|
||||
|
||||
/obj/item/clothing/under/suit_jacket/tan
|
||||
name = "tan suit"
|
||||
desc = "A tan suit with a yellow tie. Smart, but casual."
|
||||
icon_state = "tan_suit"
|
||||
item_state = "tan_suit"
|
||||
item_color = "tan_suit"
|
||||
|
||||
/obj/item/clothing/under/suit_jacket/white
|
||||
name = "white suit"
|
||||
desc = "A white suit and jacket with a blue shirt. You wanna play rough? OKAY!"
|
||||
icon_state = "white_suit"
|
||||
item_state = "white_suit"
|
||||
item_color = "white_suit"
|
||||
|
||||
/obj/item/clothing/under/burial
|
||||
name = "burial garments"
|
||||
desc = "Traditional burial garments from the early 22nd century."
|
||||
@@ -286,6 +315,7 @@
|
||||
item_state = "burial"
|
||||
item_color = "burial"
|
||||
has_sensor = NO_SENSORS
|
||||
|
||||
/obj/item/clothing/under/skirt/black
|
||||
name = "black skirt"
|
||||
desc = "A black skirt, very fancy!"
|
||||
@@ -294,6 +324,7 @@
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/skirt/blue
|
||||
name = "blue skirt"
|
||||
desc = "A blue, casual skirt."
|
||||
@@ -303,6 +334,7 @@
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/skirt/red
|
||||
name = "red skirt"
|
||||
desc = "A red, casual skirt."
|
||||
@@ -312,6 +344,7 @@
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/skirt/purple
|
||||
name = "purple skirt"
|
||||
desc = "A purple, casual skirt."
|
||||
@@ -321,6 +354,7 @@
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/schoolgirl
|
||||
name = "blue schoolgirl uniform"
|
||||
desc = "It's just like one of my Japanese animes!"
|
||||
@@ -330,21 +364,25 @@
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/schoolgirl/red
|
||||
name = "red schoolgirl uniform"
|
||||
icon_state = "schoolgirlred"
|
||||
item_state = "schoolgirlred"
|
||||
item_color = "schoolgirlred"
|
||||
|
||||
/obj/item/clothing/under/schoolgirl/green
|
||||
name = "green schoolgirl uniform"
|
||||
icon_state = "schoolgirlgreen"
|
||||
item_state = "schoolgirlgreen"
|
||||
item_color = "schoolgirlgreen"
|
||||
|
||||
/obj/item/clothing/under/schoolgirl/orange
|
||||
name = "orange schoolgirl uniform"
|
||||
icon_state = "schoolgirlorange"
|
||||
item_state = "schoolgirlorange"
|
||||
item_color = "schoolgirlorange"
|
||||
|
||||
/obj/item/clothing/under/overalls
|
||||
name = "laborer's overalls"
|
||||
desc = "A set of durable overalls for getting the job done."
|
||||
@@ -352,6 +390,7 @@
|
||||
item_state = "lb_suit"
|
||||
item_color = "overalls"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/pirate
|
||||
name = "pirate outfit"
|
||||
desc = "Yarr."
|
||||
@@ -359,6 +398,7 @@
|
||||
item_state = "pirate"
|
||||
item_color = "pirate"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/soviet
|
||||
name = "soviet uniform"
|
||||
desc = "For the Motherland!"
|
||||
@@ -366,6 +406,7 @@
|
||||
item_state = "soviet"
|
||||
item_color = "soviet"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/redcoat
|
||||
name = "redcoat uniform"
|
||||
desc = "Looks old."
|
||||
@@ -373,6 +414,7 @@
|
||||
item_state = "redcoat"
|
||||
item_color = "redcoat"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/kilt
|
||||
name = "kilt"
|
||||
desc = "Includes shoes and plaid."
|
||||
@@ -382,6 +424,7 @@
|
||||
body_parts_covered = CHEST|GROIN|LEGS|FEET
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/kilt/highlander
|
||||
desc = "You're the only one worthy of this kilt."
|
||||
|
||||
@@ -398,6 +441,7 @@
|
||||
body_parts_covered = CHEST|GROIN|LEGS
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/gladiator
|
||||
name = "gladiator uniform"
|
||||
desc = "Are you not entertained? Is that not why you are here?"
|
||||
@@ -408,9 +452,11 @@
|
||||
fitted = NO_FEMALE_UNIFORM
|
||||
can_adjust = FALSE
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/clothing/under/gladiator/ash_walker
|
||||
desc = "This gladiator uniform appears to be covered in ash and fairly dated."
|
||||
has_sensor = NO_SENSORS
|
||||
|
||||
/obj/item/clothing/under/sundress
|
||||
name = "sundress"
|
||||
desc = "Makes you want to frolic in a field of daisies."
|
||||
@@ -420,6 +466,7 @@
|
||||
body_parts_covered = CHEST|GROIN
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/captainparade
|
||||
name = "captain's parade uniform"
|
||||
desc = "A captain's luxury-wear, for special occasions."
|
||||
@@ -427,6 +474,7 @@
|
||||
item_state = "by_suit"
|
||||
item_color = "captain_parade"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/hosparademale
|
||||
name = "head of security's parade uniform"
|
||||
desc = "A male head of security's luxury-wear, for special occasions."
|
||||
@@ -434,6 +482,7 @@
|
||||
item_state = "r_suit"
|
||||
item_color = "hos_parade_male"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/hosparadefem
|
||||
name = "head of security's parade uniform"
|
||||
desc = "A female head of security's luxury-wear, for special occasions."
|
||||
@@ -442,6 +491,7 @@
|
||||
item_color = "hos_parade_fem"
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/assistantformal
|
||||
name = "assistant's formal uniform"
|
||||
desc = "An assistant's formal-wear. Why an assistant needs formal-wear is still unknown."
|
||||
@@ -449,6 +499,7 @@
|
||||
item_state = "gy_suit"
|
||||
item_color = "assistant_formal"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/blacktango
|
||||
name = "black tango dress"
|
||||
desc = "Filled with Latin fire."
|
||||
@@ -457,6 +508,7 @@
|
||||
item_color = "black_tango"
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/stripeddress
|
||||
name = "striped dress"
|
||||
desc = "Fashion in space."
|
||||
@@ -466,6 +518,7 @@
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
fitted = FEMALE_UNIFORM_FULL
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/sailordress
|
||||
name = "sailor dress"
|
||||
desc = "Formal wear for a leading lady."
|
||||
@@ -475,6 +528,7 @@
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/redeveninggown
|
||||
name = "red evening gown"
|
||||
desc = "Fancy dress for space bar singers."
|
||||
@@ -483,6 +537,7 @@
|
||||
item_color = "red_evening_gown"
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/maid
|
||||
name = "maid costume"
|
||||
desc = "Maid in China."
|
||||
@@ -492,10 +547,12 @@
|
||||
body_parts_covered = CHEST|GROIN
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/maid/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/clothing/accessory/maidapron/A = new (src)
|
||||
attach_accessory(A)
|
||||
|
||||
/obj/item/clothing/under/janimaid
|
||||
name = "maid uniform"
|
||||
desc = "A simple maid uniform for housekeeping."
|
||||
@@ -505,6 +562,7 @@
|
||||
body_parts_covered = CHEST|GROIN
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/plaid_skirt
|
||||
name = "red plaid skirt"
|
||||
desc = "A preppy red skirt with a white blouse."
|
||||
@@ -514,6 +572,7 @@
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = TRUE
|
||||
alt_covers_chest = TRUE
|
||||
|
||||
/obj/item/clothing/under/plaid_skirt/blue
|
||||
name = "blue plaid skirt"
|
||||
desc = "A preppy blue skirt with a white blouse."
|
||||
@@ -523,6 +582,7 @@
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = TRUE
|
||||
alt_covers_chest = TRUE
|
||||
|
||||
/obj/item/clothing/under/plaid_skirt/purple
|
||||
name = "purple plaid skirt"
|
||||
desc = "A preppy purple skirt with a white blouse."
|
||||
@@ -532,6 +592,7 @@
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = TRUE
|
||||
alt_covers_chest = TRUE
|
||||
|
||||
/obj/item/clothing/under/singery
|
||||
name = "yellow performer's outfit"
|
||||
desc = "Just looking at this makes you want to sing."
|
||||
@@ -542,6 +603,7 @@
|
||||
fitted = NO_FEMALE_UNIFORM
|
||||
alternate_worn_layer = ABOVE_SHOES_LAYER
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/singerb
|
||||
name = "blue performer's outfit"
|
||||
desc = "Just looking at this makes you want to sing."
|
||||
@@ -552,6 +614,7 @@
|
||||
alternate_worn_layer = ABOVE_SHOES_LAYER
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/plaid_skirt/green
|
||||
name = "green plaid skirt"
|
||||
desc = "A preppy green skirt with a white blouse."
|
||||
@@ -561,14 +624,17 @@
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = TRUE
|
||||
alt_covers_chest = TRUE
|
||||
|
||||
/obj/item/clothing/under/jester
|
||||
name = "jester suit"
|
||||
desc = "A jolly dress, well suited to entertain your master, nuncle."
|
||||
icon_state = "jester"
|
||||
item_color = "jester"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/jester/alt
|
||||
icon_state = "jester2"
|
||||
|
||||
/obj/item/clothing/under/geisha
|
||||
name = "geisha suit"
|
||||
desc = "Cute space ninja senpai not included."
|
||||
@@ -576,12 +642,14 @@
|
||||
item_color = "geisha"
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/villain
|
||||
name = "villain suit"
|
||||
desc = "A change of wardrobe is necessary if you ever want to catch a real superhero."
|
||||
icon_state = "villain"
|
||||
item_color = "villain"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/sailor
|
||||
name = "sailor suit"
|
||||
desc = "Skipper's in the wardroom drinkin gin'."
|
||||
@@ -650,6 +718,7 @@
|
||||
icon_state = "hostanclothes"
|
||||
item_state = "hostanclothes"
|
||||
item_color = "hostanclothes"
|
||||
|
||||
/obj/item/clothing/under/mummy
|
||||
name = "mummy wrapping"
|
||||
desc = "Return the slab or suffer my stale references."
|
||||
@@ -660,6 +729,7 @@
|
||||
fitted = NO_FEMALE_UNIFORM
|
||||
can_adjust = FALSE
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/clothing/under/scarecrow
|
||||
name = "scarecrow clothes"
|
||||
desc = "Perfect camouflage for hiding in botany."
|
||||
@@ -670,6 +740,7 @@
|
||||
fitted = NO_FEMALE_UNIFORM
|
||||
can_adjust = FALSE
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/clothing/under/draculass
|
||||
name = "draculass coat"
|
||||
desc = "A dress inspired by the ancient \"Victorian\" era."
|
||||
@@ -679,6 +750,7 @@
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/drfreeze
|
||||
name = "doctor freeze's jumpsuit"
|
||||
desc = "A modified scientist jumpsuit to look extra cool."
|
||||
@@ -686,6 +758,7 @@
|
||||
item_state = "drfreeze"
|
||||
item_color = "drfreeze"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/lobster
|
||||
name = "foam lobster suit"
|
||||
desc = "Who beheaded the college mascot?"
|
||||
@@ -694,6 +767,7 @@
|
||||
item_color = "lobster"
|
||||
fitted = NO_FEMALE_UNIFORM
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/gondola
|
||||
name = "gondola hide suit"
|
||||
desc = "Now you're cooking."
|
||||
@@ -701,6 +775,7 @@
|
||||
item_state = "lb_suit"
|
||||
item_color = "gondola"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/skeleton
|
||||
name = "skeleton jumpsuit"
|
||||
desc = "A black jumpsuit with a white bone pattern printed on it. Spooky!"
|
||||
@@ -720,6 +795,14 @@
|
||||
body_parts_covered = CHEST|GROIN
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/telegram
|
||||
name = "telegram suit"
|
||||
desc = "Bright and red, hard to miss. Mostly warn by hotel staff or singing telegram."
|
||||
icon_state = "telegram"
|
||||
item_state = "telegram"
|
||||
body_parts_covered = CHEST|GROIN
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/durathread
|
||||
name = "durathread jumpsuit"
|
||||
desc = "A jumpsuit made from durathread, its resilient fibres provide some protection to the wearer."
|
||||
|
||||
@@ -45,6 +45,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
throwforce = 100
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
|
||||
var/mob/living/wizard
|
||||
var/z_original = 0
|
||||
var/destination
|
||||
@@ -100,9 +101,6 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
/obj/effect/immovablerod/ex_act(severity, target)
|
||||
return 0
|
||||
|
||||
/obj/structure/closet/supplypod/prevent_content_explosion()
|
||||
return TRUE
|
||||
|
||||
/obj/effect/immovablerod/singularity_act()
|
||||
return
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
/datum/round_event/meteor_wave/setup()
|
||||
announceWhen = 1
|
||||
startWhen = rand(180, 360) //Yeah for SOME REASON this is measured in seconds and not deciseconds???
|
||||
startWhen = rand(60, 90) //Yeah for SOME REASON this is measured in seconds and not deciseconds???
|
||||
if(GLOB.singularity_counter)
|
||||
startWhen *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE)
|
||||
endWhen = startWhen + 60
|
||||
|
||||
@@ -21,7 +21,8 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
/datum/hallucination/delusion = 2,
|
||||
/datum/hallucination/shock = 1,
|
||||
/datum/hallucination/death = 1,
|
||||
/datum/hallucination/oh_yeah = 1
|
||||
/datum/hallucination/oh_yeah = 1,
|
||||
/datum/hallucination/sleeping_carp = 1
|
||||
))
|
||||
|
||||
|
||||
@@ -1294,3 +1295,26 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
H.preparePixelProjectile(target, start)
|
||||
H.fire()
|
||||
qdel(src)
|
||||
|
||||
/datum/hallucination/sleeping_carp
|
||||
|
||||
/datum/hallucination/sleeping_carp/New(mob/living/carbon/C, forced = TRUE)
|
||||
set waitfor = FALSE
|
||||
..()
|
||||
var/list/mobsyup
|
||||
for (var/mob/living/carbon/A in orange(C,1))
|
||||
if (get_dist(C,A) < 2)
|
||||
LAZYADD(mobsyup,A)
|
||||
if (!LAZYLEN(mobsyup))
|
||||
qdel(src)
|
||||
return
|
||||
var/mob/living/carbon/G = pick(mobsyup)
|
||||
if (prob(50))
|
||||
C.visible_message("<span class='warning'>[C] falls to the ground screaming and clutching [C.p_their()] wrist!</span>", \
|
||||
"<span class='userdanger'>[G] grabs your wrist and violently wrenches it to the side!</span>")
|
||||
C.emote("scream")
|
||||
C.dropItemToGround(C.get_active_held_item())
|
||||
C.Knockdown(60)
|
||||
else
|
||||
to_chat(C,"<span class='userdanger'>[G] violently grabs you!</span>")
|
||||
qdel(src)
|
||||
|
||||
@@ -319,13 +319,13 @@ All foods are distributed among various categories. Use common sense.
|
||||
if(iscorgi(M))
|
||||
var/mob/living/L = M
|
||||
if(bitecount == 0 || prob(50))
|
||||
M.emote("me", 1, "nibbles away at \the [src]")
|
||||
M.emote("me", EMOTE_VISIBLE, "nibbles away at \the [src]")
|
||||
bitecount++
|
||||
L.taste(reagents) // why should carbons get all the fun?
|
||||
if(bitecount >= 5)
|
||||
var/sattisfaction_text = pick("burps from enjoyment", "yaps for more", "woofs twice", "looks at the area where \the [src] was")
|
||||
if(sattisfaction_text)
|
||||
M.emote("me", 1, "[sattisfaction_text]")
|
||||
M.emote("me", EMOTE_VISIBLE, "[sattisfaction_text]")
|
||||
qdel(src)
|
||||
|
||||
// //////////////////////////////////////////////Store////////////////////////////////////////
|
||||
|
||||
@@ -252,12 +252,11 @@
|
||||
// Spooky Uplink Items //
|
||||
/////////////////////////
|
||||
|
||||
/datum/uplink_item/dangerous/crossbow/candy
|
||||
/datum/uplink_item/stealthy_weapons/crossbow/candy
|
||||
name = "Candy Corn Crossbow"
|
||||
desc = "A standard miniature energy crossbow that uses a hard-light projector to transform bolts into candy corn. Happy Halloween!"
|
||||
category = "Holiday"
|
||||
item = /obj/item/gun/energy/kinetic_accelerator/crossbow/halloween
|
||||
cost = 12
|
||||
surplus = 0
|
||||
|
||||
/datum/uplink_item/device_tools/emag/hack_o_lantern
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
var/cotton_name = "raw cotton"
|
||||
|
||||
/obj/item/grown/cotton/attack_self(mob/user)
|
||||
user.show_message("<span class='notice'>You pull some [cotton_name] out of the [name]!</span>", 1)
|
||||
user.show_message("<span class='notice'>You pull some [cotton_name] out of the [name]!</span>", MSG_VISUAL)
|
||||
var/seed_modifier = 0
|
||||
if(seed)
|
||||
seed_modifier = round(seed.potency / 25)
|
||||
|
||||
@@ -56,11 +56,41 @@
|
||||
/obj/item/reagent_containers/food/snacks/grown/grass/fairy
|
||||
seed = /obj/item/seeds/grass/fairy
|
||||
name = "fairygrass"
|
||||
desc = "Blue, glowing, and smells fainly of mushrooms."
|
||||
desc = "Glowing, and smells fainly of mushrooms."
|
||||
icon_state = "fairygrassclump"
|
||||
filling_color = "#3399ff"
|
||||
stacktype = /obj/item/stack/tile/fairygrass
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/grass/fairy/attack_self(mob/user)
|
||||
var/datum/plant_gene/trait/glow/G = null
|
||||
for(var/datum/plant_gene/trait/glow/gene in seed.genes)
|
||||
G = gene
|
||||
break
|
||||
|
||||
stacktype = initial(stacktype)
|
||||
|
||||
if(G)
|
||||
switch(G.type)
|
||||
if(/datum/plant_gene/trait/glow/white)
|
||||
stacktype = /obj/item/stack/tile/fairygrass/white
|
||||
if(/datum/plant_gene/trait/glow/red)
|
||||
stacktype = /obj/item/stack/tile/fairygrass/red
|
||||
if(/datum/plant_gene/trait/glow/yellow)
|
||||
stacktype = /obj/item/stack/tile/fairygrass/yellow
|
||||
if(/datum/plant_gene/trait/glow/green)
|
||||
stacktype = /obj/item/stack/tile/fairygrass/green
|
||||
if(/datum/plant_gene/trait/glow/blue)
|
||||
stacktype = /obj/item/stack/tile/fairygrass/blue
|
||||
if(/datum/plant_gene/trait/glow/purple)
|
||||
stacktype = /obj/item/stack/tile/fairygrass/purple
|
||||
if(/datum/plant_gene/trait/glow/pink)
|
||||
stacktype = /obj/item/stack/tile/fairygrass/pink
|
||||
|
||||
. = ..()
|
||||
|
||||
|
||||
|
||||
|
||||
// Carpet
|
||||
/obj/item/seeds/grass/carpet
|
||||
name = "pack of carpet seeds"
|
||||
|
||||
@@ -226,9 +226,12 @@
|
||||
/obj/item/reagent_containers/food/snacks/grown/cherry_bomb/proc/prime()
|
||||
icon_state = "cherry_bomb_lit"
|
||||
playsound(src, 'sound/effects/fuse.ogg', seed.potency, 0)
|
||||
addtimer(CALLBACK(src, /obj/item/reagent_containers/food/snacks/grown/cherry_bomb/proc/detonate), rand(50, 100))
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/cherry_bomb/proc/detonate()
|
||||
reagents.chem_temp = 1000 //Sets off the black powder
|
||||
reagents.handle_reactions()
|
||||
|
||||
|
||||
// Lavaland cactus
|
||||
|
||||
/obj/item/seeds/lavaland/cactus
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
if(W.get_sharpness())
|
||||
user.show_message("<span class='notice'>You carve a face into [src]!</span>", 1)
|
||||
user.show_message("<span class='notice'>You carve a face into [src]!</span>", MSG_VISUAL)
|
||||
new /obj/item/clothing/head/hardhat/pumpkinhead(user.loc)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
/obj/item/grown/log/attackby(obj/item/W, mob/user, params)
|
||||
if(W.sharpness)
|
||||
user.show_message("<span class='notice'>You make [plank_name] out of \the [src]!</span>", 1)
|
||||
user.show_message("<span class='notice'>You make [plank_name] out of \the [src]!</span>", MSG_VISUAL)
|
||||
var/seed_modifier = 0
|
||||
if(seed)
|
||||
seed_modifier = round(seed.potency / 25)
|
||||
|
||||
@@ -299,7 +299,7 @@
|
||||
rate = 0.04
|
||||
glow_color = "#AAD84B"
|
||||
|
||||
datum/plant_gene/trait/glow/white
|
||||
/datum/plant_gene/trait/glow/white
|
||||
name = "White Bioluminescence"
|
||||
glow_color = "#FFFFFF"
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
/* CIT CHANGE - Pffffffffffffhahahahahhaha-- No.
|
||||
//aliens are immune to stamina damage.
|
||||
/mob/living/carbon/alien/adjustStaminaLoss(amount, updating_stamina = 1)
|
||||
/mob/living/carbon/alien/adjustStaminaLoss(amount, updating_health = 1)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/setStaminaLoss(amount, updating_stamina = 1)
|
||||
/mob/living/carbon/alien/setStaminaLoss(amount, updating_health = 1)
|
||||
return
|
||||
*/
|
||||
|
||||
@@ -1043,6 +1043,21 @@
|
||||
/mob/living/carbon/human/species/golem/plastic
|
||||
race = /datum/species/golem/plastic
|
||||
|
||||
/mob/living/carbon/human/species/golem/bronze
|
||||
race = /datum/species/golem/bronze
|
||||
|
||||
/mob/living/carbon/human/species/golem/cardboard
|
||||
race = /datum/species/golem/cardboard
|
||||
|
||||
/mob/living/carbon/human/species/golem/leather
|
||||
race = /datum/species/golem/leather
|
||||
|
||||
/mob/living/carbon/human/species/golem/bone
|
||||
race = /datum/species/golem/bone
|
||||
|
||||
/mob/living/carbon/human/species/golem/durathread
|
||||
race = /datum/species/golem/durathread
|
||||
|
||||
/mob/living/carbon/human/species/golem/clockwork
|
||||
race = /datum/species/golem/clockwork
|
||||
|
||||
|
||||
@@ -661,6 +661,12 @@
|
||||
|
||||
if(health >= 0)
|
||||
if(src == M)
|
||||
if(has_status_effect(STATUS_EFFECT_CHOKINGSTRAND))
|
||||
to_chat(src, "<span class='notice'>You attempt to remove the durathread strand from around your neck.</span>")
|
||||
if(do_after(src, 35, null, src))
|
||||
to_chat(src, "<span class='notice'>You succesfuly remove the durathread strand.</span>")
|
||||
remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND)
|
||||
return
|
||||
var/to_send = ""
|
||||
visible_message("[src] examines [p_them()]self.", \
|
||||
"<span class='notice'>You check yourself for injuries.</span>")
|
||||
|
||||
@@ -1537,6 +1537,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
target.lastattacker = user.real_name
|
||||
target.lastattackerckey = user.ckey
|
||||
user.dna.species.spec_unarmedattacked(user, target)
|
||||
|
||||
if(user.limb_destroyer)
|
||||
target.dismembering_strike(user, affecting.body_zone)
|
||||
@@ -1550,6 +1551,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
else if(target.lying)
|
||||
target.forcesay(GLOB.hit_appends)
|
||||
|
||||
/datum/species/proc/spec_unarmedattacked(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
return
|
||||
|
||||
/datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
// CITADEL EDIT slap mouthy gits and booty
|
||||
var/aim_for_mouth = user.zone_selected == "mouth"
|
||||
|
||||
@@ -862,27 +862,27 @@
|
||||
if(M.stat == DEAD) //F
|
||||
return
|
||||
if(M == H)
|
||||
H.show_message("<span class='narsiesmall'>You cringe with pain as your body rings around you!</span>", 2)
|
||||
H.show_message("<span class='narsiesmall'>You cringe with pain as your body rings around you!</span>", MSG_AUDIBLE)
|
||||
H.playsound_local(H, 'sound/effects/gong.ogg', 100, TRUE)
|
||||
H.soundbang_act(2, 0, 100, 1)
|
||||
H.jitteriness += 7
|
||||
var/distance = max(0,get_dist(get_turf(H),get_turf(M)))
|
||||
switch(distance)
|
||||
if(0 to 1)
|
||||
M.show_message("<span class='narsiesmall'>GONG!</span>", 2)
|
||||
M.show_message("<span class='narsiesmall'>GONG!</span>", MSG_AUDIBLE)
|
||||
M.playsound_local(H, 'sound/effects/gong.ogg', 100, TRUE)
|
||||
M.soundbang_act(1, 0, 30, 3)
|
||||
M.confused += 10
|
||||
M.jitteriness += 4
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "gonged", /datum/mood_event/loud_gong)
|
||||
if(2 to 3)
|
||||
M.show_message("<span class='cult'>GONG!</span>", 2)
|
||||
M.show_message("<span class='cult'>GONG!</span>", MSG_AUDIBLE)
|
||||
M.playsound_local(H, 'sound/effects/gong.ogg', 75, TRUE)
|
||||
M.soundbang_act(1, 0, 15, 2)
|
||||
M.jitteriness += 3
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "gonged", /datum/mood_event/loud_gong)
|
||||
else
|
||||
M.show_message("<span class='warning'>GONG!</span>", 2)
|
||||
M.show_message("<span class='warning'>GONG!</span>", MSG_AUDIBLE)
|
||||
M.playsound_local(H, 'sound/effects/gong.ogg', 50, TRUE)
|
||||
|
||||
|
||||
@@ -944,6 +944,21 @@
|
||||
grab_sound = 'sound/weapons/whipgrab.ogg'
|
||||
attack_sound = 'sound/weapons/whip.ogg'
|
||||
|
||||
/datum/species/golem/durathread
|
||||
name = "Durathread Golem"
|
||||
id = "durathread golem"
|
||||
prefix = "Durathread"
|
||||
limbs_id = "d_golem"
|
||||
special_names = list("Boll","Weave")
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES)
|
||||
fixed_mut_color = null
|
||||
inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
|
||||
info_text = "As a <span class='danger'>Durathread Golem</span>, your strikes will cause those your targets to start choking, but your woven body won't withstand fire as well."
|
||||
|
||||
/datum/species/golem/durathread/spec_unarmedattacked(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
. = ..()
|
||||
target.apply_status_effect(STATUS_EFFECT_CHOKINGSTRAND)
|
||||
|
||||
/datum/species/golem/bone
|
||||
name = "Bone Golem"
|
||||
id = "bone golem"
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
|
||||
return not_handled
|
||||
|
||||
/mob/living/carbon/doUnEquip(obj/item/I)
|
||||
/mob/living/carbon/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE)
|
||||
. = ..() //Sets the default return value to what the parent returns.
|
||||
if(!. || !I) //We don't want to set anything to null if the parent returned 0.
|
||||
return
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
var/datum/gas_mixture/breath
|
||||
|
||||
if(!getorganslot(ORGAN_SLOT_BREATHING_TUBE))
|
||||
if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL) || (lungs && lungs.organ_flags & ORGAN_FAILING))
|
||||
if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL) || HAS_TRAIT(src, TRAIT_MAGIC_CHOKE) || (lungs && lungs.organ_flags & ORGAN_FAILING))
|
||||
losebreath++ //You can't breath at all when in critical or when being choked, so you're going to miss a breath
|
||||
|
||||
else if(health <= crit_threshold)
|
||||
|
||||
@@ -63,8 +63,6 @@
|
||||
var/amount
|
||||
if(reagents.has_reagent("morphine"))
|
||||
amount = -1
|
||||
if(reagents.has_reagent("nuka_cola"))
|
||||
amount = -1
|
||||
if(amount)
|
||||
add_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
|
||||
|
||||
|
||||
@@ -225,10 +225,10 @@
|
||||
/mob/living/proc/getStaminaLoss()
|
||||
return staminaloss
|
||||
|
||||
/mob/living/proc/adjustStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE)
|
||||
/mob/living/proc/adjustStaminaLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
return
|
||||
|
||||
/mob/living/proc/setStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE)
|
||||
/mob/living/proc/setStaminaLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
return
|
||||
|
||||
// heal ONE external organ, organ gets randomly selected from damaged ones.
|
||||
|
||||
@@ -232,12 +232,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
|
||||
// Recompose message for AI hrefs, language incomprehension.
|
||||
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode)
|
||||
message = hear_intercept(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
|
||||
|
||||
show_message(message, 2, deaf_message, deaf_type)
|
||||
return message
|
||||
|
||||
/mob/living/proc/hear_intercept(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
show_message(message, MSG_AUDIBLE, deaf_message, deaf_type)
|
||||
return message
|
||||
|
||||
/mob/living/send_speech(message, message_range = 6, obj/source = src, bubble_type = bubble_icon, list/spans, datum/language/message_language=null, message_mode)
|
||||
|
||||
@@ -827,7 +827,7 @@
|
||||
|
||||
var/rendered = "<i><span class='game say'>[start]<span class='name'>[hrefpart][namepart] ([jobpart])</a> </span><span class='message'>[raw_message]</span></span></i>"
|
||||
|
||||
show_message(rendered, 2)
|
||||
show_message(rendered, MSG_AUDIBLE)
|
||||
|
||||
/mob/living/silicon/ai/fully_replace_character_name(oldname,newname)
|
||||
..()
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
/mob/living/silicon/setCloneLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = 1, forced = FALSE)//immune to stamina damage.
|
||||
/mob/living/silicon/adjustStaminaLoss(amount, updating_health = 1, forced = FALSE)//immune to stamina damage.
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/setStaminaLoss(amount, updating_stamina = 1)
|
||||
/mob/living/silicon/setStaminaLoss(amount, updating_health = 1)
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/adjustOrganLoss(slot, amount, maximum = 500)
|
||||
|
||||
@@ -1295,6 +1295,6 @@
|
||||
bellyup = 1
|
||||
update_icons()
|
||||
|
||||
/mob/living/silicon/robot/adjustStaminaLossBuffered(amount, updating_stamina = 1)
|
||||
/mob/living/silicon/robot/adjustStaminaLossBuffered(amount, updating_health = 1)
|
||||
if(istype(cell))
|
||||
cell.charge -= amount*5
|
||||
@@ -13,6 +13,7 @@
|
||||
mob_biotypes = list(MOB_ROBOTIC)
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
|
||||
speech_span = SPAN_ROBOT
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
|
||||
no_vore = TRUE
|
||||
|
||||
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
|
||||
@@ -71,9 +72,6 @@
|
||||
/mob/living/silicon/contents_explosion(severity, target)
|
||||
return
|
||||
|
||||
/mob/living/silicon/prevent_content_explosion()
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/proc/cancelAlarm()
|
||||
return
|
||||
|
||||
|
||||
@@ -674,11 +674,11 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
destination = nearest_beacon
|
||||
|
||||
//PDA control. Some bots, especially MULEs, may have more parameters.
|
||||
/mob/living/simple_animal/bot/proc/bot_control(command, mob/user, turf/user_turf, list/user_access = list())
|
||||
/mob/living/simple_animal/bot/proc/bot_control(command, mob/user, list/user_access = list())
|
||||
if(!on || emagged == 2 || remote_disabled) //Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands.
|
||||
return TRUE //ACCESS DENIED
|
||||
if(client)
|
||||
bot_control_message(command,user,user_turf,user_access)
|
||||
bot_control_message(command, user)
|
||||
// process control input
|
||||
switch(command)
|
||||
if("patroloff")
|
||||
@@ -690,7 +690,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
|
||||
if("summon")
|
||||
bot_reset()
|
||||
summon_target = user_turf
|
||||
summon_target = get_turf(user)
|
||||
if(user_access.len != 0)
|
||||
access_card.access = user_access + prev_access //Adds the user's access, if any.
|
||||
mode = BOT_SUMMON
|
||||
@@ -702,15 +702,14 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
return
|
||||
|
||||
//
|
||||
/mob/living/simple_animal/bot/proc/bot_control_message(command,user,user_turf,user_access)
|
||||
/mob/living/simple_animal/bot/proc/bot_control_message(command, user)
|
||||
switch(command)
|
||||
if("patroloff")
|
||||
to_chat(src, "<span class='warning big'>STOP PATROL</span>")
|
||||
if("patrolon")
|
||||
to_chat(src, "<span class='warning big'>START PATROL</span>")
|
||||
if("summon")
|
||||
var/area/a = get_area(user_turf)
|
||||
to_chat(src, "<span class='warning big'>PRIORITY ALERT:[user] in [a.name]!</span>")
|
||||
to_chat(src, "<span class='warning big'>PRIORITY ALERT:[user] in [get_area_name(user)]!</span>")
|
||||
if("stop")
|
||||
to_chat(src, "<span class='warning big'>STOP!</span>")
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
bot_control(action, usr) // Kill this later.
|
||||
. = TRUE
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/bot_control(command, mob/user, pda = 0, turf/user_turf, list/user_access = list())
|
||||
/mob/living/simple_animal/bot/mulebot/bot_control(command, mob/user, pda = FALSE)
|
||||
if(pda && wires.is_cut(WIRE_RX)) // MULE wireless is controlled by wires.
|
||||
return
|
||||
|
||||
|
||||
@@ -169,40 +169,40 @@
|
||||
/mob/living/simple_animal/pet/cat/Life()
|
||||
if(!stat && !buckled && !client)
|
||||
if(prob(1))
|
||||
emote("me", 1, pick("stretches out for a belly rub.", "wags its tail.", "lies down."))
|
||||
emote("me", EMOTE_VISIBLE, pick("stretches out for a belly rub.", "wags its tail.", "lies down."))
|
||||
icon_state = "[icon_living]_rest"
|
||||
collar_type = "[initial(collar_type)]_rest"
|
||||
resting = 1
|
||||
update_canmove()
|
||||
else if (prob(1))
|
||||
emote("me", 1, pick("sits down.", "crouches on its hind legs.", "looks alert."))
|
||||
emote("me", EMOTE_VISIBLE, pick("sits down.", "crouches on its hind legs.", "looks alert."))
|
||||
icon_state = "[icon_living]_sit"
|
||||
collar_type = "[initial(collar_type)]_sit"
|
||||
resting = 1
|
||||
update_canmove()
|
||||
else if (prob(1))
|
||||
if (resting)
|
||||
emote("me", 1, pick("gets up and meows.", "walks around.", "stops resting."))
|
||||
emote("me", EMOTE_VISIBLE, pick("gets up and meows.", "walks around.", "stops resting."))
|
||||
icon_state = "[icon_living]"
|
||||
collar_type = "[initial(collar_type)]"
|
||||
resting = 0
|
||||
update_canmove()
|
||||
else
|
||||
emote("me", 1, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat."))
|
||||
emote("me", EMOTE_VISIBLE, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat."))
|
||||
|
||||
//MICE!
|
||||
if((src.loc) && isturf(src.loc))
|
||||
if(!stat && !resting && !buckled)
|
||||
for(var/mob/living/simple_animal/mouse/M in view(1,src))
|
||||
if(!M.stat && Adjacent(M))
|
||||
emote("me", 1, "splats \the [M]!")
|
||||
emote("me", EMOTE_VISIBLE, "splats \the [M]!")
|
||||
M.splat()
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
break
|
||||
for(var/obj/item/toy/cattoy/T in view(1,src))
|
||||
if (T.cooldown < (world.time - 400))
|
||||
emote("me", 1, "bats \the [T] around with its paw!")
|
||||
emote("me", EMOTE_VISIBLE, "bats \the [T] around with its paw!")
|
||||
T.cooldown = world.time
|
||||
|
||||
..()
|
||||
@@ -241,10 +241,10 @@
|
||||
if(change > 0)
|
||||
if(M && stat != DEAD)
|
||||
new /obj/effect/temp_visual/heart(loc)
|
||||
emote("me", 1, "purrs!")
|
||||
emote("me", EMOTE_VISIBLE, "purrs!")
|
||||
else
|
||||
if(M && stat != DEAD)
|
||||
emote("me", 1, "hisses!")
|
||||
emote("me", EMOTE_VISIBLE, "hisses!")
|
||||
|
||||
/mob/living/simple_animal/pet/cat/cak //I told you I'd do it, Remie
|
||||
name = "Keeki"
|
||||
|
||||
@@ -459,10 +459,10 @@
|
||||
movement_target.attack_animal(src)
|
||||
else if(ishuman(movement_target.loc) )
|
||||
if(prob(20))
|
||||
emote("me", 1, "stares at [movement_target.loc]'s [movement_target] with a sad puppy-face")
|
||||
emote("me", EMOTE_VISIBLE, "stares at [movement_target.loc]'s [movement_target] with a sad puppy-face")
|
||||
|
||||
if(prob(1))
|
||||
emote("me", 1, pick("dances around.","chases its tail!"))
|
||||
emote("me", EMOTE_VISIBLE, pick("dances around.","chases its tail!"))
|
||||
spawn(0)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
setDir(i)
|
||||
@@ -618,7 +618,7 @@
|
||||
|
||||
if(!stat && !resting && !buckled)
|
||||
if(prob(1))
|
||||
emote("me", 1, pick("dances around.","chases her tail."))
|
||||
emote("me", EMOTE_VISIBLE, pick("dances around.","chases her tail."))
|
||||
spawn(0)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
setDir(i)
|
||||
@@ -629,7 +629,7 @@
|
||||
|
||||
if(!stat && !resting && !buckled)
|
||||
if(prob(1))
|
||||
emote("me", 1, pick("chases its tail."))
|
||||
emote("me", EMOTE_VISIBLE, pick("chases its tail."))
|
||||
spawn(0)
|
||||
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
|
||||
setDir(i)
|
||||
@@ -648,8 +648,8 @@
|
||||
if(change > 0)
|
||||
if(M && stat != DEAD) // Added check to see if this mob (the dog) is dead to fix issue 2454
|
||||
new /obj/effect/temp_visual/heart(loc)
|
||||
emote("me", 1, "yaps happily!")
|
||||
emote("me", EMOTE_VISIBLE, "yaps happily!")
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "pet_corgi", /datum/mood_event/pet_corgi)
|
||||
else
|
||||
if(M && stat != DEAD) // Same check here, even though emote checks it as well (poor form to check it only in the help case)
|
||||
emote("me", 1, "growls!")
|
||||
emote("me", EMOTE_VISIBLE, "growls!")
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
ranged = 1 //technically
|
||||
ranged_message = "charges"
|
||||
ranged_cooldown_time = 20
|
||||
damage_coeff = list(BRUTE = 0, BURN = 0.5, TOX = 0.5, CLONE = 0.5, STAMINA = 0, OXY = 0.5)
|
||||
playstyle_string = "<span class='holoparasite'>As a <b>charger</b> type you do medium damage, take half damage, immunity to brute damage, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding.</span>"
|
||||
damage_coeff = list(BRUTE = 0.2, BURN = 0.5, TOX = 0.5, CLONE = 0.5, STAMINA = 0, OXY = 0.5)
|
||||
playstyle_string = "<span class='holoparasite'>As a <b>charger</b> type you do medium damage, take half damage, have near immunity to brute damage, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding.</span>"
|
||||
magic_fluff_string = "<span class='holoparasite'>..And draw the Hunter, an alien master of rapid assault.</span>"
|
||||
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Charge modules loaded. Holoparasite swarm online.</span>"
|
||||
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one! It's a charger carp, that likes running at people. But it doesn't have any legs...</span>"
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
attack_sound = 'sound/items/welder.ogg'
|
||||
attacktext = "ignites"
|
||||
melee_damage_type = BURN
|
||||
damage_coeff = list(BRUTE = 0.7, BURN = 0, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
|
||||
playstyle_string = "<span class='holoparasite'>As a <b>chaos</b> type, you take 30% damage reduction to all but burn, which you are immune to. You will ignite any enemy you bump into. in addition, your melee attacks will cause human targets to see everyone as you.</span>"
|
||||
damage_coeff = list(BRUTE = 0.7, BURN = 0.1, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
|
||||
playstyle_string = "<span class='holoparasite'>As a <b>chaos</b> type, you take 30% damage reduction to all but burn, which you are almost immune to. You will ignite any enemy you bump into. in addition, your melee attacks will cause human targets to see everyone as you.</span>"
|
||||
magic_fluff_string = "<span class='holoparasite'>..And draw the Wizard, bringer of endless chaos!</span>"
|
||||
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Crowd control modules activated. Holoparasite swarm online.</span>"
|
||||
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught one! OH GOD, EVERYTHING'S ON FIRE. Except you and the fish.</span>"
|
||||
|
||||
@@ -364,7 +364,7 @@
|
||||
/mob/living/simple_animal/hostile/proc/Aggro()
|
||||
vision_range = aggro_vision_range
|
||||
if(target && emote_taunt.len && prob(taunt_chance))
|
||||
emote("me", 1, "[pick(emote_taunt)] at [target].")
|
||||
emote("me", EMOTE_VISIBLE, "[pick(emote_taunt)] at [target].")
|
||||
taunt_chance = max(taunt_chance-7,2)
|
||||
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ Difficulty: Medium
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/visible_message()
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs)
|
||||
if(swooping & SWOOP_INVULNERABLE) //to suppress attack messages without overriding every single proc that could send a message saying we got hit
|
||||
return
|
||||
return ..()
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
|
||||
var/list/crusher_loot
|
||||
var/medal_type
|
||||
var/score_type = BOSS_SCORE
|
||||
@@ -41,9 +42,6 @@
|
||||
QDEL_NULL(internal)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/prevent_content_explosion()
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/death(gibbed)
|
||||
if(health > 0)
|
||||
return
|
||||
|
||||
@@ -437,7 +437,7 @@
|
||||
//Search for item to steal
|
||||
parrot_interest = search_for_item()
|
||||
if(parrot_interest)
|
||||
emote("me", 1, "looks in [parrot_interest]'s direction and takes flight.")
|
||||
emote("me", EMOTE_VISIBLE, "looks in [parrot_interest]'s direction and takes flight.")
|
||||
parrot_state = PARROT_SWOOP | PARROT_STEAL
|
||||
icon_state = icon_living
|
||||
return
|
||||
@@ -459,7 +459,7 @@
|
||||
if(AM)
|
||||
if(istype(AM, /obj/item) || isliving(AM)) //If stealable item
|
||||
parrot_interest = AM
|
||||
emote("me", 1, "turns and flies towards [parrot_interest].")
|
||||
emote("me", EMOTE_VISIBLE, "turns and flies towards [parrot_interest].")
|
||||
parrot_state = PARROT_SWOOP | PARROT_STEAL
|
||||
return
|
||||
else //Else it's a perch
|
||||
@@ -760,7 +760,7 @@
|
||||
held_item = null
|
||||
if(health < maxHealth)
|
||||
adjustBruteLoss(-10)
|
||||
emote("me", 1, "[src] eagerly downs the cracker.")
|
||||
emote("me", EMOTE_VISIBLE, "[src] eagerly downs the cracker.")
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
@@ -185,16 +185,16 @@
|
||||
say(pick(speak), forced = "poly")
|
||||
else
|
||||
if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len))
|
||||
emote("me", 1, pick(emote_see))
|
||||
emote("me", EMOTE_VISIBLE, pick(emote_see))
|
||||
if((emote_hear && emote_hear.len) && !(emote_see && emote_see.len))
|
||||
emote("me", 2, pick(emote_hear))
|
||||
emote("me", EMOTE_AUDIBLE, pick(emote_hear))
|
||||
if((emote_hear && emote_hear.len) && (emote_see && emote_see.len))
|
||||
var/length = emote_hear.len + emote_see.len
|
||||
var/pick = rand(1,length)
|
||||
if(pick <= emote_see.len)
|
||||
emote("me", 1, pick(emote_see))
|
||||
emote("me", EMOTE_VISIBLE, pick(emote_see))
|
||||
else
|
||||
emote("me", 2, pick(emote_hear))
|
||||
emote("me", EMOTE_AUDIBLE, pick(emote_hear))
|
||||
|
||||
|
||||
/mob/living/simple_animal/proc/environment_is_safe(datum/gas_mixture/environment, check_temp = FALSE)
|
||||
|
||||
+86
-72
@@ -85,106 +85,120 @@
|
||||
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
|
||||
|
||||
if(type)
|
||||
if(type & 1 && eye_blind )//Vision related
|
||||
if(type & MSG_VISUAL && eye_blind )//Vision related
|
||||
if(!alt_msg)
|
||||
return
|
||||
else
|
||||
msg = alt_msg
|
||||
type = alt_type
|
||||
|
||||
if(type & 2 && !can_hear())//Hearing related
|
||||
if(type & MSG_AUDIBLE && !can_hear())//Hearing related
|
||||
if(!alt_msg)
|
||||
return
|
||||
else
|
||||
msg = alt_msg
|
||||
type = alt_type
|
||||
if(type & 1 && eye_blind)
|
||||
if(type & MSG_VISUAL && eye_blind)
|
||||
return
|
||||
// voice muffling
|
||||
if(stat == UNCONSCIOUS)
|
||||
if(type & 2) //audio
|
||||
if(type & MSG_AUDIBLE) //audio
|
||||
to_chat(src, "<I>... You can almost hear something ...</I>")
|
||||
else
|
||||
to_chat(src, msg)
|
||||
return
|
||||
to_chat(src, msg)
|
||||
|
||||
// Show a message to all player mobs who sees this atom
|
||||
// Show a message to the src mob (if the src is a mob)
|
||||
// Use for atoms performing visible actions
|
||||
// message is output to anyone who can see, e.g. "The [src] does something!"
|
||||
// self_message (optional) is what the src mob sees e.g. "You do something!"
|
||||
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
|
||||
// vision_distance (optional) define how many tiles away the message can be seen.
|
||||
// ignored_mob (optional) doesn't show any message to a given mob if TRUE.
|
||||
|
||||
/atom/proc/visible_message(message, self_message, blind_message, vision_distance, list/ignored_mobs, no_ghosts = FALSE)
|
||||
/**
|
||||
* Generate a visible message from this atom
|
||||
*
|
||||
* Show a message to all player mobs who sees this atom
|
||||
*
|
||||
* Show a message to the src mob (if the src is a mob)
|
||||
*
|
||||
* Use for atoms performing visible actions
|
||||
*
|
||||
* message is output to anyone who can see, e.g. "The [src] does something!"
|
||||
*
|
||||
* Vars:
|
||||
* * self_message (optional) is what the src mob sees e.g. "You do something!"
|
||||
* * blind_message (optional) is what blind people will hear e.g. "You hear something!"
|
||||
* * vision_distance (optional) define how many tiles away the message can be seen.
|
||||
* * ignored_mobs (optional) doesn't show any message to any given mob in the list.
|
||||
*/
|
||||
/atom/proc/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return
|
||||
var/list/hearers = get_hearers_in_view(vision_distance, src) //caches the hearers and then removes ignored mobs.
|
||||
if(!length(hearers))
|
||||
return
|
||||
if(!islist(ignored_mobs))
|
||||
ignored_mobs = list(ignored_mobs)
|
||||
var/range = 7
|
||||
if(vision_distance)
|
||||
range = vision_distance
|
||||
for(var/mob/M in get_hearers_in_view(range, src))
|
||||
hearers -= ignored_mobs
|
||||
if(self_message)
|
||||
hearers -= src
|
||||
for(var/mob/M in hearers)
|
||||
if(!M.client)
|
||||
continue
|
||||
if(M in ignored_mobs)
|
||||
continue
|
||||
//This entire if/else chain could be in two lines but isn't for readibilties sake.
|
||||
var/msg = message
|
||||
if(isobserver(M) && no_ghosts)
|
||||
//CITADEL EDIT, required for vore code to remove (T != loc && T != src)) as a check
|
||||
if(M.see_invisible<invisibility) //if src is invisible to us,
|
||||
msg = blind_message
|
||||
else if(T.lighting_object && T.lighting_object.invisibility <= M.see_invisible && T.is_softly_lit()) //the light object is dark and not invisible to us
|
||||
msg = blind_message
|
||||
|
||||
if(!msg)
|
||||
continue
|
||||
if(M == src) //the src always see the main message or self message
|
||||
if(self_message)
|
||||
msg = self_message
|
||||
else //CITADEL EDIT, required for vore code to remove (T != loc && T != src)) as a check
|
||||
if(M.see_invisible<invisibility) //if src is invisible to us,
|
||||
if(blind_message) // then people see blind message if there is one, otherwise nothing.
|
||||
msg = blind_message
|
||||
else
|
||||
continue
|
||||
M.show_message(msg, MSG_VISUAL,blind_message, MSG_AUDIBLE)
|
||||
|
||||
else if(T.lighting_object)
|
||||
if(T.lighting_object.invisibility <= M.see_invisible && T.is_softly_lit()) //the light object is dark and not invisible to us
|
||||
if(blind_message)
|
||||
msg = blind_message
|
||||
else
|
||||
continue
|
||||
///Adds the functionality to self_message.
|
||||
mob/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs)
|
||||
. = ..()
|
||||
if(self_message)
|
||||
show_message(self_message, MSG_VISUAL, blind_message, MSG_AUDIBLE)
|
||||
|
||||
M.show_message(msg,1,blind_message,2)
|
||||
/**
|
||||
* Show a message to all mobs in earshot of this atom
|
||||
*
|
||||
* Use for objects performing audible actions
|
||||
*
|
||||
* vars:
|
||||
* * message is the message output to anyone who can hear.
|
||||
* * deaf_message (optional) is what deaf people will see.
|
||||
* * hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
* * ignored_mobs (optional) doesn't show any message to any given mob in the list.
|
||||
*/
|
||||
/atom/proc/audible_message(message, deaf_message, hearing_distance = DEFAULT_MESSAGE_RANGE, self_message, list/ignored_mobs)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return
|
||||
var/list/hearers = get_hearers_in_view(hearing_distance, src)
|
||||
if(!length(hearers))
|
||||
return
|
||||
if(!islist(ignored_mobs))
|
||||
ignored_mobs = list(ignored_mobs)
|
||||
hearers -= ignored_mobs
|
||||
if(self_message)
|
||||
hearers -= src
|
||||
for(var/mob/M in hearers)
|
||||
M.show_message(message, MSG_AUDIBLE, deaf_message, MSG_VISUAL)
|
||||
|
||||
// Show a message to all mobs in earshot of this one
|
||||
// This would be for audible actions by the src mob
|
||||
// message is the message output to anyone who can hear.
|
||||
// self_message (optional) is what the src mob hears.
|
||||
// deaf_message (optional) is what deaf people will see.
|
||||
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
|
||||
/mob/audible_message(message, deaf_message, hearing_distance, self_message, no_ghosts = FALSE)
|
||||
var/range = 7
|
||||
if(hearing_distance)
|
||||
range = hearing_distance
|
||||
for(var/mob/M in get_hearers_in_view(range, src))
|
||||
var/msg = message
|
||||
if(self_message && M==src)
|
||||
msg = self_message
|
||||
if(no_ghosts && isobserver(M))
|
||||
continue
|
||||
M.show_message( msg, 2, deaf_message, 1)
|
||||
|
||||
// Show a message to all mobs in earshot of this atom
|
||||
// Use for objects performing audible actions
|
||||
// message is the message output to anyone who can hear.
|
||||
// deaf_message (optional) is what deaf people will see.
|
||||
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
|
||||
/atom/proc/audible_message(message, deaf_message, hearing_distance, no_ghosts = FALSE)
|
||||
var/range = 7
|
||||
if(hearing_distance)
|
||||
range = hearing_distance
|
||||
for(var/mob/M in get_hearers_in_view(range, src))
|
||||
if(no_ghosts && isobserver(M))
|
||||
continue
|
||||
M.show_message( message, 2, deaf_message, 1)
|
||||
/**
|
||||
* Show a message to all mobs in earshot of this one
|
||||
*
|
||||
* This would be for audible actions by the src mob
|
||||
*
|
||||
* vars:
|
||||
* * message is the message output to anyone who can hear.
|
||||
* * self_message (optional) is what the src mob hears.
|
||||
* * deaf_message (optional) is what deaf people will see.
|
||||
* * hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
* * ignored_mobs (optional) doesn't show any message to any given mob in the list.
|
||||
*/
|
||||
/mob/audible_message(message, deaf_message, hearing_distance = DEFAULT_MESSAGE_RANGE, self_message, list/ignored_mobs)
|
||||
. = ..()
|
||||
if(self_message)
|
||||
show_message(self_message, MSG_AUDIBLE, deaf_message, MSG_VISUAL)
|
||||
|
||||
/mob/proc/Life()
|
||||
set waitfor = FALSE
|
||||
|
||||
@@ -173,9 +173,9 @@ proc/get_top_level_mob(var/mob/S)
|
||||
message = "<b>[user]</b> " + "<i>[message]</i>"
|
||||
|
||||
if(emote_type == EMOTE_AUDIBLE)
|
||||
user.audible_message(message=message,hearing_distance=1, no_ghosts = TRUE)
|
||||
user.audible_message(message=message,hearing_distance=1, ignored_mobs = GLOB.dead_mob_list)
|
||||
else
|
||||
user.visible_message(message=message,self_message=message,vision_distance=1, no_ghosts = TRUE)
|
||||
user.visible_message(message=message,self_message=message,vision_distance=1, ignored_mobs = GLOB.dead_mob_list)
|
||||
log_emote("[key_name(user)] : (SUBTLER) [message]")
|
||||
|
||||
message = null
|
||||
|
||||
@@ -174,11 +174,15 @@
|
||||
*/
|
||||
/obj/item/pen/edagger
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") //these wont show up if the pen is off
|
||||
sharpness = IS_SHARP
|
||||
var/on = FALSE
|
||||
|
||||
/obj/item/pen/edagger/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 60, 100, 0, 'sound/weapons/blade1.ogg', TRUE)
|
||||
AddComponent(/datum/component/butchering, 60, 100, 0, 'sound/weapons/blade1.ogg')
|
||||
|
||||
/obj/item/pen/edagger/get_sharpness()
|
||||
return on * sharpness
|
||||
|
||||
/obj/item/pen/edagger/attack_self(mob/living/user)
|
||||
if(on)
|
||||
@@ -201,8 +205,6 @@
|
||||
throwforce = 35
|
||||
playsound(user, 'sound/weapons/saberon.ogg', 5, 1)
|
||||
to_chat(user, "<span class='warning'>[src] is now active.</span>")
|
||||
var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
|
||||
butchering.butchering_enabled = on
|
||||
update_icon()
|
||||
|
||||
/obj/item/pen/edagger/update_icon()
|
||||
|
||||
@@ -360,3 +360,7 @@
|
||||
var/area/A = get_area(src)
|
||||
if(!A.lightswitch || !A.light_power)
|
||||
charge = 0 //For naturally depowered areas, we start with no power
|
||||
|
||||
//found inside the inducers ordered from cargo.
|
||||
/obj/item/stock_parts/cell/inducer_supply
|
||||
maxcharge = 5000
|
||||
|
||||
@@ -75,6 +75,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
icon_state = "darkmatter"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
|
||||
var/uid = 1
|
||||
var/static/gl_uid = 1
|
||||
light_range = 4
|
||||
@@ -676,18 +677,15 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
for(var/mob/living/L in range(10))
|
||||
investigate_log("has irradiated [key_name(L)] after consuming [AM].", INVESTIGATE_SUPERMATTER)
|
||||
if(L in view())
|
||||
L.show_message("<span class='danger'>As \the [src] slowly stops resonating, you find your skin covered in new radiation burns.</span>", 1,\
|
||||
"<span class='danger'>The unearthly ringing subsides and you notice you have new radiation burns.</span>", 2)
|
||||
L.show_message("<span class='danger'>As \the [src] slowly stops resonating, you find your skin covered in new radiation burns.</span>", MSG_VISUAL,\
|
||||
"<span class='danger'>The unearthly ringing subsides and you notice you have new radiation burns.</span>", MSG_AUDIBLE)
|
||||
else
|
||||
L.show_message("<span class='italics'>You hear an unearthly ringing and notice your skin is covered in fresh radiation burns.</span>", 2)
|
||||
L.show_message("<span class='italics'>You hear an unearthly ringing and notice your skin is covered in fresh radiation burns.</span>", MSG_AUDIBLE)
|
||||
|
||||
//Do not blow up our internal radio
|
||||
/obj/machinery/power/supermatter_crystal/contents_explosion(severity, target)
|
||||
return
|
||||
|
||||
/obj/machinery/power/supermatter_crystal/prevent_content_explosion()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/supermatter_crystal/engine
|
||||
is_main_engine = TRUE
|
||||
|
||||
|
||||
@@ -60,10 +60,10 @@
|
||||
|
||||
/obj/item/firing_pin/proc/auth_fail(mob/living/user)
|
||||
if(user)
|
||||
user.show_message(fail_message, 1)
|
||||
user.show_message(fail_message, MSG_VISUAL)
|
||||
if(selfdestruct)
|
||||
if(user)
|
||||
user.show_message("<span class='danger'>SELF-DESTRUCTING...</span><br>", 1)
|
||||
user.show_message("<span class='danger'>SELF-DESTRUCTING...</span><br>", MSG_VISUAL)
|
||||
to_chat(user, "<span class='userdanger'>[gun] explodes!</span>")
|
||||
explosion(get_turf(gun), -1, 0, 2, 3)
|
||||
if(gun)
|
||||
|
||||
@@ -407,10 +407,6 @@
|
||||
glass_name = "glass of Nuka Cola"
|
||||
glass_desc = "Don't cry, Don't raise your eye, It's only nuclear wasteland."
|
||||
|
||||
/datum/reagent/consumable/nuka_cola/on_mob_metabolize(mob/living/L)
|
||||
..()
|
||||
L.add_movespeed_modifier(id, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
|
||||
|
||||
/datum/reagent/consumable/nuka_cola/on_mob_end_metabolize(mob/living/L)
|
||||
L.remove_movespeed_modifier(id)
|
||||
..()
|
||||
|
||||
@@ -881,40 +881,49 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
|
||||
/datum/reagent/medicine/strange_reagent
|
||||
name = "Strange Reagent"
|
||||
id = "strange_reagent"
|
||||
description = "A miracle drug capable of bringing the dead back to life. Only functions if the target has less than 100 brute and burn damage (independent of one another), and causes slight damage to the living."
|
||||
description = "A miracle drug capable of bringing the dead back to life. Only functions when applied by patch or spray, if the target has less than 100 brute and burn damage (independent of one another) and hasn't been husked. Causes slight damage to the living."
|
||||
reagent_state = LIQUID
|
||||
color = "#A0E85E"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
taste_description = "magnets"
|
||||
pH = 0
|
||||
|
||||
/datum/reagent/medicine/strange_reagent/reaction_mob(mob/living/carbon/human/M, method=TOUCH, reac_volume)
|
||||
/datum/reagent/medicine/strange_reagent/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
|
||||
if(M.stat == DEAD)
|
||||
if(M.getBruteLoss() >= 100 || M.getFireLoss() >= 100)
|
||||
M.visible_message("<span class='warning'>[M]'s body convulses a bit, and then falls still once more.</span>")
|
||||
if(M.suiciding || M.hellbound) //they are never coming back
|
||||
M.visible_message("<span class='warning'>[M]'s body does not react...</span>")
|
||||
return
|
||||
M.visible_message("<span class='warning'>[M]'s body convulses a bit.</span>")
|
||||
if(!M.suiciding && !(HAS_TRAIT(M, TRAIT_NOCLONE)) && !M.hellbound)
|
||||
if(!M)
|
||||
return
|
||||
if(M.notify_ghost_cloning(source = M))
|
||||
spawn (100) //so the ghost has time to re-enter
|
||||
return
|
||||
if(M.getBruteLoss() >= 100 || M.getFireLoss() >= 100 || HAS_TRAIT(M, TRAIT_HUSK)) //body is too damaged to be revived
|
||||
M.visible_message("<span class='warning'>[M]'s body convulses a bit, and then falls still once more.</span>")
|
||||
M.do_jitter_animation(10)
|
||||
return
|
||||
else
|
||||
M.visible_message("<span class='warning'>[M]'s body starts convulsing!</span>")
|
||||
M.notify_ghost_cloning(source = M)
|
||||
M.do_jitter_animation(10)
|
||||
addtimer(CALLBACK(M, /mob/living/carbon.proc/do_jitter_animation, 10), 40) //jitter immediately, then again after 4 and 8 seconds
|
||||
addtimer(CALLBACK(M, /mob/living/carbon.proc/do_jitter_animation, 10), 80)
|
||||
|
||||
spawn(100) //so the ghost has time to re-enter
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
if(!(C.dna && C.dna.species && (NOBLOOD in C.dna.species.species_traits)))
|
||||
C.blood_volume = max(C.blood_volume, BLOOD_VOLUME_NORMAL*C.blood_ratio) //so you don't instantly re-die from a lack of blood
|
||||
for(var/organ in C.internal_organs)
|
||||
var/obj/item/organ/O = organ
|
||||
if(O.damage > O.maxHealth/2)
|
||||
O.setOrganDamage(O.maxHealth/2) //so you don't instantly die from organ damage when being revived
|
||||
|
||||
else
|
||||
M.adjustOxyLoss(-20, 0)
|
||||
M.adjustToxLoss(-20, 0)
|
||||
var/mob/living/carbon/H = M
|
||||
for(var/organ in H.internal_organs)
|
||||
var/obj/item/organ/O = organ
|
||||
O.setOrganDamage(0)
|
||||
M.updatehealth()
|
||||
|
||||
if(M.revive())
|
||||
M.grab_ghost()
|
||||
M.emote("gasp")
|
||||
log_combat(M, M, "revived", src)
|
||||
..()
|
||||
|
||||
|
||||
/datum/reagent/medicine/strange_reagent/on_mob_life(mob/living/carbon/M)
|
||||
M.adjustBruteLoss(0.5*REM, 0)
|
||||
M.adjustFireLoss(0.5*REM, 0)
|
||||
@@ -1524,5 +1533,5 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
|
||||
/datum/reagent/medicine/polypyr/overdose_process(mob/living/M)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5)
|
||||
..()
|
||||
. = 1
|
||||
. = 1
|
||||
|
||||
|
||||
@@ -99,7 +99,6 @@
|
||||
|
||||
/datum/chemical_reaction/reagent_explosion/blackpowder_explosion/on_reaction(datum/reagents/holder, created_volume)
|
||||
var/turf/T = get_turf(holder.my_atom)
|
||||
sleep(rand(50,100))
|
||||
..(holder, created_volume, T)
|
||||
|
||||
/datum/chemical_reaction/thermite
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
if(user.incapacitated())
|
||||
return
|
||||
for(var/mob/M in range(5, get_turf(src)))
|
||||
M.show_message("<FONT size=[max(0, 5 - get_dist(src, M))]>CLONG, clong!</FONT>", 2)
|
||||
M.show_message("<FONT size=[max(0, 5 - get_dist(src, M))]>CLONG, clong!</FONT>", MSG_AUDIBLE)
|
||||
playsound(src.loc, 'sound/effects/clang.ogg', 50, 0, 0)
|
||||
|
||||
// called to vent all gas in holder to a location
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
var/datum/action/innate/monkey_recycle/monkey_recycle_action
|
||||
var/datum/action/innate/slime_scan/scan_action
|
||||
var/datum/action/innate/feed_potion/potion_action
|
||||
var/datum/action/innate/hotkey_help/hotkey_help
|
||||
|
||||
var/list/stored_slimes
|
||||
var/obj/item/slimepotion/slime/current_potion
|
||||
@@ -48,6 +49,7 @@
|
||||
monkey_recycle_action = new
|
||||
scan_action = new
|
||||
potion_action = new
|
||||
hotkey_help = new
|
||||
stored_slimes = list()
|
||||
RegisterSignal(src, COMSIG_ATOM_CONTENTS_DEL, .proc/on_contents_del)
|
||||
|
||||
@@ -100,6 +102,27 @@
|
||||
potion_action.Grant(user)
|
||||
actions += potion_action
|
||||
|
||||
if(hotkey_help)
|
||||
hotkey_help.target = src
|
||||
hotkey_help.Grant(user)
|
||||
actions += hotkey_help
|
||||
|
||||
RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL, .proc/XenoSlimeClickCtrl)
|
||||
RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT, .proc/XenoSlimeClickAlt)
|
||||
RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT, .proc/XenoSlimeClickShift)
|
||||
RegisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT, .proc/XenoTurfClickShift)
|
||||
RegisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL, .proc/XenoTurfClickCtrl)
|
||||
RegisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL, .proc/XenoMonkeyClickCtrl)
|
||||
|
||||
/obj/machinery/computer/camera_advanced/xenobio/remove_eye_control(mob/living/user)
|
||||
UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL)
|
||||
UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT)
|
||||
UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT)
|
||||
UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT)
|
||||
UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL)
|
||||
UnregisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL)
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/on_contents_del(atom/deleted)
|
||||
if(current_potion == deleted)
|
||||
current_potion = null
|
||||
@@ -169,7 +192,7 @@
|
||||
S.visible_message("[S] warps in!")
|
||||
X.stored_slimes -= S
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
|
||||
to_chat(owner, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
/datum/action/innate/slime_pick_up
|
||||
name = "Pick up Slime"
|
||||
@@ -194,7 +217,7 @@
|
||||
S.forceMove(X)
|
||||
X.stored_slimes += S
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
|
||||
to_chat(owner, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
|
||||
/datum/action/innate/feed_slime
|
||||
@@ -215,9 +238,11 @@
|
||||
if (!QDELETED(food))
|
||||
food.LAssailant = C
|
||||
X.monkeys --
|
||||
to_chat(owner, "[X] now has [X.monkeys] monkeys left.")
|
||||
to_chat(owner, "<span class='notice'>[X] now has [X.monkeys] monkey(s) left.</span>")
|
||||
else
|
||||
to_chat(owner, "<span class='warning'>[X] needs to have at least 1 monkey stored. Currently has [X.monkeys] monkeys stored.</span>")
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
|
||||
to_chat(owner, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
|
||||
/datum/action/innate/monkey_recycle
|
||||
@@ -239,7 +264,7 @@
|
||||
X.monkeys = round(X.monkeys + 0.2,0.1)
|
||||
qdel(M)
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
|
||||
to_chat(owner, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
/datum/action/innate/slime_scan
|
||||
name = "Scan Slime"
|
||||
@@ -256,7 +281,7 @@
|
||||
for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
|
||||
slime_scan(S, C)
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
|
||||
to_chat(owner, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
/datum/action/innate/feed_potion
|
||||
name = "Apply Potion"
|
||||
@@ -280,7 +305,10 @@
|
||||
X.current_potion.attack(S, C)
|
||||
break
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>Target is not near a camera. Cannot proceed.</span>")
|
||||
to_chat(owner, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
|
||||
|
||||
//Demodularized Code
|
||||
|
||||
/obj/item/disk/xenobio_console_upgrade
|
||||
name = "Xenobiology console upgrade disk"
|
||||
@@ -307,3 +335,169 @@
|
||||
name = "Xenobiology console advanced slime upgrade disk"
|
||||
desc = "This disk will add the ability to remotely feed slimes potions via the Xenobiology console, and lift the restrictions on the number of slimes that can be stored inside the Xenobiology console. This includes the contents of the basic slime upgrade disk."
|
||||
upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC, XENOBIO_UPGRADE_SLIMEADV)
|
||||
|
||||
|
||||
//Xenobio Hotkeys Port
|
||||
|
||||
/datum/action/innate/hotkey_help
|
||||
name = "Hotkey Help"
|
||||
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
|
||||
button_icon_state = "hotkey_help"
|
||||
|
||||
/datum/action/innate/hotkey_help/Activate()
|
||||
if(!target || !isliving(owner))
|
||||
return
|
||||
to_chat(owner, "<b>Click shortcuts:</b>")
|
||||
to_chat(owner, "Shift-click a slime to pick it up, or the floor to drop all held slimes. (Requires Basic Slime Console upgrade)")
|
||||
to_chat(owner, "Ctrl-click a slime to scan it.")
|
||||
to_chat(owner, "Alt-click a slime to feed it a potion. (Requires Advanced Slime Console upgrade)")
|
||||
to_chat(owner, "Ctrl-click on a dead monkey to recycle it, or the floor to place a new monkey. (Requires Monkey Console upgrade)")
|
||||
|
||||
//
|
||||
// Alternate clicks for slime, monkey and open turf if using a xenobio console
|
||||
|
||||
// Scans slime
|
||||
/mob/living/simple_animal/slime/CtrlClick(mob/user)
|
||||
SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_CTRL, src)
|
||||
..()
|
||||
|
||||
//Feeds a potion to slime
|
||||
/mob/living/simple_animal/slime/AltClick(mob/user)
|
||||
SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_ALT, src)
|
||||
..()
|
||||
|
||||
//Picks up slime
|
||||
/mob/living/simple_animal/slime/ShiftClick(mob/user)
|
||||
SEND_SIGNAL(user, COMSIG_XENO_SLIME_CLICK_SHIFT, src)
|
||||
..()
|
||||
|
||||
//Place slimes
|
||||
/turf/open/ShiftClick(mob/user)
|
||||
SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_SHIFT, src)
|
||||
..()
|
||||
|
||||
//Place monkey
|
||||
/turf/open/CtrlClick(mob/user)
|
||||
SEND_SIGNAL(user, COMSIG_XENO_TURF_CLICK_CTRL, src)
|
||||
..()
|
||||
|
||||
//Pick up monkey
|
||||
/mob/living/carbon/monkey/CtrlClick(mob/user)
|
||||
SEND_SIGNAL(user, COMSIG_XENO_MONKEY_CLICK_CTRL, src)
|
||||
..()
|
||||
|
||||
// Scans slime
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickCtrl(mob/living/user, mob/living/simple_animal/slime/S)
|
||||
if(!GLOB.cameranet.checkTurfVis(S.loc))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
return
|
||||
var/mob/living/C = user
|
||||
var/mob/camera/aiEye/remote/xenobio/E = C.remote_control
|
||||
var/area/mobarea = get_area(S.loc)
|
||||
if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible)
|
||||
slime_scan(S, C)
|
||||
|
||||
//Feeds a potion to slime
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickAlt(mob/living/user, mob/living/simple_animal/slime/S)
|
||||
if(!(upgradetier & XENOBIO_UPGRADE_SLIMEADV)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEADV
|
||||
to_chat(user, "<span class='warning'>This console does not have the advanced slime upgrade.</span>")
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(S.loc))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
return
|
||||
var/mob/living/C = user
|
||||
var/mob/camera/aiEye/remote/xenobio/E = C.remote_control
|
||||
var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin
|
||||
var/area/mobarea = get_area(S.loc)
|
||||
if(QDELETED(X.current_potion))
|
||||
to_chat(C, "<span class='warning'>No potion loaded.</span>")
|
||||
return
|
||||
if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible)
|
||||
X.current_potion.attack(S, C)
|
||||
|
||||
//Picks up slime
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickShift(mob/living/user, mob/living/simple_animal/slime/S)
|
||||
if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC
|
||||
to_chat(user, "<span class='warning'>This console does not have the basic slime upgrade.</span>")
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(S.loc))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
return
|
||||
var/mob/living/C = user
|
||||
var/mob/camera/aiEye/remote/xenobio/E = C.remote_control
|
||||
var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin
|
||||
var/area/mobarea = get_area(S.loc)
|
||||
if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible)
|
||||
if(X.stored_slimes.len >= X.max_slimes)
|
||||
to_chat(C, "<span class='warning'>Slime storage is full.</span>")
|
||||
return
|
||||
if(S.ckey)
|
||||
to_chat(C, "<span class='warning'>The slime wiggled free!</span>")
|
||||
return
|
||||
if(S.buckled)
|
||||
S.Feedstop(silent = TRUE)
|
||||
S.visible_message("[S] vanishes in a flash of light!")
|
||||
S.forceMove(X)
|
||||
X.stored_slimes += S
|
||||
|
||||
//Place slimes
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickShift(mob/living/user, turf/open/T)
|
||||
if(!(upgradetier & XENOBIO_UPGRADE_SLIMEBASIC)) //CIT CHANGE - makes slime-related actions require XENOBIO_UPGRADE_SLIMEBASIC
|
||||
to_chat(user, "<span class='warning'>This console does not have the basic slime upgrade.</span>")
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(T))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
return
|
||||
var/mob/living/C = user
|
||||
var/mob/camera/aiEye/remote/xenobio/E = C.remote_control
|
||||
var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin
|
||||
var/area/turfarea = get_area(T)
|
||||
if(turfarea.name == E.allowed_area || turfarea.xenobiology_compatible)
|
||||
for(var/mob/living/simple_animal/slime/S in X.stored_slimes)
|
||||
S.forceMove(T)
|
||||
S.visible_message("[S] warps in!")
|
||||
X.stored_slimes -= S
|
||||
|
||||
//Place monkey
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickCtrl(mob/living/user, turf/open/T)
|
||||
if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS)) // CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
|
||||
to_chat(user, "<span class='warning'>This console does not have the monkey upgrade.</span>")
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(T))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
return
|
||||
var/mob/living/C = user
|
||||
var/mob/camera/aiEye/remote/xenobio/E = C.remote_control
|
||||
var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin
|
||||
var/area/turfarea = get_area(T)
|
||||
if(turfarea.name == E.allowed_area || turfarea.xenobiology_compatible)
|
||||
if(X.monkeys >= 1)
|
||||
var/mob/living/carbon/monkey/food = new /mob/living/carbon/monkey(T, TRUE, C)
|
||||
if (!QDELETED(food))
|
||||
food.LAssailant = C
|
||||
X.monkeys--
|
||||
X.monkeys = round(X.monkeys, 0.1) //Prevents rounding errors
|
||||
to_chat(C, "<span class='notice'>[X] now has [X.monkeys] monkey(s) stored.</span>")
|
||||
else
|
||||
to_chat(C, "<span class='warning'>[X] needs to have at least 1 monkey stored. Currently has [X.monkeys] monkeys stored.</span>")
|
||||
|
||||
//Pick up monkey
|
||||
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoMonkeyClickCtrl(mob/living/user, mob/living/carbon/monkey/M)
|
||||
if(!(upgradetier & XENOBIO_UPGRADE_MONKEYS)) // CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
|
||||
to_chat(user, "<span class='warning'>This console does not have the monkey upgrade.</span>")
|
||||
return
|
||||
if(!GLOB.cameranet.checkTurfVis(M.loc))
|
||||
to_chat(user, "<span class='warning'>Target is not near a camera. Cannot proceed.</span>")
|
||||
return
|
||||
var/mob/living/C = user
|
||||
var/mob/camera/aiEye/remote/xenobio/E = C.remote_control
|
||||
var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin
|
||||
var/area/mobarea = get_area(M.loc)
|
||||
if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible)
|
||||
if(!M.stat)
|
||||
return
|
||||
M.visible_message("[M] vanishes as [p_theyre()] reclaimed for recycling!")
|
||||
X.monkeys = round(X.monkeys + 0.2,0.1)
|
||||
qdel(M)
|
||||
if (X.monkeys == (round(X.monkeys,1)))
|
||||
to_chat(C, "<span class='notice'>[X] now has [X.monkeys] monkey(s) available.</span>")
|
||||
|
||||
@@ -85,7 +85,8 @@
|
||||
/obj/item/stack/tile/bronze = /datum/species/golem/bronze,
|
||||
/obj/item/stack/sheet/cardboard = /datum/species/golem/cardboard,
|
||||
/obj/item/stack/sheet/leather = /datum/species/golem/leather,
|
||||
/obj/item/stack/sheet/bone = /datum/species/golem/bone)
|
||||
/obj/item/stack/sheet/bone = /datum/species/golem/bone,
|
||||
/obj/item/stack/sheet/cotton/durathread = /datum/species/golem/durathread)
|
||||
|
||||
if(istype(I, /obj/item/stack))
|
||||
var/obj/item/stack/O = I
|
||||
|
||||
@@ -754,7 +754,7 @@
|
||||
var/static/regex/punish_words = regex("bad boy|bad girl|bad pet|bad job|spot of bother|gone and done it now|blast it|buggered it up")
|
||||
//phase 0
|
||||
var/static/regex/saymyname_words = regex("say my name|who am i|whoami")
|
||||
var/static/regex/wakeup_words = regex("revert|awaken|snap|attention")
|
||||
var/static/regex/wakeup_words = regex("revert|awaken|snap|attention")
|
||||
//phase1
|
||||
var/static/regex/petstatus_words = regex("how are you|what is your status|are you okay")
|
||||
var/static/regex/silence_words = regex("shut up|silence|be silent|ssh|quiet|hush")
|
||||
@@ -1143,7 +1143,7 @@
|
||||
switch(E.phase)
|
||||
if(2 to INFINITY)
|
||||
playsound(get_turf(H), pick('sound/effects/meow1.ogg', 'modular_citadel/sound/voice/nya.ogg'), 50, 1, -1) //I'm very tempted to write a Fermis clause that makes them merowr.ogg if it's me. But, I also don't think snowflakism is okay. I would've gotten away for it too, if it wern't for my morals.
|
||||
H.emote("me", 1, "lets out a nya!")
|
||||
H.emote("me", EMOTE_VISIBLE, "lets out a nya!")
|
||||
E.cooldown += 1
|
||||
|
||||
//SLEEP
|
||||
@@ -1230,7 +1230,7 @@
|
||||
var/datum/status_effect/chem/enthrall/E = C.has_status_effect(/datum/status_effect/chem/enthrall)
|
||||
if (E.phase == 3)
|
||||
var/speaktrigger = ""
|
||||
C.emote("me", 1, "whispers something quietly.")
|
||||
C.emote("me", EMOTE_VISIBLE, "whispers something quietly.")
|
||||
if (get_dist(user, C) > 1)//Requires user to be next to their pet.
|
||||
to_chat(user, "<span class='warning'>You need to be next to your pet to hear them!</b></span>")
|
||||
continue
|
||||
@@ -1253,7 +1253,7 @@
|
||||
to_chat(user, "<span class='warning'>[H] seems incapable of being implanted with triggers.</b></span>")
|
||||
continue
|
||||
else
|
||||
user.emote("me", 1, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.")
|
||||
user.emote("me", EMOTE_VISIBLE, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.")
|
||||
user.SetStun(1000)//Hands are handy, so you have to stay still
|
||||
H.SetStun(1000)
|
||||
if (E.mental_capacity >= 5)
|
||||
@@ -1294,7 +1294,7 @@
|
||||
to_chat(user, "<span class='warning'>[H] seems incapable of being implanted with an echoing phrase.</b></span>")
|
||||
continue
|
||||
else
|
||||
user.emote("me", 1, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.")
|
||||
user.emote("me", EMOTE_VISIBLE, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.")
|
||||
user.SetStun(1000)//Hands are handy, so you have to stay still
|
||||
H.SetStun(1000)
|
||||
var/trigger = stripped_input(user, "Enter the loop phrase", MAX_MESSAGE_LEN)
|
||||
@@ -1317,7 +1317,7 @@
|
||||
to_chat(user, "<span class='warning'>You need to be next to your pet to give them a new objective!</b></span>")
|
||||
continue
|
||||
else
|
||||
user.emote("me", 1, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.'")
|
||||
user.emote("me", EMOTE_VISIBLE, "puts their hands upon [H.name]'s head and looks deep into their eyes, whispering something to them.'")
|
||||
user.SetStun(1000)//So you can't run away!
|
||||
H.SetStun(1000)
|
||||
if (E.mental_capacity >= 200)
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
/proc/get_uplink_items(var/datum/game_mode/gamemode = null, allow_sales = TRUE, allow_restricted = TRUE)
|
||||
var/list/filtered_uplink_items = list()
|
||||
/proc/get_uplink_items(datum/game_mode/gamemode, allow_sales = TRUE, allow_restricted = TRUE)
|
||||
var/list/filtered_uplink_items = GLOB.uplink_categories.Copy() // list of uplink categories without associated values.
|
||||
var/list/sale_items = list()
|
||||
|
||||
for(var/path in GLOB.uplink_items)
|
||||
var/datum/uplink_item/I = new path
|
||||
if(!I.item)
|
||||
continue
|
||||
if(I.include_modes.len)
|
||||
if(!gamemode && SSticker.mode && !(SSticker.mode.type in I.include_modes))
|
||||
continue
|
||||
@@ -23,9 +19,8 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
if (I.restricted && !allow_restricted)
|
||||
continue
|
||||
|
||||
if(!filtered_uplink_items[I.category])
|
||||
filtered_uplink_items[I.category] = list()
|
||||
filtered_uplink_items[I.category][I.name] = I
|
||||
LAZYSET(filtered_uplink_items[I.category], I.name, I)
|
||||
|
||||
if(I.limited_stock < 0 && !I.cant_discount && I.item && I.cost > 1)
|
||||
sale_items += I
|
||||
if(allow_sales)
|
||||
@@ -45,9 +40,12 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
A.desc += " Normally costs [initial(A.cost)] TC. All sales final. [pick(disclaimer)]"
|
||||
A.item = I.item
|
||||
|
||||
if(!filtered_uplink_items[A.category])
|
||||
filtered_uplink_items[A.category] = list()
|
||||
filtered_uplink_items[A.category][A.name] = A
|
||||
LAZYSET(filtered_uplink_items[A.category], A.name, A)
|
||||
|
||||
for(var/category in filtered_uplink_items)
|
||||
if(!filtered_uplink_items[category]) //empty categories with no associated uplink item. Remove.
|
||||
filtered_uplink_items -= category
|
||||
|
||||
return filtered_uplink_items
|
||||
|
||||
|
||||
@@ -106,16 +104,77 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
to_chat(user, "[A] materializes onto the floor.")
|
||||
return A
|
||||
|
||||
//Discounts (dynamically filled above)
|
||||
/datum/uplink_item/discounts
|
||||
category = "Discounted Gear"
|
||||
/*
|
||||
Uplink Categories:
|
||||
Due to how the typesof() in-built byond proc works, it should be kept in mind
|
||||
the order categories are displayed in the uplink UI is same to the order they are loaded in the code.
|
||||
I trust no extra filter is needed as long as they are all contained within the following lines.
|
||||
When adding new uplink categories, please keep them separate from their sub paths here and without set item.
|
||||
Failure to comply may result in the new categories being listed at the bottom of the UI.
|
||||
*/
|
||||
|
||||
/datum/uplink_item/holiday
|
||||
category = "Holiday"
|
||||
|
||||
//All bundles and telecrystals
|
||||
/datum/uplink_item/bundles_TC
|
||||
category = "Bundles and Telecrystals"
|
||||
surplus = 0
|
||||
cant_discount = TRUE
|
||||
|
||||
/datum/uplink_item/dangerous
|
||||
category = "Conspicuous and Dangerous Weapons"
|
||||
|
||||
/datum/uplink_item/stealthy_weapons
|
||||
category = "Stealthy and Inconspicuous Weapons"
|
||||
|
||||
/datum/uplink_item/ammo
|
||||
category = "Ammunition"
|
||||
surplus = 40
|
||||
|
||||
/datum/uplink_item/explosives
|
||||
category = "Grenades and Explosives"
|
||||
|
||||
/datum/uplink_item/support
|
||||
category = "Support and Mechanized Exosuits"
|
||||
surplus = 0
|
||||
include_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/suits
|
||||
category = "Space Suits, Hardsuits and Clothing"
|
||||
surplus = 40
|
||||
|
||||
/datum/uplink_item/stealthy_tools
|
||||
category = "Stealth and Camouflage Items"
|
||||
|
||||
/datum/uplink_item/device_tools
|
||||
category = "Devices and Tools"
|
||||
|
||||
/datum/uplink_item/implants
|
||||
category = "Implants"
|
||||
surplus = 50
|
||||
|
||||
/datum/uplink_item/role_restricted
|
||||
category = "Role-Restricted"
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
|
||||
surplus = 0
|
||||
|
||||
/datum/uplink_item/badass
|
||||
category = "(Pointless) Badassery"
|
||||
surplus = 0
|
||||
|
||||
//Discounts (dynamically filled above)
|
||||
/datum/uplink_item/discounts
|
||||
category = "Discounted Gear"
|
||||
|
||||
|
||||
/*
|
||||
Uplink Items:
|
||||
Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list,
|
||||
When adding new entries to the file, please keep them sorted by category.
|
||||
*/
|
||||
|
||||
//All bundles and telecrystals
|
||||
|
||||
/datum/uplink_item/bundles_TC/chemical
|
||||
name = "Bioterror bundle"
|
||||
desc = "For the madman: Contains a handheld Bioterror chem sprayer, a Bioterror foam grenade, a box of lethal chemicals, a dart pistol, \
|
||||
@@ -288,8 +347,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
cost = 20
|
||||
|
||||
// Dangerous Items
|
||||
/datum/uplink_item/dangerous
|
||||
category = "Conspicuous and Dangerous Weapons"
|
||||
|
||||
/datum/uplink_item/dangerous/pistol
|
||||
name = "Stechkin Pistol"
|
||||
@@ -544,8 +601,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
surplus = 10
|
||||
|
||||
// Stealthy Weapons
|
||||
/datum/uplink_item/stealthy_weapons
|
||||
category = "Stealthy and Inconspicuous Weapons"
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/combatglovesplus
|
||||
name = "Combat Gloves Plus"
|
||||
@@ -564,12 +619,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
cost = 13
|
||||
surplus = 0
|
||||
|
||||
/datum/uplink_item/dangerous/phantomthief
|
||||
name = "Syndicate Mask"
|
||||
desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles"
|
||||
item = /obj/item/clothing/glasses/phantomthief/syndicate
|
||||
cost = 2
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/dart_pistol
|
||||
name = "Dart Pistol"
|
||||
desc = "A miniaturized version of a normal syringe gun. It is very quiet when fired and can fit into any \
|
||||
@@ -671,9 +720,6 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
|
||||
cost = 6
|
||||
|
||||
// Ammunition
|
||||
/datum/uplink_item/ammo
|
||||
category = "Ammunition"
|
||||
surplus = 40
|
||||
|
||||
/datum/uplink_item/ammo/pistol
|
||||
name = "10mm Handgun Magazine"
|
||||
@@ -923,8 +969,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
|
||||
cost = 1
|
||||
include_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/explosives
|
||||
category = "Grenades and Explosives"
|
||||
//Grenades and Explosives
|
||||
|
||||
/datum/uplink_item/explosives/bioterrorfoam
|
||||
name = "Bioterror Foam Grenade"
|
||||
@@ -1081,10 +1126,6 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
|
||||
|
||||
|
||||
//Support and Mechs
|
||||
/datum/uplink_item/support
|
||||
category = "Support and Mechanized Exosuits"
|
||||
surplus = 0
|
||||
include_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/support/clown_reinforcement
|
||||
name = "Clown Reinforcements"
|
||||
@@ -1155,8 +1196,6 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
|
||||
cost = 140
|
||||
|
||||
// Stealth Items
|
||||
/datum/uplink_item/stealthy_tools
|
||||
category = "Stealth and Camouflage Items"
|
||||
|
||||
/datum/uplink_item/stealthy_tools/agent_card
|
||||
name = "Agent Identification Card"
|
||||
@@ -1266,17 +1305,6 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
|
||||
item = /obj/item/jammer
|
||||
cost = 5
|
||||
|
||||
/*/datum/uplink_item/stealthy_tools/syndi_borer
|
||||
name = "Syndicate Brain Slug"
|
||||
desc = "A small cortical borer, modified to be completely loyal to the owner. \
|
||||
Genetically infertile, these brain slugs can assist medically in a support role, or take direct action \
|
||||
to assist their host."
|
||||
item = /obj/item/antag_spawner/syndi_borer
|
||||
refundable = TRUE
|
||||
cost = 10
|
||||
surplus = 20 //Let's not have this be too common
|
||||
exclude_modes = list(/datum/game_mode/nuclear) */
|
||||
|
||||
/datum/uplink_item/stealthy_tools/smugglersatchel
|
||||
name = "Smuggler's Satchel"
|
||||
desc = "This satchel is thin enough to be hidden in the gap between plating and tiling; great for stashing \
|
||||
@@ -1287,9 +1315,6 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
|
||||
surplus = 30
|
||||
|
||||
//Space Suits and Hardsuits
|
||||
/datum/uplink_item/suits
|
||||
category = "Space Suits, Hardsuits and Clothing"
|
||||
surplus = 40
|
||||
|
||||
/datum/uplink_item/suits/turtlenck
|
||||
name = "Tactical Turtleneck"
|
||||
@@ -1364,8 +1389,6 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
|
||||
exclude_modes = list()
|
||||
|
||||
// Devices and Tools
|
||||
/datum/uplink_item/device_tools
|
||||
category = "Devices and Tools"
|
||||
|
||||
/datum/uplink_item/device_tools/emag
|
||||
name = "Cryptographic Sequencer"
|
||||
@@ -1380,6 +1403,12 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
|
||||
item = /obj/item/emagrecharge
|
||||
cost = 2
|
||||
|
||||
/datum/uplink_item/device_tools/phantomthief
|
||||
name = "Syndicate Mask"
|
||||
desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles"
|
||||
item = /obj/item/clothing/glasses/phantomthief/syndicate
|
||||
cost = 2
|
||||
|
||||
/datum/uplink_item/device_tools/cutouts
|
||||
name = "Adaptive Cardboard Cutouts"
|
||||
desc = "These cardboard cutouts are coated with a thin material that prevents discoloration and makes the images on them appear more lifelike. \
|
||||
@@ -1599,9 +1628,6 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
|
||||
|
||||
|
||||
// Implants
|
||||
/datum/uplink_item/implants
|
||||
category = "Implants"
|
||||
surplus = 50
|
||||
|
||||
/datum/uplink_item/implants/adrenal
|
||||
name = "Adrenal Implant"
|
||||
@@ -1698,10 +1724,6 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
|
||||
include_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
// Role-specific items
|
||||
/datum/uplink_item/role_restricted
|
||||
category = "Role-Restricted"
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
|
||||
surplus = 0
|
||||
|
||||
/datum/uplink_item/role_restricted/ancient_jumpsuit
|
||||
name = "Ancient Jumpsuit"
|
||||
@@ -1929,10 +1951,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
|
||||
item = /obj/item/gun/energy/emitter
|
||||
restricted_roles = list("Chief Engineer", "Station Engineer", "Atmospheric Technician")
|
||||
|
||||
// Pointless
|
||||
/datum/uplink_item/badass
|
||||
category = "(Pointless) Badassery"
|
||||
surplus = 0
|
||||
// Pointless (Badassery)
|
||||
|
||||
/datum/uplink_item/badass/costumes/obvious_chameleon
|
||||
name = "Broken Chameleon Kit"
|
||||
@@ -1986,12 +2005,6 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
|
||||
item = /obj/item/storage/secure/briefcase/syndie
|
||||
cost = 1
|
||||
|
||||
/datum/uplink_item/badass/phantomthief
|
||||
name = "Syndicate Mask"
|
||||
desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles"
|
||||
item = /obj/item/clothing/glasses/phantomthief/syndicate
|
||||
cost = 2
|
||||
|
||||
/datum/uplink_item/badass/syndiecards
|
||||
name = "Syndicate Playing Cards"
|
||||
desc = "A special deck of space-grade playing cards with a mono-molecular edge and metal reinforcement, \
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
.++
|
||||
|
||||
/obj/vehicle/proc/return_controllers_with_flag(flag)
|
||||
RETURN_TYPE(/list/mob)
|
||||
. = list()
|
||||
for(var/i in occupants)
|
||||
if(occupants[i] & flag)
|
||||
|
||||
@@ -595,7 +595,7 @@
|
||||
|
||||
for(var/mob/living/H in hearing_mobs)
|
||||
if(H && H.client && (isturf(H.loc)))
|
||||
H.show_message(struggle_outer_message, 1) // visible
|
||||
H.show_message(struggle_outer_message, MSG_VISUAL) // visible
|
||||
|
||||
to_chat(R,struggle_user_message)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user