This commit is contained in:
Ghommie
2019-06-24 16:48:15 +02:00
637 changed files with 17918 additions and 12263 deletions

View File

@@ -80,7 +80,7 @@ GLOBAL_VAR(antag_prototypes)
var/list/result = list()
if(!current)
result += "<span class='bad'>No body!</span>"
if(current && current.has_trait(TRAIT_MINDSHIELD))
if(current && HAS_TRAIT(current, TRAIT_MINDSHIELD))
result += "<span class='good'>Mindshielded</span>"
//Move these to mob
if(iscyborg(current))

View File

@@ -29,69 +29,62 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
/client/proc/callproc()
set category = "Debug"
set name = "Advanced ProcCall"
set waitfor = 0
set waitfor = FALSE
if(!check_rights(R_DEBUG))
return
var/datum/target = null
var/targetselected = 0
var/targetselected = FALSE
var/returnval = null
switch(alert("Proc owned by something?",,"Yes","No"))
if("Yes")
targetselected = 1
var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT))
if (!value["class"] || !value["value"])
return
target = value["value"]
if("No")
target = null
targetselected = 0
var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
if(!procname)
return
//hascall() doesn't support proc paths (eg: /proc/gib(), it only supports "gib")
var/testname = procname
if(targetselected)
//Find one of the 3 possible ways they could have written /proc/PROCNAME
if(findtext(procname, "/proc/"))
testname = replacetext(procname, "/proc/", "")
else if(findtext(procname, "/proc"))
testname = replacetext(procname, "/proc", "")
else if(findtext(procname, "proc/"))
testname = replacetext(procname, "proc/", "")
//Clear out any parenthesis if they're a dummy
testname = replacetext(testname, "()", "")
if(targetselected && !hascall(target,testname))
to_chat(usr, "<font color='red'>Error: callproc(): type [target.type] has no proc named [procname].</font>")
return
else
var/procpath = text2path(procname)
if (!procpath)
to_chat(usr, "<font color='red'>Error: callproc(): proc [procname] does not exist. (Did you forget the /proc/ part?)</font>")
if(alert("Proc owned by something?",,"Yes","No") == "Yes")
targetselected = TRUE
var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT))
if (!value["class"] || !value["value"])
return
target = value["value"]
var/procpath = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
if(!procpath)
return
//strip away everything but the proc name
var/list/proclist = splittext(procpath, "/")
if (!length(proclist))
return
var/procname = proclist[proclist.len]
var/proctype = ("verb" in proclist) ? "verb" :"proc"
if(targetselected)
if(!hascall(target, procname))
to_chat(usr, "<span class='warning'>Error: callproc(): type [target.type] has no [proctype] named [procpath].</span>")
return
else
procpath = "/[proctype]/[procname]"
if(!text2path(procpath))
to_chat(usr, "<span class='warning'>Error: callproc(): [procpath] does not exist.</span>")
return
var/list/lst = get_callproc_args()
if(!lst)
return
if(targetselected)
if(!target)
to_chat(usr, "<font color='red'>Error: callproc(): owner of proc no longer exists.</font>")
to_chat(usr, "<span class='warning'>Error: callproc(): owner of proc no longer exists.</span>")
return
var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no argument"]."
log_admin(msg)
message_admins(msg)
admin_ticket_log(target, msg)
returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc
returnval = WrapAdminProcCall(target, procname, lst)
else
//this currently has no hascall protection. wasn't able to get it working.
log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc
var/msg = "[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no argument"]."
log_admin(msg)
message_admins(msg)
returnval = WrapAdminProcCall(GLOBAL_PROC, procpath, lst) //calling globals needs full qualified name (e.g /proc/foo)
. = get_callproc_returnval(returnval, procname)
if(.)
to_chat(usr, .)
@@ -111,8 +104,8 @@ GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention)
GLOBAL_PROTECT(AdminProcCallSpamPrevention)
/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
if(target && procname == "Del")
to_chat(usr, "Calling Del() is not allowed")
if(target != GLOBAL_PROC && procname == "Del")
to_chat(usr, "<span class='warning'>Calling Del() is not allowed</span>")
return
if(target != GLOBAL_PROC && !target.CanProcCall(procname))
@@ -159,7 +152,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
set category = "Debug"
set name = "Atom ProcCall"
set waitfor = 0
set waitfor = FALSE
if(!check_rights(R_DEBUG))
return
@@ -168,7 +161,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
if(!procname)
return
if(!hascall(A,procname))
to_chat(usr, "<font color='red'>Error: callproc_datum(): type [A.type] has no proc named [procname].</font>")
to_chat(usr, "<span class='warning'>Error: callproc_datum(): type [A.type] has no proc named [procname].</span>")
return
var/list/lst = get_callproc_args()
if(!lst)
@@ -177,8 +170,8 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
if(!A || !IsValidSrc(A))
to_chat(usr, "<span class='warning'>Error: callproc_datum(): owner of proc no longer exists.</span>")
return
log_admin("[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
log_admin(msg)
message_admins(msg)
admin_ticket_log(A, msg)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Atom ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -188,8 +181,6 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
if(.)
to_chat(usr, .)
/client/proc/get_callproc_args()
var/argnum = input("Number of arguments","Number:",0) as num|null
if(isnull(argnum))
@@ -213,7 +204,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
. = ""
if(islist(returnval))
var/list/returnedlist = returnval
. = "<font color='blue'>"
. = "<span class='notice'>"
if(returnedlist.len)
var/assoc_check = returnedlist[1]
if(istext(assoc_check) && (returnedlist[assoc_check] != null))
@@ -227,11 +218,10 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
. += "\n[elem]"
else
. = "[procname] returned an empty list"
. += "</font>"
. += "</span>"
else
. = "<font color='blue'>[procname] returned: [!isnull(returnval) ? returnval : "null"]</font>"
. = "<span class='notice'>[procname] returned: [!isnull(returnval) ? returnval : "null"]</span>"
/client/proc/Cell()
set category = "Debug"
@@ -841,8 +831,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
if(Rad.anchored)
if(!Rad.loaded_tank)
var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad)
Plasma.air_contents.assert_gas(/datum/gas/plasma)
Plasma.air_contents.gases[/datum/gas/plasma][MOLES] = 70
Plasma.air_contents.gases[/datum/gas/plasma] = 70
Rad.drainratio = 0
Rad.loaded_tank = Plasma
Plasma.forceMove(Rad)

View File

@@ -9,10 +9,9 @@
var/list/lines = list("<span class='adminnotice'>[AREACOORD(target)]: [env.temperature] K ([env.temperature - T0C] C), [env.return_pressure()] kPa[(burning)?(", <font color='red'>burning</font>"):(null)]</span>")
for(var/id in env_gases)
var/gas = env_gases[id]
var/moles = gas[MOLES]
var/moles = env_gases[id]
if (moles >= 0.00001)
lines += "[gas[GAS_META][META_GAS_NAME]]: [moles] mol"
lines += "[GLOB.meta_gas_names[id]]: [moles] mol"
to_chat(usr, lines.Join("\n"))
/client/proc/air_status(turf/target)

View File

@@ -34,14 +34,14 @@
deity = "Nar'Sie"
else if(isliving(usr))
var/mob/living/L = usr
if(L.has_trait(TRAIT_SPIRITUAL))
if(HAS_TRAIT(L, TRAIT_SPIRITUAL))
cross.icon_state = "holylight"
font_color = "blue"
prayer_type = "SPIRITUAL PRAYER"
var/msg_tmp = msg
msg = "<span class='adminnotice'>[icon2html(cross, GLOB.admins)]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> <span class='linkify'>[msg]</span></span>"
for(var/client/C in GLOB.admins)
if(C.prefs.chat_toggles & CHAT_PRAYER)
to_chat(C, msg)

View File

@@ -108,20 +108,7 @@
to_chat(loc, "<span class='warning'>Combat injection is still recharging.</span>")
return
var/mob/living/carbon/human/M = loc
M.SetSleeping(0)
M.SetUnconscious(0)
M.SetStun(0)
M.SetKnockdown(0)
M.reagents.add_reagent("inaprovaline", 3)
M.reagents.add_reagent("synaptizine", 10)
M.reagents.add_reagent("stimulants", 10)
M.adjustStaminaLoss(-150)
M.stuttering = 0
M.updatehealth()
M.update_stamina()
M.resting = 0
M.lying = 0
M.update_canmove()
M.do_adrenaline(150, FALSE, 0, 0, TRUE, list("inaprovaline" = 3, "synaptizine" = 10, "omnizine" = 10), "<span class='boldnotice'>You feel a sudden surge of energy!</span>")
combat_cooldown = 0
START_PROCESSING(SSobj, src)

View File

@@ -272,10 +272,10 @@
/obj/item/organ/heart/gland/electric/Insert(mob/living/carbon/M, special = 0)
..()
owner.add_trait(TRAIT_SHOCKIMMUNE, ORGAN_TRAIT)
ADD_TRAIT(owner, TRAIT_SHOCKIMMUNE, ORGAN_TRAIT)
/obj/item/organ/heart/gland/electric/Remove(mob/living/carbon/M, special = 0)
owner.remove_trait(TRAIT_SHOCKIMMUNE, ORGAN_TRAIT)
REMOVE_TRAIT(owner, TRAIT_SHOCKIMMUNE, ORGAN_TRAIT)
..()
/obj/item/organ/heart/gland/electric/activate()

View File

@@ -126,8 +126,20 @@
if(vest)
vest.flip_mode()
/obj/machinery/abductor/console/proc/SelectDisguise(remote = 0)
var/entry_name = input( "Choose Disguise", "Disguise") as null|anything in disguises
/obj/machinery/abductor/console/proc/SelectDisguise(remote = FALSE)
var/list/disguises2 = list()
for(var/name in disguises)
var/datum/icon_snapshot/snap = disguises[name]
var/image/dummy = image(snap.icon, src, snap.icon_state)
dummy.overlays = snap.overlays
disguises2[name] = dummy
var/entry_name
if(remote)
entry_name = show_radial_menu(usr, camera.eyeobj, disguises2)
else
entry_name = show_radial_menu(usr, src, disguises2)
var/datum/icon_snapshot/chosen = disguises[entry_name]
if(chosen && vest && (remote || in_range(usr,src)))
vest.SetDisguise(chosen)

View File

@@ -169,7 +169,7 @@
to_chat(owner.current, "We have reached our capacity for abilities.")
return
if(owner.current.has_trait(TRAIT_DEATHCOMA))//To avoid potential exploits by buying new powers while in stasis, which clears your verblist.
if(HAS_TRAIT(owner.current, TRAIT_DEATHCOMA))//To avoid potential exploits by buying new powers while in stasis, which clears your verblist.
to_chat(owner.current, "We lack the energy to evolve new abilities right now.")
return
@@ -239,7 +239,7 @@
if(verbose)
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
return
if((target.has_trait(TRAIT_NOCLONE)) || (target.has_trait(TRAIT_NOCLONE)))
if((HAS_TRAIT(target, TRAIT_NOCLONE)) || (HAS_TRAIT(target, TRAIT_NOCLONE)))
if(verbose)
to_chat(user, "<span class='warning'>DNA of [target] is ruined beyond usability!</span>")
return

View File

@@ -68,7 +68,7 @@
if(req_stat < user.stat)
to_chat(user, "<span class='warning'>We are incapacitated.</span>")
return 0
if((user.has_trait(TRAIT_DEATHCOMA)) && (!ignores_fakedeath))
if((HAS_TRAIT(user, TRAIT_DEATHCOMA)) && (!ignores_fakedeath))
to_chat(user, "<span class='warning'>We are incapacitated.</span>")
return 0
return 1

View File

@@ -12,21 +12,5 @@
//Recover from stuns.
/obj/effect/proc_holder/changeling/adrenaline/sting_action(mob/living/user)
to_chat(user, "<span class='notice'>Energy rushes through us.[user.lying ? " We arise." : ""]</span>")
user.SetSleeping(0)
user.SetUnconscious(0)
user.SetStun(0)
user.SetKnockdown(0)
user.reagents.add_reagent("changelingadrenaline", 10)
user.reagents.add_reagent("changelinghaste", 2) //For a really quick burst of speed
user.reagents.add_reagent("inaprovaline", 3) //let's give another chance to dumb fucks who forget to breathe
user.adjustStaminaLoss(-150)
user.stuttering = 0
user.updatehealth()
user.update_stamina()
user.resting = 0
user.lying = 0
user.update_canmove()
user.do_adrenaline(0, FALSE, 70, 0, TRUE, list("epinephrine" = 3, "changelingmeth" = 10, "mannitol" = 10, "regen_jelly" = 10, "changelingadrenaline" = 5), "<span class='notice'>Energy rushes through us.</span>", 0, 0.75, 0)
return TRUE

View File

@@ -33,7 +33,7 @@
RV.action.Grant(user)
/obj/effect/proc_holder/changeling/fakedeath/can_sting(mob/living/user)
if(user.has_trait(TRAIT_DEATHCOMA, "changeling"))
if(HAS_TRAIT_FROM(user, TRAIT_DEATHCOMA, "changeling"))
to_chat(user, "<span class='warning'>We are already reviving.</span>")
return
if(!user.stat) //Confirmation for living changelings if they want to fake their death

View File

@@ -10,7 +10,7 @@
action_background_icon_state = "bg_ling"
/obj/effect/proc_holder/changeling/hivemind_comms/sting_action(var/mob/living/user)
if (user.has_trait(CHANGELING_HIVEMIND_MUTE))
if (HAS_TRAIT(user, CHANGELING_HIVEMIND_MUTE))
to_chat(user, "<span class='warning'>The poison in the air hinders our ability to interact with the hivemind.</span>")
return
var/input = html_decode(stripped_input(usr, "Please choose a message to transmit.", "Changeling Hivemind", ""))
@@ -47,7 +47,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank)
action_background_icon_state = "bg_ling"
/obj/effect/proc_holder/changeling/hivemind_upload/sting_action(var/mob/living/user)
if (user.has_trait(CHANGELING_HIVEMIND_MUTE))
if (HAS_TRAIT(user, CHANGELING_HIVEMIND_MUTE))
to_chat(user, "<span class='warning'>The poison in the air hinders our ability to interact with the hivemind.</span>")
return
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
@@ -86,7 +86,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank)
/obj/effect/proc_holder/changeling/hivemind_download/can_sting(mob/living/carbon/user)
if(!..())
return
if (user.has_trait(CHANGELING_HIVEMIND_MUTE))
if (HAS_TRAIT(user, CHANGELING_HIVEMIND_MUTE))
to_chat(user, "<span class='warning'>The poison in the air hinders our ability to interact with the hivemind.</span>")
return
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)

View File

@@ -344,9 +344,8 @@
if(isitem(target))
var/obj/item/I = target
if(!I.anchored)
to_chat(firer, "<span class='notice'>You pull [I] towards yourself.</span>")
H.throw_mode_on()
I.throw_at(H, 10, 2)
to_chat(firer, "<span class='notice'>You pull [I] right into your grasp.</span>")
H.put_in_hands(I) //Because throwing it is goofy as fuck and unreliable. If you land the tentacle despite the penalties to accuracy, you should have your reward.
. = 1
else if(isliving(target))

View File

@@ -29,7 +29,7 @@
O.forceMove(get_turf(user))
user.reagents.add_reagent("mutadone", 10)
user.reagents.add_reagent("pen_acid", 20)
user.reagents.add_reagent("pen_jelly", 20)
user.reagents.add_reagent("antihol", 10)
user.reagents.add_reagent("mannitol", 25)

View File

@@ -37,7 +37,7 @@
if(!.)
return
if(user.has_trait(CHANGELING_DRAIN) || ((user.stat != DEAD) && !(user.has_trait(TRAIT_DEATHCOMA))))
if(HAS_TRAIT(user, CHANGELING_DRAIN) || ((user.stat != DEAD) && !(HAS_TRAIT(user, TRAIT_DEATHCOMA))))
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
changeling.purchasedpowers -= src
return FALSE

View File

@@ -19,7 +19,7 @@
if(active)
to_chat(user, "<span class='notice'>Our muscles tense and strengthen.</span>")
else
user.remove_trait(TRAIT_GOTTAGOFAST, "changeling_muscles")
REMOVE_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles")
to_chat(user, "<span class='notice'>Our muscles relax.</span>")
if(stacks >= 10)
to_chat(user, "<span class='danger'>We collapse in exhaustion.</span>")
@@ -32,12 +32,12 @@
/obj/effect/proc_holder/changeling/strained_muscles/proc/muscle_loop(mob/living/carbon/user)
while(active)
user.add_trait(TRAIT_GOTTAGOFAST, "changeling_muscles")
ADD_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles")
if(user.stat != CONSCIOUS || user.staminaloss >= 90)
active = !active
to_chat(user, "<span class='notice'>Our muscles relax without the energy to strengthen them.</span>")
user.Knockdown(40)
user.remove_trait(TRAIT_GOTTAGOFAST, "changeling_muscles")
REMOVE_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles")
break
stacks++

View File

@@ -91,7 +91,7 @@
/obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/living/carbon/target)
if(!..())
return
if((target.has_trait(TRAIT_HUSK)) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits))
if((HAS_TRAIT(target, TRAIT_HUSK)) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits))
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
return 0
return 1
@@ -134,7 +134,7 @@
return
if(isliving(target))
var/mob/living/L = target
if((L.has_trait(TRAIT_HUSK)) || !L.has_dna())
if((HAS_TRAIT(L, TRAIT_HUSK)) || !L.has_dna())
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
return 0
return 1

View File

@@ -32,7 +32,7 @@
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
if(src == H.glasses && !up)
if(H.has_trait(TRAIT_BLIND))
if(HAS_TRAIT(H, TRAIT_BLIND))
to_chat(H, "<span class='heavy_brass'>\"You're blind, idiot. Stop embarrassing yourself.\"</span>")
return
if(blind_cultist(H))
@@ -76,7 +76,7 @@
..()
if(slot != SLOT_GLASSES || up)
return
if(user.has_trait(TRAIT_BLIND))
if(HAS_TRAIT(user, TRAIT_BLIND))
to_chat(user, "<span class='heavy_brass'>\"You're blind, idiot. Stop embarrassing yourself.\"</span>" )
return
if(blind_cultist(user)) //Cultists instantly go blind
@@ -115,11 +115,11 @@
var/obj/item/clothing/glasses/wraith_spectacles/WS = L.glasses
desc = "[glasses_right && !WS.up ? "<font color=#DAAA18><b>":""]You are [glasses_right ? "":"not "]wearing wraith spectacles[glasses_right && !WS.up ? "!</b></font>":"."]<br>\
You have taken <font color=#DAAA18><b>[W.eye_damage_done]</b></font> eye damage from them.<br>"
if(L.has_trait(TRAIT_NEARSIGHT))
if(HAS_TRAIT(L, TRAIT_NEARSIGHT))
desc += "<font color=#DAAA18><b>You are nearsighted!</b></font><br>"
else if(glasses_right && !WS.up)
desc += "You will become nearsighted at <font color=#DAAA18><b>[W.nearsight_breakpoint]</b></font> eye damage.<br>"
if(L.has_trait(TRAIT_BLIND))
if(HAS_TRAIT(L, TRAIT_BLIND))
desc += "<font color=#DAAA18><b>You are blind!</b></font>"
else if(glasses_right && !WS.up)
desc += "You will become blind at <font color=#DAAA18><b>[W.blind_breakpoint]</b></font> eye damage."
@@ -153,18 +153,18 @@
qdel(src)
/datum/status_effect/wraith_spectacles/proc/apply_eye_damage(mob/living/carbon/human/H)
if(H.has_trait(TRAIT_BLIND))
if(HAS_TRAIT(H, TRAIT_BLIND))
return
H.adjust_eye_damage(0.5)
eye_damage_done += 0.5
if(eye_damage_done >= 20)
H.adjust_blurriness(2)
if(eye_damage_done >= nearsight_breakpoint)
if(!H.has_trait(TRAIT_NEARSIGHT))
if(!HAS_TRAIT(H, TRAIT_NEARSIGHT))
to_chat(H, "<span class='nzcrentr'>Your vision doubles, then trembles. Darkness begins to close in. You can't keep this up!</span>")
H.become_nearsighted(EYE_DAMAGE)
if(eye_damage_done >= blind_breakpoint)
if(!H.has_trait(TRAIT_BLIND))
if(!HAS_TRAIT(H, TRAIT_BLIND))
to_chat(H, "<span class='nzcrentr_large'>A piercing white light floods your vision. Suddenly, all goes dark!</span>")
H.become_blind(EYE_DAMAGE)

View File

@@ -110,7 +110,7 @@
if(!(BI.resistance_flags & ON_FIRE))
BI.fire_act()
continue
if(is_servant_of_ratvar(L) || (L.has_trait(TRAIT_BLIND)) || L.anti_magic_check(TRUE, TRUE))
if(is_servant_of_ratvar(L) || (HAS_TRAIT(L, TRAIT_BLIND)) || L.anti_magic_check(TRUE, TRUE))
continue
if(L.stat || L.lying)
continue

View File

@@ -0,0 +1,86 @@
/obj/structure/destructible/clockwork/reflector
name = "reflector"
desc = "A large lantern-shaped machine made of thin brass. It looks fragile."
clockwork_desc = "A lantern-shaped generator that produces power when near starlight."
icon_state = "reflector"
unanchored_icon = "reflector_unwrenched"
max_integrity = 40
construction_value = 5
layer = WALL_OBJ_LAYER
break_message = "<span class='warning'>The reflectors's fragile shield shatters into pieces!</span>"
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
light_color = "#DAAA18"
var/list/allowed_projectile_typecache = list(
/obj/item/projectile/beam
)
var/ini_dir = null
/obj/structure/destructible/clockwork/reflector/Initialize()
. = ..()
allowed_projectile_typecache = typecacheof(allowed_projectile_typecache)
/obj/structure/destructible/clockwork/reflector/ComponentInitialize()
. = ..()
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS ,null,CALLBACK(src, .proc/can_be_rotated),CALLBACK(src,.proc/after_rotation))
/obj/structure/destructible/clockwork/reflector/bullet_act(obj/item/projectile/P)
if(!anchored || !allowed_projectile_typecache[P.type] || !(P.dir in GLOB.cardinals))
return ..()
if(auto_reflect(P, P.dir, get_turf(P), P.Angle) != -1)
return ..()
return -1
/obj/structure/destructible/clockwork/reflector/proc/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle)
//Yell at me if this exists already.
var/real_angle = 0
switch(dir)
if(NORTH)
real_angle = 0
if(EAST)
real_angle = 90
if(SOUTH)
real_angle = 180
if(WEST)
real_angle = 270
var/incidence = GET_ANGLE_OF_INCIDENCE(real_angle, (P.Angle + 180))
if(abs(incidence) > 90 && abs(incidence) < 270)
return FALSE
var/new_angle = SIMPLIFY_DEGREES(real_angle + incidence)
P.setAngle(new_angle)
P.ignore_source_check = TRUE
P.range = P.decayedRange
P.decayedRange = max(P.decayedRange--, 0)
return -1
/obj/structure/destructible/clockwork/reflector/proc/can_be_rotated(mob/user,rotation_type)
if(anchored)
to_chat(user, "<span class='warning'>[src] cannot be rotated while it is fastened to the floor!</span>")
return FALSE
return TRUE
/obj/structure/destructible/clockwork/reflector/Move()
. = ..()
setDir(ini_dir)
/obj/structure/destructible/clockwork/reflector/proc/after_rotation(mob/user,rotation_type)
ini_dir = dir
add_fingerprint(user)
/obj/structure/destructible/clockwork/reflector/wrench_act(mob/living/user, obj/item/I)
if(!is_servant_of_ratvar(user))
return ..()
anchored = !anchored
to_chat(user, "<span class='notice'>You [anchored ? "secure" : "unsecure"] \the [src].</span>")
I.play_tool_sound(src)
return TRUE

View File

@@ -131,7 +131,7 @@
var/mob/living/carbon/human/H = current
H.eye_color = initial(H.eye_color)
H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
H.remove_trait(CULT_EYES)
REMOVE_TRAIT(H, TRAIT_CULT_EYES, "valid_cultist")
H.update_body()
H.cut_overlays()
H.regenerate_icons()
@@ -225,7 +225,7 @@
var/mob/living/carbon/human/H = current
H.eye_color = initial(H.eye_color)
H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
H.remove_trait(CULT_EYES)
REMOVE_TRAIT(H, TRAIT_CULT_EYES, "valid_cultist")
H.cut_overlays()
H.regenerate_icons()
@@ -301,7 +301,7 @@
var/mob/living/carbon/human/H = cultist
H.eye_color = "f00"
H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
H.add_trait(CULT_EYES)
ADD_TRAIT(H, TRAIT_CULT_EYES, "valid_cultist")
H.update_body()
/datum/team/cult/proc/ascend(cultist)
@@ -361,6 +361,7 @@
reshape.Shift(EAST, 1)
reshape.Crop(7,4,26,31)
reshape.Crop(-5,-3,26,30)
return reshape
/mob/living/carbon/human/get_sac_image()
var/datum/job/sacjob = SSjob.GetJob(mind.assigned_role)
@@ -370,6 +371,7 @@
reshape.Shift(EAST, 1)
reshape.Crop(7,4,26,31)
reshape.Crop(-5,-3,26,30)
return reshape
/datum/objective/sacrifice
var/sacced = FALSE

View File

@@ -342,10 +342,7 @@
if(cooldown>world.time)
to_chat(owner, "<span class='cultbold'>You aren't ready to place another blood mark yet!</span>")
return
if(owner.orbiting && owner.orbiting.orbiting)
target = owner.orbiting.orbiting
else
target = get_turf(owner)
target = owner.orbiting?.parent || get_turf(owner)
if(!target)
return
C.cult_team.blood_target = target

View File

@@ -990,6 +990,6 @@
continue
throw_at(Next, 3, 1, D.thrower)
return
throw_at(D.thrower, 7, 1, D.thrower)
throw_at(D.thrower, 7, 1, null)
else
..()

View File

@@ -123,7 +123,7 @@ structure_check() searches for nearby cultist structures required for the invoca
continue
if(ishuman(L))
var/mob/living/carbon/human/H = L
if((H.has_trait(TRAIT_MUTE)) || H.silent)
if((HAS_TRAIT(H, TRAIT_MUTE)) || H.silent)
continue
if(L.stat)
continue
@@ -250,14 +250,14 @@ structure_check() searches for nearby cultist structures required for the invoca
currentconversionman = convertee
conversiontimeout = world.time + (10 SECONDS)
convertee.Stun(100)
convertee.add_trait(TRAIT_MUTE, "conversionrune")
ADD_TRAIT(convertee, TRAIT_MUTE, "conversionrune")
conversionresult = FALSE
while(world.time < conversiontimeout && convertee && !conversionresult)
stoplag(1)
currentconversionman = null
if(!convertee)
return FALSE
convertee.remove_trait(TRAIT_MUTE, "conversionrune")
REMOVE_TRAIT(convertee, TRAIT_MUTE, "conversionrune")
if(get_turf(convertee) != get_turf(src))
return FALSE
if(!conversionresult)

View File

@@ -94,7 +94,7 @@
visible_message("<span class='warning'>[src] easily breaks out of [p_their()] handcuffs!</span>", \
"<span class='notice'>With just a thought your handcuffs fall off.</span>")
/mob/living/carbon/true_devil/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE)
/mob/living/carbon/true_devil/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
if(incapacitated())
to_chat(src, "<span class='warning'>You can't do that right now!</span>")
return FALSE

View File

@@ -7,11 +7,11 @@
/datum/antagonist/highlander/apply_innate_effects(mob/living/mob_override)
var/mob/living/L = owner.current || mob_override
L.add_trait(TRAIT_NOGUNS, "highlander")
ADD_TRAIT(L, TRAIT_NOGUNS, "highlander")
/datum/antagonist/highlander/remove_innate_effects(mob/living/mob_override)
var/mob/living/L = owner.current || mob_override
L.remove_trait(TRAIT_NOGUNS, "highlander")
REMOVE_TRAIT(L, TRAIT_NOGUNS, "highlander")
/datum/antagonist/highlander/proc/forge_objectives()
var/datum/objective/steal/steal_objective = new

View File

@@ -37,7 +37,7 @@
if(M == user)
to_chat(user,"<span class='warning'>You cannot convert yourself!</span>")
return
if(M.has_trait(TRAIT_MINDSHIELD))
if(HAS_TRAIT(M, TRAIT_MINDSHIELD))
to_chat(user, "<span class='danger'>This mind is too strong to convert, try to remove whatever is protecting it first!</span>")
return
M.visible_message("<span class='warning'>[user] is attempting to implant [M].</span>")

View File

@@ -17,7 +17,7 @@
return FALSE
if(new_owner.unconvertable)
return FALSE
if(new_owner.current && new_owner.current.has_trait(TRAIT_MINDSHIELD))
if(new_owner.current && HAS_TRAIT(new_owner.current, TRAIT_MINDSHIELD))
return FALSE
/datum/antagonist/rev/apply_innate_effects(mob/living/mob_override)

View File

@@ -27,6 +27,7 @@
var/datum/wires/connected = null
var/next_activate = 0 //When we're next allowed to activate - for spam control
var/activate_cooldown = 3 SECONDS
/obj/item/assembly/get_part_rating()
return 1
@@ -78,7 +79,7 @@
/obj/item/assembly/proc/activate()
if(QDELETED(src) || !secured || (next_activate > world.time))
return FALSE
next_activate = world.time + 30
next_activate = world.time + activate_cooldown
return TRUE

View File

@@ -1,203 +1,202 @@
/obj/item/onetankbomb
name = "bomb"
icon = 'icons/obj/tank.dmi'
item_state = "assembly"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
throwforce = 5
w_class = WEIGHT_CLASS_NORMAL
throw_speed = 2
throw_range = 4
flags_1 = CONDUCT_1
var/status = FALSE //0 - not readied //1 - bomb finished with welder
var/obj/item/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device
var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank
/obj/item/onetankbomb/IsSpecialAssembly()
return TRUE
/obj/item/onetankbomb/examine(mob/user)
bombtank.examine(user)
/obj/item/onetankbomb/update_icon()
cut_overlays()
if(bombtank)
icon = bombtank.icon
icon_state = bombtank.icon_state
if(bombassembly)
add_overlay(bombassembly.icon_state)
copy_overlays(bombassembly)
add_overlay("bomb_assembly")
/obj/item/onetankbomb/wrench_act(mob/living/user, obj/item/I)
to_chat(user, "<span class='notice'>You disassemble [src]!</span>")
if(bombassembly)
bombassembly.forceMove(drop_location())
bombassembly.master = null
bombassembly = null
if(bombtank)
bombtank.forceMove(drop_location())
bombtank.master = null
bombtank = null
qdel(src)
return TRUE
/obj/item/onetankbomb/welder_act(mob/living/user, obj/item/I)
. = FALSE
if(status)
to_chat(user, "<span class='notice'>[bombtank] already has a pressure hole!</span>")
return
if(!I.tool_start_check(user, amount=0))
return
if(I.use_tool(src, user, 0, volume=40))
status = TRUE
GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
message_admins("[ADMIN_LOOKUPFLW(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]")
to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>")
add_fingerprint(user)
return TRUE
/obj/item/onetankbomb/analyzer_act(mob/living/user, obj/item/I)
bombtank.analyzer_act(user, I)
/obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly
bombassembly.attack_self(user, TRUE)
add_fingerprint(user)
return
/obj/item/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here.
audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*")
playsound(src, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
sleep(10)
if(QDELETED(src))
return
if(status)
bombtank.ignite() //if its not a dud, boom (or not boom if you made shitty mix) the ignite proc is below, in this file
else
bombtank.release()
//Assembly / attached device memes
/obj/item/onetankbomb/Crossed(atom/movable/AM as mob|obj) //for mousetraps
. = ..()
if(bombassembly)
bombassembly.Crossed(AM)
/obj/item/onetankbomb/on_found(mob/finder) //for mousetraps
if(bombassembly)
bombassembly.on_found(finder)
/obj/item/onetankbomb/attack_hand() //also for mousetraps
. = ..()
if(.)
return
if(bombassembly)
bombassembly.attack_hand()
/obj/item/onetankbomb/Move()
. = ..()
if(bombassembly)
bombassembly.setDir(dir)
bombassembly.Move()
/obj/item/onetankbomb/dropped()
. = ..()
if(bombassembly)
bombassembly.dropped()
// ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ----------
//Bomb assembly proc. This turns assembly+tank into a bomb
/obj/item/tank/proc/bomb_assemble(obj/item/assembly_holder/assembly, mob/living/user)
//Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
if(isigniter(assembly.a_left) == isigniter(assembly.a_right))
return
if((src in user.get_equipped_items(TRUE)) && !user.canUnEquip(src))
to_chat(user, "<span class='warning'>[src] is stuck to you!</span>")
return
if(!user.canUnEquip(assembly))
to_chat(user, "<span class='warning'>[assembly] is stuck to your hand!</span>")
return
var/obj/item/onetankbomb/bomb = new
user.transferItemToLoc(src, bomb)
user.transferItemToLoc(assembly, bomb)
bomb.bombassembly = assembly //Tell the bomb about its assembly part
assembly.master = bomb //Tell the assembly about its new owner
bomb.bombtank = src //Same for tank
master = bomb
forceMove(bomb)
bomb.update_icon()
user.put_in_hands(bomb) //Equips the bomb if possible, or puts it on the floor.
to_chat(user, "<span class='notice'>You attach [assembly] to [src].</span>")
return
/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode
air_contents.assert_gases(/datum/gas/plasma, /datum/gas/oxygen)
var/fuel_moles = air_contents.gases[/datum/gas/plasma][MOLES] + air_contents.gases[/datum/gas/oxygen][MOLES]/6
air_contents.garbage_collect()
var/datum/gas_mixture/bomb_mixture = air_contents.copy()
var/strength = 1
var/turf/ground_zero = get_turf(loc)
if(master)
qdel(master)
qdel(src)
if(bomb_mixture.temperature > (T0C + 400))
strength = (fuel_moles/15)
if(strength >=1)
explosion(ground_zero, round(strength,1), round(strength*2,1), round(strength*3,1), round(strength*4,1))
else if(strength >=0.5)
explosion(ground_zero, 0, 1, 2, 4)
else if(strength >=0.2)
explosion(ground_zero, -1, 0, 1, 2)
else
ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125)
else if(bomb_mixture.temperature > (T0C + 250))
strength = (fuel_moles/20)
if(strength >=1)
explosion(ground_zero, 0, round(strength,1), round(strength*2,1), round(strength*3,1))
else if (strength >=0.5)
explosion(ground_zero, -1, 0, 1, 2)
else
ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125)
else if(bomb_mixture.temperature > (T0C + 100))
strength = (fuel_moles/25)
if (strength >=1)
explosion(ground_zero, -1, 0, round(strength,1), round(strength*3,1))
else
ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125)
else
ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125)
ground_zero.air_update_turf()
/obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out.
var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src)
if(!T)
return
T.assume_air(removed)
air_update_turf()
/obj/item/onetankbomb
name = "bomb"
icon = 'icons/obj/tank.dmi'
item_state = "assembly"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
throwforce = 5
w_class = WEIGHT_CLASS_NORMAL
throw_speed = 2
throw_range = 4
flags_1 = CONDUCT_1
var/status = FALSE //0 - not readied //1 - bomb finished with welder
var/obj/item/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device
var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank
/obj/item/onetankbomb/IsSpecialAssembly()
return TRUE
/obj/item/onetankbomb/examine(mob/user)
bombtank.examine(user)
/obj/item/onetankbomb/update_icon()
cut_overlays()
if(bombtank)
icon = bombtank.icon
icon_state = bombtank.icon_state
if(bombassembly)
add_overlay(bombassembly.icon_state)
copy_overlays(bombassembly)
add_overlay("bomb_assembly")
/obj/item/onetankbomb/wrench_act(mob/living/user, obj/item/I)
to_chat(user, "<span class='notice'>You disassemble [src]!</span>")
if(bombassembly)
bombassembly.forceMove(drop_location())
bombassembly.master = null
bombassembly = null
if(bombtank)
bombtank.forceMove(drop_location())
bombtank.master = null
bombtank = null
qdel(src)
return TRUE
/obj/item/onetankbomb/welder_act(mob/living/user, obj/item/I)
. = FALSE
if(status)
to_chat(user, "<span class='notice'>[bombtank] already has a pressure hole!</span>")
return
if(!I.tool_start_check(user, amount=0))
return
if(I.use_tool(src, user, 0, volume=40))
status = TRUE
GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
message_admins("[ADMIN_LOOKUPFLW(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]")
to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>")
add_fingerprint(user)
return TRUE
/obj/item/onetankbomb/analyzer_act(mob/living/user, obj/item/I)
bombtank.analyzer_act(user, I)
/obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly
bombassembly.attack_self(user, TRUE)
add_fingerprint(user)
return
/obj/item/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here.
audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*")
playsound(src, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
sleep(10)
if(QDELETED(src))
return
if(status)
bombtank.ignite() //if its not a dud, boom (or not boom if you made shitty mix) the ignite proc is below, in this file
else
bombtank.release()
//Assembly / attached device memes
/obj/item/onetankbomb/Crossed(atom/movable/AM as mob|obj) //for mousetraps
. = ..()
if(bombassembly)
bombassembly.Crossed(AM)
/obj/item/onetankbomb/on_found(mob/finder) //for mousetraps
if(bombassembly)
bombassembly.on_found(finder)
/obj/item/onetankbomb/attack_hand() //also for mousetraps
. = ..()
if(.)
return
if(bombassembly)
bombassembly.attack_hand()
/obj/item/onetankbomb/Move()
. = ..()
if(bombassembly)
bombassembly.setDir(dir)
bombassembly.Move()
/obj/item/onetankbomb/dropped()
. = ..()
if(bombassembly)
bombassembly.dropped()
// ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ----------
//Bomb assembly proc. This turns assembly+tank into a bomb
/obj/item/tank/proc/bomb_assemble(obj/item/assembly_holder/assembly, mob/living/user)
//Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
if(isigniter(assembly.a_left) == isigniter(assembly.a_right))
return
if((src in user.get_equipped_items(TRUE)) && !user.canUnEquip(src))
to_chat(user, "<span class='warning'>[src] is stuck to you!</span>")
return
if(!user.canUnEquip(assembly))
to_chat(user, "<span class='warning'>[assembly] is stuck to your hand!</span>")
return
var/obj/item/onetankbomb/bomb = new
user.transferItemToLoc(src, bomb)
user.transferItemToLoc(assembly, bomb)
bomb.bombassembly = assembly //Tell the bomb about its assembly part
assembly.master = bomb //Tell the assembly about its new owner
bomb.bombtank = src //Same for tank
master = bomb
forceMove(bomb)
bomb.update_icon()
user.put_in_hands(bomb) //Equips the bomb if possible, or puts it on the floor.
to_chat(user, "<span class='notice'>You attach [assembly] to [src].</span>")
return
/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode
var/fuel_moles = air_contents.gases[/datum/gas/plasma] + air_contents.gases[/datum/gas/oxygen]/6
GAS_GARBAGE_COLLECT(air_contents.gases)
var/datum/gas_mixture/bomb_mixture = air_contents.copy()
var/strength = 1
var/turf/ground_zero = get_turf(loc)
if(master)
qdel(master)
qdel(src)
if(bomb_mixture.temperature > (T0C + 400))
strength = (fuel_moles/15)
if(strength >=1)
explosion(ground_zero, round(strength,1), round(strength*2,1), round(strength*3,1), round(strength*4,1))
else if(strength >=0.5)
explosion(ground_zero, 0, 1, 2, 4)
else if(strength >=0.2)
explosion(ground_zero, -1, 0, 1, 2)
else
ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125)
else if(bomb_mixture.temperature > (T0C + 250))
strength = (fuel_moles/20)
if(strength >=1)
explosion(ground_zero, 0, round(strength,1), round(strength*2,1), round(strength*3,1))
else if (strength >=0.5)
explosion(ground_zero, -1, 0, 1, 2)
else
ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125)
else if(bomb_mixture.temperature > (T0C + 100))
strength = (fuel_moles/25)
if (strength >=1)
explosion(ground_zero, -1, 0, round(strength,1), round(strength*3,1))
else
ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125)
else
ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125)
ground_zero.air_update_turf()
/obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out.
var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src)
if(!T)
return
T.assume_air(removed)
air_update_turf()

View File

@@ -43,7 +43,7 @@
holder.update_icon()
/obj/item/assembly/flash/proc/clown_check(mob/living/carbon/human/user)
if(user.has_trait(TRAIT_CLUMSY) && prob(50))
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
flash_carbon(user, user, 15, 0)
return FALSE
return TRUE

View File

@@ -18,7 +18,7 @@
if(!armed)
if(ishuman(usr))
var/mob/living/carbon/human/user = usr
if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50))
if((HAS_TRAIT(user, TRAIT_DUMB) || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
to_chat(user, "<span class='warning'>Your hand slips, setting off the trigger!</span>")
pulse(FALSE)
update_icon()
@@ -38,7 +38,7 @@
var/obj/item/bodypart/affecting = null
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.has_trait(TRAIT_PIERCEIMMUNE))
if(HAS_TRAIT(H, TRAIT_PIERCEIMMUNE))
playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
armed = FALSE
update_icon()
@@ -70,7 +70,7 @@
if(!armed)
to_chat(user, "<span class='notice'>You arm [src].</span>")
else
if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50))
if((HAS_TRAIT(user, TRAIT_DUMB) || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
var/which_hand = BODY_ZONE_PRECISE_L_HAND
if(!(user.active_hand_index % 2))
which_hand = BODY_ZONE_PRECISE_R_HAND
@@ -87,7 +87,7 @@
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/assembly/mousetrap/attack_hand(mob/living/carbon/human/user)
if(armed)
if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50))
if((HAS_TRAIT(user, TRAIT_DUMB) || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
var/which_hand = BODY_ZONE_PRECISE_L_HAND
if(!(user.active_hand_index % 2))
which_hand = BODY_ZONE_PRECISE_R_HAND

View File

@@ -14,9 +14,9 @@
if(!air_contents)
return 0
var/oxy = air_contents.gases[/datum/gas/oxygen] ? air_contents.gases[/datum/gas/oxygen][MOLES] : 0
var/tox = air_contents.gases[/datum/gas/plasma] ? air_contents.gases[/datum/gas/plasma][MOLES] : 0
var/trit = air_contents.gases[/datum/gas/tritium] ? air_contents.gases[/datum/gas/tritium][MOLES] : 0
var/oxy = air_contents.gases[/datum/gas/oxygen]
var/tox = air_contents.gases[/datum/gas/plasma]
var/trit = air_contents.gases[/datum/gas/tritium]
if(active_hotspot)
if(soh)
if((tox > 0.5 || trit > 0.5) && oxy > 0.5)
@@ -162,7 +162,7 @@
color = list(LERP(0.3, 1, 1-greyscale_fire) * heat_r,0.3 * heat_g * greyscale_fire,0.3 * heat_b * greyscale_fire, 0.59 * heat_r * greyscale_fire,LERP(0.59, 1, 1-greyscale_fire) * heat_g,0.59 * heat_b * greyscale_fire, 0.11 * heat_r * greyscale_fire,0.11 * heat_g * greyscale_fire,LERP(0.11, 1, 1-greyscale_fire) * heat_b, 0,0,0)
alpha = heat_a
#define INSUFFICIENT(path) (!location.air.gases[path] || location.air.gases[path][MOLES] < 0.5)
#define INSUFFICIENT(path) (location.air.gases[path] < 0.5)
/obj/effect/hotspot/process()
if(just_spawned)
just_spawned = FALSE
@@ -184,7 +184,7 @@
return
//Not enough to burn
if(((!location.air.gases[/datum/gas/plasma] || location.air.gases[/datum/gas/plasma][MOLES] < 0.5) && (!location.air.gases[/datum/gas/tritium] || location.air.gases[/datum/gas/tritium][MOLES] < 0.5)) || location.air.gases[/datum/gas/oxygen][MOLES] < 0.5)
if((location.air.gases[/datum/gas/plasma] < 0.5 && location.air.gases[/datum/gas/tritium] < 0.5) || location.air.gases[/datum/gas/oxygen] < 0.5)
qdel(src)
return

View File

@@ -88,7 +88,7 @@
temperature_archived = temperature
/turf/open/archive()
air.archive()
ARCHIVE_TEMPERATURE(air)
archived_cycle = SSair.times_fired
temperature_archived = temperature
@@ -121,10 +121,9 @@
if (nonoverlaying_gases[id])
continue
var/gas = gases[id]
var/gas_meta = gas[GAS_META]
var/gas_overlay = gas_meta[META_GAS_OVERLAY]
if(gas_overlay && gas[MOLES] > gas_meta[META_GAS_MOLES_VISIBLE])
. += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(gas[MOLES] / MOLES_GAS_VISIBLE_STEP, 1))]
var/gas_overlay = GLOB.meta_gas_overlays[id]
if(gas_overlay && gas > GLOB.meta_gas_visibility[id])
. += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(gas / MOLES_GAS_VISIBLE_STEP, 1))]
/proc/typecache_of_gases_with_no_overlays()
. = list()
@@ -215,7 +214,7 @@
if (planet_atmos) //share our air with the "atmosphere" "above" the turf
var/datum/gas_mixture/G = new
G.copy_from_turf(src)
G.archive()
ARCHIVE_TEMPERATURE(G)
if(our_air.compare(G))
if(!our_excited_group)
var/datum/excited_group/EG = new
@@ -232,6 +231,11 @@
atmos_cooldown = cached_atmos_cooldown
/turf/open/space/process_cell(fire_count) //dumb hack to prevent space pollution
. = ..()
var/datum/gas_mixture/immutable/I = space_gas
I.after_process_cell()
/turf/proc/process_cell_reaction()
SSair.remove_from_react_queue(src)
@@ -327,7 +331,7 @@
A.merge(T.air)
for(var/id in A_gases)
A_gases[id][MOLES] /= turflen
A_gases[id] /= turflen
for(var/t in turf_list)
var/turf/open/T = t

View File

@@ -5,82 +5,38 @@ What are the archived variables for?
*/
#define MINIMUM_HEAT_CAPACITY 0.0003
#define MINIMUM_MOLE_COUNT 0.01
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm
GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
/proc/init_gaslist_cache()
. = list()
for(var/id in GLOB.meta_gas_info)
var/list/cached_gas = new(3)
.[id] = cached_gas
cached_gas[MOLES] = 0
cached_gas[ARCHIVE] = 0
cached_gas[GAS_META] = GLOB.meta_gas_info[id]
//Unomos - global list inits for all of the meta gas lists.
//This setup allows procs to only look at one list instead of trying to dig around in lists-within-lists
GLOBAL_LIST_INIT(meta_gas_specific_heats, meta_gas_heat_list())
GLOBAL_LIST_INIT(meta_gas_names, meta_gas_name_list())
GLOBAL_LIST_INIT(meta_gas_visibility, meta_gas_visibility_list())
GLOBAL_LIST_INIT(meta_gas_overlays, meta_gas_overlay_list())
GLOBAL_LIST_INIT(meta_gas_dangers, meta_gas_danger_list())
GLOBAL_LIST_INIT(meta_gas_ids, meta_gas_id_list())
GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture
var/list/gases
var/list/gases = list()
var/temperature = 0 //kelvins
var/tmp/temperature_archived = 0
var/volume = CELL_VOLUME //liters
var/last_share = 0
var/list/reaction_results
var/list/reaction_results = list()
var/list/analyzer_results //used for analyzer feedback - not initialized until its used
var/gc_share = FALSE // Whether to call garbage_collect() on the sharer during shares, used for immutable mixtures
/datum/gas_mixture/New(volume)
gases = new
if (!isnull(volume))
src.volume = volume
reaction_results = new
//listmos procs
//use the macros in performance intensive areas. for their definitions, refer to code/__DEFINES/atmospherics.dm
//assert_gas(gas_id) - used to guarantee that the gas list for this id exists in gas_mixture.gases.
//Must be used before adding to a gas. May be used before reading from a gas.
/datum/gas_mixture/proc/assert_gas(gas_id)
ASSERT_GAS(gas_id, src)
//assert_gases(args) - shorthand for calling ASSERT_GAS() once for each gas type.
/datum/gas_mixture/proc/assert_gases()
for(var/id in args)
ASSERT_GAS(id, src)
//add_gas(gas_id) - similar to assert_gas(), but does not check for an existing
//gas list for this id. This can clobber existing gases.
//Used instead of assert_gas() when you know the gas does not exist. Faster than assert_gas().
/datum/gas_mixture/proc/add_gas(gas_id)
ADD_GAS(gas_id, gases)
//add_gases(args) - shorthand for calling add_gas() once for each gas_type.
/datum/gas_mixture/proc/add_gases()
var/cached_gases = gases
for(var/id in args)
ADD_GAS(id, cached_gases)
//garbage_collect() - removes any gas list which is empty.
//If called with a list as an argument, only removes gas lists with IDs from that list.
//Must be used after subtracting from a gas. Must be used after assert_gas()
//if assert_gas() was called only to read from the gas.
//By removing empty gases, processing speed is increased.
/datum/gas_mixture/proc/garbage_collect(list/tocheck)
var/list/cached_gases = gases
for(var/id in (tocheck || cached_gases))
if(QUANTIZE(cached_gases[id][MOLES]) <= 0 && QUANTIZE(cached_gases[id][ARCHIVE]) <= 0)
cached_gases -= id
//PV = nRT
/datum/gas_mixture/proc/heat_capacity(data = MOLES) //joules per kelvin
/datum/gas_mixture/proc/heat_capacity() //joules per kelvin
var/list/cached_gases = gases
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
. = 0
for(var/id in cached_gases)
var/gas_data = cached_gases[id]
. += gas_data[data] * gas_data[GAS_META][META_GAS_SPECIFIC_HEAT]
. += cached_gases[id] * cached_gasheats[id]
/datum/gas_mixture/turf/heat_capacity()
. = ..()
@@ -108,10 +64,6 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
/datum/gas_mixture/proc/thermal_energy() //joules
return THERMAL_ENERGY(src) //see code/__DEFINES/atmospherics.dm; use the define in performance critical areas
/datum/gas_mixture/proc/archive()
//Update archived versions of variables
//Returns: 1 in all cases
/datum/gas_mixture/proc/merge(datum/gas_mixture/giver)
//Merges all air from giver into self. Deletes giver.
//Returns: 1 if we are mutable, 0 otherwise
@@ -156,14 +108,6 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
//Performs various reactions such as combustion or fusion (LOL)
//Returns: 1 if any reaction took place; 0 otherwise
/datum/gas_mixture/archive()
var/list/cached_gases = gases
temperature_archived = temperature
for(var/id in cached_gases)
cached_gases[id][ARCHIVE] = cached_gases[id][MOLES]
return 1
/datum/gas_mixture/merge(datum/gas_mixture/giver)
if(!giver)
@@ -181,8 +125,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
var/list/giver_gases = giver.gases
//gas transfer
for(var/giver_id in giver_gases)
ASSERT_GAS(giver_id, src)
cached_gases[giver_id][MOLES] += giver_gases[giver_id][MOLES]
cached_gases[giver_id] += giver_gases[giver_id]
return 1
@@ -198,10 +141,9 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
removed.temperature = temperature
for(var/id in cached_gases)
ADD_GAS(id, removed.gases)
removed_gases[id][MOLES] = QUANTIZE((cached_gases[id][MOLES] / sum) * amount)
cached_gases[id][MOLES] -= removed_gases[id][MOLES]
garbage_collect()
removed_gases[id] = QUANTIZE((cached_gases[id] / sum) * amount)
cached_gases[id] -= removed_gases[id]
GAS_GARBAGE_COLLECT(gases)
return removed
@@ -216,11 +158,10 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
removed.temperature = temperature
for(var/id in cached_gases)
ADD_GAS(id, removed.gases)
removed_gases[id][MOLES] = QUANTIZE(cached_gases[id][MOLES] * ratio)
cached_gases[id][MOLES] -= removed_gases[id][MOLES]
removed_gases[id] = QUANTIZE(cached_gases[id] * ratio)
cached_gases[id] -= removed_gases[id]
garbage_collect()
GAS_GARBAGE_COLLECT(gases)
return removed
@@ -231,8 +172,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
copy.temperature = temperature
for(var/id in cached_gases)
ADD_GAS(id, copy.gases)
copy_gases[id][MOLES] = cached_gases[id][MOLES]
copy_gases[id] = cached_gases[id]
return copy
@@ -243,8 +183,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
temperature = sample.temperature
for(var/id in sample_gases)
ASSERT_GAS(id,src)
cached_gases[id][MOLES] = sample_gases[id][MOLES]
cached_gases[id] = sample_gases[id]
//remove all gases not in the sample
cached_gases &= sample_gases
@@ -272,8 +211,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
var/path = id
if(!ispath(path))
path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around
ADD_GAS(path, gases)
gases[path][MOLES] = text2num(gas[id])
gases[path] = text2num(gas[id])
return 1
/datum/gas_mixture/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
@@ -296,26 +234,25 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
var/moved_moles = 0
var/abs_moved_moles = 0
//we're gonna define these vars outside of this for loop because as it turns out, var declaration is pricy
var/delta
var/gas_heat_capacity
//and also cache this shit rq because that results in sanic speed for reasons byond explanation
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
//GAS TRANSFER
for(var/id in sharer_gases - cached_gases) // create gases not in our cache
ADD_GAS(id, gases)
for(var/id in cached_gases) // transfer gases
ASSERT_GAS(id, sharer)
for(var/id in cached_gases | sharer_gases) // transfer gases
var/gas = cached_gases[id]
var/sharergas = sharer_gases[id]
var/delta = QUANTIZE(gas[ARCHIVE] - sharergas[ARCHIVE])/(atmos_adjacent_turfs+1) //the amount of gas that gets moved between the mixtures
delta = QUANTIZE(cached_gases[id] - sharer_gases[id])/(atmos_adjacent_turfs+1) //the amount of gas that gets moved between the mixtures
if(delta && abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/gas_heat_capacity = delta * gas[GAS_META][META_GAS_SPECIFIC_HEAT]
gas_heat_capacity = delta * cached_gasheats[id]
if(delta > 0)
heat_capacity_self_to_sharer += gas_heat_capacity
else
heat_capacity_sharer_to_self -= gas_heat_capacity //subtract here instead of adding the absolute value because we know that delta is negative.
gas[MOLES] -= delta
sharergas[MOLES] += delta
cached_gases[id] -= delta
sharer_gases[id] += delta
moved_moles += delta
abs_moved_moles += abs(delta)
@@ -338,11 +275,8 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.1) // <10% change in sharer heat capacity
temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
if(length(cached_gases ^ sharer_gases)) //if all gases were present in both mixtures, we know that no gases are 0
garbage_collect(cached_gases - sharer_gases) //any gases the sharer had, we are guaranteed to have. gases that it didn't have we are not.
sharer.garbage_collect(sharer_gases - cached_gases) //the reverse is equally true
if (initial(sharer.gc_share))
sharer.garbage_collect()
GAS_GARBAGE_COLLECT(sharer.gases)
if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
var/our_moles
TOTAL_MOLES(cached_gases,our_moles)
@@ -356,8 +290,8 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
sharer_temperature = sharer.temperature_archived
var/temperature_delta = temperature_archived - sharer_temperature
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = heat_capacity(ARCHIVE)
sharer_heat_capacity = sharer_heat_capacity || sharer.heat_capacity(ARCHIVE)
var/self_heat_capacity = heat_capacity()
sharer_heat_capacity = sharer_heat_capacity || sharer.heat_capacity()
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
var/heat = conduction_coefficient*temperature_delta* \
@@ -376,9 +310,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
for(var/id in cached_gases | sample_gases) // compare gases from either mixture
var/gas_moles = cached_gases[id]
gas_moles = gas_moles ? gas_moles[MOLES] : 0
var/sample_moles = sample_gases[id]
sample_moles = sample_moles ? sample_moles[MOLES] : 0
var/delta = abs(gas_moles - sample_moles)
if(delta > MINIMUM_MOLES_DELTA_TO_MOVE && \
delta > gas_moles * MINIMUM_AIR_RATIO_TO_MOVE)
@@ -425,7 +357,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
for(var/id in min_reqs)
if (id == "TEMP" || id == "ENER")
continue
if(!cached_gases[id] || cached_gases[id][MOLES] < min_reqs[id])
if(cached_gases[id] < min_reqs[id])
continue reaction_loop
//at this point, all minimum requirements for the reaction are satisfied.
@@ -449,7 +381,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
if (. & STOP_REACTIONS)
break
if(.)
garbage_collect()
GAS_GARBAGE_COLLECT(gases)
if(temperature < TCMB) //just for safety
temperature = TCMB

View File

@@ -1,33 +1,66 @@
GLOBAL_LIST_INIT(hardcoded_gases, list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/plasma)) //the main four gases, which were at one time hardcoded
GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/pluoxium, /datum/gas/stimulum, /datum/gas/nitryl))) //unable to react amongst themselves
/proc/meta_gas_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/list/gas_info = new(7)
var/datum/gas/gas = gas_path
gas_info[META_GAS_SPECIFIC_HEAT] = initial(gas.specific_heat)
gas_info[META_GAS_NAME] = initial(gas.name)
gas_info[META_GAS_MOLES_VISIBLE] = initial(gas.moles_visible)
if(initial(gas.moles_visible) != null)
gas_info[META_GAS_OVERLAY] = new /list(FACTOR_GAS_VISIBLE_MAX)
for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX)
gas_info[META_GAS_OVERLAY][i] = new /obj/effect/overlay/gas(initial(gas.gas_overlay), i * 255 / FACTOR_GAS_VISIBLE_MAX)
gas_info[META_GAS_FUSION_POWER] = initial(gas.fusion_power)
gas_info[META_GAS_DANGER] = initial(gas.dangerous)
gas_info[META_GAS_ID] = initial(gas.id)
.[gas_path] = gas_info
/proc/gas_id2path(id)
var/list/meta_gas = GLOB.meta_gas_info
var/list/meta_gas = GLOB.meta_gas_ids
if(id in meta_gas)
return id
for(var/path in meta_gas)
if(meta_gas[path][META_GAS_ID] == id)
if(meta_gas[path] == id)
return path
return ""
//Unomos - oh god oh fuck oh shit oh lord have mercy this is messy as fuck oh god
//my addiction to seeing better performance numbers isn't healthy, kids
//you see this shit, children?
//i am not a good idol. don't take after me.
//this is literally worse than my alcohol addiction
/proc/meta_gas_heat_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.specific_heat)
/proc/meta_gas_name_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.name)
/proc/meta_gas_visibility_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.moles_visible)
/proc/meta_gas_overlay_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = 0 //gotta make sure if(GLOB.meta_gas_overlays[gaspath]) doesn't break
if(initial(gas.moles_visible) != null)
.[gas_path] = new /list(FACTOR_GAS_VISIBLE_MAX)
for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX)
.[gas_path][i] = new /obj/effect/overlay/gas(initial(gas.gas_overlay), i * 255 / FACTOR_GAS_VISIBLE_MAX)
/proc/meta_gas_danger_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.dangerous)
/proc/meta_gas_id_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.id)
/proc/meta_gas_fusion_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.fusion_power)
/*||||||||||||||/----------\||||||||||||||*\
||||||||||||||||[GAS DATUMS]||||||||||||||||
||||||||||||||||\__________/||||||||||||||||

View File

@@ -7,22 +7,18 @@
/datum/gas_mixture/immutable/New()
..()
garbage_collect()
/datum/gas_mixture/immutable/garbage_collect()
temperature = initial_temperature
temperature_archived = initial_temperature
gases.Cut()
/datum/gas_mixture/immutable/archive()
return 1 //nothing changes, so we do nothing and the archive is successful
/datum/gas_mixture/immutable/merge()
return 0 //we're immutable.
/datum/gas_mixture/immutable/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
. = ..(sharer, 0)
garbage_collect()
temperature = initial_temperature
temperature_archived = initial_temperature
gases.Cut()
/datum/gas_mixture/immutable/react()
return 0 //we're immutable.
@@ -43,6 +39,10 @@
. = ..()
temperature = initial_temperature
/datum/gas_mixture/immutable/proc/after_process_cell()
temperature = initial_temperature
temperature_archived = initial_temperature
gases.Cut()
//used by space tiles
/datum/gas_mixture/immutable/space
@@ -62,10 +62,13 @@
/datum/gas_mixture/immutable/cloner
initial_temperature = T20C
/datum/gas_mixture/immutable/cloner/garbage_collect()
/datum/gas_mixture/immutable/cloner/New()
..()
ADD_GAS(/datum/gas/nitrogen, gases)
gases[/datum/gas/nitrogen][MOLES] = MOLES_O2STANDARD + MOLES_N2STANDARD
gases[/datum/gas/nitrogen] = MOLES_O2STANDARD + MOLES_N2STANDARD
/datum/gas_mixture/immutable/cloner/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
. = ..(sharer, 0)
gases[/datum/gas/nitrogen] = MOLES_O2STANDARD + MOLES_N2STANDARD
/datum/gas_mixture/immutable/cloner/heat_capacity()
return (MOLES_O2STANDARD + MOLES_N2STANDARD)*20 //specific heat of nitrogen is 20

View File

@@ -60,7 +60,7 @@
if(location && location.freon_gas_act())
. = REACTING
else if(location && location.water_vapor_gas_act())
air.gases[/datum/gas/water_vapor][MOLES] -= MOLES_GAS_VISIBLE
air.gases[/datum/gas/water_vapor] -= MOLES_GAS_VISIBLE
. = REACTING
//tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic
@@ -86,21 +86,20 @@
var/turf/open/location = isturf(holder) ? holder : null
var/burned_fuel = 0
if(cached_gases[/datum/gas/oxygen][MOLES] < cached_gases[/datum/gas/tritium][MOLES])
burned_fuel = cached_gases[/datum/gas/oxygen][MOLES]/TRITIUM_BURN_OXY_FACTOR
cached_gases[/datum/gas/tritium][MOLES] -= burned_fuel
if(cached_gases[/datum/gas/oxygen] < cached_gases[/datum/gas/tritium])
burned_fuel = cached_gases[/datum/gas/oxygen]/TRITIUM_BURN_OXY_FACTOR
cached_gases[/datum/gas/tritium] -= burned_fuel
else
burned_fuel = cached_gases[/datum/gas/tritium][MOLES]*TRITIUM_BURN_TRIT_FACTOR
cached_gases[/datum/gas/tritium][MOLES] -= cached_gases[/datum/gas/tritium][MOLES]/TRITIUM_BURN_TRIT_FACTOR
cached_gases[/datum/gas/oxygen][MOLES] -= cached_gases[/datum/gas/tritium][MOLES]
burned_fuel = cached_gases[/datum/gas/tritium]*TRITIUM_BURN_TRIT_FACTOR
cached_gases[/datum/gas/tritium] -= cached_gases[/datum/gas/tritium]/TRITIUM_BURN_TRIT_FACTOR
cached_gases[/datum/gas/oxygen] -= cached_gases[/datum/gas/tritium]
if(burned_fuel)
energy_released += FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel
if(location && prob(10) && burned_fuel > TRITIUM_MINIMUM_RADIATION_ENERGY) //woah there let's not crash the server
radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR)
ASSERT_GAS(/datum/gas/water_vapor, air) //oxygen+more-or-less hydrogen=H2O
cached_gases[/datum/gas/water_vapor][MOLES] += burned_fuel/TRITIUM_BURN_OXY_FACTOR
cached_gases[/datum/gas/water_vapor] += burned_fuel/TRITIUM_BURN_OXY_FACTOR
cached_results["fire"] += burned_fuel
@@ -157,23 +156,21 @@
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
if(temperature_scale > 0)
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
if(cached_gases[/datum/gas/oxygen][MOLES] / cached_gases[/datum/gas/plasma][MOLES] > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium.
if(cached_gases[/datum/gas/oxygen] / cached_gases[/datum/gas/plasma] > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium.
super_saturation = TRUE
if(cached_gases[/datum/gas/oxygen][MOLES] > cached_gases[/datum/gas/plasma][MOLES]*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (cached_gases[/datum/gas/plasma][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA
if(cached_gases[/datum/gas/oxygen] > cached_gases[/datum/gas/plasma]*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (cached_gases[/datum/gas/plasma]*temperature_scale)/PLASMA_BURN_RATE_DELTA
else
plasma_burn_rate = (temperature_scale*(cached_gases[/datum/gas/oxygen][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
plasma_burn_rate = (temperature_scale*(cached_gases[/datum/gas/oxygen]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
plasma_burn_rate = min(plasma_burn_rate,cached_gases[/datum/gas/plasma][MOLES],cached_gases[/datum/gas/oxygen][MOLES]/oxygen_burn_rate) //Ensures matter is conserved properly
cached_gases[/datum/gas/plasma][MOLES] = QUANTIZE(cached_gases[/datum/gas/plasma][MOLES] - plasma_burn_rate)
cached_gases[/datum/gas/oxygen][MOLES] = QUANTIZE(cached_gases[/datum/gas/oxygen][MOLES] - (plasma_burn_rate * oxygen_burn_rate))
plasma_burn_rate = min(plasma_burn_rate,cached_gases[/datum/gas/plasma],cached_gases[/datum/gas/oxygen]/oxygen_burn_rate) //Ensures matter is conserved properly
cached_gases[/datum/gas/plasma] = QUANTIZE(cached_gases[/datum/gas/plasma] - plasma_burn_rate)
cached_gases[/datum/gas/oxygen] = QUANTIZE(cached_gases[/datum/gas/oxygen] - (plasma_burn_rate * oxygen_burn_rate))
if (super_saturation)
ASSERT_GAS(/datum/gas/tritium,air)
cached_gases[/datum/gas/tritium][MOLES] += plasma_burn_rate
cached_gases[/datum/gas/tritium] += plasma_burn_rate
else
ASSERT_GAS(/datum/gas/carbon_dioxide,air)
cached_gases[/datum/gas/carbon_dioxide][MOLES] += plasma_burn_rate
cached_gases[/datum/gas/carbon_dioxide] += plasma_burn_rate
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
@@ -231,21 +228,21 @@
var/old_heat_capacity = air.heat_capacity()
var/reaction_energy = 0
var/mediation = FUSION_MEDIATION_FACTOR*(air.heat_capacity()-(cached_gases[/datum/gas/plasma][MOLES]*cached_gases[/datum/gas/plasma][GAS_META][META_GAS_SPECIFIC_HEAT]))/(air.total_moles()-cached_gases[/datum/gas/plasma][MOLES]) //This is the average specific heat of the mixture,not including plasma.
var/mediation = FUSION_MEDIATION_FACTOR*(air.heat_capacity()-(cached_gases[/datum/gas/plasma]*GLOB.meta_gas_specific_heats[/datum/gas/plasma]))/(air.total_moles()-cached_gases[/datum/gas/plasma]) //This is the average specific heat of the mixture,not including plasma.
var/gases_fused = air.total_moles() - cached_gases[/datum/gas/plasma][MOLES]
var/plasma_differential = (cached_gases[/datum/gas/plasma][MOLES] - gases_fused) / air.total_moles()
var/gases_fused = air.total_moles() - cached_gases[/datum/gas/plasma]
var/plasma_differential = (cached_gases[/datum/gas/plasma] - gases_fused) / air.total_moles()
var/reaction_efficiency = FUSION_EFFICIENCY_BASE ** -((plasma_differential ** 2) / FUSION_EFFICIENCY_DIVISOR) //https://www.desmos.com/calculator/6jjx3vdrvx
var/gas_power = 0
for (var/gas_id in cached_gases)
gas_power += reaction_efficiency * (cached_gases[gas_id][GAS_META][META_GAS_FUSION_POWER]*cached_gases[gas_id][MOLES])
gas_power += reaction_efficiency * (GLOB.meta_gas_fusions[gas_id]*cached_gases[gas_id])
var/power_ratio = gas_power/mediation
cached_scan_results[id] = power_ratio //used for analyzer feedback
for (var/gas_id in cached_gases) //and now we fuse
cached_gases[gas_id][MOLES] = 0
cached_gases[gas_id] = 0
var/radiation_power = (FUSION_RADIATION_FACTOR * power_ratio) / (power_ratio + FUSION_RADIATION_CONSTANT) //https://www.desmos.com/calculator/4i1f296phl
var/zap_power = ((FUSION_ZAP_POWER_ASYMPTOTE * power_ratio) / (power_ratio + FUSION_ZAP_POWER_CONSTANT)) + FUSION_ZAP_POWER_BASE //https://www.desmos.com/calculator/n0zkdpxnrr
@@ -255,33 +252,30 @@
if (power_ratio > FUSION_SUPER_TIER_THRESHOLD) //power ratio 50+: SUPER TIER. The gases become so energized that they fuse into a ton of tritium, which is pretty nice! Until you consider the fact that everything just exploded, the canister is probably going to break and you're irradiated.
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_SUPER * (power_ratio / FUSION_ENERGY_DIVISOR_SUPER)
cached_gases[/datum/gas/tritium][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_TRITIUM //60% of the gas is converted to energy, 40% to trit
cached_gases[/datum/gas/tritium] += gases_fused * FUSION_GAS_CREATION_FACTOR_TRITIUM //60% of the gas is converted to energy, 40% to trit
fusion_prepare_to_die_edition_rng = 100 //Wait a minute..
do_explosion = TRUE
zap_range = FUSION_ZAP_RANGE_SUPER
else if (power_ratio > FUSION_HIGH_TIER_THRESHOLD) //power ratio 20-50; High tier. The reaction is so energized that it fuses into a small amount of stimulum, and some pluoxium. Very dangerous, but super cool and super useful.
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_HIGH * (power_ratio / FUSION_ENERGY_DIVISOR_HIGH)
air.assert_gases(/datum/gas/stimulum, /datum/gas/pluoxium)
cached_gases[/datum/gas/stimulum][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_STIM //40% of the gas is converted to energy, 60% to stim and pluox
cached_gases[/datum/gas/pluoxium][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_PLUOX
cached_gases[/datum/gas/stimulum] += gases_fused * FUSION_GAS_CREATION_FACTOR_STIM //40% of the gas is converted to energy, 60% to stim and pluox
cached_gases[/datum/gas/pluoxium] += gases_fused * FUSION_GAS_CREATION_FACTOR_PLUOX
fusion_prepare_to_die_edition_rng = power_ratio //Now we're getting into dangerous territory
do_explosion = TRUE
zap_range = FUSION_ZAP_RANGE_HIGH
else if (power_ratio > FUSION_MID_TIER_THRESHOLD) //power_ratio 5 to 20; Mediation is overpowered, fusion reaction starts to break down.
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_MID * (power_ratio / FUSION_ENERGY_DIVISOR_MID)
air.assert_gases(/datum/gas/nitryl,/datum/gas/nitrous_oxide)
cached_gases[/datum/gas/nitryl][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_NITRYL //20% of the gas is converted to energy, 80% to nitryl and N2O
cached_gases[/datum/gas/nitrous_oxide][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_N2O
cached_gases[/datum/gas/nitryl] += gases_fused * FUSION_GAS_CREATION_FACTOR_NITRYL //20% of the gas is converted to energy, 80% to nitryl and N2O
cached_gases[/datum/gas/nitrous_oxide] += gases_fused * FUSION_GAS_CREATION_FACTOR_N2O
fusion_prepare_to_die_edition_rng = power_ratio * FUSION_MID_TIER_RAD_PROB_FACTOR //Still unlikely, but don't stand next to the reaction unprotected
zap_range = FUSION_ZAP_RANGE_MID
else //power ratio 0 to 5; Gas power is overpowered. Fusion isn't nearly as powerful.
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_LOW * (power_ratio / FUSION_ENERGY_DIVISOR_LOW)
air.assert_gases(/datum/gas/bz, /datum/gas/carbon_dioxide)
cached_gases[/datum/gas/bz][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_BZ //10% of the gas is converted to energy, 90% to BZ and CO2
cached_gases[/datum/gas/carbon_dioxide][MOLES] += gases_fused * FUSION_GAS_CREATION_FACTOR_CO2
cached_gases[/datum/gas/bz] += gases_fused * FUSION_GAS_CREATION_FACTOR_BZ //10% of the gas is converted to energy, 90% to BZ and CO2
cached_gases[/datum/gas/carbon_dioxide] += gases_fused * FUSION_GAS_CREATION_FACTOR_CO2
fusion_prepare_to_die_edition_rng = power_ratio * FUSION_LOW_TIER_RAD_PROB_FACTOR //Low, but still something to look out for
zap_range = FUSION_ZAP_RANGE_LOW
@@ -322,14 +316,13 @@
var/temperature = air.temperature
var/old_heat_capacity = air.heat_capacity()
var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),cached_gases[/datum/gas/oxygen][MOLES],cached_gases[/datum/gas/nitrogen][MOLES])
var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),cached_gases[/datum/gas/oxygen],cached_gases[/datum/gas/nitrogen])
var/energy_used = heat_efficency*NITRYL_FORMATION_ENERGY
ASSERT_GAS(/datum/gas/nitryl,air)
if ((cached_gases[/datum/gas/oxygen][MOLES] - heat_efficency < 0 )|| (cached_gases[/datum/gas/nitrogen][MOLES] - heat_efficency < 0)) //Shouldn't produce gas from nothing.
if ((cached_gases[/datum/gas/oxygen] - heat_efficency < 0 )|| (cached_gases[/datum/gas/nitrogen] - heat_efficency < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
cached_gases[/datum/gas/oxygen][MOLES] -= heat_efficency
cached_gases[/datum/gas/nitrogen][MOLES] -= heat_efficency
cached_gases[/datum/gas/nitryl][MOLES] += heat_efficency*2
cached_gases[/datum/gas/oxygen] -= heat_efficency
cached_gases[/datum/gas/nitrogen] -= heat_efficency
cached_gases[/datum/gas/nitryl] += heat_efficency*2
if(energy_used > 0)
var/new_heat_capacity = air.heat_capacity()
@@ -355,14 +348,13 @@
var/pressure = air.return_pressure()
var/old_heat_capacity = air.heat_capacity()
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma][MOLES]/cached_gases[/datum/gas/nitrous_oxide][MOLES],1))),cached_gases[/datum/gas/nitrous_oxide][MOLES],cached_gases[/datum/gas/plasma][MOLES]/2)
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma]/cached_gases[/datum/gas/nitrous_oxide],1))),cached_gases[/datum/gas/nitrous_oxide],cached_gases[/datum/gas/plasma]/2)
var/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED
if ((cached_gases[/datum/gas/nitrous_oxide][MOLES] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma][MOLES] - (2*reaction_efficency) < 0)) //Shouldn't produce gas from nothing.
if ((cached_gases[/datum/gas/nitrous_oxide] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma] - (2*reaction_efficency) < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
ASSERT_GAS(/datum/gas/bz,air)
cached_gases[/datum/gas/bz][MOLES] += reaction_efficency
cached_gases[/datum/gas/nitrous_oxide][MOLES] -= reaction_efficency
cached_gases[/datum/gas/plasma][MOLES] -= 2*reaction_efficency
cached_gases[/datum/gas/bz] += reaction_efficency
cached_gases[/datum/gas/nitrous_oxide] -= reaction_efficency
cached_gases[/datum/gas/plasma] -= 2*reaction_efficency
if(energy_released > 0)
@@ -388,16 +380,15 @@
var/list/cached_gases = air.gases
var/old_heat_capacity = air.heat_capacity()
var/heat_scale = min(air.temperature/STIMULUM_HEAT_SCALE,cached_gases[/datum/gas/tritium][MOLES],cached_gases[/datum/gas/plasma][MOLES],cached_gases[/datum/gas/nitryl][MOLES])
var/heat_scale = min(air.temperature/STIMULUM_HEAT_SCALE,cached_gases[/datum/gas/tritium],cached_gases[/datum/gas/plasma],cached_gases[/datum/gas/nitryl])
var/stim_energy_change = heat_scale + STIMULUM_FIRST_RISE*(heat_scale**2) - STIMULUM_FIRST_DROP*(heat_scale**3) + STIMULUM_SECOND_RISE*(heat_scale**4) - STIMULUM_ABSOLUTE_DROP*(heat_scale**5)
ASSERT_GAS(/datum/gas/stimulum,air)
if ((cached_gases[/datum/gas/tritium][MOLES] - heat_scale < 0 )|| (cached_gases[/datum/gas/plasma][MOLES] - heat_scale < 0) || (cached_gases[/datum/gas/nitryl][MOLES] - heat_scale < 0)) //Shouldn't produce gas from nothing.
if ((cached_gases[/datum/gas/tritium] - heat_scale < 0 )|| (cached_gases[/datum/gas/plasma] - heat_scale < 0) || (cached_gases[/datum/gas/nitryl] - heat_scale < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
cached_gases[/datum/gas/stimulum][MOLES]+= heat_scale/10
cached_gases[/datum/gas/tritium][MOLES] -= heat_scale
cached_gases[/datum/gas/plasma][MOLES] -= heat_scale
cached_gases[/datum/gas/nitryl][MOLES] -= heat_scale
cached_gases[/datum/gas/stimulum]+= heat_scale/10
cached_gases[/datum/gas/tritium] -= heat_scale
cached_gases[/datum/gas/plasma] -= heat_scale
cached_gases[/datum/gas/nitryl] -= heat_scale
if(stim_energy_change)
var/new_heat_capacity = air.heat_capacity()
@@ -418,15 +409,14 @@
/datum/gas_reaction/nobliumformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
air.assert_gases(/datum/gas/hypernoblium,/datum/gas/bz)
var/old_heat_capacity = air.heat_capacity()
var/nob_formed = min((cached_gases[/datum/gas/nitrogen][MOLES]+cached_gases[/datum/gas/tritium][MOLES])/100,cached_gases[/datum/gas/tritium][MOLES]/10,cached_gases[/datum/gas/nitrogen][MOLES]/20)
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(cached_gases[/datum/gas/bz][MOLES],1)))
if ((cached_gases[/datum/gas/tritium][MOLES] - 10*nob_formed < 0) || (cached_gases[/datum/gas/nitrogen][MOLES] - 20*nob_formed < 0))
var/nob_formed = min((cached_gases[/datum/gas/nitrogen]+cached_gases[/datum/gas/tritium])/100,cached_gases[/datum/gas/tritium]/10,cached_gases[/datum/gas/nitrogen]/20)
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(cached_gases[/datum/gas/bz],1)))
if ((cached_gases[/datum/gas/tritium] - 10*nob_formed < 0) || (cached_gases[/datum/gas/nitrogen] - 20*nob_formed < 0))
return NO_REACTION
cached_gases[/datum/gas/tritium][MOLES] -= 10*nob_formed
cached_gases[/datum/gas/nitrogen][MOLES] -= 20*nob_formed
cached_gases[/datum/gas/hypernoblium][MOLES]+= nob_formed
cached_gases[/datum/gas/tritium] -= 10*nob_formed
cached_gases[/datum/gas/nitrogen] -= 20*nob_formed
cached_gases[/datum/gas/hypernoblium]+= nob_formed
if (nob_formed)
@@ -449,14 +439,13 @@
/datum/gas_reaction/miaster/react(datum/gas_mixture/air, datum/holder)
var/list/cached_gases = air.gases
// As the name says it, it needs to be dry
if(cached_gases[/datum/gas/water_vapor] && cached_gases[/datum/gas/water_vapor][MOLES]/air.total_moles() > 0.1)
if(cached_gases[/datum/gas/water_vapor] && cached_gases[/datum/gas/water_vapor]/air.total_moles() > 0.1)
return
//Replace miasma with oxygen
var/cleaned_air = min(cached_gases[/datum/gas/miasma][MOLES], 20 + (air.temperature - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
cached_gases[/datum/gas/miasma][MOLES] -= cleaned_air
ASSERT_GAS(/datum/gas/oxygen,air)
cached_gases[/datum/gas/oxygen][MOLES] += cleaned_air
var/cleaned_air = min(cached_gases[/datum/gas/miasma], 20 + (air.temperature - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
cached_gases[/datum/gas/miasma] -= cleaned_air
cached_gases[/datum/gas/oxygen] += cleaned_air
//Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable
air.temperature += cleaned_air * 0.002

File diff suppressed because it is too large Load Diff

View File

@@ -27,7 +27,12 @@ Thus, the two variables affect pump operation are set in New():
construction_type = /obj/item/pipe/directional
pipe_state = "pump"
/obj/machinery/atmospherics/components/binary/pump/examine(mob/user)
. = ..()
to_chat(user,"<span class='notice'>You can hold <b>Ctrl</b> and click on it to toggle it on and off.</span>")
to_chat(user,"<span class='notice'>You can hold <b>Alt</b> and click on it to maximize its pressure.</span>")
/obj/machinery/atmospherics/components/binary/pump/CtrlClick(mob/user)
var/area/A = get_area(src)
var/turf/T = get_turf(src)
@@ -37,7 +42,7 @@ Thus, the two variables affect pump operation are set in New():
investigate_log("Pump, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Pump, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
return ..()
/obj/machinery/atmospherics/components/binary/pump/AltClick(mob/user)
var/area/A = get_area(src)
var/turf/T = get_turf(src)
@@ -46,7 +51,7 @@ Thus, the two variables affect pump operation are set in New():
to_chat(user,"<span class='notice'>You maximize the pressure on the [src].</span>")
investigate_log("Pump, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Pump, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
/obj/machinery/atmospherics/components/binary/pump/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X

View File

@@ -28,16 +28,21 @@ Thus, the two variables affect pump operation are set in New():
construction_type = /obj/item/pipe/directional
pipe_state = "volumepump"
/obj/machinery/atmospherics/components/binary/volume_pump/examine(mob/user)
. = ..()
to_chat(user,"<span class='notice'>You can hold <b>Ctrl</b> and click on it to toggle it on and off.</span>")
to_chat(user,"<span class='notice'>You can hold <b>Alt</b> and click on it to maximize its pressure.</span>")
/obj/machinery/atmospherics/components/binary/volume_pump/CtrlClick(mob/user)
var/area/A = get_area(src)
var/turf/T = get_turf(src)
if(user.canUseTopic(src, BE_CLOSE, FALSE,))
on = !on
update_icon()
investigate_log("Pump, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Pump, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
investigate_log("Volume Pump, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Volume Pump, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
return ..()
/obj/machinery/atmospherics/components/binary/volume_pump/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X

View File

@@ -12,25 +12,30 @@
construction_type = /obj/item/pipe/trinary/flippable
pipe_state = "filter"
/obj/machinery/atmospherics/components/trinary/filter/examine(mob/user)
. = ..()
to_chat(user,"<span class='notice'>You can hold <b>Ctrl</b> and click on it to toggle it on and off.</span>")
to_chat(user,"<span class='notice'>You can hold <b>Alt</b> and click on it to maximize its pressure.</span>")
/obj/machinery/atmospherics/components/trinary/filter/CtrlClick(mob/user)
var/area/A = get_area(src)
var/turf/T = get_turf(src)
if(user.canUseTopic(src, BE_CLOSE, FALSE,))
on = !on
update_icon()
investigate_log("Pump, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Pump, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
investigate_log("Filter, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Filter, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
return ..()
/obj/machinery/atmospherics/components/trinary/filter/AltClick(mob/user)
var/area/A = get_area(src)
var/turf/T = get_turf(src)
if(user.canUseTopic(src, BE_CLOSE, FALSE,))
target_pressure = MAX_OUTPUT_PRESSURE
to_chat(user,"<span class='notice'>You maximize the pressure on the [src].</span>")
investigate_log("Pump, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Pump, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
investigate_log("Filter, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Filter, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
/obj/machinery/atmospherics/components/trinary/filter/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X
@@ -178,11 +183,10 @@
var/datum/gas_mixture/filtered_out = new
filtered_out.temperature = removed.temperature
filtered_out.add_gas(filter_type)
filtered_out.gases[filter_type][MOLES] = removed.gases[filter_type][MOLES]
filtered_out.gases[filter_type] = removed.gases[filter_type]
removed.gases[filter_type][MOLES] = 0
removed.garbage_collect()
removed.gases[filter_type] = 0
GAS_GARBAGE_COLLECT(removed.gases)
var/datum/gas_mixture/target = (air2.return_pressure() < target_pressure ? air2 : air1) //if there's no room for the filtered gas; just leave it in air1
target.merge(filtered_out)
@@ -210,9 +214,8 @@
data["filter_types"] = list()
data["filter_types"] += list(list("name" = "Nothing", "path" = "", "selected" = !filter_type))
for(var/path in GLOB.meta_gas_info)
var/list/gas = GLOB.meta_gas_info[path]
data["filter_types"] += list(list("name" = gas[META_GAS_NAME], "id" = gas[META_GAS_ID], "selected" = (path == gas_id2path(filter_type))))
for(var/path in GLOB.meta_gas_ids)
data["filter_types"] += list(list("name" = GLOB.meta_gas_names[path], "id" = GLOB.meta_gas_ids[path], "selected" = (path == gas_id2path(filter_type))))
return data
@@ -243,9 +246,9 @@
filter_type = null
var/filter_name = "nothing"
var/gas = gas_id2path(params["mode"])
if(gas in GLOB.meta_gas_info)
if(gas in GLOB.meta_gas_names)
filter_type = gas
filter_name = GLOB.meta_gas_info[gas][META_GAS_NAME]
filter_name = GLOB.meta_gas_names[gas]
investigate_log("was set to filter [filter_name] by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE
update_icon()

View File

@@ -14,25 +14,31 @@
pipe_state = "mixer"
//node 3 is the outlet, nodes 1 & 2 are intakes
/obj/machinery/atmospherics/components/trinary/mixer/examine(mob/user)
. = ..()
to_chat(user,"<span class='notice'>You can hold <b>Ctrl</b> and click on it to toggle it on and off.</span>")
to_chat(user,"<span class='notice'>You can hold <b>Alt</b> and click on it to maximize its pressure.</span>")
/obj/machinery/atmospherics/components/trinary/mixer/CtrlClick(mob/user)
var/area/A = get_area(src)
var/turf/T = get_turf(src)
if(user.canUseTopic(src, BE_CLOSE, FALSE,))
on = !on
update_icon()
investigate_log("Pump, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Pump, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
investigate_log("Mixer, [src.name], turned on by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Mixer, [src.name], turned [on ? "on" : "off"] by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
return ..()
/obj/machinery/atmospherics/components/trinary/mixer/AltClick(mob/user)
var/area/A = get_area(src)
var/turf/T = get_turf(src)
if(user.canUseTopic(src, BE_CLOSE, FALSE,))
target_pressure = MAX_OUTPUT_PRESSURE
to_chat(user,"<span class='notice'>You maximize the pressure on the [src].</span>")
investigate_log("Pump, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Pump, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
investigate_log("Mixer, [src.name], was maximized by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS)
message_admins("Mixer, [src.name], was maximized by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]")
//node 3 is the outlet, nodes 1 & 2 are intakes
/obj/machinery/atmospherics/components/trinary/mixer/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X

View File

@@ -183,8 +183,8 @@
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
beaker.reagents.reaction(occupant, VAPOR)
air1.gases[/datum/gas/oxygen][MOLES] -= max(0,air1.gases[/datum/gas/oxygen][MOLES] - 2 / efficiency) //Let's use gas for this
air1.garbage_collect()
air1.gases[/datum/gas/oxygen] -= max(0,air1.gases[/datum/gas/oxygen] - 2 / efficiency) //Let's use gas for this
GAS_GARBAGE_COLLECT(air1.gases)
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
@@ -198,7 +198,7 @@
var/datum/gas_mixture/air1 = airs[1]
if(!nodes[1] || !airs[1] || !air1.gases.len || air1.gases[/datum/gas/oxygen][MOLES] < 5) // Turn off if the machine won't work.
if(!nodes[1] || !airs[1] || !air1.gases.len || air1.gases[/datum/gas/oxygen] < 5) // Turn off if the machine won't work.
on = FALSE
update_icon()
return
@@ -220,8 +220,8 @@
air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB)
mob_occupant.adjust_bodytemperature(heat / heat_capacity, TCMB)
air1.gases[/datum/gas/oxygen][MOLES] = max(0,air1.gases[/datum/gas/oxygen][MOLES] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic.
air1.garbage_collect()
air1.gases[/datum/gas/oxygen] = max(0,air1.gases[/datum/gas/oxygen] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic.
GAS_GARBAGE_COLLECT(air1.gases)
/obj/machinery/atmospherics/components/unary/cryo_cell/power_change()
..()

View File

@@ -17,9 +17,8 @@
air_contents.volume = volume
air_contents.temperature = T20C
if(gas_type)
air_contents.assert_gas(gas_type)
air_contents.gases[gas_type][MOLES] = AIR_CONTENTS
name = "[name] ([air_contents.gases[gas_type][GAS_META][META_GAS_NAME]])"
air_contents.gases[gas_type] = AIR_CONTENTS
name = "[name] ([GLOB.meta_gas_names[gas_type]])"
/obj/machinery/atmospherics/components/unary/tank/carbon_dioxide
gas_type = /datum/gas/carbon_dioxide
@@ -44,6 +43,5 @@
/obj/machinery/atmospherics/components/unary/tank/air/New()
..()
var/datum/gas_mixture/air_contents = airs[1]
air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
air_contents.gases[/datum/gas/oxygen][MOLES] = AIR_CONTENTS * 0.2
air_contents.gases[/datum/gas/nitrogen][MOLES] = AIR_CONTENTS * 0.8
air_contents.gases[/datum/gas/oxygen] = AIR_CONTENTS * 0.2
air_contents.gases[/datum/gas/nitrogen] = AIR_CONTENTS * 0.8

View File

@@ -1,330 +1,328 @@
#define SIPHONING 0
#define SCRUBBING 1
/obj/machinery/atmospherics/components/unary/vent_scrubber
name = "air scrubber"
desc = "Has a valve and pump attached to it."
icon_state = "scrub_map"
use_power = IDLE_POWER_USE
idle_power_usage = 10
active_power_usage = 60
can_unwrench = TRUE
welded = FALSE
level = 1
layer = GAS_SCRUBBER_LAYER
var/id_tag = null
var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing
var/filter_types = list(/datum/gas/carbon_dioxide)
var/volume_rate = 200
var/widenet = 0 //is this scrubber acting on the 3x3 area around it.
var/list/turf/adjacent_turfs = list()
var/frequency = FREQ_ATMOS_CONTROL
var/datum/radio_frequency/radio_connection
var/radio_filter_out
var/radio_filter_in
pipe_state = "scrubber"
/obj/machinery/atmospherics/components/unary/vent_scrubber/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X
pixel_y = -PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/unary/vent_scrubber/layer3
piping_layer = PIPING_LAYER_MAX
pixel_x = PIPING_LAYER_P_X
pixel_y = PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/unary/vent_scrubber/New()
..()
if(!id_tag)
id_tag = assign_uid_vents()
for(var/f in filter_types)
if(istext(f))
filter_types -= f
filter_types += gas_id2path(f)
/obj/machinery/atmospherics/components/unary/vent_scrubber/on
on = TRUE
icon_state = "scrub_map_on"
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X
pixel_y = -PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3
piping_layer = PIPING_LAYER_MAX
pixel_x = PIPING_LAYER_P_X
pixel_y = PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy()
var/area/A = get_area(src)
if (A)
A.air_scrub_names -= id_tag
A.air_scrub_info -= id_tag
SSradio.remove_object(src,frequency)
radio_connection = null
adjacent_turfs.Cut()
return ..()
/obj/machinery/atmospherics/components/unary/vent_scrubber/auto_use_power()
if(!on || welded || !is_operational() || !powered(power_channel))
return FALSE
var/amount = idle_power_usage
if(scrubbing & SCRUBBING)
amount += idle_power_usage * length(filter_types)
else //scrubbing == SIPHONING
amount = active_power_usage
if(widenet)
amount += amount * (adjacent_turfs.len * (adjacent_turfs.len / 2))
use_power(amount, power_channel)
return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes()
cut_overlays()
if(showpipe)
add_overlay(getpipeimage(icon, "scrub_cap", initialize_directions))
if(welded)
icon_state = "scrub_welded"
return
if(!nodes[1] || !on || !is_operational())
icon_state = "scrub_off"
return
if(scrubbing & SCRUBBING)
if(widenet)
icon_state = "scrub_wide"
else
icon_state = "scrub_on"
else //scrubbing == SIPHONING
icon_state = "scrub_purge"
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, radio_filter_in)
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/broadcast_status()
if(!radio_connection)
return FALSE
var/list/f_types = list()
for(var/path in GLOB.meta_gas_info)
var/list/gas = GLOB.meta_gas_info[path]
f_types += list(list("gas_id" = gas[META_GAS_ID], "gas_name" = gas[META_GAS_NAME], "enabled" = (path in filter_types)))
var/datum/signal/signal = new(list(
"tag" = id_tag,
"frequency" = frequency,
"device" = "VS",
"timestamp" = world.time,
"power" = on,
"scrubbing" = scrubbing,
"widenet" = widenet,
"filter_types" = f_types,
"sigtype" = "status"
))
var/area/A = get_area(src)
if(!A.air_scrub_names[id_tag])
name = "\improper [A.name] air scrubber #[A.air_scrub_names.len + 1]"
A.air_scrub_names[id_tag] = name
A.air_scrub_info[id_tag] = signal.data
radio_connection.post_signal(src, signal, radio_filter_out)
return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/atmosinit()
radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null
radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null
if(frequency)
set_frequency(frequency)
broadcast_status()
check_turfs()
..()
/obj/machinery/atmospherics/components/unary/vent_scrubber/process_atmos()
..()
if(welded || !is_operational())
return FALSE
if(!nodes[1] || !on)
on = FALSE
return FALSE
scrub(loc)
if(widenet)
for(var/turf/tile in adjacent_turfs)
scrub(tile)
return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/scrub(var/turf/tile)
if(!istype(tile))
return FALSE
var/datum/gas_mixture/environment = tile.return_air()
var/datum/gas_mixture/air_contents = airs[1]
var/list/env_gases = environment.gases
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE)
return FALSE
if(scrubbing & SCRUBBING)
if(length(env_gases & filter_types))
var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
//Take a gas sample
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
//Nothing left to remove from the tile
if(isnull(removed))
return FALSE
var/list/removed_gases = removed.gases
//Filter it
var/datum/gas_mixture/filtered_out = new
var/list/filtered_gases = filtered_out.gases
filtered_out.temperature = removed.temperature
for(var/gas in filter_types & removed_gases)
filtered_out.add_gas(gas)
filtered_gases[gas][MOLES] = removed_gases[gas][MOLES]
removed_gases[gas][MOLES] = 0
removed.garbage_collect()
//Remix the resulting gases
air_contents.merge(filtered_out)
tile.assume_air(removed)
tile.air_update_turf()
else //Just siphoning all air
var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume)
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
air_contents.merge(removed)
tile.air_update_turf()
update_parents()
return TRUE
//There is no easy way for an object to be notified of changes to atmos can pass flags
// So we check every machinery process (2 seconds)
/obj/machinery/atmospherics/components/unary/vent_scrubber/process()
if(widenet)
check_turfs()
//we populate a list of turfs with nonatmos-blocked cardinal turfs AND
// diagonal turfs that can share atmos with *both* of the cardinal turfs
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/check_turfs()
adjacent_turfs.Cut()
var/turf/T = get_turf(src)
if(istype(T))
adjacent_turfs = T.GetAtmosAdjacentTurfs(alldir = 1)
/obj/machinery/atmospherics/components/unary/vent_scrubber/receive_signal(datum/signal/signal)
if(!is_operational() || !signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
return 0
var/mob/signal_sender = signal.data["user"]
if("power" in signal.data)
on = text2num(signal.data["power"])
if("power_toggle" in signal.data)
on = !on
if("widenet" in signal.data)
widenet = text2num(signal.data["widenet"])
if("toggle_widenet" in signal.data)
widenet = !widenet
var/old_scrubbing = scrubbing
if("scrubbing" in signal.data)
scrubbing = text2num(signal.data["scrubbing"])
if("toggle_scrubbing" in signal.data)
scrubbing = !scrubbing
if(scrubbing != old_scrubbing)
investigate_log(" was toggled to [scrubbing ? "scrubbing" : "siphon"] mode by [key_name(signal_sender)]",INVESTIGATE_ATMOS)
if("toggle_filter" in signal.data)
filter_types ^= gas_id2path(signal.data["toggle_filter"])
if("set_filters" in signal.data)
filter_types = list()
for(var/gas in signal.data["set_filters"])
filter_types += gas_id2path(gas)
if("init" in signal.data)
name = signal.data["init"]
return
if("status" in signal.data)
broadcast_status()
return //do not update_icon
broadcast_status()
update_icon()
return
/obj/machinery/atmospherics/components/unary/vent_scrubber/power_change()
..()
update_icon_nopipes()
/obj/machinery/atmospherics/components/unary/vent_scrubber/welder_act(mob/living/user, obj/item/I)
if(!I.tool_start_check(user, amount=0))
return TRUE
to_chat(user, "<span class='notice'>Now welding the scrubber.</span>")
if(I.use_tool(src, user, 20, volume=50))
if(!welded)
user.visible_message("[user] welds the scrubber shut.","You weld the scrubber shut.", "You hear welding.")
welded = TRUE
else
user.visible_message("[user] unwelds the scrubber.", "You unweld the scrubber.", "You hear welding.")
welded = FALSE
update_icon()
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
pipe_vision_img.plane = ABOVE_HUD_PLANE
return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/can_unwrench(mob/user)
. = ..()
if(. && on && is_operational())
to_chat(user, "<span class='warning'>You cannot unwrench [src], turn it off first!</span>")
return FALSE
/obj/machinery/atmospherics/components/unary/vent_scrubber/examine(mob/user)
..()
if(welded)
to_chat(user, "It seems welded shut.")
/obj/machinery/atmospherics/components/unary/vent_scrubber/can_crawl_through()
return !welded
/obj/machinery/atmospherics/components/unary/vent_scrubber/attack_alien(mob/user)
if(!welded || !(do_after(user, 20, target = src)))
return
user.visible_message("[user] furiously claws at [src]!", "You manage to clear away the stuff blocking the scrubber.", "You hear loud scraping noises.")
welded = FALSE
update_icon()
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
pipe_vision_img.plane = ABOVE_HUD_PLANE
playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1)
#undef SIPHONING
#undef SCRUBBING
#define SIPHONING 0
#define SCRUBBING 1
/obj/machinery/atmospherics/components/unary/vent_scrubber
name = "air scrubber"
desc = "Has a valve and pump attached to it."
icon_state = "scrub_map"
use_power = IDLE_POWER_USE
idle_power_usage = 10
active_power_usage = 60
can_unwrench = TRUE
welded = FALSE
level = 1
layer = GAS_SCRUBBER_LAYER
var/id_tag = null
var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing
var/filter_types = list(/datum/gas/carbon_dioxide)
var/volume_rate = 200
var/widenet = 0 //is this scrubber acting on the 3x3 area around it.
var/list/turf/adjacent_turfs = list()
var/frequency = FREQ_ATMOS_CONTROL
var/datum/radio_frequency/radio_connection
var/radio_filter_out
var/radio_filter_in
pipe_state = "scrubber"
/obj/machinery/atmospherics/components/unary/vent_scrubber/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X
pixel_y = -PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/unary/vent_scrubber/layer3
piping_layer = PIPING_LAYER_MAX
pixel_x = PIPING_LAYER_P_X
pixel_y = PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/unary/vent_scrubber/New()
..()
if(!id_tag)
id_tag = assign_uid_vents()
for(var/f in filter_types)
if(istext(f))
filter_types -= f
filter_types += gas_id2path(f)
/obj/machinery/atmospherics/components/unary/vent_scrubber/on
on = TRUE
icon_state = "scrub_map_on"
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1
piping_layer = PIPING_LAYER_MIN
pixel_x = -PIPING_LAYER_P_X
pixel_y = -PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer3
piping_layer = PIPING_LAYER_MAX
pixel_x = PIPING_LAYER_P_X
pixel_y = PIPING_LAYER_P_Y
/obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy()
var/area/A = get_area(src)
if (A)
A.air_scrub_names -= id_tag
A.air_scrub_info -= id_tag
SSradio.remove_object(src,frequency)
radio_connection = null
adjacent_turfs.Cut()
return ..()
/obj/machinery/atmospherics/components/unary/vent_scrubber/auto_use_power()
if(!on || welded || !is_operational() || !powered(power_channel))
return FALSE
var/amount = idle_power_usage
if(scrubbing & SCRUBBING)
amount += idle_power_usage * length(filter_types)
else //scrubbing == SIPHONING
amount = active_power_usage
if(widenet)
amount += amount * (adjacent_turfs.len * (adjacent_turfs.len / 2))
use_power(amount, power_channel)
return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes()
cut_overlays()
if(showpipe)
add_overlay(getpipeimage(icon, "scrub_cap", initialize_directions))
if(welded)
icon_state = "scrub_welded"
return
if(!nodes[1] || !on || !is_operational())
icon_state = "scrub_off"
return
if(scrubbing & SCRUBBING)
if(widenet)
icon_state = "scrub_wide"
else
icon_state = "scrub_on"
else //scrubbing == SIPHONING
icon_state = "scrub_purge"
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, radio_filter_in)
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/broadcast_status()
if(!radio_connection)
return FALSE
var/list/f_types = list()
for(var/path in GLOB.meta_gas_ids)
f_types += list(list("gas_id" = GLOB.meta_gas_ids[path], "gas_name" = GLOB.meta_gas_names[path], "enabled" = (path in filter_types)))
var/datum/signal/signal = new(list(
"tag" = id_tag,
"frequency" = frequency,
"device" = "VS",
"timestamp" = world.time,
"power" = on,
"scrubbing" = scrubbing,
"widenet" = widenet,
"filter_types" = f_types,
"sigtype" = "status"
))
var/area/A = get_area(src)
if(!A.air_scrub_names[id_tag])
name = "\improper [A.name] air scrubber #[A.air_scrub_names.len + 1]"
A.air_scrub_names[id_tag] = name
A.air_scrub_info[id_tag] = signal.data
radio_connection.post_signal(src, signal, radio_filter_out)
return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/atmosinit()
radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null
radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null
if(frequency)
set_frequency(frequency)
broadcast_status()
check_turfs()
..()
/obj/machinery/atmospherics/components/unary/vent_scrubber/process_atmos()
..()
if(welded || !is_operational())
return FALSE
if(!nodes[1] || !on)
on = FALSE
return FALSE
scrub(loc)
if(widenet)
for(var/turf/tile in adjacent_turfs)
scrub(tile)
return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/scrub(var/turf/tile)
if(!istype(tile))
return FALSE
var/datum/gas_mixture/environment = tile.return_air()
var/datum/gas_mixture/air_contents = airs[1]
var/list/env_gases = environment.gases
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE)
return FALSE
if(scrubbing & SCRUBBING)
if(length(env_gases & filter_types))
var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
//Take a gas sample
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
//Nothing left to remove from the tile
if(isnull(removed))
return FALSE
var/list/removed_gases = removed.gases
//Filter it
var/datum/gas_mixture/filtered_out = new
var/list/filtered_gases = filtered_out.gases
filtered_out.temperature = removed.temperature
for(var/gas in filter_types & removed_gases)
filtered_gases[gas] = removed_gases[gas]
removed_gases[gas] = 0
GAS_GARBAGE_COLLECT(removed.gases)
//Remix the resulting gases
air_contents.merge(filtered_out)
tile.assume_air(removed)
tile.air_update_turf()
else //Just siphoning all air
var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume)
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
air_contents.merge(removed)
tile.air_update_turf()
update_parents()
return TRUE
//There is no easy way for an object to be notified of changes to atmos can pass flags
// So we check every machinery process (2 seconds)
/obj/machinery/atmospherics/components/unary/vent_scrubber/process()
if(widenet)
check_turfs()
//we populate a list of turfs with nonatmos-blocked cardinal turfs AND
// diagonal turfs that can share atmos with *both* of the cardinal turfs
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/check_turfs()
adjacent_turfs.Cut()
var/turf/T = get_turf(src)
if(istype(T))
adjacent_turfs = T.GetAtmosAdjacentTurfs(alldir = 1)
/obj/machinery/atmospherics/components/unary/vent_scrubber/receive_signal(datum/signal/signal)
if(!is_operational() || !signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
return 0
var/mob/signal_sender = signal.data["user"]
if("power" in signal.data)
on = text2num(signal.data["power"])
if("power_toggle" in signal.data)
on = !on
if("widenet" in signal.data)
widenet = text2num(signal.data["widenet"])
if("toggle_widenet" in signal.data)
widenet = !widenet
var/old_scrubbing = scrubbing
if("scrubbing" in signal.data)
scrubbing = text2num(signal.data["scrubbing"])
if("toggle_scrubbing" in signal.data)
scrubbing = !scrubbing
if(scrubbing != old_scrubbing)
investigate_log(" was toggled to [scrubbing ? "scrubbing" : "siphon"] mode by [key_name(signal_sender)]",INVESTIGATE_ATMOS)
if("toggle_filter" in signal.data)
filter_types ^= gas_id2path(signal.data["toggle_filter"])
if("set_filters" in signal.data)
filter_types = list()
for(var/gas in signal.data["set_filters"])
filter_types += gas_id2path(gas)
if("init" in signal.data)
name = signal.data["init"]
return
if("status" in signal.data)
broadcast_status()
return //do not update_icon
broadcast_status()
update_icon()
return
/obj/machinery/atmospherics/components/unary/vent_scrubber/power_change()
..()
update_icon_nopipes()
/obj/machinery/atmospherics/components/unary/vent_scrubber/welder_act(mob/living/user, obj/item/I)
if(!I.tool_start_check(user, amount=0))
return TRUE
to_chat(user, "<span class='notice'>Now welding the scrubber.</span>")
if(I.use_tool(src, user, 20, volume=50))
if(!welded)
user.visible_message("[user] welds the scrubber shut.","You weld the scrubber shut.", "You hear welding.")
welded = TRUE
else
user.visible_message("[user] unwelds the scrubber.", "You unweld the scrubber.", "You hear welding.")
welded = FALSE
update_icon()
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
pipe_vision_img.plane = ABOVE_HUD_PLANE
return TRUE
/obj/machinery/atmospherics/components/unary/vent_scrubber/can_unwrench(mob/user)
. = ..()
if(. && on && is_operational())
to_chat(user, "<span class='warning'>You cannot unwrench [src], turn it off first!</span>")
return FALSE
/obj/machinery/atmospherics/components/unary/vent_scrubber/examine(mob/user)
..()
if(welded)
to_chat(user, "It seems welded shut.")
/obj/machinery/atmospherics/components/unary/vent_scrubber/can_crawl_through()
return !welded
/obj/machinery/atmospherics/components/unary/vent_scrubber/attack_alien(mob/user)
if(!welded || !(do_after(user, 20, target = src)))
return
user.visible_message("[user] furiously claws at [src]!", "You manage to clear away the stuff blocking the scrubber.", "You hear loud scraping noises.")
welded = FALSE
update_icon()
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
pipe_vision_img.plane = ABOVE_HUD_PLANE
playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1)
#undef SIPHONING
#undef SCRUBBING

View File

@@ -145,7 +145,7 @@
var/member_gases = member.air_temporary.gases
for(var/id in member_gases)
member_gases[id][MOLES] *= member.volume/air.volume
member_gases[id] *= member.volume/air.volume
member.air_temporary.temperature = air.temperature
@@ -254,4 +254,4 @@
G.copy_from(total_gas_mixture)
var/list/G_gases = G.gases
for(var/id in G_gases)
G_gases[id][MOLES] *= G.volume/total_gas_mixture.volume
G_gases[id] *= G.volume/total_gas_mixture.volume

View File

@@ -131,8 +131,7 @@
if(!isopenturf(O))
return FALSE
var/datum/gas_mixture/merger = new
merger.assert_gas(spawn_id)
merger.gases[spawn_id][MOLES] = (spawn_mol)
merger.gases[spawn_id] = (spawn_mol)
merger.temperature = spawn_temp
O.assume_air(merger)
O.air_update_turf(TRUE)

View File

@@ -204,16 +204,14 @@
/obj/machinery/portable_atmospherics/canister/proc/create_gas()
if(gas_type)
air_contents.add_gas(gas_type)
if(starter_temp)
air_contents.temperature = starter_temp
air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
air_contents.gases[gas_type] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
if(starter_temp)
air_contents.temperature = starter_temp
/obj/machinery/portable_atmospherics/canister/air/create_gas()
air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
air_contents.gases[/datum/gas/oxygen][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
air_contents.gases[/datum/gas/nitrogen][MOLES] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
air_contents.gases[/datum/gas/oxygen] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
air_contents.gases[/datum/gas/nitrogen] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
#define HOLDING (1<<0)
#define CONNECTED (1<<1)
@@ -439,10 +437,10 @@
var/list/danger = list()
for(var/id in air_contents.gases)
var/gas = air_contents.gases[id]
if(!gas[GAS_META][META_GAS_DANGER])
if(!GLOB.meta_gas_dangers[id])
continue
if(gas[MOLES] > (gas[GAS_META][META_GAS_MOLES_VISIBLE] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility
danger[gas[GAS_META][META_GAS_NAME]] = gas[MOLES] //ex. "plasma" = 20
if(gas > (GLOB.meta_gas_visibility[id] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility
danger[GLOB.meta_gas_names[id]] = gas //ex. "plasma" = 20
if(danger.len)
message_admins("[ADMIN_LOOKUPFLW(usr)] opened a canister that contains the following at [ADMIN_VERBOSEJMP(src)]:")

View File

@@ -1,146 +1,144 @@
/obj/machinery/portable_atmospherics/scrubber
name = "portable air scrubber"
icon_state = "pscrubber:0"
density = TRUE
var/on = FALSE
var/volume_rate = 1000
volume = 1000
var/list/scrubbing = list(/datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitryl, /datum/gas/tritium, /datum/gas/hypernoblium, /datum/gas/water_vapor)
/obj/machinery/portable_atmospherics/scrubber/Destroy()
var/turf/T = get_turf(src)
T.assume_air(air_contents)
air_update_turf()
return ..()
/obj/machinery/portable_atmospherics/scrubber/update_icon()
icon_state = "pscrubber:[on]"
cut_overlays()
if(holding)
add_overlay("scrubber-open")
if(connected_port)
add_overlay("scrubber-connector")
/obj/machinery/portable_atmospherics/scrubber/process_atmos()
..()
if(!on)
return
if(holding)
scrub(holding.air_contents)
else
var/turf/T = get_turf(src)
scrub(T.return_air())
/obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture)
var/transfer_moles = min(1, volume_rate / mixture.volume) * mixture.total_moles()
var/datum/gas_mixture/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter.
var/datum/gas_mixture/filtered = new
if(!filtering)
return
filtered.temperature = filtering.temperature
for(var/gas in filtering.gases & scrubbing)
filtered.add_gas(gas)
filtered.gases[gas][MOLES] = filtering.gases[gas][MOLES] // Shuffle the "bad" gasses to the filtered mixture.
filtering.gases[gas][MOLES] = 0
filtering.garbage_collect() // Now that the gasses are set to 0, clean up the mixture.
air_contents.merge(filtered) // Store filtered out gasses.
mixture.merge(filtering) // Returned the cleaned gas.
if(!holding)
air_update_turf()
/obj/machinery/portable_atmospherics/scrubber/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
if(is_operational())
if(prob(50 / severity))
on = !on
update_icon()
/obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "portable_scrubber", name, 420, 435, master_ui, state)
ui.open()
/obj/machinery/portable_atmospherics/scrubber/ui_data()
var/data = list()
data["on"] = on
data["connected"] = connected_port ? 1 : 0
data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
data["id_tag"] = -1 //must be defined in order to reuse code between portable and vent scrubbers
data["filter_types"] = list()
for(var/path in GLOB.meta_gas_info)
var/list/gas = GLOB.meta_gas_info[path]
data["filter_types"] += list(list("gas_id" = gas[META_GAS_ID], "gas_name" = gas[META_GAS_NAME], "enabled" = (path in scrubbing)))
if(holding)
data["holding"] = list()
data["holding"]["name"] = holding.name
data["holding"]["pressure"] = round(holding.air_contents.return_pressure())
return data
/obj/machinery/portable_atmospherics/scrubber/ui_act(action, params)
if(..())
return
switch(action)
if("power")
on = !on
. = TRUE
if("eject")
if(holding)
holding.forceMove(drop_location())
holding = null
. = TRUE
if("toggle_filter")
scrubbing ^= gas_id2path(params["val"])
. = TRUE
update_icon()
/obj/machinery/portable_atmospherics/scrubber/huge
name = "huge air scrubber"
icon_state = "scrubber:0"
anchored = TRUE
active_power_usage = 500
idle_power_usage = 10
volume_rate = 1500
volume = 50000
var/movable = FALSE
/obj/machinery/portable_atmospherics/scrubber/huge/movable
movable = TRUE
/obj/machinery/portable_atmospherics/scrubber/huge/update_icon()
icon_state = "scrubber:[on]"
/obj/machinery/portable_atmospherics/scrubber/huge/process_atmos()
if((!anchored && !movable) || !is_operational())
on = FALSE
update_icon()
use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE
if(!on)
return
..()
if(!holding)
var/turf/T = get_turf(src)
for(var/turf/AT in T.GetAtmosAdjacentTurfs(alldir = TRUE))
scrub(AT.return_air())
/obj/machinery/portable_atmospherics/scrubber/huge/attackby(obj/item/W, mob/user)
if(default_unfasten_wrench(user, W))
if(!movable)
on = FALSE
else
return ..()
/obj/machinery/portable_atmospherics/scrubber
name = "portable air scrubber"
icon_state = "pscrubber:0"
density = TRUE
var/on = FALSE
var/volume_rate = 1000
volume = 1000
var/list/scrubbing = list(/datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitryl, /datum/gas/tritium, /datum/gas/hypernoblium, /datum/gas/water_vapor)
/obj/machinery/portable_atmospherics/scrubber/Destroy()
var/turf/T = get_turf(src)
T.assume_air(air_contents)
air_update_turf()
return ..()
/obj/machinery/portable_atmospherics/scrubber/update_icon()
icon_state = "pscrubber:[on]"
cut_overlays()
if(holding)
add_overlay("scrubber-open")
if(connected_port)
add_overlay("scrubber-connector")
/obj/machinery/portable_atmospherics/scrubber/process_atmos()
..()
if(!on)
return
if(holding)
scrub(holding.air_contents)
else
var/turf/T = get_turf(src)
scrub(T.return_air())
/obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture)
var/transfer_moles = min(1, volume_rate / mixture.volume) * mixture.total_moles()
var/datum/gas_mixture/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter.
var/datum/gas_mixture/filtered = new
if(!filtering)
return
filtered.temperature = filtering.temperature
for(var/gas in filtering.gases & scrubbing)
filtered.gases[gas] = filtering.gases[gas] // Shuffle the "bad" gasses to the filtered mixture.
filtering.gases[gas] = 0
GAS_GARBAGE_COLLECT(filtering.gases)
air_contents.merge(filtered) // Store filtered out gasses.
mixture.merge(filtering) // Returned the cleaned gas.
if(!holding)
air_update_turf()
/obj/machinery/portable_atmospherics/scrubber/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
if(is_operational())
if(prob(50 / severity))
on = !on
update_icon()
/obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "portable_scrubber", name, 420, 435, master_ui, state)
ui.open()
/obj/machinery/portable_atmospherics/scrubber/ui_data()
var/data = list()
data["on"] = on
data["connected"] = connected_port ? 1 : 0
data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
data["id_tag"] = -1 //must be defined in order to reuse code between portable and vent scrubbers
data["filter_types"] = list()
for(var/path in GLOB.meta_gas_ids)
data["filter_types"] += list(list("gas_id" = GLOB.meta_gas_ids[path], "gas_name" = GLOB.meta_gas_names[path], "enabled" = (path in scrubbing)))
if(holding)
data["holding"] = list()
data["holding"]["name"] = holding.name
data["holding"]["pressure"] = round(holding.air_contents.return_pressure())
return data
/obj/machinery/portable_atmospherics/scrubber/ui_act(action, params)
if(..())
return
switch(action)
if("power")
on = !on
. = TRUE
if("eject")
if(holding)
holding.forceMove(drop_location())
holding = null
. = TRUE
if("toggle_filter")
scrubbing ^= gas_id2path(params["val"])
. = TRUE
update_icon()
/obj/machinery/portable_atmospherics/scrubber/huge
name = "huge air scrubber"
icon_state = "scrubber:0"
anchored = TRUE
active_power_usage = 500
idle_power_usage = 10
volume_rate = 1500
volume = 50000
var/movable = FALSE
/obj/machinery/portable_atmospherics/scrubber/huge/movable
movable = TRUE
/obj/machinery/portable_atmospherics/scrubber/huge/update_icon()
icon_state = "scrubber:[on]"
/obj/machinery/portable_atmospherics/scrubber/huge/process_atmos()
if((!anchored && !movable) || !is_operational())
on = FALSE
update_icon()
use_power = on ? ACTIVE_POWER_USE : IDLE_POWER_USE
if(!on)
return
..()
if(!holding)
var/turf/T = get_turf(src)
for(var/turf/AT in T.GetAtmosAdjacentTurfs(alldir = TRUE))
scrub(AT.return_air())
/obj/machinery/portable_atmospherics/scrubber/huge/attackby(obj/item/W, mob/user)
if(default_unfasten_wrench(user, W))
if(!movable)
on = FALSE
else
return ..()

View File

@@ -12,7 +12,7 @@
var/obj/item/tank/T = O
if(!T.air_contents.gases[gas_type])
return FALSE
return T.air_contents.gases[gas_type][MOLES] >= moles_required
return T.air_contents.gases[gas_type] >= moles_required
/datum/bounty/item/engineering/gas/nitryl_tank
name = "Full Tank of Nitryl"

View File

@@ -80,13 +80,13 @@
// Paper work done correctly
/datum/export/paperwork_correct
cost = 50
cost = 150
unit_name = "correct paperwork"
export_types = list(/obj/item/paper/fluff/jobs/cargo/manifest/paperwork_correct)
export_types = list(/obj/item/folder/paperwork_correct)
// Paper work not done retruned
/datum/export/paperwork_incorrect
cost = -500 // Failed to meet NT standers
unit_name = "returned incorrect paperwork"
export_types = list(/obj/item/paper/fluff/jobs/cargo/manifest/paperwork)
export_types = list(/obj/item/folder/paperwork)

View File

@@ -97,12 +97,14 @@
return C
//Paperwork for NT
/obj/item/paper/fluff/jobs/cargo/manifest/paperwork
/obj/item/folder/paperwork
name = "Incomplete Paperwork"
desc = "These should've been filled out four months ago! Unfinished grant papers issued by Nanotrasen's finance department. Complete this page for additional funding."
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "docs_generic"
/obj/item/paper/fluff/jobs/cargo/manifest/paperwork_correct
/obj/item/folder/paperwork_correct
name = "Finished Paperwork"
desc = "A neat stack of filled-out forms, in triplicate and signed. Is there anything more satisfying? Make sure they get stamped."
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "docs_verified"

View File

@@ -433,7 +433,6 @@
/datum/supply_pack/security/russianclothing
name = "Russian Surplus Clothing"
desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproff armor, a few union suits and some warm hats!"
hidden = TRUE
contraband = TRUE
cost = 5000 // Its basicly sec suits, good boots/gloves
contains = list(/obj/item/clothing/suit/security/officer/russian,
@@ -517,14 +516,16 @@
/datum/supply_pack/security/armory/ballistic
name = "Combat Shotguns Crate"
desc = "For when the enemy absolutely needs to be replaced with lead. Contains three Aussec-designed Combat Shotguns, and three Shotgun Bandoliers. Requires Armory access to open."
desc = "For when the enemy absolutely needs to be replaced with lead. Contains three Aussec-designed Combat Shotguns, with three Shotgun Bandoliers, as well as seven buchshot and 12g shotgun slugs. Requires Armory access to open."
cost = 8000
contains = list(/obj/item/gun/ballistic/shotgun/automatic/combat,
/obj/item/gun/ballistic/shotgun/automatic/combat,
/obj/item/gun/ballistic/shotgun/automatic/combat,
/obj/item/storage/belt/bandolier,
/obj/item/storage/belt/bandolier,
/obj/item/storage/belt/bandolier)
/obj/item/storage/belt/bandolier,
/obj/item/storage/box/lethalshot,
/obj/item/storage/box/lethalslugs)
crate_name = "combat shotguns crate"
/datum/supply_pack/security/armory/dragnetgun
@@ -568,7 +569,7 @@
/datum/supply_pack/security/armory/fire
name = "Incendiary Weapons Crate"
desc = "Burn, baby burn. Contains three incendiary grenades, three plasma canisters, and a flamethrower. Requires Brige access to open."
desc = "Burn, baby burn. Contains three incendiary grenades, seven incendiary slugs, three plasma canisters, and a flamethrower. Requires Brige access to open."
cost = 1500
access = ACCESS_HEADS
contains = list(/obj/item/flamethrower/full,
@@ -577,7 +578,8 @@
/obj/item/tank/internals/plasma,
/obj/item/grenade/chem_grenade/incendiary,
/obj/item/grenade/chem_grenade/incendiary,
/obj/item/grenade/chem_grenade/incendiary)
/obj/item/grenade/chem_grenade/incendiary,
/obj/item/storage/box/fireshot)
crate_name = "incendiary weapons crate"
crate_type = /obj/structure/closet/crate/secure/plasma
dangerous = TRUE
@@ -630,11 +632,13 @@
/datum/supply_pack/security/armory/riotshotguns
name = "Riot Shotgun Crate"
desc = "For when the greytide gets really uppity. Contains three riot Shotguns. Requires Armory access to open."
desc = "For when the greytide gets really uppity. Contains three riot shotguns, seven rubber shot and beanbag shells. Requires Armory access to open."
cost = 6000
contains = list(/obj/item/gun/ballistic/shotgun/riot,
/obj/item/gun/ballistic/shotgun/riot,
/obj/item/gun/ballistic/shotgun/riot)
/obj/item/gun/ballistic/shotgun/riot,
/obj/item/storage/box/rubbershot,
/obj/item/storage/box/beanbag)
crate_name = "riot shotgun crate"
/datum/supply_pack/security/armory/swat
@@ -881,7 +885,6 @@
)
crate_name= "shield sat crate"
/datum/supply_pack/engineering/shield_sat_control
name = "Shield System Control Board"
desc = "A control system for the Shield Generator Satellite system."
@@ -889,7 +892,6 @@
contains = list(/obj/item/circuitboard/computer/sat_control)
crate_name= "shield control board crate"
//////////////////////////////////////////////////////////////////////////////
//////////////////////// Engine Construction /////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -959,6 +961,15 @@
crate_name = "grounding rod crate"
crate_type = /obj/structure/closet/crate/engineering/electrical
/datum/supply_pack/engine/mason
name = "M.A.S.O.N RIG Crate"
desc = "The rare M.A.S.O.N RIG. Requires CE access to open."
cost = 15000
access = ACCESS_CE
contains = list(/obj/item/clothing/suit/space/hardsuit/ancient/mason)
crate_name = "M.A.S.O.N Rig"
crate_type = /obj/structure/closet/crate/secure/engineering
/datum/supply_pack/engine/PA
name = "Particle Accelerator Crate"
desc = "A supermassive black hole or hyper-powered teslaball are the perfect way to spice up any party! This \"My First Apocalypse\" kit contains everything you need to build your own Particle Accelerator! Ages 10 and up."
@@ -1534,6 +1545,15 @@
crate_type = /obj/structure/closet/crate/secure/science
dangerous = TRUE
/datum/supply_pack/science/tech_slugs
name = "Tech Slug Ammo Shells"
desc = "A new type of shell that is able to be made into a few different dangerous types. Contains two boxes of tech slugs, 14 shells in all."
cost = 1000
contains = list(/obj/item/storage/box/techsslug,
/obj/item/storage/box/techsslug)
crate_name = "tech slug crate"
//////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Service //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -1541,7 +1561,6 @@
/datum/supply_pack/service
group = "Service"
/datum/supply_pack/service/advlighting
name = "Advanced Lighting crate"
desc = "Thanks to advanced lighting tech we here at the Lamp Factory have be able to produce more lamps and lamp items! This crate has three lamps, a box of lights and a state of the art rapid-light-device!"
@@ -1566,6 +1585,14 @@
/obj/item/stack/packageWrap)
crate_name = "cargo supplies crate"
/datum/supply_pack/service/food_cart
name = "Food Cart Crate"
desc = "Want to sell food on the go? Cook lost their cart? Well we just so happen to have a few carts to spare!"
cost = 1000
contains = list(/obj/machinery/food_cart)
crate_name = "food cart crate"
crate_type = /obj/structure/closet/crate
/datum/supply_pack/service/noslipfloor
name = "High-traction Floor Tiles"
desc = "Make slipping a thing of the past with sixty industrial-grade anti-slip floortiles!"
@@ -1574,6 +1601,14 @@
/obj/item/stack/tile/noslip/thirty)
crate_name = "high-traction floor tiles crate"
/datum/supply_pack/service/icecream_cart
name = "Ice Cream Cart Crate"
desc = "Plasma fire a to hot for you, want a nice treat after a hard days work? Well now we have the cart for you! This Ice Cream Vat has everthing you need to make you and your friends so ice cream treats! This cart comes stocked with some ingredients for each type of scoopable icecream."
cost = 2750 //Comes prestocked with basic ingredients
contains = list(/obj/machinery/icecream_vat)
crate_name = "ice cream vat crate"
crate_type = /obj/structure/closet/crate
/datum/supply_pack/service/janitor
name = "Janitorial Supplies Crate"
desc = "Fight back against dirt and grime with Nanotrasen's Janitorial Essentials(tm)! Contains three buckets, caution signs, and cleaner grenades. Also has a single mop, spray cleaner, rag, NT soap and a trash bag."
@@ -1702,6 +1737,10 @@
crate_name = "shaft miner starter kit"
crate_type = /obj/structure/closet/crate/secure
//////////////////////////////////////////////////////////////////////////////
/////////////////////////// Vending Restocks /////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/datum/supply_pack/service/vending/bartending
name = "Bartending Supply Crate"
desc = "Bring on the booze with vending machine refills, as well as a free book containing the well-kept secrets to the bartending trade!"
@@ -2671,16 +2710,16 @@
name = "Freelance Paper work"
desc = "The Nanotrasen Primary Bureaucratic Database Intelligence (PDBI) reports that the station has not completed its funding and grant paperwork this solar cycle. In order to gain further funding, your station is required to fill out (10) ten of these forms or no additional capital will be disbursed. We have sent you ten copies of the following form and we expect every one to be up to Nanotrasen Standards." // Disbursement. It's not a typo, look it up.
cost = 400 // Net of 0 credits
contains = list(/obj/item/paper/fluff/jobs/cargo/manifest/paperwork,
/obj/item/paper/fluff/jobs/cargo/manifest/paperwork,
/obj/item/paper/fluff/jobs/cargo/manifest/paperwork,
/obj/item/paper/fluff/jobs/cargo/manifest/paperwork,
/obj/item/paper/fluff/jobs/cargo/manifest/paperwork,
/obj/item/paper/fluff/jobs/cargo/manifest/paperwork,
/obj/item/paper/fluff/jobs/cargo/manifest/paperwork,
/obj/item/paper/fluff/jobs/cargo/manifest/paperwork,
/obj/item/paper/fluff/jobs/cargo/manifest/paperwork,
/obj/item/paper/fluff/jobs/cargo/manifest/paperwork,
contains = list(/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/folder/paperwork,
/obj/item/pen/fountain,
/obj/item/pen/fountain,
/obj/item/pen/fountain,

View File

@@ -155,6 +155,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
)
var/list/custom_names = list()
var/preferred_ai_core_display = "Blue"
var/prefered_security_department = SEC_DEPT_RANDOM
var/custom_species = null
@@ -304,10 +305,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
old_group = namedata["group"]
dat += "<br>"
dat += "<a href ='?_src_=prefs;preference=[custom_name_id];task=input'><b>[namedata["pref_name"]]:</b> [custom_names[custom_name_id]]</a> "
dat += "<br>"
dat += "<b>Custom job preferences:</b><BR>"
dat += "<a href='?_src_=prefs;preference=sec_dept;task=input'><b>Prefered security department:</b> [prefered_security_department]</a><BR></td>"
dat += "<br><br>"
dat += "<b>Custom job preferences:</b><BR>"
dat += "<a href='?_src_=prefs;preference=ai_core_icon;task=input'><b>Preferred AI Core Display:</b> [preferred_ai_core_display]</a><br>"
dat += "<a href='?_src_=prefs;preference=sec_dept;task=input'><b>Preferred Security Department:</b> [prefered_security_department]</a><BR></td>"
dat += "</tr></table>"
//Character Appearance
@@ -1941,8 +1943,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(new_loc)
uplink_spawn_loc = new_loc
if("ai_core_icon")
var/ai_core_icon = input(user, "Choose your preferred AI core display screen:", "AI Core Display Screen Selection") as null|anything in GLOB.ai_core_display_screens
if(ai_core_icon)
preferred_ai_core_display = ai_core_icon
if("sec_dept")
var/department = input(user, "Choose your prefered security department:", "Security Departments") as null|anything in GLOB.security_depts_prefs
var/department = input(user, "Choose your preferred security department:", "Security Departments") as null|anything in GLOB.security_depts_prefs
if(department)
prefered_security_department = department
@@ -2235,8 +2242,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character.hair_style = hair_style
character.facial_hair_style = facial_hair_style
character.underwear = underwear
character.saved_underwear = underwear
character.undershirt = undershirt
character.saved_undershirt = undershirt
character.socks = socks
character.saved_socks = socks
character.backbag = backbag

View File

@@ -286,6 +286,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
var/savefile_slot_name = custom_name_id + "_name" //TODO remove this
S[savefile_slot_name] >> custom_names[custom_name_id]
S["preferred_ai_core_display"] >> preferred_ai_core_display
S["prefered_security_department"] >> prefered_security_department
//Jobs
@@ -485,6 +486,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
var/savefile_slot_name = custom_name_id + "_name" //TODO remove this
WRITE_FILE(S[savefile_slot_name],custom_names[custom_name_id])
WRITE_FILE(S["preferred_ai_core_display"] , preferred_ai_core_display)
WRITE_FILE(S["prefered_security_department"] , prefered_security_department)
//Jobs

View File

@@ -216,6 +216,34 @@ BLIND // can't see anything
..()
/obj/item/clothing/under/CtrlClick(mob/user)
. = ..()
if (!(item_flags & IN_INVENTORY))
return
if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
if(has_sensor == LOCKED_SENSORS)
to_chat(user, "The controls are locked.")
return
if(has_sensor == BROKEN_SENSORS)
to_chat(user, "The sensors have shorted out!")
return
if(has_sensor <= NO_SENSORS)
to_chat(user, "This suit does not have any sensors.")
return
sensor_mode = SENSOR_COORDS
to_chat(user, "<span class='notice'>Your suit will now report your exact vital lifesigns as well as your coordinate position.</span>")
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.w_uniform == src)
H.update_suit_sensors()
/obj/item/clothing/under/AltClick(mob/user)
if(..())
return 1

View File

@@ -45,7 +45,7 @@
/obj/item/clothing/glasses/proc/thermal_overload()
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
if(!(H.has_trait(TRAIT_BLIND)))
if(!(HAS_TRAIT(H, TRAIT_BLIND)))
if(H.glasses == src)
to_chat(H, "<span class='danger'>[src] overloads and blinds you!</span>")
H.flash_act(visual = 1)

View File

@@ -7,6 +7,7 @@
permeability_coefficient = 0.05
item_color="yellow"
resistance_flags = NONE
var/can_be_cut = 1
/obj/item/clothing/gloves/color/fyellow //Cheap Chinese Crap
desc = "These gloves are cheap knockoffs of the coveted ones - no way this can end badly."
@@ -17,6 +18,7 @@
permeability_coefficient = 0.05
item_color="yellow"
resistance_flags = NONE
var/can_be_cut = 1
/obj/item/clothing/gloves/color/fyellow/New()
..()
@@ -30,6 +32,38 @@
. = ..()
siemens_coefficient = pick(0,0,0,0.5,0.5,0.5,0.75)
/obj/item/clothing/gloves/cut
desc = "These gloves would protect the wearer from electric shock.. if the fingers were covered."
name = "fingerless insulated gloves"
icon_state = "yellowcut"
item_state = "yglovescut"
siemens_coefficient = 1
permeability_coefficient = 1
resistance_flags = NONE
transfer_prints = TRUE
/obj/item/clothing/gloves/cut/family
desc = "The old gloves your great grandfather stole from Engineering, many moons ago. They've seen some tough times recently."
name = "fingerless insulated gloves"
/obj/item/clothing/gloves/color/yellow/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/wirecutters))
if(can_be_cut && icon_state == initial(icon_state))//only if not dyed
to_chat(user, "<span class='notice'>You snip the fingertips off of [src].</span>")
I.play_tool_sound(src)
new /obj/item/clothing/gloves/cut(drop_location())
qdel(src)
..()
/obj/item/clothing/gloves/color/fyellow/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/wirecutters))
if(can_be_cut && icon_state == initial(icon_state))//only if not dyed
to_chat(user, "<span class='notice'>You snip the fingertips off of [src].</span>")
I.play_tool_sound(src)
new /obj/item/clothing/gloves/cut(drop_location())
qdel(src)
..()
/obj/item/clothing/gloves/color/black
desc = "These gloves are fire-resistant."
name = "black gloves"

View File

@@ -1,3 +1,8 @@
//defines the drill hat's yelling setting
#define DRILL_DEFAULT "default"
#define DRILL_SHOUTING "shouting"
#define DRILL_YELLING "yelling"
#define DRILL_CANADIAN "canadian"
//Chef
/obj/item/clothing/head/chefhat
@@ -148,6 +153,65 @@
strip_delay = 60
dog_fashion = /datum/dog_fashion/head/warden
/obj/item/clothing/head/warden/drill
name = "warden's campaign hat"
desc = "A special armored campaign hat with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection. Has the letters 'FMJ' enscribed on its side."
icon_state = "wardendrill"
item_state = "wardendrill"
dog_fashion = null
var/mode = DRILL_DEFAULT
/obj/item/clothing/head/warden/drill/screwdriver_act(mob/living/carbon/human/user, obj/item/I)
if(..())
return TRUE
switch(mode)
if(DRILL_DEFAULT)
to_chat(user, "<span class='notice'>You set the voice circuit to the middle position.</span>")
mode = DRILL_SHOUTING
if(DRILL_SHOUTING)
to_chat(user, "<span class='notice'>You set the voice circuit to the last position.</span>")
mode = DRILL_YELLING
if(DRILL_YELLING)
to_chat(user, "<span class='notice'>You set the voice circuit to the first position.</span>")
mode = DRILL_DEFAULT
if(DRILL_CANADIAN)
to_chat(user, "<span class='danger'>You adjust voice circuit but nothing happens, probably because it's broken.</span>")
return TRUE
/obj/item/clothing/head/warden/drill/wirecutter_act(mob/living/user, obj/item/I)
if(mode != DRILL_CANADIAN)
to_chat(user, "<span class='danger'>You broke the voice circuit!</span>")
mode = DRILL_CANADIAN
return TRUE
/obj/item/clothing/head/warden/drill/speechModification(M)
if(copytext(M, 1, 2) != "*")
if(mode == DRILL_DEFAULT)
M = " [M]"
return trim(M)
if(mode == DRILL_SHOUTING)
M = " [M]!"
return trim(M)
if(mode == DRILL_YELLING)
M = " [M]!!"
return trim(M)
if(mode == DRILL_CANADIAN)
M = " [M]"
var/list/canadian_words = strings("canadian_replacement.json", "canadian")
for(var/key in canadian_words)
var/value = canadian_words[key]
if(islist(value))
value = pick(value)
M = replacetextEx(M, " [uppertext(key)]", " [uppertext(value)]")
M = replacetextEx(M, " [capitalize(key)]", " [capitalize(value)]")
M = replacetextEx(M, " [key]", " [value]")
if(prob(30))
M += pick(", eh?", ", EH?")
return trim(M)
/obj/item/clothing/head/beret/sec
name = "security beret"
desc = "A robust beret with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection."
@@ -201,3 +265,8 @@
name = "quartermaster's beret"
desc = "This headwear shows off your Cargonian leadership"
icon_state = "qmberet"
#undef DRILL_DEFAULT
#undef DRILL_SHOUTING
#undef DRILL_YELLING
#undef DRILL_CANADIAN

View File

@@ -66,7 +66,7 @@
var/obj/item/organ/heart/heart = M.getorganslot(ORGAN_SLOT_HEART)
var/obj/item/organ/lungs/lungs = M.getorganslot(ORGAN_SLOT_LUNGS)
if(!(M.stat == DEAD || (M.has_trait(TRAIT_FAKEDEATH))))
if(!(M.stat == DEAD || (HAS_TRAIT(M, TRAIT_FAKEDEATH))))
if(heart && istype(heart))
heart_strength = "<span class='danger'>an unstable</span>"
if(heart.beating)

View File

@@ -13,7 +13,7 @@
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if(!(H.has_trait(TRAIT_CLUMSY)) && !(H.mind && H.mind.assigned_role == "Clown"))
if(!(HAS_TRAIT(H, TRAIT_CLUMSY)) && !(H.mind && H.mind.assigned_role == "Clown"))
return
if(slot == SLOT_SHOES)
spells = new

View File

@@ -435,7 +435,6 @@
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, FALSE)
//Medical hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/medical
name = "medical hardsuit helmet"
@@ -445,6 +444,7 @@
item_color = "medical"
flash_protect = 0
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75)
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
scan_reagents = 1
/obj/item/clothing/suit/space/hardsuit/medical
@@ -499,8 +499,6 @@
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/rd
tauric = TRUE //Citadel Add for tauric hardsuits
//Security hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/security
name = "security hardsuit helmet"
@@ -510,7 +508,6 @@
item_color = "sec"
armor = list("melee" = 35, "bullet" = 15, "laser" = 30,"energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75)
/obj/item/clothing/suit/space/hardsuit/security
icon_state = "hardsuit-sec"
name = "security hardsuit"
@@ -532,7 +529,6 @@
item_color = "hos"
armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95)
/obj/item/clothing/suit/space/hardsuit/security/hos
icon_state = "hardsuit-hos"
name = "head of security's hardsuit"
@@ -623,6 +619,49 @@
var/footstep = 1
var/datum/component/mobhook
/obj/item/clothing/suit/space/hardsuit/ancient/mason
name = "M.A.S.O.N RIG"
desc = "The Multi-Augmented Severe Operations Networked Resource Integration Gear is an man-portable tank designed for extreme environmental situations. It is excessively bulky, but rated for all but the most atomic of hazards. The specialized armor is surprisingly weak to conventional weaponry. The exo slot can attach most storge bags on to the suit."
icon_state = "hardsuit-ancient"
item_state = "anc_hardsuit"
armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 500, "bomb" = 500, "bio" = 500, "rad" = 500, "fire" = 500, "acid" = 500)
slowdown = 6 //Slow
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage, /obj/item/construction/rcd, /obj/item/pipe_dispenser)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason
name = "M.A.S.O.N RIG helmet"
desc = "The M.A.S.O.N RIG helmet is complimentary to the rest of the armor. It features a very large, high powered flood lamp and robust flash protection."
icon_state = "hardsuit0-ancient"
item_state = "anc_helm"
armor = list("melee" = 10, "bullet" = 5, "laser" = 5, "energy" = 500, "bomb" = 500, "bio" = 500, "rad" = 500, "fire" = 500, "acid" = 500)
item_color = "ancient"
brightness_on = 16
scan_reagents = 1
flash_protect = 5 //We will not be flash by bombs
tint = 1
var/obj/machinery/doppler_array/integrated/bomb_radar
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/Initialize()
. = ..()
bomb_radar = new /obj/machinery/doppler_array/integrated(src)
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/equipped(mob/living/carbon/human/user, slot)
..()
if (slot == SLOT_HEAD)
var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC]
DHUD.add_hud_to(user)
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/dropped(mob/living/carbon/human/user)
..()
if (user.head == src)
var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC]
DHUD.remove_hud_from(user)
/obj/item/clothing/suit/space/hardsuit/ancient/proc/on_mob_move()
var/mob/living/carbon/human/H = loc
if(!istype(H) || H.wear_suit != src)
@@ -692,7 +731,6 @@
return 1
return 0
/obj/item/clothing/suit/space/hardsuit/shielded/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
@@ -750,8 +788,6 @@
item_state = "ert_command"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/blue
/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf
name = "shielded hardsuit helmet"
desc = "Standard issue hardsuit helmet for playing capture the flag."
@@ -760,7 +796,6 @@
item_color = "ert_medical"
armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95)
/obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red
icon_state = "hardsuit0-ert_security"
item_state = "hardsuit0-ert_security"
@@ -773,10 +808,6 @@
item_state = "hardsuit0-ert_commander"
item_color = "ert_commander"
//////Syndicate Version
/obj/item/clothing/suit/space/hardsuit/shielded/syndi
@@ -791,7 +822,6 @@
slowdown = 0
tauric = TRUE //Citadel Add for tauric hardsuits
/obj/item/clothing/suit/space/hardsuit/shielded/syndi/Initialize()
jetpack = new /obj/item/tank/jetpack/suit(src)
. = ..()

View File

@@ -124,6 +124,9 @@
icon_state = "suitjacket_black"
item_state = "ro_suit"
/obj/item/clothing/suit/toggle/lawyer/black/syndie
desc = "A snappy dress jacket. Suspiciously has no tags or branding."
armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40)
//Mime
/obj/item/clothing/suit/suspenders

File diff suppressed because it is too large Load Diff

View File

@@ -21,6 +21,8 @@
CAT_BURGER,
CAT_CAKE,
CAT_EGG,
CAT_FISH,
CAT_ICE, //Called Frozen
CAT_MEAT,
CAT_MISCFOOD,
CAT_PASTRY,
@@ -28,7 +30,6 @@
CAT_PIZZA,
CAT_SALAD,
CAT_SANDWICH,
CAT_SUSHI,
CAT_SOUP,
CAT_SPAGHETTI),
CAT_CLOTHING) //Clothing subcategories

View File

@@ -365,28 +365,6 @@
parts = list(/obj/item/camera = 1)
category = CAT_MISC
/datum/crafting_recipe/lizardhat
name = "Lizard Cloche Hat"
result = /obj/item/clothing/head/lizard
time = 10
reqs = list(/obj/item/organ/tail/lizard = 1)
category = CAT_MISC
/datum/crafting_recipe/lizardhat_alternate
name = "Lizard Cloche Hat"
result = /obj/item/clothing/head/lizard
time = 10
reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1)
category = CAT_MISC
/datum/crafting_recipe/kittyears
name = "Kitty Ears"
result = /obj/item/clothing/head/kitty/genuine
time = 10
reqs = list(/obj/item/organ/tail/cat = 1,
/obj/item/organ/ears/cat = 1)
category = CAT_MISC
/datum/crafting_recipe/skateboard
name = "Skateboard"
result = /obj/vehicle/ridden/scooter/skateboard
@@ -558,6 +536,14 @@
/obj/item/stack/sheet/animalhide/ashdrake = 5)
category = CAT_PRIMAL
/datum/crafting_recipe/bonebag
name = "Bone Satchel"
result = /obj/item/storage/backpack/satchel/bone
time = 30
reqs = list(/obj/item/stack/sheet/bone = 3,
/obj/item/stack/sheet/sinew = 2)
category = CAT_PRIMAL
/datum/crafting_recipe/gold_horn
name = "Golden Bike Horn"
result = /obj/item/bikehorn/golden
@@ -633,6 +619,15 @@
/obj/item/assembly/igniter = 1)
category = CAT_MISC
/datum/crafting_recipe/wheelchair
name = "Wheelchair"
result = /obj/vehicle/ridden/wheelchair
reqs = list(/obj/item/stack/sheet/plasteel = 2,
/obj/item/stack/rods = 8)
time = 100
category = CAT_MISC
/datum/crafting_recipe/rcl
name = "Makeshift Rapid Cable Layer"
result = /obj/item/twohanded/rcl/ghetto
@@ -664,6 +659,28 @@
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
category = CAT_MISC
/datum/crafting_recipe/lizardhat
name = "Lizard Cloche Hat"
result = /obj/item/clothing/head/lizard
time = 10
reqs = list(/obj/item/organ/tail/lizard = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/lizardhat_alternate
name = "Lizard Cloche Hat"
result = /obj/item/clothing/head/lizard
time = 10
reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/kittyears
name = "Kitty Ears"
result = /obj/item/clothing/head/kitty/genuine
time = 10
reqs = list(/obj/item/organ/tail/cat = 1,
/obj/item/organ/ears/cat = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/hudsunsec
name = "Security HUDsunglasses"
result = /obj/item/clothing/glasses/hud/security/sunglasses
@@ -746,10 +763,10 @@
/datum/crafting_recipe/paperwork
name = "Filed Paper Work"
result = /obj/item/paper/fluff/jobs/cargo/manifest/paperwork_correct
time = 90 //Takes time for people to file and complete paper work!
result = /obj/item/folder/paperwork_correct
time = 60 //Takes time for people to file and complete paper work!
reqs = list(/obj/item/pen = 1,
/obj/item/paper/fluff/jobs/cargo/manifest/paperwork = 2)
/obj/item/folder/paperwork = 2)
category = CAT_MISC
/datum/crafting_recipe/ghettojetpack
@@ -773,3 +790,36 @@
/datum/reagent/water = 15)
time = 40
category = CAT_MISC
/datum/crafting_recipe/smartdart
name = "Medical smartdart"
result = /obj/item/reagent_containers/syringe/dart
reqs = list(/obj/item/stack/sheet/metal = 1,
/obj/item/stack/sheet/glass = 1,
/obj/item/stack/sheet/plastic = 1)
time = 10
category = CAT_WEAPONRY
subcategory = CAT_AMMO
/datum/crafting_recipe/medolier
name = "Medolier"
result = /obj/item/storage/belt/medolier
reqs = list(/obj/item/stack/sheet/metal = 2,
/obj/item/stack/sheet/cloth = 3,
/obj/item/stack/sheet/plastic = 4)
time = 30
category = CAT_WEAPONRY
subcategory = CAT_AMMO
/datum/crafting_recipe/smartdartgun
name = "Smart dartgun"
result = /obj/item/gun/syringe/dart
reqs = list(/obj/item/stack/sheet/metal = 15,
/obj/item/stack/sheet/glass = 10,
/obj/item/tank/internals = 1,
/obj/item/reagent_containers/glass/beaker = 1,
/obj/item/stack/sheet/plastic = 10,
/obj/item/stack/cable_coil = 2)
time = 150 //It's a gun
category = CAT_WEAPONRY
subcategory = CAT_WEAPON

View File

@@ -13,7 +13,7 @@
icon = 'icons/obj/toy.dmi'
icon_state = "rag"
item_flags = NOBLUDGEON
container_type = OPENCONTAINER
reagent_flags = OPENCONTAINER
amount_per_transfer_from_this = 5
possible_transfer_amounts = list()
volume = 5

View File

@@ -39,7 +39,7 @@
continue
if(H.stat == DEAD)
continue
if(H.has_trait(TRAIT_VIRUSIMMUNE)) //Don't pick someone who's virus immune, only for it to not do anything.
if(HAS_TRAIT(H, TRAIT_VIRUSIMMUNE)) //Don't pick someone who's virus immune, only for it to not do anything.
continue
var/foundAlready = FALSE // don't infect someone that already has a disease
for(var/thing in H.diseases)
@@ -51,7 +51,7 @@
var/datum/disease/D
if(!advanced_virus)
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
if(!H.dna || (H.has_trait(TRAIT_BLIND))) //A blindness disease would be the worst.
if(!H.dna || (HAS_TRAIT(H, TRAIT_BLIND))) //A blindness disease would be the worst.
continue
D = new virus_type()
var/datum/disease/dnaspread/DS = D

View File

@@ -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
var/mob/living/wizard
var/z_original = 0
var/destination
var/notify = TRUE
@@ -140,3 +141,23 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
H.adjustBruteLoss(160)
if(L && (L.density || prob(10)))
L.ex_act(EXPLODE_HEAVY)
obj/effect/immovablerod/attack_hand(mob/living/user)
if(ishuman(user))
var/mob/living/carbon/human/U = user
if(U.job in list("Research Director"))
playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1)
for(var/mob/M in urange(8, src))
if(!M.stat)
shake_camera(M, 2, 3)
if(wizard)
U.visible_message("<span class='boldwarning'>[src] transforms into [wizard] as [U] suplexes them!</span>", "<span class='warning'>As you grab [src], it suddenly turns into [wizard] as you suplex them!</span>")
to_chat(wizard, "<span class='boldwarning'>You're suddenly jolted out of rod-form as [U] somehow manages to grab you, slamming you into the ground!</span>")
wizard.Stun(60)
wizard.apply_damage(25, BRUTE)
qdel(src)
else
U.visible_message("<span class='boldwarning'>[U] suplexes [src] into the ground!</span>", "<span class='warning'>You suplex [src] into the ground!</span>")
new /obj/structure/festivus/anchored(drop_location())
new /obj/effect/anomaly/flux(drop_location())
qdel(src)

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@
icon_state = null
lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
container_type = OPENCONTAINER
reagent_flags = OPENCONTAINER
var/gulp_size = 5 //This is now officially broken ... need to think of a nice way to fix it.
possible_transfer_amounts = list(5,10,15,20,25,30,50)
volume = 50
@@ -36,7 +36,7 @@
if(M == user)
user.visible_message("<span class='notice'>[user] swallows a gulp of [src].</span>", "<span class='notice'>You swallow a gulp of [src].</span>")
if(M.has_trait(TRAIT_VORACIOUS))
if(HAS_TRAIT(M, TRAIT_VORACIOUS))
M.changeNext_move(CLICK_CD_MELEE * 0.5) //chug! chug! chug!
else
@@ -152,7 +152,6 @@
possible_transfer_amounts = list()
volume = 5
flags_1 = CONDUCT_1
container_type = OPENCONTAINER
spillable = TRUE
resistance_flags = FIRE_PROOF
isGlass = FALSE
@@ -399,7 +398,7 @@
name = "soda can"
lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
container_type = NONE
reagent_flags = NONE
spillable = FALSE
isGlass = FALSE
@@ -423,7 +422,7 @@
/obj/item/reagent_containers/food/drinks/soda_cans/attack_self(mob/user)
if(!is_drainable())
to_chat(user, "You pull back the tab of \the [src] with a satisfying pop.") //Ahhhhhhhh
container_type = OPENCONTAINER
ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
playsound(src, "can_open", 50, 1)
spillable = TRUE
return

View File

@@ -57,7 +57,7 @@
if(user.a_intent != INTENT_HARM || !isGlass)
return ..()
if(user.has_trait(TRAIT_PACIFISM))
if(HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "<span class='warning'>You don't want to harm [target]!</span>")
return

View File

@@ -4,7 +4,7 @@
/obj/item/reagent_containers/food
possible_transfer_amounts = list()
volume = 50 //Sets the default container amount for all food items.
container_type = INJECTABLE
reagent_flags = INJECTABLE
resistance_flags = FLAMMABLE
var/foodtype = NONE
var/last_check_time
@@ -19,7 +19,7 @@
if(last_check_time + 50 < world.time)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(!H.has_trait(TRAIT_AGEUSIA))
if(!HAS_TRAIT(H, TRAIT_AGEUSIA))
if(foodtype & H.dna.species.toxic_food)
to_chat(H,"<span class='warning'>What the hell was that thing?!</span>")
H.adjust_disgust(25 + 30 * fraction)

View File

@@ -10,7 +10,7 @@
desc = "Just your average condiment container."
icon = 'icons/obj/food/containers.dmi'
icon_state = "emptycondiment"
container_type = OPENCONTAINER
reagent_flags = OPENCONTAINER
possible_transfer_amounts = list(1, 5, 10, 15, 20, 25, 30, 50)
volume = 50
//Possible_states has the reagent id as key and a list of, in order, the icon_state, the name and the desc as values. Used in the on_reagent_change(changetype) to change names, descs and sprites.

View File

@@ -290,7 +290,7 @@
desc = "A simple bowl, used for soups and salads."
icon = 'icons/obj/food/soupsalad.dmi'
icon_state = "bowl"
container_type = OPENCONTAINER
reagent_flags = OPENCONTAINER
materials = list(MAT_GLASS = 500)
w_class = WEIGHT_CLASS_NORMAL

View File

@@ -112,7 +112,7 @@ All foods are distributed among various categories. Use common sense.
else if(fullness > (600 * (1 + M.overeatduration / 2000))) // The more you eat - the more you can eat
user.visible_message("<span class='warning'>[user] cannot force any more of \the [src] to go down [user.p_their()] throat!</span>", "<span class='danger'>You cannot force any more of \the [src] to go down your throat!</span>")
return 0
if(M.has_trait(TRAIT_VORACIOUS))
if(HAS_TRAIT(M, TRAIT_VORACIOUS))
M.changeNext_move(CLICK_CD_MELEE * 0.5) //nom nom nom
else
if(!isbrain(M)) //If you're feeding it to someone else.

View File

@@ -0,0 +1,187 @@
/obj/item/reagent_containers/food/snacks/icecreamsandwich
name = "icecream sandwich"
desc = "Portable Ice-cream in its own packaging."
icon = 'icons/obj/food/food.dmi'
icon_state = "icecreamsandwich"
bonus_reagents = list("nutriment" = 1, "ice" = 2)
list_reagents = list("nutriment" = 2, "ice" = 2)
tastes = list("ice cream" = 1)
foodtype = GRAIN | DAIRY
/obj/item/reagent_containers/food/snacks/sundae
name = "sundae"
desc = "A classic dessert."
icon_state = "sundae"
bonus_reagents = list("nutriment" = 2, "vitamin" = 1)
list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2)
filling_color = "#FFFACD"
tastes = list("ice cream" = 1, "banana" = 1)
foodtype = FRUIT | DAIRY | SUGAR
/obj/item/reagent_containers/food/snacks/honkdae
name = "honkdae"
desc = "The clown's favorite dessert."
icon_state = "honkdae"
bonus_reagents = list("nutriment" = 2, "vitamin" = 2)
list_reagents = list("nutriment" = 6, "banana" = 10, "vitamin" = 4)
filling_color = "#FFFACD"
tastes = list("ice cream" = 1, "banana" = 1, "a bad joke" = 1)
foodtype = FRUIT | DAIRY | SUGAR
/obj/item/reagent_containers/food/snacks/spacefreezy
name = "space freezy"
desc = "The best icecream in space."
icon_state = "spacefreezy"
bonus_reagents = list("nutriment" = 2, "vitamin" = 2)
list_reagents = list("nutriment" = 6, "bluecherryjelly" = 5, "vitamin" = 4)
filling_color = "#87CEFA"
tastes = list("blue cherries" = 2, "ice cream" = 2)
foodtype = FRUIT | DAIRY
/////////////
//SNOWCONES//
/////////////
/obj/item/reagent_containers/food/snacks/snowcones //We use this as a base for all other snowcones
name = "flaverless snowcone"
desc = "Its just harden water slivers. Still fun to chew on."
icon = 'icons/obj/food/snowcones.dmi'
icon_state = "flaverless_sc"
trash = /obj/item/reagent_containers/food/drinks/sillycup //We dont eat paper cups
bonus_reagents = list("water" = 10) //Base line will allways give water
list_reagents = list("water" = 1) // We dont get food for water/juices
filling_color = "#FFFFFF" //Ice is white
tastes = list("ice" = 1, "water" = 1)
foodtype = SUGAR //We use SUGAR as a base line to act in as junkfood, other wise we use fruit
/obj/item/reagent_containers/food/snacks/snowcones/lime
name = "lime flavored snowcone"
desc = "A lime flavord snowball in a paper cup."
icon_state = "lime_sc"
list_reagents = list("nutriment" = 1, "limejuice" = 5)
tastes = list("ice" = 1, "water" = 1, "limes" = 5)
foodtype = FRUIT
/obj/item/reagent_containers/food/snacks/snowcones/lemon
name = "lemon flavored snowcone"
desc = "A lemon flavord snowball in a paper cup."
icon_state = "lemon_sc"
list_reagents = list("nutriment" = 1, "lemonjuice" = 5)
tastes = list("ice" = 1, "water" = 1, "lemons" = 5)
foodtype = FRUIT
/obj/item/reagent_containers/food/snacks/snowcones/apple
name = "apple flavored snowcone"
desc = "A apple flavord snowball in a paper cup."
icon_state = "blue_sc"
list_reagents = list("nutriment" = 1, "applejuice" = 5)
tastes = list("ice" = 1, "water" = 1, "apples" = 5)
foodtype = FRUIT
/obj/item/reagent_containers/food/snacks/snowcones/grape
name = "grape flavored snowcone"
desc = "A grape flavord snowball in a paper cup."
icon_state = "grape_sc"
list_reagents = list("nutriment" = 1, "berryjuice" = 5)
tastes = list("ice" = 1, "water" = 1, "grape" = 5)
foodtype = FRUIT
/obj/item/reagent_containers/food/snacks/snowcones/orange
name = "orange flavored snowcone"
desc = "A mix of different flavors dizzled on a snowball in a paper cup."
icon_state = "orange_sc"
list_reagents = list("nutriment" = 1, "orangejuice" = 10)
tastes = list("ice" = 1, "water" = 1, "berries" = 5)
foodtype = FRUIT
/obj/item/reagent_containers/food/snacks/snowcones/blue
name = "bluecherry flavored snowcone"
desc = "A bluecharry flavord snowball in a paper cup, how rare!"
icon_state = "red_sc"
list_reagents = list("nutriment" = 1, "bluecherryjelly" = 5)
tastes = list("ice" = 1, "water" = 1, "blue" = 5)
foodtype = FRUIT
/obj/item/reagent_containers/food/snacks/snowcones/red
name = "cherry flavored snowcone"
desc = "A cherry flavord snowball in a paper cup."
icon_state = "blue_sc"
list_reagents = list("nutriment" = 1, "cherryjelly" = 5)
tastes = list("ice" = 1, "water" = 1, "red" = 5)
foodtype = FRUIT
/obj/item/reagent_containers/food/snacks/snowcones/kiwi
name = "kiwi flavored snowcone"
desc = "A kiwi flavord snowball in a paper cup."
icon_state = "kiwi_sc"
list_reagents = list("nutriment" = 3, "vitamin" = 6)
tastes = list("ice" = 1, "space" = 3, "kiwi" = 5)
foodtype = FRUIT
/obj/item/reagent_containers/food/snacks/snowcones/mix
name = "mixed berry flavored snowcone"
desc = "A mix of different flavors dizzled on a snowball in a paper cup."
icon_state = "berry_sc"
list_reagents = list("nutriment" = 1, "berryjuice" = 10)
tastes = list("ice" = 1, "water" = 1, "berries" = 5)
foodtype = FRUIT
/obj/item/reagent_containers/food/snacks/snowcones/fruitsalad
name = "mixed fruit flavored snowcone"
desc = "A mix of different flavors dizzled on a snowball in a paper cup."
icon_state = "fruitsalad_sc"
list_reagents = list("nutriment" = 1, "lemonjuice" = 5, "limejuice" = 5, "lemonjuice" = 5, "orangejuice" = 5)
tastes = list("ice" = 1, "water" = 1, "fruits" = 25)
foodtype = FRUIT
/obj/item/reagent_containers/food/snacks/snowcones/pineapple
name = "pineapple flavored snowcone"
desc = "A pineapple flavord snowball in a paper cup."
icon_state = "pineapple_sc"
list_reagents = list("nutriment" = 1, "water" = 1)
tastes = list("ice" = 1, "water" = 1, "pineapples" = 5)
foodtype = PINEAPPLE //Pineapple to allow all that like pineapple to enjoy
/obj/item/reagent_containers/food/snacks/snowcones/mime
name = "mime snowcone"
desc = "..."
icon_state = "mime_sc"
list_reagents = list("nutriment" = 1, "nothing" = 5)
tastes = list("nothing" = 5)
/obj/item/reagent_containers/food/snacks/snowcones/clown
name = "joke flavored snowcone"
desc = "A waterd down jokeful flavord snowball in a paper cup."
icon_state = "clown_sc"
list_reagents = list("nutriment" = 1, "laughter" = 5)
tastes = list("jokes" = 5, "brainfreeze" = 5, "joy" = 5)
/obj/item/reagent_containers/food/snacks/snowcones/soda
name = "sodawater flavored snowcone"
desc = "A waterd down sodawater flavored snowcone snowball in a paper cup."
icon_state = "soda_sc"
list_reagents = list("nutriment" = 1, "sodawater" = 5)
tastes = list("surgar" = 1, "water" = 5, "soda" = 5)
foodtype = JUNKFOOD | SUGAR
/obj/item/reagent_containers/food/snacks/snowcones/pwgrmer
name = "pwergamer flavored snowcone"
desc = "A waterd down pwergamer soda flavord snowball in a paper cup."
icon_state = "pwergamer_sc"
list_reagents = list("nutriment" = 1, "laughter" = 1)
tastes = list("vaild" = 5, "salt" = 5, "wats" = 5)
foodtype = JUNKFOOD | SUGAR
/obj/item/reagent_containers/food/snacks/snowcones/honey
name = "honey flavored snowcone"
desc = "A honey flavord snowball in a paper cup."
icon_state = "honey_sc"
list_reagents = list("nutriment" = 1, "honey" = 5)
tastes = list("pollen" = 5, "sweetness" = 5, "wax" = 1)
/obj/item/reagent_containers/food/snacks/snowcones/rainbow
name = "rainbow color snowcone"
desc = "A rainbow color snowball in a paper cup."
icon_state = "rainbow_sc"
list_reagents = list("nutriment" = 5, "laughter" = 25)
tastes = list("sunlight" = 5, "light" = 5, "slime" = 5, "paint" = 3, "clouds" = 3)

View File

@@ -340,36 +340,6 @@
tastes = list("melon" = 1)
foodtype = FRUIT
/obj/item/reagent_containers/food/snacks/spacefreezy
name = "space freezy"
desc = "The best icecream in space."
icon_state = "spacefreezy"
bonus_reagents = list("nutriment" = 2, "vitamin" = 2)
list_reagents = list("nutriment" = 6, "bluecherryjelly" = 5, "vitamin" = 4)
filling_color = "#87CEFA"
tastes = list("blue cherries" = 2, "ice cream" = 2)
foodtype = FRUIT | DAIRY
/obj/item/reagent_containers/food/snacks/sundae
name = "sundae"
desc = "A classic dessert."
icon_state = "sundae"
bonus_reagents = list("nutriment" = 2, "vitamin" = 1)
list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2)
filling_color = "#FFFACD"
tastes = list("ice cream" = 1, "banana" = 1)
foodtype = FRUIT | DAIRY | SUGAR
/obj/item/reagent_containers/food/snacks/honkdae
name = "honkdae"
desc = "The clown's favorite dessert."
icon_state = "honkdae"
bonus_reagents = list("nutriment" = 2, "vitamin" = 2)
list_reagents = list("nutriment" = 6, "banana" = 10, "vitamin" = 4)
filling_color = "#FFFACD"
tastes = list("ice cream" = 1, "banana" = 1, "a bad joke" = 1)
foodtype = FRUIT | DAIRY | SUGAR
/obj/item/reagent_containers/food/snacks/nachos
name = "nachos"
desc = "Chips from Space Mexico."

View File

@@ -28,7 +28,7 @@
if(last_check_time + 50 < world.time)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.mind && H.mind.assigned_role == "Security Officer" || H.mind.assigned_role == "Detective" || H.mind.assigned_role == "Warden" || H.mind.assigned_role == "Head of Security" && !H.has_trait(TRAIT_AGEUSIA))
if(H.mind && H.mind.assigned_role == "Security Officer" || H.mind.assigned_role == "Detective" || H.mind.assigned_role == "Warden" || H.mind.assigned_role == "Head of Security" && !HAS_TRAIT(H, TRAIT_AGEUSIA))
to_chat(H,"<span class='notice'>I love this taste!</span>")
H.adjust_disgust(-5 + -2.5 * fraction)
GET_COMPONENT_FROM(mood, /datum/component/mood, H)

View File

@@ -53,6 +53,7 @@
H.adjust_blurriness(1)
H.visible_message("<span class='warning'>[H] is creamed by [src]!</span>", "<span class='userdanger'>You've been creamed by [src]!</span>")
playsound(H, "desceration", 50, TRUE)
reagents.trans_to(H,15) //Transfers the cream pies total volume of reagents to target on it
if(!H.creamed) // one layer at a time
H.add_overlay(creamoverlay)
H.creamed = TRUE
@@ -268,3 +269,24 @@
bonus_reagents = list("nutriment" = 4, "vitamin" = 6)
tastes = list("mint" = 1, "pie" = 1)
foodtype = GRAIN | FRUIT | SUGAR
/obj/item/reagent_containers/food/snacks/pie/baklava
name = "baklava"
desc = "A delightful healthy snake made of nut layers with thin bread."
icon_state = "baklava"
slice_path = /obj/item/reagent_containers/food/snacks/baklavaslice
slices_num = 6
bonus_reagents = list("nutriment" = 2, "vitamin" = 6)
tastes = list("nuts" = 1, "pie" = 1)
foodtype = GRAIN
/obj/item/reagent_containers/food/snacks/baklavaslice
name = "baklava dish"
desc = "A portion delightful healthy snake made of nut layers with thin bread"
icon = 'icons/obj/food/piecake.dmi'
icon_state = "baklavaslice"
trash = /obj/item/trash/plate
filling_color = "#1E90FF"
list_reagents = list("nutriment" = 2, "vitamins" = 4)
tastes = list("nuts" = 1, "pie" = 1)
foodtype = GRAIN

View File

@@ -52,16 +52,6 @@
list_reagents = list("nutriment" = 2, "cherryjelly" = 5, "vitamin" = 2)
foodtype = GRAIN | FRUIT
/obj/item/reagent_containers/food/snacks/icecreamsandwich
name = "icecream sandwich"
desc = "Portable Ice-cream in its own packaging."
icon = 'icons/obj/food/food.dmi'
icon_state = "icecreamsandwich"
bonus_reagents = list("nutriment" = 1, "ice" = 2)
list_reagents = list("nutriment" = 2, "ice" = 2)
tastes = list("ice cream" = 1)
foodtype = GRAIN | DAIRY
/obj/item/reagent_containers/food/snacks/notasandwich
name = "not-a-sandwich"
desc = "Something seems to be wrong with this, you can't quite figure what. Maybe it's his moustache."

View File

@@ -28,7 +28,6 @@ God bless America.
density = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 5
container_type = OPENCONTAINER
layer = BELOW_OBJ_LAYER
var/obj/item/reagent_containers/food/snacks/deepfryholder/frying //What's being fried RIGHT NOW?
var/cook_time = 0
@@ -52,7 +51,7 @@ God bless America.
/obj/machinery/deepfryer/Initialize()
. = ..()
create_reagents(50)
create_reagents(50, OPENCONTAINER)
reagents.add_reagent("cooking_oil", 25)
component_parts = list()
component_parts += new /obj/item/circuitboard/machine/deep_fryer(null)

View File

@@ -15,13 +15,11 @@
var/portion = 10
var/selected_drink
var/list/stored_food = list()
container_type = OPENCONTAINER
var/obj/item/reagent_containers/mixer
/obj/machinery/food_cart/Initialize()
. = ..()
create_reagents(LIQUID_CAPACIY)
reagents.set_reacting(FALSE)
create_reagents(LIQUID_CAPACIY, OPENCONTAINER | NO_REACT)
mixer = new /obj/item/reagent_containers(src, MIXER_CAPACITY)
mixer.name = "Mixer"

View File

@@ -14,7 +14,6 @@
anchored = FALSE
use_power = NO_POWER_USE
layer = BELOW_OBJ_LAYER
container_type = OPENCONTAINER
max_integrity = 300
var/list/product_types = list()
var/dispense_flavour = ICECREAM_VANILLA
@@ -65,8 +64,7 @@
. = ..()
while(product_types.len < 6)
product_types.Add(5)
create_reagents()
reagents.set_reacting(FALSE)
create_reagents(100, OPENCONTAINER | NO_REACT)
for(var/reagent in icecream_vat_reagents)
reagents.add_reagent(reagent, icecream_vat_reagents[reagent])

View File

@@ -86,7 +86,6 @@
src.icon_state = "mw"
src.broken = 0 // Fix it!
src.dirty = 0 // just to be sure
src.container_type = OPENCONTAINER
return 0 //to use some fuel
else
to_chat(user, "<span class='warning'>It's broken!</span>")
@@ -103,7 +102,6 @@
src.dirty = 0 // It's clean!
src.broken = 0 // just to be sure
src.icon_state = "mw"
src.container_type = OPENCONTAINER
src.updateUsrDialog()
return 1 // Disables the after-attack so we don't spray the floor/user.
else
@@ -124,7 +122,6 @@
src.dirty = 0 // It's clean!
src.broken = 0 // just to be sure
src.icon_state = "mw"
src.container_type = OPENCONTAINER
else if(src.dirty==100) // The microwave is all dirty so can't be used!
to_chat(user, "<span class='warning'>It's dirty!</span>")

View File

@@ -15,11 +15,11 @@
var/max_n_of_items = 1500
var/allow_ai_retrieve = FALSE
var/list/initial_contents
var/visible_contents = TRUE
/obj/machinery/smartfridge/Initialize()
. = ..()
create_reagents()
reagents.set_reacting(FALSE)
create_reagents(100, NO_REACT)
if(islist(initial_contents))
for(var/typekey in initial_contents)
@@ -38,11 +38,21 @@
update_icon()
/obj/machinery/smartfridge/update_icon()
var/startstate = initial(icon_state)
if(!stat)
icon_state = startstate
if(visible_contents)
switch(contents.len)
if(0)
icon_state = "[initial(icon_state)]"
if(1 to 25)
icon_state = "[initial(icon_state)]1"
if(26 to 75)
icon_state = "[initial(icon_state)]2"
if(76 to INFINITY)
icon_state = "[initial(icon_state)]3"
else
icon_state = "[initial(icon_state)]"
else
icon_state = "[startstate]-off"
icon_state = "[initial(icon_state)]-off"
@@ -51,7 +61,14 @@
********************/
/obj/machinery/smartfridge/attackby(obj/item/O, mob/user, params)
if(default_deconstruction_screwdriver(user, "smartfridge_open", "smartfridge", O))
if(user.a_intent == INTENT_HARM)
return ..()
if(default_deconstruction_screwdriver(user, icon_state, icon_state, O))
cut_overlays()
if(panel_open)
add_overlay("[initial(icon_state)]-panel")
updateUsrDialog()
return
if(default_pry_open(O))
@@ -65,49 +82,46 @@
updateUsrDialog()
return
if(!stat)
if(contents.len >= max_n_of_items)
to_chat(user, "<span class='warning'>\The [src] is full!</span>")
return FALSE
if(accept_check(O))
load(O)
user.visible_message("[user] has added \the [O] to \the [src].", "<span class='notice'>You add \the [O] to \the [src].</span>")
updateUsrDialog()
return TRUE
if(istype(O, /obj/item/storage/bag))
var/obj/item/storage/P = O
var/loaded = 0
for(var/obj/G in P.contents)
if(contents.len >= max_n_of_items)
break
if(accept_check(G))
load(G)
loaded++
updateUsrDialog()
if(loaded)
if(contents.len >= max_n_of_items)
user.visible_message("[user] loads \the [src] with \the [O].", \
"<span class='notice'>You fill \the [src] with \the [O].</span>")
else
user.visible_message("[user] loads \the [src] with \the [O].", \
"<span class='notice'>You load \the [src] with \the [O].</span>")
if(O.contents.len > 0)
to_chat(user, "<span class='warning'>Some items are refused.</span>")
return TRUE
else
to_chat(user, "<span class='warning'>There is nothing in [O] to put in [src]!</span>")
return FALSE
if(user.a_intent != INTENT_HARM)
to_chat(user, "<span class='warning'>\The [src] smartly refuses [O].</span>")
if(stat)
updateUsrDialog()
return FALSE
else
return ..()
if(contents.len >= max_n_of_items)
to_chat(user, "<span class='warning'>\The [src] is full!</span>")
return FALSE
if(accept_check(O))
load(O)
user.visible_message("[user] has added \the [O] to \the [src].", "<span class='notice'>You add \the [O] to \the [src].</span>")
updateUsrDialog()
if (visible_contents)
update_icon()
return TRUE
if(istype(O, /obj/item/storage/bag))
var/obj/item/storage/P = O
var/loaded = 0
for(var/obj/G in P.contents)
if(contents.len >= max_n_of_items)
break
if(accept_check(G))
load(G)
loaded++
updateUsrDialog()
if(loaded)
user.visible_message("[user] loads \the [src] with \the [O].", \
"<span class='notice'>You [contents.len >= max_n_of_items ? "fill" : "load"] \the [src] with \the [O].</span>")
if(O.contents.len > 0)
to_chat(user, "<span class='warning'>Some items are refused.</span>")
return TRUE
else
to_chat(user, "<span class='warning'>There is nothing in [O] to put in [src]!</span>")
return FALSE
to_chat(user, "<span class='warning'>\The [src] smartly refuses [O].</span>")
updateUsrDialog()
return FALSE
@@ -187,6 +201,8 @@
O.forceMove(drop_location())
adjust_item_drop_location(O)
break
if (visible_contents)
update_icon()
return TRUE
for(var/obj/item/O in src)
@@ -196,6 +212,8 @@
O.forceMove(drop_location())
adjust_item_drop_location(O)
desired--
if (visible_contents)
update_icon()
return TRUE
return FALSE
@@ -211,6 +229,7 @@
use_power = IDLE_POWER_USE
idle_power_usage = 5
active_power_usage = 200
visible_contents = FALSE
var/drying = FALSE
/obj/machinery/smartfridge/drying_rack/Initialize()
@@ -415,6 +434,7 @@
name = "disk compartmentalizer"
desc = "A machine capable of storing a variety of disks. Denoted by most as the DSU (disk storage unit)."
icon_state = "disktoaster"
visible_contents = FALSE
pass_flags = PASSTABLE
/obj/machinery/smartfridge/disks/accept_check(obj/item/O)

View File

@@ -0,0 +1,244 @@
/datum/crafting_recipe/food/icecreamsandwich
name = "Icecream sandwich"
reqs = list(
/datum/reagent/consumable/cream = 5,
/datum/reagent/consumable/ice = 5,
/obj/item/reagent_containers/food/snacks/icecream = 1
)
result = /obj/item/reagent_containers/food/snacks/icecreamsandwich
subcategory = CAT_ICE
/datum/crafting_recipe/food/spacefreezy
name ="Space freezy"
reqs = list(
/datum/reagent/consumable/bluecherryjelly = 5,
/datum/reagent/consumable/spacemountainwind = 15,
/obj/item/reagent_containers/food/snacks/icecream = 1
)
result = /obj/item/reagent_containers/food/snacks/spacefreezy
subcategory = CAT_ICE
/datum/crafting_recipe/food/sundae
name ="Sundae"
reqs = list(
/datum/reagent/consumable/cream = 5,
/obj/item/reagent_containers/food/snacks/grown/cherries = 1,
/obj/item/reagent_containers/food/snacks/grown/banana = 1,
/obj/item/reagent_containers/food/snacks/icecream = 1
)
result = /obj/item/reagent_containers/food/snacks/sundae
subcategory = CAT_ICE
/datum/crafting_recipe/food/honkdae
name ="Honkdae"
reqs = list(
/datum/reagent/consumable/cream = 5,
/obj/item/clothing/mask/gas/clown_hat = 1,
/obj/item/reagent_containers/food/snacks/grown/cherries = 1,
/obj/item/reagent_containers/food/snacks/grown/banana = 2,
/obj/item/reagent_containers/food/snacks/icecream = 1
)
result = /obj/item/reagent_containers/food/snacks/honkdae
subcategory = CAT_ICE
//////////////////////////SNOW CONES///////////////////////
/datum/crafting_recipe/food/flaverless_sc
name = "Flaverless snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15
)
result = /obj/item/reagent_containers/food/snacks/snowcones
subcategory = CAT_ICE
/datum/crafting_recipe/food/pineapple_sc
name = "Pineapple snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/obj/item/reagent_containers/food/snacks/pineappleslice = 2
)
result = /obj/item/reagent_containers/food/snacks/snowcones/pineapple
subcategory = CAT_ICE
/datum/crafting_recipe/food/lime_sc
name = "Lime snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/limejuice = 5
)
result = /obj/item/reagent_containers/food/snacks/snowcones/lime
subcategory = CAT_ICE
/datum/crafting_recipe/food/lemon_sc
name = "Lemon snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/lemonjuice = 5
)
result = /obj/item/reagent_containers/food/snacks/snowcones/lemon
subcategory = CAT_ICE
/datum/crafting_recipe/food/apple_sc
name = "Apple snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/applejuice = 5
)
result = /obj/item/reagent_containers/food/snacks/snowcones/apple
subcategory = CAT_ICE
/datum/crafting_recipe/food/grape_sc
name = "Grape snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/berryjuice = 5
)
result = /obj/item/reagent_containers/food/snacks/snowcones/grape
subcategory = CAT_ICE
/datum/crafting_recipe/food/orange_sc
name = "Orange snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/orangejuice = 5
)
result = /obj/item/reagent_containers/food/snacks/snowcones/orange
subcategory = CAT_ICE
/datum/crafting_recipe/food/blue_sc
name = "Bluecherry snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/bluecherryjelly= 5
)
result = /obj/item/reagent_containers/food/snacks/snowcones/blue
subcategory = CAT_ICE
/datum/crafting_recipe/food/red_sc
name = "Cherry snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/cherryjelly= 5
)
result = /obj/item/reagent_containers/food/snacks/snowcones/red
subcategory = CAT_ICE
/datum/crafting_recipe/food/mix_sc
name = "Mixed berrie snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/berryjuice = 15
)
result = /obj/item/reagent_containers/food/snacks/snowcones/mix
subcategory = CAT_ICE
/datum/crafting_recipe/food/fruitsalad_sc
name = "Fruit Salad snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/orangejuice = 5,
/datum/reagent/consumable/limejuice = 5,
/datum/reagent/consumable/lemonjuice = 5
)
result = /obj/item/reagent_containers/food/snacks/snowcones/fruitsalad
subcategory = CAT_ICE
/datum/crafting_recipe/food/mime_sc
name = "Mime snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/nothing = 5
)
result = /obj/item/reagent_containers/food/snacks/snowcones/mime
subcategory = CAT_ICE
/datum/crafting_recipe/food/clown_sc
name = "Clown snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/clownstears = 5
)
result = /obj/item/reagent_containers/food/snacks/snowcones/clown
subcategory = CAT_ICE
/datum/crafting_recipe/food/soda_sc
name = "Soda water snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/sodawater = 15
)
result = /obj/item/reagent_containers/food/snacks/snowcones/soda
subcategory = CAT_ICE
/datum/crafting_recipe/food/pwgrmer_sc
name = "Pwergamer snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/pwr_game = 15
)
result = /obj/item/reagent_containers/food/snacks/snowcones/pwgrmer
subcategory = CAT_ICE
/datum/crafting_recipe/food/kiwi_sc
name = "Soda water snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/obj/item/reagent_containers/food/snacks/egg/kiwiEgg = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15
)
result = /obj/item/reagent_containers/food/snacks/snowcones/kiwi
subcategory = CAT_ICE
/datum/crafting_recipe/food/honey_sc
name = "Honey snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/consumable/honey = 5
)
result = /obj/item/reagent_containers/food/snacks/snowcones/honey
subcategory = CAT_ICE
/datum/crafting_recipe/food/honey_sc
name = "Rainbow snowcone"
reqs = list(
/obj/item/reagent_containers/food/drinks/sillycup = 1,
/datum/reagent/water = 5,
/datum/reagent/consumable/ice = 15,
/datum/reagent/colorful_reagent = 1 //Hard to make
)
result = /obj/item/reagent_containers/food/snacks/snowcones/rainbow
subcategory = CAT_ICE

View File

@@ -38,37 +38,6 @@
// see code/module/crafting/table.dm
////////////////////////////////////////////////FISH////////////////////////////////////////////////
/datum/crafting_recipe/food/cubancarp
name = "Cuban carp"
reqs = list(
/datum/reagent/consumable/flour = 5,
/obj/item/reagent_containers/food/snacks/grown/chili = 1,
/obj/item/reagent_containers/food/snacks/carpmeat = 1
)
result = /obj/item/reagent_containers/food/snacks/cubancarp
subcategory = CAT_MEAT
/datum/crafting_recipe/food/fishandchips
name = "Fish and chips"
reqs = list(
/obj/item/reagent_containers/food/snacks/fries = 1,
/obj/item/reagent_containers/food/snacks/carpmeat = 1
)
result = /obj/item/reagent_containers/food/snacks/fishandchips
subcategory = CAT_MEAT
/datum/crafting_recipe/food/fishfingers
name = "Fish fingers"
reqs = list(
/datum/reagent/consumable/flour = 5,
/obj/item/reagent_containers/food/snacks/bun = 1,
/obj/item/reagent_containers/food/snacks/carpmeat = 1
)
result = /obj/item/reagent_containers/food/snacks/fishfingers
subcategory = CAT_MEAT
////////////////////////////////////////////////MR SPIDER////////////////////////////////////////////////
/datum/crafting_recipe/food/spidereggsham

View File

@@ -186,39 +186,6 @@
result = /obj/item/reagent_containers/food/snacks/melonfruitbowl
subcategory = CAT_MISCFOOD
/datum/crafting_recipe/food/spacefreezy
name ="Space freezy"
reqs = list(
/datum/reagent/consumable/bluecherryjelly = 5,
/datum/reagent/consumable/spacemountainwind = 15,
/obj/item/reagent_containers/food/snacks/icecream = 1
)
result = /obj/item/reagent_containers/food/snacks/spacefreezy
subcategory = CAT_MISCFOOD
/datum/crafting_recipe/food/sundae
name ="Sundae"
reqs = list(
/datum/reagent/consumable/cream = 5,
/obj/item/reagent_containers/food/snacks/grown/cherries = 1,
/obj/item/reagent_containers/food/snacks/grown/banana = 1,
/obj/item/reagent_containers/food/snacks/icecream = 1
)
result = /obj/item/reagent_containers/food/snacks/sundae
subcategory = CAT_MISCFOOD
/datum/crafting_recipe/food/honkdae
name ="Honkdae"
reqs = list(
/datum/reagent/consumable/cream = 5,
/obj/item/clothing/mask/gas/clown_hat = 1,
/obj/item/reagent_containers/food/snacks/grown/cherries = 1,
/obj/item/reagent_containers/food/snacks/grown/banana = 2,
/obj/item/reagent_containers/food/snacks/icecream = 1
)
result = /obj/item/reagent_containers/food/snacks/honkdae
subcategory = CAT_MISCFOOD
/datum/crafting_recipe/food/nachos
name ="Nachos"
reqs = list(

View File

@@ -22,7 +22,7 @@
)
result = /obj/item/reagent_containers/food/snacks/donut
subcategory = CAT_PASTRY
/datum/crafting_recipe/food/donut
time = 15
name = "Semen donut"
@@ -104,7 +104,7 @@ datum/crafting_recipe/food/donut/meat
/datum/crafting_recipe/food/rofflewaffles
name = "Roffle waffles"
reqs = list(
/datum/reagent/mushroomhallucinogen = 5,
/datum/reagent/drug/mushroomhallucinogen = 5,
/obj/item/reagent_containers/food/snacks/pastrybase = 2
)
result = /obj/item/reagent_containers/food/snacks/rofflewaffles
@@ -205,16 +205,6 @@ datum/crafting_recipe/food/donut/meat
////////////////////////////////////////////OTHER////////////////////////////////////////////
/datum/crafting_recipe/food/hotdog
name = "Hot dog"
reqs = list(
/datum/reagent/consumable/ketchup = 5,
/obj/item/reagent_containers/food/snacks/bun = 1,
/obj/item/reagent_containers/food/snacks/sausage = 1
)
result = /obj/item/reagent_containers/food/snacks/hotdog
subcategory = CAT_PASTRY
/datum/crafting_recipe/food/meatbun
name = "Meat bun"
reqs = list(

View File

@@ -159,3 +159,13 @@
)
result = /obj/item/reagent_containers/food/snacks/pie/frostypie
subcategory = CAT_PIE
/datum/crafting_recipe/food/baklava
name = "Baklava pie"
reqs = list(
/obj/item/reagent_containers/food/snacks/butter = 1,
/obj/item/reagent_containers/food/snacks/tortilla = 4, //Layers
/obj/item/seeds/wheat/oat = 3
)
result = /obj/item/reagent_containers/food/snacks/pie/baklava
subcategory = CAT_PIE

View File

@@ -43,16 +43,6 @@
result = /obj/item/reagent_containers/food/snacks/jellysandwich/cherry
subcategory = CAT_SANDWICH
/datum/crafting_recipe/food/icecreamsandwich
name = "Icecream sandwich"
reqs = list(
/datum/reagent/consumable/cream = 5,
/datum/reagent/consumable/ice = 5,
/obj/item/reagent_containers/food/snacks/icecream = 1
)
result = /obj/item/reagent_containers/food/snacks/icecreamsandwich
subcategory = CAT_SANDWICH
/datum/crafting_recipe/food/notasandwich
name = "Not a sandwich"
reqs = list(
@@ -62,7 +52,7 @@
result = /obj/item/reagent_containers/food/snacks/notasandwich
subcategory = CAT_SANDWICH
/datum/crafting_recipe/food/notasandwich
/datum/crafting_recipe/food/tunasandwich
name = "Tuna sandwich"
reqs = list(
/obj/item/reagent_containers/food/snacks/breadslice/plain = 2,
@@ -72,3 +62,13 @@
)
result = /obj/item/reagent_containers/food/snacks/tuna_sandwich
subcategory = CAT_SANDWICH
/datum/crafting_recipe/food/hotdog
name = "Hot dog"
reqs = list(
/datum/reagent/consumable/ketchup = 5,
/obj/item/reagent_containers/food/snacks/bun = 1,
/obj/item/reagent_containers/food/snacks/sausage = 1
)
result = /obj/item/reagent_containers/food/snacks/hotdog
subcategory = CAT_SANDWICH

View File

@@ -7,7 +7,7 @@
/datum/reagent/consumable/rice = 10
)
result = /obj/item/reagent_containers/food/snacks/sushi_rice
subcategory = CAT_SUSHI
subcategory = CAT_FISH
/datum/crafting_recipe/food/sea_weed
name = "Sea Weed Sheet"
@@ -17,7 +17,7 @@
/obj/item/reagent_containers/food/snacks/grown/kudzupod = 1,
)
result = /obj/item/reagent_containers/food/snacks/sea_weed
subcategory = CAT_SUSHI
subcategory = CAT_FISH
/datum/crafting_recipe/food/tuna_can
name = "Can of Tuna"
@@ -27,7 +27,7 @@
/obj/item/reagent_containers/food/snacks/carpmeat = 1,
)
result = /obj/item/reagent_containers/food/snacks/tuna
subcategory = CAT_SUSHI
subcategory = CAT_FISH
//////////////////////////Sushi/////////////////////////////////
@@ -39,7 +39,7 @@
/obj/item/reagent_containers/food/snacks/carpmeat = 1
)
result = /obj/item/reagent_containers/food/snacks/sashimi
subcategory = CAT_SUSHI
subcategory = CAT_FISH
/datum/crafting_recipe/food/riceball
name = "Onigiri"
@@ -49,7 +49,7 @@
/obj/item/reagent_containers/food/snacks/sushi_rice = 1
)
result = /obj/item/reagent_containers/food/snacks/riceball
subcategory = CAT_SUSHI
subcategory = CAT_FISH
/datum/crafting_recipe/food/sushie_egg
name = "Tobiko"
@@ -59,7 +59,7 @@
/obj/item/reagent_containers/food/snacks/sea_weed = 2,
)
result = /obj/item/reagent_containers/food/snacks/tobiko
subcategory = CAT_SUSHI
subcategory = CAT_FISH
/datum/crafting_recipe/food/sushie_basic
name = "Funa Hosomaki"
@@ -70,7 +70,7 @@
/obj/item/reagent_containers/food/snacks/sea_weed = 3,
)
result = /obj/item/reagent_containers/food/snacks/sushie_basic
subcategory = CAT_SUSHI
subcategory = CAT_FISH
/datum/crafting_recipe/food/sushie_adv
name = "Funa Nigiri"
@@ -80,7 +80,7 @@
/obj/item/reagent_containers/food/snacks/carpmeat = 1
)
result = /obj/item/reagent_containers/food/snacks/sushie_adv
subcategory = CAT_SUSHI
subcategory = CAT_FISH
/datum/crafting_recipe/food/sushie_pro
name = "Well made Funa Nigiri"
@@ -91,4 +91,35 @@
/obj/item/reagent_containers/food/snacks/sea_weed = 1
)
result = /obj/item/reagent_containers/food/snacks/sushie_pro
subcategory = CAT_SUSHI
subcategory = CAT_FISH
///////////////Gaijin junk/////////////////////////////////////
/datum/crafting_recipe/food/fishfingers
name = "Fish fingers"
reqs = list(
/datum/reagent/consumable/flour = 5,
/obj/item/reagent_containers/food/snacks/bun = 1,
/obj/item/reagent_containers/food/snacks/carpmeat = 1
)
result = /obj/item/reagent_containers/food/snacks/fishfingers
subcategory = CAT_FISH
/datum/crafting_recipe/food/cubancarp
name = "Cuban carp"
reqs = list(
/datum/reagent/consumable/flour = 5,
/obj/item/reagent_containers/food/snacks/grown/chili = 1,
/obj/item/reagent_containers/food/snacks/carpmeat = 1
)
result = /obj/item/reagent_containers/food/snacks/cubancarp
subcategory = CAT_FISH
/datum/crafting_recipe/food/fishandchips
name = "Fish and chips"
reqs = list(
/obj/item/reagent_containers/food/snacks/fries = 1,
/obj/item/reagent_containers/food/snacks/carpmeat = 1
)
result = /obj/item/reagent_containers/food/snacks/fishandchips
subcategory = CAT_FISH

View File

@@ -158,7 +158,16 @@ function byondDecode(message) {
// The replace for + is because FOR SOME REASON, BYOND replaces spaces with a + instead of %20, and a plus with %2b.
// Marvelous.
message = message.replace(/\+/g, "%20");
message = decoder(message);
try {
// This is a workaround for the above not always working when BYOND's shitty url encoding breaks. (byond bug id:2399401)
if (decodeURIComponent) {
message = decodeURIComponent(message);
} else {
throw new Error("Easiest way to trigger the fallback")
}
} catch (err) {
message = unescape(message);
}
return message;
}
@@ -361,7 +370,7 @@ function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = 'expires='+d.toUTCString();
document.cookie = cname + '=' + cvalue + '; ' + expires;
document.cookie = cname + '=' + cvalue + '; ' + expires + "; path=/";
}
function getCookie(cname) {
@@ -462,15 +471,6 @@ function ehjaxCallback(data) {
handleClientData(data.clientData.ckey, data.clientData.ip, data.clientData.compid);
}
sendVolumeUpdate();
} else if (data.firebug) {
if (data.trigger) {
internalOutput('<span class="internal boldnshit">Loading firebug console, triggered by '+data.trigger+'...</span>', 'internal');
} else {
internalOutput('<span class="internal boldnshit">Loading firebug console...</span>', 'internal');
}
var firebugEl = document.createElement('script');
firebugEl.src = 'https://getfirebug.com/firebug-lite-debug.js';
document.body.appendChild(firebugEl);
} else if (data.adminMusic) {
if (typeof data.adminMusic === 'string') {
var adminMusic = byondDecode(data.adminMusic);

View File

@@ -5,14 +5,13 @@
icon_state = "barrel"
density = TRUE
anchored = FALSE
container_type = DRAINABLE | AMOUNT_VISIBLE
pressure_resistance = 2 * ONE_ATMOSPHERE
max_integrity = 300
var/open = FALSE
var/speed_multiplier = 1 //How fast it distills. Defaults to 100% (1.0). Lower is better.
/obj/structure/fermenting_barrel/Initialize()
create_reagents(300) //Bluespace beakers, but without the portability or efficiency in circuits.
create_reagents(300, DRAINABLE | AMOUNT_VISIBLE) //Bluespace beakers, but without the portability or efficiency in circuits.
. = ..()
/obj/structure/fermenting_barrel/examine(mob/user)
@@ -56,10 +55,12 @@
/obj/structure/fermenting_barrel/attack_hand(mob/user)
open = !open
if(open)
container_type = REFILLABLE | AMOUNT_VISIBLE
DISABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE)
ENABLE_BITFIELD(reagents.reagents_holder_flags, REFILLABLE)
to_chat(user, "<span class='notice'>You open [src], letting you fill it.</span>")
else
container_type = DRAINABLE | AMOUNT_VISIBLE
DISABLE_BITFIELD(reagents.reagents_holder_flags, REFILLABLE)
ENABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE)
to_chat(user, "<span class='notice'>You close [src], letting you draw from its tap.</span>")
update_icon()

View File

@@ -56,7 +56,7 @@
var/mob/living/carbon/C = user
if(C.gloves)
return FALSE
if(C.has_trait(TRAIT_PIERCEIMMUNE))
if(HAS_TRAIT(C, TRAIT_PIERCEIMMUNE))
return FALSE
var/hit_zone = (C.held_index_to_dir(C.active_hand_index) == "l" ? "l_":"r_") + "arm"
var/obj/item/bodypart/affecting = C.get_bodypart(hit_zone)

View File

@@ -7,7 +7,6 @@
species = "replicapod"
plantname = "Replica Pod"
product = /mob/living/carbon/human //verrry special -- Urist
container_type = INJECTABLE|DRAWABLE
lifespan = 50
endurance = 8
maturation = 10
@@ -28,7 +27,7 @@
/obj/item/seeds/replicapod/Initialize()
. = ..()
create_reagents(volume)
create_reagents(volume, INJECTABLE | DRAWABLE)
/obj/item/seeds/replicapod/on_reagent_change(changetype)
if(changetype == ADD_REAGENT)

View File

@@ -187,7 +187,7 @@
var/turf/open/O = loc
if(O.air)
var/loc_gases = O.air.gases
if(loc_gases[/datum/gas/oxygen][MOLES] > 13)
if(loc_gases[/datum/gas/oxygen] > 13)
return TRUE
return FALSE

View File

@@ -310,10 +310,10 @@
/datum/plant_gene/trait/noreact/on_new(obj/item/reagent_containers/food/snacks/grown/G, newloc)
..()
G.reagents.set_reacting(FALSE)
ENABLE_BITFIELD(G.reagents.reagents_holder_flags, NO_REACT)
/datum/plant_gene/trait/noreact/on_squash(obj/item/reagent_containers/food/snacks/grown/G, atom/target)
G.reagents.set_reacting(TRUE)
DISABLE_BITFIELD(G.reagents.reagents_holder_flags, NO_REACT)
G.reagents.handle_reactions()

Some files were not shown because too many files have changed in this diff Show More