Your station has been selected to carry out the Gateway Project.
The equipment will be shipped to you at the start of the next quarter. You are to prepare a secure location to house the equipment as outlined in the attached documents.
Do you hate the concept of having to use your legs, let alone walk to places? Well, with the Quantum Pad (tm), never again will the fear of cardio keep you from going places!
How to set up your Quantum Pad(tm)
1.Unscrew the Quantum Pad(tm) you wish to link. 2. Use your multi-tool to cache the buffer of the Quantum Pad(tm) you wish to link. 3. Apply the multi-tool to the secondary Quantum Pad(tm) you wish to link to the first Quantum Pad(tm)
If you followed these instructions carefully, your Quantum Pad(tm) should now be properly linked together for near-instant movement across the station! Bear in mind that this is technically a one-way teleport, so you'll need to do the same process with the secondary pad to the first one if you wish to travel between both.
[where] is a folder containing secret documents that another Syndicate group wants. We have set up a meeting with one of their agents on station to make an exchange. Exercise extreme caution as they cannot be trusted and may be hostile. ")
+
diff --git a/code/game/gamemodes/devil/devilinfo.dm b/code/datums/antagonists/devil.dm
similarity index 93%
rename from code/game/gamemodes/devil/devilinfo.dm
rename to code/datums/antagonists/devil.dm
index 0ea5231cfd7..18ad9cbdc19 100644
--- a/code/game/gamemodes/devil/devilinfo.dm
+++ b/code/datums/antagonists/devil.dm
@@ -95,34 +95,22 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/list/datum/mind/soulsOwned = new
var/reviveNumber = 0
var/form = BASIC_DEVIL
- var/exists = 0
- var/static/list/removable_devil_spells = list(
+ var/static/list/devil_spells = typecacheof(list(
/obj/effect/proc_holder/spell/aimed/fireball/hellish,
/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork,
- /obj/effect/proc_holder/spell/aimed/fireball/hellish,
- /obj/effect/proc_holder/spell/targeted/infernal_jaunt,
/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater,
- /obj/effect/proc_holder/spell/targeted/sintouch,
/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/ascended,
- /obj/effect/proc_holder/spell/targeted/sintouch/ascended)
- var/static/list/devil_spells = list(
- /obj/effect/proc_holder/spell/aimed/fireball/hellish,
- /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork,
- /obj/effect/proc_holder/spell/aimed/fireball/hellish,
/obj/effect/proc_holder/spell/targeted/infernal_jaunt,
- /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater,
/obj/effect/proc_holder/spell/targeted/sintouch,
- /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/ascended,
/obj/effect/proc_holder/spell/targeted/sintouch/ascended,
/obj/effect/proc_holder/spell/targeted/summon_contract,
/obj/effect/proc_holder/spell/targeted/conjure_item/violin,
- /obj/effect/proc_holder/spell/targeted/summon_dancefloor)
+ /obj/effect/proc_holder/spell/targeted/summon_dancefloor))
var/ascendable = FALSE
/datum/antagonist/devil/New()
..()
- devil_spells = typecacheof(devil_spells)
truename = randomDevilName()
ban = randomdevilban()
bane = randomdevilbane()
@@ -176,7 +164,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
switch(SOULVALUE)
if(0)
to_chat(owner.current, "Your hellish powers have been restored.")
- give_base_spells()
+ give_appropriate_spells()
if(BLOOD_THRESHOLD)
increase_blood_lizard()
if(TRUE_THRESHOLD)
@@ -208,7 +196,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/mob/living/carbon/human/H = owner.current
H.set_species(/datum/species/human, 1)
H.regenerate_icons()
- give_base_spells()
+ give_appropriate_spells()
if(istype(owner.current.loc, /obj/effect/dummy/slaughter/))
owner.current.forceMove(get_turf(owner.current))//Fixes dying while jaunted leaving you permajaunted.
form = BASIC_DEVIL
@@ -218,7 +206,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
to_chat(D, "Your powers weaken, have more contracts be signed to regain power.")
D.oldform.loc = D.loc
owner.transfer_to(D.oldform)
- give_lizard_spells()
+ give_appropriate_spells()
qdel(D)
form = BLOOD_LIZARD
update_hud()
@@ -237,7 +225,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
H.regenerate_icons()
else //Did the devil get hit by a staff of transmutation?
owner.current.color = "#501010"
- give_lizard_spells()
+ give_appropriate_spells()
form = BLOOD_LIZARD
@@ -251,11 +239,10 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
A.oldform = owner.current
owner.transfer_to(A)
A.set_name()
- give_true_spells()
+ give_appropriate_spells()
form = TRUE_DEVIL
update_hud()
-
/datum/antagonist/devil/proc/increase_arch_devil()
if(!ascendable)
return
@@ -293,7 +280,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
return
to_chat(world, "\"SLOTH, WRATH, GLUTTONY, ACEDIA, ENVY, GREED, PRIDE! FIRES OF HELL AWAKEN!!\"")
world << 'sound/hallucinations/veryfar_noise.ogg'
- give_arch_spells()
+ give_appropriate_spells()
D.convert_to_archdevil()
if(istype(D.loc, /obj/effect/dummy/slaughter/))
D.forceMove(get_turf(D))//Fixes dying while jaunted leaving you permajaunted.
@@ -309,39 +296,44 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
/datum/antagonist/devil/proc/remove_spells()
for(var/X in owner.spell_list)
var/obj/effect/proc_holder/spell/S = X
- if(is_type_in_typecache(S, removable_devil_spells))
+ if(is_type_in_typecache(S, devil_spells))
owner.RemoveSpell(S)
/datum/antagonist/devil/proc/give_summon_contract()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_contract(null))
+ if(obligation == OBLIGATION_FIDDLE)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/violin(null))
+ else if(obligation == OBLIGATION_DANCEOFF)
+ owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_dancefloor(null))
-
-/datum/antagonist/devil/proc/give_base_spells(give_summon_contract = 0)
+/datum/antagonist/devil/proc/give_appropriate_spells()
remove_spells()
+ give_summon_contract()
+ if(SOULVALUE >= ARCH_THRESHOLD)
+ give_arch_spells()
+ else if(SOULVALUE >= TRUE_THRESHOLD)
+ give_true_spells()
+ else if(SOULVALUE >= BLOOD_THRESHOLD)
+ give_blood_spells()
+ else if(SOULVALUE >= 0)
+ give_base_spells()
+
+/datum/antagonist/devil/proc/give_base_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null))
- if(give_summon_contract)
- give_summon_contract()
- if(obligation == OBLIGATION_FIDDLE)
- owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/violin(null))
- if(obligation == OBLIGATION_DANCEOFF)
- owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_dancefloor(null))
-/datum/antagonist/devil/proc/give_lizard_spells()
- remove_spells()
+/datum/antagonist/devil/proc/give_blood_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null))
/datum/antagonist/devil/proc/give_true_spells()
- remove_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/greater(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch(null))
/datum/antagonist/devil/proc/give_arch_spells()
- remove_spells()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork/ascended(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch/ascended(null))
@@ -502,7 +494,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
.=..()
/datum/antagonist/devil/apply_innate_effects(mob/living/mob_override)
- give_base_spells(1)
+ give_appropriate_spells()
owner.current.grant_all_languages(TRUE)
update_hud()
.=..()
@@ -521,10 +513,12 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/obligation
var/ban
var/banish
+ var/ascendable
/datum/fakeDevil/New(name = randomDevilName())
truename = name
bane = randomdevilbane()
obligation = randomdevilobligation()
ban = randomdevilban()
- banish = randomdevilbanish()
\ No newline at end of file
+ banish = randomdevilbanish()
+ ascendable = prob(25)
diff --git a/code/datums/browser.dm b/code/datums/browser.dm
index 62a005b5d96..c854d20f18f 100644
--- a/code/datums/browser.dm
+++ b/code/datums/browser.dm
@@ -92,6 +92,10 @@
"}
/datum/browser/proc/open(use_onclose = 1)
+ if(isnull(window_id)) //null check because this can potentially nuke goonchat
+ WARNING("Browser [title] tried to open with a null ID")
+ to_chat(user, "The [title] browser you tried to open failed a sanity check! Please report this on github!")
+ return
var/window_size = ""
if (width && height)
window_size = "size=[width]x[height];"
@@ -111,7 +115,10 @@
break
/datum/browser/proc/close()
- user << browse(null, "window=[window_id]")
+ if(!isnull(window_id))//null check because this can potentially nuke goonchat
+ user << browse(null, "window=[window_id]")
+ else
+ WARNING("Browser [title] tried to close with a null ID")
/datum/browser/alert
var/selectedbutton = 0
diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm
index fbf6af136ef..cc11d0e6d2e 100644
--- a/code/datums/diseases/_disease.dm
+++ b/code/datums/diseases/_disease.dm
@@ -115,12 +115,19 @@
else
return
- if(isturf(source.loc))
+ var/turf/T = source.loc
+ if(istype(T))
for(var/mob/living/carbon/C in oview(spread_range, source))
- if(isturf(C.loc))
- if(AStar(source, C.loc,/turf/proc/Distance, spread_range, adjacent = (spread_flags & AIRBORNE) ? /turf/proc/reachableAdjacentAtmosTurfs : /turf/proc/reachableAdjacentTurfs))
- C.ContractDisease(src)
-
+ var/turf/V = get_turf(C)
+ if(V)
+ while(TRUE)
+ if(V == T)
+ C.ContractDisease(src)
+ break
+ var/turf/Temp = get_step_towards(V, T)
+ if(!CANATMOSPASS(V, Temp))
+ break
+ V = Temp
/datum/disease/process()
if(!holder)
diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm
index 321d6691b3a..8197b1510b7 100644
--- a/code/datums/diseases/advance/symptoms/sensory.dm
+++ b/code/datums/diseases/advance/symptoms/sensory.dm
@@ -125,4 +125,4 @@ Bonus
if(12 to 24)
M.drowsyness += 1
if(24 to INFINITY)
- M.Sleeping(2, 0)
+ M.Sleeping(40)
diff --git a/code/datums/diseases/advance/symptoms/vomit.dm b/code/datums/diseases/advance/symptoms/vomit.dm
index 9407c95d5ba..b1e8100c35e 100644
--- a/code/datums/diseases/advance/symptoms/vomit.dm
+++ b/code/datums/diseases/advance/symptoms/vomit.dm
@@ -75,7 +75,7 @@ Bonus
severity = 5
/datum/symptom/vomit/blood/Vomit(mob/living/carbon/M)
- M.vomit(0, 1)
+ M.vomit(0,TRUE)
/*
@@ -103,4 +103,4 @@ Bonus
level = 4
/datum/symptom/vomit/projectile/Vomit(mob/living/carbon/M)
- M.vomit(6,0,1,5,1)
+ M.vomit(6, distance = 5)
diff --git a/code/datums/diseases/advance/symptoms/weakness.dm b/code/datums/diseases/advance/symptoms/weakness.dm
index 91b18c1eabc..a96266effe8 100644
--- a/code/datums/diseases/advance/symptoms/weakness.dm
+++ b/code/datums/diseases/advance/symptoms/weakness.dm
@@ -40,5 +40,5 @@ Bonus
M.adjustStaminaLoss(30)
if(M.getStaminaLoss() > 60 && !M.stat)
M.visible_message("[M] faints!", "You swoon and faint...")
- M.AdjustSleeping(5)
+ M.AdjustSleeping(100)
return
diff --git a/code/datums/diseases/appendicitis.dm b/code/datums/diseases/appendicitis.dm
index 5b91db4d44d..eba5e1173b9 100644
--- a/code/datums/diseases/appendicitis.dm
+++ b/code/datums/diseases/appendicitis.dm
@@ -27,7 +27,7 @@
A.update_icon()
if(prob(3))
to_chat(affected_mob, "You feel a stabbing pain in your abdomen!")
- affected_mob.Stun(rand(2,3))
+ affected_mob.Stun(rand(40,60))
affected_mob.adjustToxLoss(1)
if(3)
if(prob(1))
diff --git a/code/datums/diseases/brainrot.dm b/code/datums/diseases/brainrot.dm
index 58f4e6975dd..77cef7a8d3d 100644
--- a/code/datums/diseases/brainrot.dm
+++ b/code/datums/diseases/brainrot.dm
@@ -50,7 +50,7 @@
if(prob(3))
to_chat(affected_mob, "You lose consciousness...")
affected_mob.visible_message("[affected_mob] suddenly collapses")
- affected_mob.Paralyse(rand(5,10))
+ affected_mob.Unconscious(rand(100,200))
if(prob(1))
affected_mob.emote("snore")
if(prob(15))
diff --git a/code/datums/diseases/retrovirus.dm b/code/datums/diseases/retrovirus.dm
index 7791c589f6d..e8a8c48d8ef 100644
--- a/code/datums/diseases/retrovirus.dm
+++ b/code/datums/diseases/retrovirus.dm
@@ -52,7 +52,7 @@
to_chat(affected_mob, "You feel very strange.")
if (prob(4))
to_chat(affected_mob, "You feel a stabbing pain in your head!")
- affected_mob.Paralyse(2)
+ affected_mob.Unconscious(40)
if (prob(4))
to_chat(affected_mob, "Your stomach churns.")
if(3)
diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm
index aa7755f6d83..30b11b8f696 100644
--- a/code/datums/diseases/transformation.dm
+++ b/code/datums/diseases/transformation.dm
@@ -138,7 +138,7 @@
affected_mob.say(pick("Beep, boop", "beep, beep!", "Boop...bop"))
if (prob(4))
to_chat(affected_mob, "You feel a stabbing pain in your head.")
- affected_mob.Paralyse(2)
+ affected_mob.Unconscious(40)
if(4)
if (prob(20))
affected_mob.say(pick("beep, beep!", "Boop bop boop beep.", "kkkiiiill mmme", "I wwwaaannntt tttoo dddiiieeee..."))
@@ -167,7 +167,7 @@
if(3)
if (prob(4))
to_chat(affected_mob, "You feel a stabbing pain in your head.")
- affected_mob.Paralyse(2)
+ affected_mob.Unconscious(40)
if(4)
if (prob(20))
affected_mob.say(pick("You look delicious.", "Going to... devour you...", "Hsssshhhhh!"))
diff --git a/code/datums/diseases/tuberculosis.dm b/code/datums/diseases/tuberculosis.dm
index b16a0a2193f..4b57c2655b6 100644
--- a/code/datums/diseases/tuberculosis.dm
+++ b/code/datums/diseases/tuberculosis.dm
@@ -41,7 +41,7 @@
if(prob(10))
affected_mob.adjustStaminaLoss(100)
affected_mob.visible_message("[affected_mob] faints!", "You surrender yourself and feel at peace...")
- affected_mob.AdjustSleeping(5)
+ affected_mob.AdjustSleeping(100)
if(prob(2))
to_chat(affected_mob, "You feel your mind relax and your thoughts drift!")
affected_mob.confused = min(100, affected_mob.confused + 8)
diff --git a/code/datums/explosion.dm b/code/datums/explosion.dm
index 11f6bc5146f..11453769679 100644
--- a/code/datums/explosion.dm
+++ b/code/datums/explosion.dm
@@ -279,16 +279,9 @@ GLOBAL_LIST_EMPTY(explosions)
var/turf/T = affected_turfs[I]
var/current_exp_block = T.density ? T.explosion_block : 0
- for(var/obj/machinery/door/D in T)
- if(D.density)
- current_exp_block += D.explosion_block
-
- for(var/obj/structure/window/W in T)
- if(W.reinf && W.fulltile)
- current_exp_block += W.explosion_block
-
- for(var/obj/structure/blob/B in T)
- current_exp_block += B.explosion_block
+ for(var/obj/O in T)
+ var/the_block = O.explosion_block
+ current_exp_block += the_block == EXPLOSION_BLOCK_PROC ? O.GetExplosionBlock() : the_block
.[T] = current_exp_block
@@ -351,19 +344,12 @@ GLOBAL_LIST_EMPTY(explosions)
var/turf/TT = T
while(TT != epicenter)
TT = get_step_towards(TT,epicenter)
- if(TT.density && TT.explosion_block)
+ if(TT.density)
dist += TT.explosion_block
-
- for(var/obj/machinery/door/D in TT)
- if(D.density && D.explosion_block)
- dist += D.explosion_block
-
- for(var/obj/structure/window/W in TT)
- if(W.explosion_block && W.fulltile)
- dist += W.explosion_block
-
- for(var/obj/structure/blob/B in T)
- dist += B.explosion_block
+
+ for(var/obj/O in T)
+ var/the_block = O.explosion_block
+ dist += the_block == EXPLOSION_BLOCK_PROC ? O.GetExplosionBlock() : the_block
if(dist < dev)
T.color = "red"
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index 2f51ae302a5..d5c0e74839c 100644
--- a/code/datums/helper_datums/getrev.dm
+++ b/code/datums/helper_datums/getrev.dm
@@ -6,13 +6,15 @@
var/date
/datum/getrev/New()
- if(fexists(SERVICE_PR_TEST_JSON))
+ if(world.RunningService() && fexists(SERVICE_PR_TEST_JSON))
testmerge = json_decode(file2text(SERVICE_PR_TEST_JSON))
+#ifdef SERVERTOOLS
else if(!world.RunningService() && fexists("../prtestjob.lk")) //tgs2 support
var/list/tmp = world.file2list("..\\prtestjob.lk")
for(var/I in tmp)
if(I)
testmerge |= I
+#endif
log_world("Running /tg/ revision:")
var/list/logs = world.file2list(".git/logs/HEAD")
if(logs)
@@ -71,13 +73,13 @@
return ""
. = header ? "The following pull requests are currently test merged: " : ""
for(var/line in testmerge)
- var/cm = testmerge[line]["commit"]
var/details
if(world.RunningService())
+ var/cm = testmerge[line]["commit"]
details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["author"]) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 7)))
else if(has_pr_details) //tgs2 support
details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["user"]["login"])
- . += "#[line][details] "
+ . += "#[line][details] "
/client/verb/showrevinfo()
set category = "OOC"
@@ -91,7 +93,7 @@
to_chat(src, GLOB.revdata.GetTestMergeInfo())
prefix = "Based off origin/master commit: "
var/pc = GLOB.revdata.originmastercommit
- to_chat(src, "[prefix][copytext(pc, 1, min(length(pc), 7))]")
+ to_chat(src, "[prefix][copytext(pc, 1, min(length(pc), 7))]")
else
to_chat(src, "Revision unknown")
to_chat(src, "Current Infomational Settings:")
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index 07ed28b575b..d6f679c3314 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -15,7 +15,6 @@
var/soundout //soundfile to play after teleportation
var/force_teleport = 1 //if false, teleport will use Move() proc (dense objects will prevent teleportation)
-
/datum/teleport/proc/start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null)
if(!initTeleport(arglist(args)))
return 0
@@ -100,21 +99,7 @@
var/turf/destturf
var/turf/curturf = get_turf(teleatom)
- if(precision)
- var/list/posturfs = list()
- var/center = get_turf(destination)
- if(!center)
- center = destination
- for(var/turf/T in range(precision,center))
- if(T.is_transition_turf())
- continue // Avoid picking these.
- var/area/A = T.loc
- if(!A.noteleport)
- posturfs.Add(T)
-
- destturf = safepick(posturfs)
- else
- destturf = get_turf(destination)
+ destturf = get_teleport_turf(get_turf(destination), precision)
if(!destturf || !curturf || destturf.is_transition_turf())
return 0
@@ -124,13 +109,16 @@
return 0
playSpecials(curturf,effectin,soundin)
-
if(force_teleport)
teleatom.forceMove(destturf)
+ if(ismegafauna(teleatom))
+ message_admins("[teleatom] [ADMIN_FLW(teleatom)] has teleported from [ADMIN_COORDJMP(curturf)] to [ADMIN_COORDJMP(destturf)].")
playSpecials(destturf,effectout,soundout)
else
if(teleatom.Move(destturf))
playSpecials(destturf,effectout,soundout)
+ if(ismegafauna(teleatom))
+ message_admins("[teleatom] [ADMIN_FLW(teleatom)] has teleported from [ADMIN_COORDJMP(curturf)] to [ADMIN_COORDJMP(destturf)].")
return 1
/datum/teleport/proc/teleport()
@@ -225,3 +213,18 @@
// DING! You have passed the gauntlet, and are "probably" safe.
return F
+
+/proc/get_teleport_turfs(turf/center, precision = 0)
+ if(!precision)
+ return list(center)
+ var/list/posturfs = list()
+ for(var/turf/T in range(precision,center))
+ if(T.is_transition_turf())
+ continue // Avoid picking these.
+ var/area/A = T.loc
+ if(!A.noteleport)
+ posturfs.Add(T)
+ return posturfs
+
+/proc/get_teleport_turf(turf/center, precision = 0)
+ return safepick(get_teleport_turfs(center, precision))
diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm
index 54809a708ac..4e7490f8eed 100644
--- a/code/datums/holocall.dm
+++ b/code/datums/holocall.dm
@@ -15,6 +15,7 @@
var/mob/camera/aiEye/remote/holo/eye //user's eye, once connected
var/obj/effect/overlay/holo_pad_hologram/hologram //user's hologram, once connected
+ var/datum/action/innate/end_holocall/hangup //hangup action
var/call_start_time
@@ -42,6 +43,8 @@
//cleans up ALL references :)
/datum/holocall/Destroy()
+ QDEL_NULL(hangup)
+
var/user_good = !QDELETED(user)
if(user_good)
user.reset_perspective()
@@ -144,6 +147,8 @@
user.reset_perspective(eye)
eye.setLoc(H.loc)
+ hangup = new(eye, src)
+
//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise
/datum/holocall/proc/Check()
for(var/I in dialed_holopads)
@@ -166,3 +171,15 @@
if(!.)
testing("Holocall Check fail")
qdel(src)
+
+/datum/action/innate/end_holocall
+ name = "End Holocall"
+ button_icon_state = "camera_off"
+ var/datum/holocall/hcall
+
+/datum/action/innate/end_holocall/New(Target, datum/holocall/HC)
+ ..()
+ hcall = HC
+
+/datum/action/innate/end_holocall/Activate()
+ hcall.Disconnect(hcall.calling_holopad)
diff --git a/code/datums/martial.dm b/code/datums/martial.dm
index fa02a2f0923..e7adf28b911 100644
--- a/code/datums/martial.dm
+++ b/code/datums/martial.dm
@@ -68,9 +68,9 @@
add_logs(A, D, "punched")
if((D.stat != DEAD) && damage >= A.dna.species.punchstunthreshold)
- D.visible_message("[A] has weakened [D]!!", \
- "[A] has weakened [D]!")
- D.apply_effect(4, WEAKEN, armor_block)
+ D.visible_message("[A] has knocked [D] down!!", \
+ "[A] has knocked [D] down!")
+ D.apply_effect(40, KNOCKDOWN, armor_block)
D.forcesay(GLOB.hit_appends)
else if(D.lying)
D.forcesay(GLOB.hit_appends)
diff --git a/code/datums/martial/boxing.dm b/code/datums/martial/boxing.dm
index 6a3a0598908..db77d7095a8 100644
--- a/code/datums/martial/boxing.dm
+++ b/code/datums/martial/boxing.dm
@@ -39,8 +39,8 @@
if((D.stat != DEAD) && prob(knockout_prob))
D.visible_message("[A] has knocked [D] out with a haymaker!", \
"[A] has knocked [D] out with a haymaker!")
- D.apply_effect(10,WEAKEN,armor_block)
- D.SetSleeping(5)
+ D.apply_effect(200,KNOCKDOWN,armor_block)
+ D.SetSleeping(100)
D.forcesay(GLOB.hit_appends)
add_logs(A, D, "knocked out (boxing) ")
else if(D.lying)
diff --git a/code/datums/martial/cqc.dm b/code/datums/martial/cqc.dm
index ebb570fa0c0..b7c69d8895e 100644
--- a/code/datums/martial/cqc.dm
+++ b/code/datums/martial/cqc.dm
@@ -35,17 +35,17 @@
return 0
/datum/martial_art/cqc/proc/Slam(mob/living/carbon/human/A, mob/living/carbon/human/D)
- if(!D.stat || !D.weakened)
+ if(!D.stat || !D.knockdown)
D.visible_message("[A] slams [D] into the ground!", \
"[A] slams you into the ground!")
playsound(get_turf(A), 'sound/weapons/slam.ogg', 50, 1, -1)
D.apply_damage(10, BRUTE)
- D.Weaken(6)
+ D.Knockdown(120)
add_logs(A, D, "cqc slammed")
return 1
/datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D)
- if(!D.stat || !D.weakened)
+ if(!D.stat || !D.knockdown)
D.visible_message("[A] kicks [D] back!", \
"[A] kicks you back!")
playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
@@ -53,11 +53,11 @@
D.throw_at(throw_target, 1, 14, A)
D.apply_damage(10, BRUTE)
add_logs(A, D, "cqc kicked")
- if(D.weakened && !D.stat)
+ if(D.knockdown && !D.stat)
D.visible_message("[A] kicks [D]'s head, knocking them out!", \
"[A] kicks your head, knocking you out!")
playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1)
- D.SetSleeping(15)
+ D.SetSleeping(300)
D.adjustBrainLoss(25)
return 1
@@ -74,7 +74,7 @@
D.visible_message("[A] locks [D] into a restraining position!", \
"[A] locks you into a restraining position!")
D.adjustStaminaLoss(20)
- D.Stun(5)
+ D.Stun(100)
restraining = 1
addtimer(CALLBACK(src, .proc/drop_restraining), 50, TIMER_UNIQUE)
return 1
@@ -114,7 +114,7 @@
A.do_attack_animation(D)
var/picked_hit_type = pick("CQC'd", "Big Bossed")
var/bonus_damage = 13
- if(D.weakened || D.resting || D.lying)
+ if(D.knockdown || D.resting || D.lying)
bonus_damage += 5
picked_hit_type = "stomps on"
D.apply_damage(bonus_damage, BRUTE)
@@ -125,12 +125,12 @@
D.visible_message("[A] [picked_hit_type] [D]!", \
"[A] [picked_hit_type] you!")
add_logs(A, D, "[picked_hit_type] with CQC")
- if(A.resting && !D.stat && !D.weakened)
+ if(A.resting && !D.stat && !D.knockdown)
D.visible_message("[A] leg sweeps [D]!", \
"[A] leg sweeps you!")
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
D.apply_damage(10, BRUTE)
- D.Weaken(3)
+ D.Knockdown(60)
add_logs(A, D, "cqc sweeped")
return 1
@@ -140,7 +140,7 @@
if(check_streak(A,D))
return 1
if(prob(65))
- if(!D.stat || !D.weakened || !restraining)
+ if(!D.stat || !D.knockdown || !restraining)
I = D.get_active_held_item()
D.visible_message("[A] strikes [D]'s jaw with their hand!", \
"[A] strikes your jaw, disorienting you!")
@@ -157,7 +157,7 @@
if(restraining && A.pulling == D)
D.visible_message("[A] puts [D] into a chokehold!", \
"[A] puts you into a chokehold!")
- D.SetSleeping(20)
+ D.SetSleeping(400)
restraining = 0
if(A.grab_state < GRAB_NECK)
A.grab_state = GRAB_NECK
@@ -173,8 +173,8 @@
to_chat(usr, "You try to remember some of the basics of CQC.")
- to_chat(usr, "Slam: Grab Harm. Slam opponent into the ground, weakens and knocks down.")
- to_chat(usr, "CQC Kick: Harm Disarm Harm. Knocks opponent away. Knocks out stunned or weakened opponents.")
+ to_chat(usr, "Slam: Grab Harm. Slam opponent into the ground, knocking them down.")
+ to_chat(usr, "CQC Kick: Harm Disarm Harm. Knocks opponent away. Knocks out stunned or knocked down opponents.")
to_chat(usr, "Restrain: Grab Grab. Locks opponents into a restraining position, disarm to knock them out with a choke hold.")
to_chat(usr, "Pressure: Disarm Grab. Decent stamina damage.")
to_chat(usr, "Consecutive CQC: Disarm Disarm Harm. Mainly offensive move, huge damage and decent stamina damage.")
diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm
index eb5f74b411b..9e86a7f08ab 100644
--- a/code/datums/martial/krav_maga.dm
+++ b/code/datums/martial/krav_maga.dm
@@ -84,13 +84,13 @@
return 0
/datum/martial_art/krav_maga/proc/leg_sweep(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
- if(D.stat || D.weakened)
+ if(D.stat || D.knockdown)
return 0
D.visible_message("[A] leg sweeps [D]!", \
"[A] leg sweeps you!")
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
D.apply_damage(5, BRUTE)
- D.Weaken(2)
+ D.Knockdown(40)
add_logs(A, D, "leg sweeped")
return 1
@@ -126,7 +126,7 @@
add_logs(A, D, "punched")
var/picked_hit_type = pick("punches", "kicks")
var/bonus_damage = 10
- if(D.weakened || D.resting || D.lying)
+ if(D.knockdown || D.resting || D.lying)
bonus_damage += 5
picked_hit_type = "stomps on"
D.apply_damage(bonus_damage, BRUTE)
diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm
index f079d2a7db1..6c545153f5b 100644
--- a/code/datums/martial/sleeping_carp.dm
+++ b/code/datums/martial/sleeping_carp.dm
@@ -35,7 +35,7 @@
return 0
/datum/martial_art/the_sleeping_carp/proc/wristWrench(mob/living/carbon/human/A, mob/living/carbon/human/D)
- if(!D.stat && !D.stunned && !D.weakened)
+ if(!D.stat && !D.IsStun() && !D.knockdown)
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("[A] grabs [D]'s wrist and wrenches it sideways!", \
"[A] grabs your wrist and violently wrenches it to the side!")
@@ -43,51 +43,51 @@
D.emote("scream")
D.drop_item()
D.apply_damage(5, BRUTE, pick("l_arm", "r_arm"))
- D.Stun(3)
+ D.Stun(60)
return 1
add_logs(A, D, "wrist wrenched (Sleeping Carp)")
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/backKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
- if(A.dir == D.dir && !D.stat && !D.weakened)
+ if(A.dir == D.dir && !D.stat && !D.knockdown)
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("[A] kicks [D] in the back!", \
"[A] kicks you in the back, making you stumble and fall!")
step_to(D,get_step(D,D.dir),1)
- D.Weaken(4)
+ D.Knockdown(80)
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
return 1
add_logs(A, D, "back-kicked (Sleeping Carp)")
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/kneeStomach(mob/living/carbon/human/A, mob/living/carbon/human/D)
- if(!D.stat && !D.weakened)
+ if(!D.stat && !D.knockdown)
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
D.visible_message("[A] knees [D] in the stomach!", \
"[A] winds you with a knee in the stomach!")
D.audible_message("[D] gags!")
D.losebreath += 3
- D.Stun(2)
+ D.Stun(40)
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
return 1
add_logs(A, D, "stomach kneed (Sleeping Carp)")
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/headKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
- if(!D.stat && !D.weakened)
+ if(!D.stat && !D.knockdown)
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
D.visible_message("[A] kicks [D] in the head!", \
"[A] kicks you in the jaw!")
D.apply_damage(20, BRUTE, "head")
D.drop_item()
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
- D.Stun(4)
+ D.Stun(80)
return 1
add_logs(A, D, "head kicked (Sleeping Carp)")
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/elbowDrop(mob/living/carbon/human/A, mob/living/carbon/human/D)
- if(D.weakened || D.resting || D.stat)
+ if(D.knockdown || D.resting || D.stat)
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("[A] elbow drops [D]!", \
"[A] piledrives you with their elbow!")
@@ -130,7 +130,7 @@
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 25, 1, -1)
if(prob(D.getBruteLoss()) && !D.lying)
D.visible_message("[D] stumbles and falls!", "The blow sends you to the ground!")
- D.Weaken(4)
+ D.Knockdown(80)
add_logs(A, D, "[atk_verb] (Sleeping Carp)")
return 1
@@ -196,7 +196,7 @@
add_fingerprint(user)
if((CLUMSY in user.disabilities) && prob(50))
to_chat(user, "You club yourself over the head with [src].")
- user.Weaken(3)
+ user.Knockdown(60)
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.apply_damage(2*force, BRUTE, "head")
@@ -230,18 +230,18 @@
if(prob(10))
H.visible_message("[H] collapses!", \
"Your legs give out!")
- H.Weaken(4)
- if(H.staminaloss && !H.sleeping)
+ H.Knockdown(80)
+ if(H.staminaloss && !H.IsSleeping())
var/total_health = (H.health - H.staminaloss)
if(total_health <= HEALTH_THRESHOLD_CRIT && !H.stat)
H.visible_message("[user] delivers a heavy hit to [H]'s head, knocking them out cold!", \
"[user] knocks you unconscious!")
- H.SetSleeping(30)
+ H.SetSleeping(600)
H.adjustBrainLoss(25)
else
return ..()
-/obj/item/weapon/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
+/obj/item/weapon/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(wielded)
return ..()
return 0
diff --git a/code/datums/martial/wrestling.dm b/code/datums/martial/wrestling.dm
index fc1c7a9b6d8..fb47def85ac 100644
--- a/code/datums/martial/wrestling.dm
+++ b/code/datums/martial/wrestling.dm
@@ -134,7 +134,7 @@
D.forceMove(A.loc)
D.setDir(get_dir(D, A))
- D.Stun(4)
+ D.Stun(80)
A.visible_message("[A] starts spinning around with [D]!")
A.emote("scream")
@@ -192,7 +192,7 @@
if (T && isturf(T))
if (!D.stat)
D.emote("scream")
- D.throw_at(T, 10, 4, callback = CALLBACK(D, /mob/living/carbon/human/.Weaken, 2))
+ D.throw_at(T, 10, 4, callback = CALLBACK(D, /mob/living/carbon/human/.Knockdown, 20))
add_logs(A, D, "has thrown with wrestling")
return 0
@@ -288,8 +288,7 @@
playsound(A.loc, "swing_hit", 50, 1)
if (!D.stat)
D.emote("scream")
- D.weakened += 2
- D.stunned += 2
+ D.Knockdown(40)
switch(rand(1,3))
if (2)
@@ -331,7 +330,7 @@
A.visible_message("[A] headbutts [D]!")
D.adjustBruteLoss(rand(10,20))
playsound(A.loc, "swing_hit", 50, 1)
- D.Paralyse(1)
+ D.Unconscious(20)
add_logs(A, D, "headbutted")
/datum/martial_art/wrestling/proc/kick(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -347,7 +346,7 @@
var/turf/T = get_edge_target_turf(A, get_dir(A, get_step_away(D, A)))
if (T && isturf(T))
- D.Weaken(1)
+ D.Knockdown(20)
D.throw_at(T, 3, 2)
add_logs(A, D, "roundhouse-kicked")
@@ -383,7 +382,7 @@
if (falling == 1)
A.visible_message("...and dives head-first into the ground, ouch!")
A.adjustBruteLoss(rand(10,20))
- A.Weaken(3)
+ A.Knockdown(60)
to_chat(A, "[D] is too far away!")
return 0
@@ -412,8 +411,7 @@
else
D.adjustBruteLoss(rand(20,30))
- D.Weaken(1)
- D.Stun(2)
+ D.Knockdown(40)
A.pixel_y = 0
@@ -437,7 +435,7 @@
A.start_pulling(D)
D.visible_message("[A] gets [D] in a cinch!", \
"[A] gets [D] in a cinch!")
- D.Stun(rand(3,5))
+ D.Stun(rand(60,100))
add_logs(A, D, "cinched")
return 1
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index c05243b7e23..8bcb36e2c1c 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -23,7 +23,7 @@
new_mob.key = key
- The Login proc will handle making a new mob for that mobtype (including setting up stuff like mind.name). Simple!
+ The Login proc will handle making a new mind for that mobtype (including setting up stuff like mind.name). Simple!
However if you want that mind to have any special properties like being a traitor etc you will have to do that
yourself.
@@ -147,6 +147,7 @@
A.on_removal()
return TRUE
+
/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us.
for(var/a in antag_datums)
var/datum/antagonist/A = a
@@ -187,15 +188,7 @@
/datum/mind/proc/remove_traitor()
if(src in SSticker.mode.traitors)
- SSticker.mode.traitors -= src
- if(isAI(current))
- var/mob/living/silicon/ai/A = current
- A.set_zeroth_law("")
- A.verbs -= /mob/living/silicon/ai/proc/choose_modules
- A.malf_picker.remove_verbs(A)
- qdel(A.malf_picker)
- special_role = null
- remove_antag_equip()
+ src.remove_antag_datum(ANTAG_DATUM_TRAITOR)
SSticker.mode.update_traitor_icons_removed(src)
/datum/mind/proc/remove_nukeop()
@@ -263,6 +256,67 @@
if(gang_datum)
gang_datum.remove_gang_hud(src)
+/datum/mind/proc/equip_traitor(var/employer = "The Syndicate", var/silent = FALSE)
+ if(!current)
+ return
+ var/mob/living/carbon/human/traitor_mob = current
+ if (!istype(traitor_mob))
+ return
+ . = 1
+
+ var/list/all_contents = traitor_mob.GetAllContents()
+ var/obj/item/device/pda/PDA = locate() in all_contents
+ var/obj/item/device/radio/R = locate() in all_contents
+ var/obj/item/weapon/pen/P = locate() in all_contents //including your PDA-pen!
+
+ var/obj/item/uplink_loc
+
+ if(traitor_mob.client && traitor_mob.client.prefs)
+ switch(traitor_mob.client.prefs.uplink_spawn_loc)
+ if(UPLINK_PDA)
+ uplink_loc = PDA
+ if(!uplink_loc)
+ uplink_loc = R
+ if(!uplink_loc)
+ uplink_loc = P
+ if(UPLINK_RADIO)
+ uplink_loc = R
+ if(!uplink_loc)
+ uplink_loc = PDA
+ if(!uplink_loc)
+ uplink_loc = P
+ if(UPLINK_PEN)
+ uplink_loc = P
+ if(!uplink_loc)
+ uplink_loc = PDA
+ if(!uplink_loc)
+ uplink_loc = R
+
+ if (!uplink_loc)
+ if(!silent) to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.")
+ . = 0
+ else
+ var/obj/item/device/uplink/U = new(uplink_loc)
+ U.owner = "[traitor_mob.key]"
+ uplink_loc.hidden_uplink = U
+
+ if(uplink_loc == R)
+ R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ))
+
+ if(!silent) to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.")
+ traitor_mob.mind.store_memory("Radio Frequency: [format_frequency(R.traitor_frequency)] ([R.name]).")
+
+ else if(uplink_loc == PDA)
+ PDA.lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
+
+ if(!silent) to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
+ traitor_mob.mind.store_memory("Uplink Passcode: [PDA.lock_code] ([PDA.name]).")
+
+ else if(uplink_loc == P)
+ P.traitor_unlock_degrees = rand(1, 360)
+
+ if(!silent) to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.")
+ traitor_mob.mind.store_memory("Uplink Degrees: [P.traitor_unlock_degrees] ([P.name]).")
//Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does.
@@ -989,7 +1043,7 @@
if(!G || (src in G.bosses))
return
SSticker.mode.remove_gangster(src,0,2,1)
- G.bosses += src
+ G.bosses[src] = GANGSTER_BOSS_STARTING_INFLUENCE
gang_datum = G
special_role = "[G.name] Gang Boss"
G.add_gang_hud(src)
@@ -1157,27 +1211,28 @@
else if (href_list["traitor"])
switch(href_list["traitor"])
if("clear")
+ to_chat(current, "You have been brainwashed!")
remove_traitor()
- to_chat(current, "You have been brainwashed! You are no longer a traitor!")
message_admins("[key_name_admin(usr)] has de-traitor'ed [current].")
log_admin("[key_name(usr)] has de-traitor'ed [current].")
SSticker.mode.update_traitor_icons_removed(src)
if("traitor")
if(!(src in SSticker.mode.traitors))
- SSticker.mode.traitors += src
- special_role = "traitor"
- to_chat(current, "You are a traitor!")
message_admins("[key_name_admin(usr)] has traitor'ed [current].")
log_admin("[key_name(usr)] has traitor'ed [current].")
- if(isAI(current))
- var/mob/living/silicon/ai/A = current
- SSticker.mode.add_law_zero(A)
- SSticker.mode.update_traitor_icons_added(src)
+ make_Traitor()
if("autoobjectives")
- SSticker.mode.forge_traitor_objectives(src)
- to_chat(usr, "The objectives for traitor [key] have been generated. You can edit them and anounce manually.")
+ var/datum/antagonist/traitor/traitordatum = has_antag_datum(ANTAG_DATUM_TRAITOR)
+ if(!traitordatum)
+ message_admins("[key_name_admin(usr)] has traitor'ed [current] as part of autoobjectives.")
+ log_admin("[key_name(usr)] has traitor'ed [current] as part of autoobjectives.")
+ make_Traitor()
+ else
+ log_admin("[key_name(usr)] has forged objectives for [current] as part of autoobjectives.")
+ traitordatum.forge_traitor_objectives()
+ to_chat(usr, "The objectives for traitor [key] have been generated. You can edit them and anounce manually.")
else if(href_list["devil"])
var/datum/antagonist/devil/devilinfo = has_antag_datum(ANTAG_DATUM_DEVIL)
@@ -1289,7 +1344,6 @@
else if (istype(M) && length(M.viruses))
for(var/datum/disease/D in M.viruses)
D.cure(0)
- sleep(0) //because deleting of virus is done through spawn(0)
if("infected")
if (check_rights(R_ADMIN, 0))
var/mob/living/carbon/human/H = current
@@ -1354,9 +1408,11 @@
message_admins("[key_name_admin(usr)] changed [current]'s telecrystal count to [crystals].")
log_admin("[key_name(usr)] changed [current]'s telecrystal count to [crystals].")
if("uplink")
- if(!SSticker.mode.equip_traitor(current, !(src in SSticker.mode.traitors)))
+ if(!equip_traitor())
to_chat(usr, "Equipping a syndicate failed!")
- log_admin("[key_name(usr)] attempted to give [current] an uplink.")
+ log_admin("[key_name(usr)] tried and failed to give [current] an uplink.")
+ else
+ log_admin("[key_name(usr)] gave [current] an uplink.")
else if (href_list["obj_announce"])
announce_objectives()
@@ -1384,12 +1440,10 @@
qdel(H)
/datum/mind/proc/make_Traitor()
- if(!(src in SSticker.mode.traitors))
- SSticker.mode.traitors += src
- special_role = "traitor"
- SSticker.mode.forge_traitor_objectives(src)
- SSticker.mode.finalize_traitor(src)
- SSticker.mode.greet_traitor(src)
+ if(!(has_antag_datum(ANTAG_DATUM_TRAITOR)))
+ var/datum/antagonist/traitor/traitordatum = add_antag_datum(ANTAG_DATUM_TRAITOR)
+ return traitordatum
+
/datum/mind/proc/make_Nuke(turf/spawnloc, nuke_code, leader=0, telecrystals = TRUE)
if(!(src in SSticker.mode.syndicates))
@@ -1448,7 +1502,7 @@
special_role = "Wizard"
assigned_role = "Wizard"
if(!GLOB.wizardstart.len)
- current.loc = pick(GLOB.latejoin)
+ SSjob.SendToLateJoin(current)
to_chat(current, "HOT INSERTION, GO GO GO")
else
current.loc = pick(GLOB.wizardstart)
@@ -1495,7 +1549,6 @@
qdel(flash)
take_uplink()
var/fail = 0
-// fail |= !SSticker.mode.equip_traitor(current, 1)
fail |= !SSticker.mode.equip_revolutionary(current)
diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm
index 05e4f4d4582..657082f5781 100644
--- a/code/datums/mutations.dm
+++ b/code/datums/mutations.dm
@@ -126,7 +126,7 @@ GLOBAL_LIST_EMPTY(mutations_list)
/datum/mutation/human/hulk/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
- var/status = CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH
+ var/status = CANSTUN | CANKNOCKDOWN | CANUNCONSCIOUS | CANPUSH
owner.status_flags &= ~status
owner.update_body_parts()
@@ -142,7 +142,7 @@ GLOBAL_LIST_EMPTY(mutations_list)
/datum/mutation/human/hulk/on_losing(mob/living/carbon/human/owner)
if(..())
return
- owner.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE | CANPUSH
+ owner.status_flags |= CANSTUN | CANKNOCKDOWN | CANUNCONSCIOUS | CANPUSH
owner.update_body_parts()
/datum/mutation/human/hulk/say_mod(message)
@@ -233,9 +233,9 @@ GLOBAL_LIST_EMPTY(mutations_list)
text_gain_indication = "You get a headache."
/datum/mutation/human/epilepsy/on_life(mob/living/carbon/human/owner)
- if(prob(1) && !owner.paralysis)
+ if(prob(1) && !owner.unconscious)
owner.visible_message("[owner] starts having a seizure!", "You have a seizure!")
- owner.Paralyse(10)
+ owner.Unconscious(200)
owner.Jitter(1000)
addtimer(CALLBACK(src, .proc/jitter_less, owner), 90)
@@ -269,7 +269,7 @@ GLOBAL_LIST_EMPTY(mutations_list)
text_gain_indication = "You start coughing."
/datum/mutation/human/cough/on_life(mob/living/carbon/human/owner)
- if((prob(5) && owner.paralysis <= 1))
+ if((prob(5) && owner.unconscious <= 1))
owner.drop_item()
owner.emote("cough")
@@ -317,8 +317,8 @@ GLOBAL_LIST_EMPTY(mutations_list)
text_gain_indication = "You twitch."
/datum/mutation/human/tourettes/on_life(mob/living/carbon/human/owner)
- if((prob(10) && owner.paralysis <= 1))
- owner.Stun(10)
+ if((prob(10) && owner.unconscious <= 1))
+ owner.Stun(200)
switch(rand(1, 3))
if(1)
owner.emote("twitch")
@@ -408,6 +408,11 @@ GLOBAL_LIST_EMPTY(mutations_list)
/datum/mutation/human/chameleon/on_move(mob/living/carbon/human/owner)
owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
+/datum/mutation/human/chameleon/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity)
+ if(proximity) //stops tk from breaking chameleon
+ owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
+ return
+
/datum/mutation/human/chameleon/on_losing(mob/living/carbon/human/owner)
if(..())
return
diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm
old mode 100644
new mode 100755
index 4c39d116916..1cced13cb42
--- a/code/datums/outfit.dm
+++ b/code/datums/outfit.dm
@@ -22,6 +22,7 @@
var/internals_slot = null //ID of slot containing a gas tank
var/list/backpack_contents = null // In the list(path=count,otherpath=count) format
var/list/implants = null
+ var/accessory = null
var/can_be_admin_equipped = TRUE // Set to FALSE if your outfit requires runtime parameters
@@ -64,6 +65,13 @@
if(suit_store)
H.equip_to_slot_or_del(new suit_store(H),slot_s_store)
+ if(accessory)
+ var/obj/item/clothing/under/U = H.w_uniform
+ if(U)
+ U.attach_accessory(new accessory(H))
+ else
+ WARNING("Unable to equip accessory [accessory] in outfit [name]. No uniform present!")
+
if(l_hand)
H.put_in_l_hand(new l_hand(H))
if(r_hand)
diff --git a/code/datums/riding.dm b/code/datums/riding.dm
index e06c2044ab0..e1ced9e9896 100644
--- a/code/datums/riding.dm
+++ b/code/datums/riding.dm
@@ -40,12 +40,14 @@
passindex++
var/mob/living/buckled_mob = m
var/list/offsets = get_offsets(passindex)
+ var/rider_dir = get_rider_dir(passindex)
+ buckled_mob.setDir(rider_dir)
dir_loop:
for(var/offsetdir in offsets)
if(offsetdir == ridden_dir)
var/list/diroffsets = offsets[offsetdir]
buckled_mob.pixel_x = diroffsets[1]
- if(diroffsets.len == 2)
+ if(diroffsets.len >= 2)
buckled_mob.pixel_y = diroffsets[2]
if(diroffsets.len == 3)
buckled_mob.layer = diroffsets[3]
@@ -56,6 +58,11 @@
/datum/riding/proc/get_offsets(pass_index) // list(dir = x, y, layer)
return list("[NORTH]" = list(0, 0), "[SOUTH]" = list(0, 0), "[EAST]" = list(0, 0), "[WEST]" = list(0, 0))
+//Override this to set the passengers/riders dir based on which passenger they are.
+//ie: rider facing the vehicle's dir, but passenger 2 facing backwards, etc.
+/datum/riding/proc/get_rider_dir(pass_index)
+ return ridden.dir
+
//KEYS
/datum/riding/proc/keycheck(mob/user)
if(keytype)
@@ -99,9 +106,6 @@
if(ridden.has_gravity())
return 1
- if(ridden.pulledby)
- return 1
-
return 0
/datum/riding/space/Process_Spacemove(direction)
@@ -164,7 +168,7 @@
/datum/riding/janicart/get_offsets(pass_index) // list(dir = x, y, layer)
- return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(-12, 7), "[EAST]" = list(0, 7), "[WEST]" = list( 12, 7))
+ return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(0, 7), "[EAST]" = list(-12, 7), "[WEST]" = list( 12, 7))
//scooter
/datum/riding/scooter/handle_vehicle_layer()
@@ -326,8 +330,7 @@
/datum/riding/human/force_dismount(mob/living/user)
ridden.unbuckle_mob(user)
- user.Weaken(3)
- user.Stun(3)
+ user.Knockdown(60)
user.visible_message("[ridden] pushes [user] off of them!")
/datum/riding/cyborg
@@ -382,7 +385,7 @@
M.Move(targetm)
M.visible_message("[M] is thrown clear of [ridden]!")
M.throw_at(target, 14, 5, ridden)
- M.Weaken(3)
+ M.Knockdown(60)
/datum/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1)
var/amount_equipped = 0
diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm
index b9853013e43..4f6be75f4fa 100644
--- a/code/datums/ruins/lavaland.dm
+++ b/code/datums/ruins/lavaland.dm
@@ -184,10 +184,10 @@
allow_duplicates = FALSE
cost = 20
-/datum/map_template/ruin/lavaland/marine_crash
- name = "Crashed Marine Transport"
- id = "marine"
- description = "A Marine Transport that has crashed, with one sole survivor"
- suffix = "lavaland_surface_ueg_crash1.dmm"
+/datum/map_template/ruin/lavaland/miningripley
+ name = "Ripley"
+ id = "ripley"
+ description = "A heavily-damaged mining ripley, property of a very unfortunate miner. You might have to do a bit of work to fix this thing up."
+ suffix = "lavaland_surface_random_ripley.dmm"
allow_duplicates = FALSE
cost = 5
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index a0338f72b0d..0f37131d0c8 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -12,7 +12,7 @@
/datum/status_effect/shadow_mend/on_apply()
owner.visible_message("Violet light wraps around [owner]'s body!", "Violet light wraps around your body!")
- playsound(owner, 'sound/magic/Teleport_app.ogg', 50, 1)
+ playsound(owner, 'sound/magic/teleport_app.ogg', 50, 1)
return ..()
/datum/status_effect/shadow_mend/tick()
@@ -21,7 +21,7 @@
/datum/status_effect/shadow_mend/on_remove()
owner.visible_message("The violet light around [owner] glows black!", "The tendrils around you cinch tightly and reap their toll...")
- playsound(owner, 'sound/magic/Teleport_diss.ogg', 50, 1)
+ playsound(owner, 'sound/magic/teleport_diss.ogg', 50, 1)
owner.apply_status_effect(STATUS_EFFECT_VOID_PRICE)
@@ -37,7 +37,7 @@
icon_state = "shadow_mend"
/datum/status_effect/void_price/tick()
- owner << sound('sound/magic/Summon_Karp.ogg', volume = 25)
+ owner << sound('sound/magic/summon_karp.ogg', volume = 25)
owner.adjustBruteLoss(3)
@@ -73,8 +73,8 @@
add_logs(owner, null, "gained Vanguard stun immunity")
owner.add_stun_absorption("vanguard", 200, 1, "'s yellow aura momentarily intensifies!", "Your ward absorbs the stun!", " radiating with a soft yellow light!")
owner.visible_message("[owner] begins to faintly glow!", "You will absorb all stuns for the next twenty seconds.")
- owner.SetStunned(0, FALSE)
- owner.SetWeakened(0)
+ owner.SetStun(0, FALSE)
+ owner.SetKnockdown(0)
progbar = new(owner, duration, owner)
progbar.bar.color = list("#FAE48C", "#FAE48C", "#FAE48C", rgb(0,0,0))
progbar.update(duration - world.time)
@@ -96,13 +96,12 @@
otheractiveabsorptions = TRUE
if(!GLOB.ratvar_awakens && stuns_blocked && !otheractiveabsorptions)
vanguard["end_time"] = 0 //so it doesn't absorb the stuns we're about to apply
- owner.Stun(stuns_blocked)
- owner.Weaken(stuns_blocked)
+ owner.Knockdown(stuns_blocked)
message_to_owner = "The weight of the Vanguard's protection crashes down upon you!"
if(stuns_blocked >= 15)
message_to_owner += "\nYou faint from the exertion!"
stuns_blocked *= 2
- owner.Paralyse(stuns_blocked)
+ owner.Unconscious(stuns_blocked)
else
stuns_blocked = 0 //so logging is correct in cases where there were stuns blocked but we didn't stun for other reasons
owner.visible_message("[owner]'s glowing aura fades!", message_to_owner)
@@ -130,14 +129,14 @@
owner.status_flags |= GODMODE
animate(owner, color = oldcolor, time = 150, easing = EASE_IN)
addtimer(CALLBACK(owner, /atom/proc/update_atom_colour), 150)
- playsound(owner, 'sound/magic/Ethereal_Enter.ogg', 50, 1)
+ playsound(owner, 'sound/magic/ethereal_enter.ogg', 50, 1)
return ..()
/datum/status_effect/inathneqs_endowment/on_remove()
add_logs(owner, null, "lost Inath-neq's invulnerability")
owner.visible_message("The light around [owner] flickers and dissipates!", "You feel Inath-neq's power fade from your body!")
owner.status_flags &= ~GODMODE
- playsound(owner, 'sound/magic/Ethereal_Exit.ogg', 50, 1)
+ playsound(owner, 'sound/magic/ethereal_exit.ogg', 50, 1)
/datum/status_effect/cyborg_power_regen
@@ -232,19 +231,20 @@
/datum/status_effect/cult_master
id = "The Cult Master"
duration = -1
- tick_interval = 100
alert_type = null
+ on_remove_on_mob_delete = TRUE
var/alive = TRUE
/datum/status_effect/cult_master/proc/deathrattle()
+ if(!QDELETED(GLOB.cult_narsie))
+ return //if nar-sie is alive, don't even worry about it
var/area/A = get_area(owner)
for(var/datum/mind/B in SSticker.mode.cult)
if(isliving(B.current))
var/mob/living/M = B.current
M << 'sound/hallucinations/veryfar_noise.ogg'
- to_chat(M, "The Cult's Master, [owner], has fallen in the [A]!")
-
-
+ to_chat(M, "The Cult's Master, [owner], has fallen in \the [A]!")
+
/datum/status_effect/cult_master/tick()
if(owner.stat != DEAD && !alive)
alive = TRUE
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index f5a34128ab1..b752696bf07 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -1,5 +1,68 @@
//Largely negative status effects go here, even if they have small benificial effects
+//STUN EFFECTS
+/datum/status_effect/incapacitating
+ tick_interval = 0
+ status_type = STATUS_EFFECT_REPLACE
+ alert_type = null
+ var/update_canmove = TRUE
+/datum/status_effect/incapacitating/on_apply()
+ if(update_canmove)
+ owner.update_canmove()
+ update_canmove = TRUE
+ return ..()
+
+/datum/status_effect/incapacitating/on_remove()
+ if(update_canmove)
+ owner.update_canmove()
+
+//STUN
+/datum/status_effect/incapacitating/stun
+ id = "stun"
+
+//SLEEPING
+/datum/status_effect/incapacitating/sleeping
+ id = "sleeping"
+ alert_type = /obj/screen/alert/status_effect/asleep
+ var/mob/living/carbon/carbon_owner
+ var/mob/living/carbon/human/human_owner
+
+/datum/status_effect/incapacitating/sleeping/Destroy()
+ carbon_owner = null
+ human_owner = null
+ return ..()
+
+/datum/status_effect/incapacitating/sleeping/on_apply()
+ if(update_canmove)
+ owner.update_stat()
+ if(iscarbon(owner)) //to avoid repeated istypes
+ carbon_owner = owner
+ if(ishuman(owner))
+ human_owner = owner
+ return ..()
+
+/datum/status_effect/incapacitating/sleeping/tick()
+ if(owner.staminaloss)
+ owner.adjustStaminaLoss(-0.35) //reduce stamina loss by 0.35 per tick, 7 per 2 seconds
+ if(human_owner && human_owner.drunkenness)
+ human_owner.drunkenness *= 0.997 //reduce drunkenness by 0.3% per tick, 6% per 2 seconds
+ if(prob(20))
+ if(carbon_owner)
+ carbon_owner.handle_dreams()
+ if(prob(10) && owner.health > HEALTH_THRESHOLD_CRIT)
+ owner.emote("snore")
+
+/datum/status_effect/incapacitating/sleeping/on_remove()
+ ..()
+ if(update_canmove)
+ owner.update_stat()
+
+/obj/screen/alert/status_effect/asleep
+ name = "Asleep"
+ desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."
+ icon_state = "asleep"
+
+//OTHER DEBUFFS
/datum/status_effect/his_wrath //does minor damage over time unless holding His Grace
id = "his_wrath"
duration = -1
@@ -47,7 +110,7 @@
if(iscarbon(owner) && !is_servant_of_ratvar(owner) && !owner.null_rod_check() && number_legs)
if(force_damage || owner.m_intent != MOVE_INTENT_WALK)
if(GLOB.ratvar_awakens)
- owner.Weaken(1)
+ owner.Knockdown(20)
if(iscultist(owner))
owner.apply_damage(cultist_damage_on_toggle * 0.5, BURN, "l_leg")
owner.apply_damage(cultist_damage_on_toggle * 0.5, BURN, "r_leg")
@@ -138,7 +201,7 @@
if(is_eligible_servant(owner))
to_chat(owner, "\"[text2ratvar("You are mine and his, now.")]\"")
add_servant_of_ratvar(owner)
- owner.Paralyse(5)
+ owner.Unconscious(100)
else
if(prob(severity * 0.15))
to_chat(owner, "\"[text2ratvar(pick(mania_messages))]\"")
diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm
index 09464083234..ae0301762e5 100644
--- a/code/datums/status_effects/neutral.dm
+++ b/code/datums/status_effects/neutral.dm
@@ -16,3 +16,29 @@
status_type = STATUS_EFFECT_UNIQUE
alert_type = null
var/total_damage = 0
+
+/datum/status_effect/syphon_mark
+ id = "syphon_mark"
+ duration = 50
+ status_type = STATUS_EFFECT_MULTIPLE
+ alert_type = null
+ on_remove_on_mob_delete = TRUE
+ var/obj/item/borg/upgrade/modkit/bounty/reward_target
+
+/datum/status_effect/syphon_mark/on_apply()
+ if(owner.stat == DEAD)
+ return FALSE
+ return ..()
+
+/datum/status_effect/syphon_mark/proc/get_kill()
+ if(reward_target)
+ reward_target.get_kill(owner)
+
+/datum/status_effect/syphon_mark/tick()
+ if(owner.stat == DEAD)
+ get_kill()
+ qdel(src)
+
+/datum/status_effect/syphon_mark/on_remove()
+ get_kill()
+ . = ..()
diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm
index f0e2c63c6e4..610d44a1e05 100644
--- a/code/datums/status_effects/status_effect.dm
+++ b/code/datums/status_effects/status_effect.dm
@@ -17,7 +17,7 @@
owner = new_owner
if(owner)
LAZYADD(owner.status_effects, src)
- addtimer(CALLBACK(src, .proc/start_ticking), 1) //Give us time to set any variables
+ addtimer(CALLBACK(src, .proc/start_ticking), 0) //Give us the minimum possible time to set any variables
/datum/status_effect/Destroy()
STOP_PROCESSING(SSfastprocess, src)
@@ -35,8 +35,8 @@
qdel(src)
return
if(duration != -1)
- duration = world.time + initial(duration)
- tick_interval = world.time + initial(tick_interval)
+ duration = world.time + duration
+ tick_interval = world.time + tick_interval
if(alert_type)
var/obj/screen/alert/status_effect/A = owner.throw_alert(id, alert_type)
A.attached_effect = src //so the alert can reference us, if it needs to
diff --git a/code/datums/verbs.dm b/code/datums/verbs.dm
new file mode 100644
index 00000000000..48f990d2acb
--- /dev/null
+++ b/code/datums/verbs.dm
@@ -0,0 +1,102 @@
+/datum/verbs
+ var/name
+ var/list/children
+ var/datum/verbs/parent
+ var/list/verblist
+ var/abstract = FALSE
+
+//returns the master list for verbs of a type
+/datum/verbs/proc/GetList()
+ CRASH("Abstract verblist for [type]")
+
+//do things for each entry in Generate_list
+//return value sets Generate_list[verbpath]
+/datum/verbs/proc/HandleVerb(list/entry, atom/verb/verbpath, ...)
+ return entry
+
+/datum/verbs/New()
+ var/mainlist = GetList()
+ var/ourentry = mainlist[type]
+ children = list()
+ verblist = list()
+ if (ourentry)
+ if (!islist(ourentry)) //some of our childern already loaded
+ qdel(src)
+ CRASH("Verb double load: [type]")
+ Add_children(ourentry)
+
+ mainlist[type] = src
+
+ Load_verbs(type, typesof("[type]/verb"))
+
+ var/datum/verbs/parent = mainlist[parent_type]
+ if (!parent)
+ mainlist[parent_type] = list(src)
+ else if (islist(parent))
+ parent += src
+ else
+ parent.Add_children(list(src))
+
+/datum/verbs/proc/Set_parent(datum/verbs/_parent)
+ parent = _parent
+ if (abstract)
+ parent.Add_children(children)
+ var/list/verblistoftypes = list()
+ for(var/thing in verblist)
+ LAZYADD(verblistoftypes[verblist[thing]], thing)
+
+ for(var/verbparenttype in verblistoftypes)
+ parent.Load_verbs(verbparenttype, verblistoftypes[verbparenttype])
+
+/datum/verbs/proc/Add_children(list/kids)
+ if (abstract && parent)
+ parent.Add_children(kids)
+ return
+
+ for(var/thing in kids)
+ var/datum/verbs/item = thing
+ item.Set_parent(src)
+ if (!item.abstract)
+ children += item
+
+/datum/verbs/proc/Load_verbs(verb_parent_type, list/verbs)
+ if (abstract && parent)
+ parent.Load_verbs(verb_parent_type, verbs)
+ return
+
+ for (var/verbpath in verbs)
+ verblist[verbpath] = verb_parent_type
+
+/datum/verbs/proc/Generate_list(...)
+ . = list()
+ if (length(children))
+ for (var/thing in children)
+ var/datum/verbs/child = thing
+ var/list/childlist = child.Generate_list(arglist(args))
+ if (childlist)
+ var/childname = "[child]"
+ if (childname == "[child.type]")
+ var/list/tree = splittext(childname, "/")
+ childname = tree[tree.len]
+ .[child.type] = "parent=[url_encode(type)];name=[url_encode(childname)]"
+ . += childlist
+
+ for (var/thing in verblist)
+ var/atom/verb/verbpath = thing
+ if (!verbpath)
+ stack_trace("Bad VERB in [type] verblist: [english_list(verblist)]")
+ var/list/entry = list()
+ entry["parent"] = "[type]"
+ entry["name"] = verbpath.desc
+ if (copytext(verbpath.name,1,2) == "@")
+ entry["command"] = copytext(verbpath.name,2)
+ else
+ entry["command"] = replacetext(verbpath.name, " ", "-")
+
+ .[verbpath] = HandleVerb(arglist(list(entry, verbpath) + args))
+
+/world/proc/LoadVerbs(verb_type)
+ if(!ispath(verb_type, /datum/verbs) || verb_type == /datum/verbs)
+ CRASH("Invalid verb_type: [verb_type]")
+ for (var/typepath in subtypesof(verb_type))
+ new typepath()
diff --git a/code/datums/wires/mulebot.dm b/code/datums/wires/mulebot.dm
index bec3a5d73c8..00b2dd10b89 100644
--- a/code/datums/wires/mulebot.dm
+++ b/code/datums/wires/mulebot.dm
@@ -20,12 +20,12 @@
var/mob/living/simple_animal/bot/mulebot/M = holder
switch(wire)
if(WIRE_POWER1, WIRE_POWER2)
- holder.visible_message("\icon[M] The charge light flickers.")
+ holder.visible_message("[bicon(M)] The charge light flickers.")
if(WIRE_AVOIDANCE)
- holder.visible_message("\icon[M] The external warning lights flash briefly.")
+ holder.visible_message("[bicon(M)] The external warning lights flash briefly.")
if(WIRE_LOADCHECK)
- holder.visible_message("\icon[M] The load platform clunks.")
+ holder.visible_message("[bicon(M)] The load platform clunks.")
if(WIRE_MOTOR1, WIRE_MOTOR2)
- holder.visible_message("\icon[M] The drive motor whines briefly.")
+ holder.visible_message("[bicon(M)] The drive motor whines briefly.")
else
- holder.visible_message("\icon[M] You hear a radio crackle.")
\ No newline at end of file
+ holder.visible_message("[bicon(M)] You hear a radio crackle.")
\ No newline at end of file
diff --git a/code/datums/wires/particle_accelerator.dm b/code/datums/wires/particle_accelerator.dm
index 6c69742f9b1..436b8be3ecd 100644
--- a/code/datums/wires/particle_accelerator.dm
+++ b/code/datums/wires/particle_accelerator.dm
@@ -25,7 +25,7 @@
if(WIRE_INTERFACE)
C.interface_control = !C.interface_control
if(WIRE_LIMIT)
- C.visible_message("\icon[C][C] makes a large whirring noise.")
+ C.visible_message("[bicon(C)][C] makes a large whirring noise.")
/datum/wires/particle_accelerator/control_box/on_cut(wire, mend)
var/obj/machinery/particle_accelerator/control_box/C = holder
diff --git a/code/datums/wires/syndicatebomb.dm b/code/datums/wires/syndicatebomb.dm
index 80b5a9d6518..78acc42eb04 100644
--- a/code/datums/wires/syndicatebomb.dm
+++ b/code/datums/wires/syndicatebomb.dm
@@ -19,21 +19,21 @@
switch(wire)
if(WIRE_BOOM)
if(B.active)
- holder.visible_message("\icon[B] An alarm sounds! It's go-")
+ holder.visible_message("[bicon(B)] An alarm sounds! It's go-")
B.explode_now = TRUE
tell_admins(B)
if(WIRE_UNBOLT)
- holder.visible_message("\icon[B] The bolts spin in place for a moment.")
+ holder.visible_message("[bicon(B)] The bolts spin in place for a moment.")
if(WIRE_DELAY)
if(B.delayedbig)
- holder.visible_message("\icon[B] The bomb has already been delayed.")
+ holder.visible_message("[bicon(B)] The bomb has already been delayed.")
else
- holder.visible_message("\icon[B] The bomb chirps.")
+ holder.visible_message("[bicon(B)] The bomb chirps.")
playsound(B, 'sound/machines/chime.ogg', 30, 1)
B.detonation_timer += 300
B.delayedbig = TRUE
if(WIRE_PROCEED)
- holder.visible_message("\icon[B] The bomb buzzes ominously!")
+ holder.visible_message("[bicon(B)] The bomb buzzes ominously!")
playsound(B, 'sound/machines/buzz-sigh.ogg', 30, 1)
var/seconds = B.seconds_remaining()
if(seconds >= 61) // Long fuse bombs can suddenly become more dangerous if you tinker with them.
@@ -44,13 +44,13 @@
B.detonation_timer = world.time + 100
if(WIRE_ACTIVATE)
if(!B.active && !B.defused)
- holder.visible_message("\icon[B] You hear the bomb start ticking!")
+ holder.visible_message("[bicon(B)] You hear the bomb start ticking!")
B.activate()
B.update_icon()
else if(B.delayedlittle)
- holder.visible_message("\icon[B] Nothing happens.")
+ holder.visible_message("[bicon(B)] Nothing happens.")
else
- holder.visible_message("\icon[B] The bomb seems to hesitate for a moment.")
+ holder.visible_message("[bicon(B)] The bomb seems to hesitate for a moment.")
B.detonation_timer += 100
B.delayedlittle = TRUE
@@ -62,24 +62,24 @@
B.defused = FALSE // Cutting and mending all the wires of an inactive bomb will thus cure any sabotage.
else
if(B.active)
- holder.visible_message("\icon[B] An alarm sounds! It's go-")
+ holder.visible_message("[bicon(B)] An alarm sounds! It's go-")
B.explode_now = TRUE
tell_admins(B)
else
B.defused = TRUE
if(WIRE_UNBOLT)
if(!mend && B.anchored)
- holder.visible_message("\icon[B] The bolts lift out of the ground!")
+ holder.visible_message("[bicon(B)] The bolts lift out of the ground!")
playsound(B, 'sound/effects/stealthoff.ogg', 30, 1)
B.anchored = FALSE
if(WIRE_PROCEED)
if(!mend && B.active)
- holder.visible_message("\icon[B] An alarm sounds! It's go-")
+ holder.visible_message("[bicon(B)] An alarm sounds! It's go-")
B.explode_now = TRUE
tell_admins(B)
if(WIRE_ACTIVATE)
if(!mend && B.active)
- holder.visible_message("\icon[B] The timer stops! The bomb has been defused!")
+ holder.visible_message("[bicon(B)] The timer stops! The bomb has been defused!")
B.active = FALSE
B.defused = TRUE
B.update_icon()
diff --git a/code/game/area/areas/ruins.dm b/code/game/area/areas/ruins.dm
index eb99903a89a..b71314408d4 100644
--- a/code/game/area/areas/ruins.dm
+++ b/code/game/area/areas/ruins.dm
@@ -43,7 +43,7 @@
/area/ruin/powered/greed
icon_state = "dk_yellow"
-
+
/area/ruin/unpowered/hierophant
name = "Hierophant's Arena"
icon_state = "dk_yellow"
@@ -222,16 +222,48 @@
name = "Deep Storage"
icon_state = "storage"
+/area/ruin/deepstorage/airlock
+ name = "Deep Storage Airlock"
+ icon_state = "quart"
+
+/area/ruin/deepstorage/power
+ name = "Deep Storage Power and Atmospherics Room"
+ icon_state = "engi_storage"
+
+/area/ruin/deepstorage/hydroponics
+ name = "Deep Storage Hydroponics"
+ icon_state = "garden"
+
+/area/ruin/deepstorage/armory
+ name = "Deep Storage Secure Storage"
+ icon_state = "armory"
+
+/area/ruin/deepstorage/storage
+ name = "Deep Storage Storage"
+ icon_state = "storage_wing"
+
+/area/ruin/deepstorage/dorm
+ name = "Deep Storage Dormory"
+ icon_state = "crew_quarters"
+
+/area/ruin/deepstorage/kitchen
+ name = "Deep Storage Kitchen"
+ icon_state = "kitchen"
+
+/area/ruin/deepstorage/crusher
+ name = "Deep Storage Recycler"
+ icon_state = "storage"
+
//Ruin of Abandoned Zoo
/area/ruin/abandonedzoo
name = "Abandoned Zoo"
icon_state = "green"
-
-
+
+
//Xeno Nest
-
+
/area/ruin/xenonest
name = "The Hive"
always_unpowered = 1
@@ -239,4 +271,3 @@
power_equip = 0
power_light = 0
poweralm = 0
-
\ No newline at end of file
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 959f85febfa..e2fae1f5e99 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -79,13 +79,8 @@
return INITIALIZE_HINT_NORMAL
//called if Initialize returns INITIALIZE_HINT_LATELOAD
-//This version shouldn't be called
/atom/proc/LateInitialize()
- var/static/list/warned_types = list()
- if(!warned_types[type])
- WARNING("Old style LateInitialize behaviour detected in [type]!")
- warned_types[type] = TRUE
- Initialize(FALSE)
+ return
/atom/Destroy()
if(alternate_appearances)
@@ -249,7 +244,7 @@
f_name = "a "
f_name += "blood-stained [name]!"
- to_chat(user, "\icon[src] That's [f_name]")
+ to_chat(user, "[bicon(src)] That's [f_name]")
if(desc)
to_chat(user, desc)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 4c5f408f52a..670ebba21ea 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -198,6 +198,8 @@
QDEL_NULL(proximity_monitor)
QDEL_NULL(language_holder)
+ unbuckle_all_mobs(force=1)
+
. = ..()
if(loc)
loc.handle_atom_del(src)
@@ -211,7 +213,8 @@
// Previously known as HasEntered()
// This is automatically called when something enters your square
-/atom/movable/Crossed(atom/movable/AM)
+//oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called!
+/atom/movable/Crossed(atom/movable/AM, oldloc)
return
/atom/movable/Bump(atom/A, yes) //the "yes" arg is to differentiate our Bump proc from byond's, without it every Bump() call would become a double Bump().
@@ -247,7 +250,7 @@
for(var/atom/movable/AM in destination)
if(AM == src)
continue
- AM.Crossed(src)
+ AM.Crossed(src, oldloc)
Moved(oldloc, 0)
return 1
@@ -590,7 +593,7 @@
/atom/movable/proc/in_bounds()
. = FALSE
var/turf/currentturf = get_turf(src)
- if(currentturf && (currentturf.z == ZLEVEL_CENTCOM || currentturf.z == ZLEVEL_STATION))
+ if(currentturf && (currentturf.z == ZLEVEL_CENTCOM || currentturf.z == ZLEVEL_STATION || currentturf.z == ZLEVEL_TRANSIT))
. = TRUE
@@ -684,3 +687,10 @@
//Returns an atom's power cell, if it has one. Overload for individual items.
/atom/movable/proc/get_cell()
return
+
+/atom/movable/proc/can_be_pulled(user)
+ if(src == user || !isturf(loc))
+ return FALSE
+ if(anchored || throwing)
+ return FALSE
+ return TRUE
\ No newline at end of file
diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm
index e1cbd922bdf..8da7cb31690 100644
--- a/code/game/gamemodes/antag_spawner.dm
+++ b/code/game/gamemodes/antag_spawner.dm
@@ -251,7 +251,7 @@
spawn_antag(theghost.client, get_turf(src), initial(demon_type.name))
to_chat(user, shatter_msg)
to_chat(user, veil_msg)
- playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1)
+ playsound(user.loc, 'sound/effects/glassbr1.ogg', 100, 1)
qdel(src)
else
to_chat(user, "You can't seem to work up the nerve to shatter the bottle. Perhaps you should try again later.")
diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm
index 15e914efd6e..ea6bd07c58c 100644
--- a/code/game/gamemodes/blob/blob_report.dm
+++ b/code/game/gamemodes/blob/blob_report.dm
@@ -14,7 +14,7 @@
intercepttext += " 3. Avoid damage to the capital infrastructure of the station. "
intercepttext += " Note in the event of a quarantine breach or uncontrolled spread of the biohazard, Biohazard Response Procedure 5-12 may be issued. "
print_command_report(text=intercepttext,title="Level 5-6 Biohazard Response Procedures",announce=FALSE)
- priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg')
+ priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg')
if(2)
var/nukecode = random_nukecode()
for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines)
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
index e80e92337ed..0b59cc0b052 100644
--- a/code/game/gamemodes/blob/theblob.dm
+++ b/code/game/gamemodes/blob/theblob.dm
@@ -262,7 +262,7 @@
else
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/structure/blob/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
switch(damage_type)
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index d7c962c4805..87f09d8be05 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -200,7 +200,7 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
to_chat(changeling.current, "You are [changeling.changeling.changelingID], a changeling! You have absorbed and taken the form of a human.")
to_chat(changeling.current, "Use say \":g message\" to communicate with your fellow changelings.")
to_chat(changeling.current, "You must complete the following tasks:")
- changeling.current.playsound_local('sound/ambience/antag/ling_aler.ogg',100,0)
+ changeling.current.playsound_local(get_turf(changeling.current), 'sound/ambience/antag/ling_aler.ogg', 100, FALSE, pressure_affected = FALSE)
if (changeling.current.mind)
var/mob/living/carbon/human/H = changeling.current
diff --git a/code/game/gamemodes/changeling/powers/adrenaline.dm b/code/game/gamemodes/changeling/powers/adrenaline.dm
index 5effe8898f8..cc001ba85a1 100644
--- a/code/game/gamemodes/changeling/powers/adrenaline.dm
+++ b/code/game/gamemodes/changeling/powers/adrenaline.dm
@@ -11,9 +11,9 @@
/obj/effect/proc_holder/changeling/adrenaline/sting_action(mob/living/user)
to_chat(user, "Energy rushes through us.[user.lying ? " We arise." : ""]")
user.SetSleeping(0)
- user.SetParalysis(0)
- user.SetStunned(0)
- user.SetWeakened(0)
+ user.SetUnconscious(0)
+ user.SetStun(0)
+ user.SetKnockdown(0)
user.reagents.add_reagent("changelingAdrenaline", 10)
user.reagents.add_reagent("changelingAdrenaline2", 2) //For a really quick burst of speed
user.adjustStaminaLoss(-75)
diff --git a/code/game/gamemodes/changeling/powers/headcrab.dm b/code/game/gamemodes/changeling/powers/headcrab.dm
index a9f6381082e..94d83e25207 100644
--- a/code/game/gamemodes/changeling/powers/headcrab.dm
+++ b/code/game/gamemodes/changeling/powers/headcrab.dm
@@ -17,13 +17,13 @@
explosion(get_turf(user),0,0,2,0,silent=1)
for(var/mob/living/carbon/human/H in range(2,user))
to_chat(H, "You are blinded by a shower of blood!")
- H.Stun(1)
+ H.Stun(20)
H.blur_eyes(20)
H.adjust_eye_damage(5)
H.confused += 3
for(var/mob/living/silicon/S in range(2,user))
to_chat(S, "Your sensors are disabled by a shower of blood!")
- S.Weaken(3)
+ S.Knockdown(60)
var/turf = get_turf(user)
user.gib()
. = TRUE
diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm
index aef9b6f1d26..99631f18f49 100644
--- a/code/game/gamemodes/changeling/powers/mutations.dm
+++ b/code/game/gamemodes/changeling/powers/mutations.dm
@@ -403,7 +403,7 @@
if(ismob(loc))
loc.visible_message("The end of [loc.name]\'s hand inflates rapidly, forming a huge shield-like mass!", "We inflate our hand into a strong shield.", "You hear organic matter ripping and tearing!")
-/obj/item/weapon/shield/changeling/hit_reaction()
+/obj/item/weapon/shield/changeling/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(remaining_uses < 1)
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
diff --git a/code/game/gamemodes/changeling/powers/panacea.dm b/code/game/gamemodes/changeling/powers/panacea.dm
index afc7655bc18..7023e30010d 100644
--- a/code/game/gamemodes/changeling/powers/panacea.dm
+++ b/code/game/gamemodes/changeling/powers/panacea.dm
@@ -17,7 +17,7 @@
B.leave_victim()
if(iscarbon(user))
var/mob/living/carbon/C = user
- C.vomit(0)
+ C.vomit(0, toxic = TRUE)
to_chat(user, "A parasite exits our form.")
var/list/bad_organs = list(
user.getorgan(/obj/item/organ/body_egg),
@@ -31,7 +31,7 @@
O.Remove(user)
if(iscarbon(user))
var/mob/living/carbon/C = user
- C.vomit(0)
+ C.vomit(0, toxic = TRUE)
O.forceMove(get_turf(user))
user.reagents.add_reagent("mutadone", 10)
diff --git a/code/game/gamemodes/changeling/powers/regenerate.dm b/code/game/gamemodes/changeling/powers/regenerate.dm
index bd7308b033a..a74b966bd85 100644
--- a/code/game/gamemodes/changeling/powers/regenerate.dm
+++ b/code/game/gamemodes/changeling/powers/regenerate.dm
@@ -17,7 +17,7 @@
var/mob/living/carbon/C = user
var/list/missing = C.get_missing_limbs()
if(missing.len)
- playsound(user, 'sound/magic/Demon_consume.ogg', 50, 1)
+ playsound(user, 'sound/magic/demon_consume.ogg', 50, 1)
C.visible_message("[user]'s missing limbs \
reform, making a loud, grotesque sound!",
"Your limbs regrow, making a \
diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm
index dc1592c9864..8729c0dd126 100644
--- a/code/game/gamemodes/changeling/powers/revive.dm
+++ b/code/game/gamemodes/changeling/powers/revive.dm
@@ -14,7 +14,7 @@
var/list/missing = user.get_missing_limbs()
missing -= "head" // headless changelings are funny
if(missing.len)
- playsound(user, 'sound/magic/Demon_consume.ogg', 50, 1)
+ playsound(user, 'sound/magic/demon_consume.ogg', 50, 1)
user.visible_message("[user]'s missing limbs \
reform, making a loud, grotesque sound!",
"Your limbs regrow, making a \
diff --git a/code/game/gamemodes/changeling/powers/shriek.dm b/code/game/gamemodes/changeling/powers/shriek.dm
index d94be6f4db7..099d991062a 100644
--- a/code/game/gamemodes/changeling/powers/shriek.dm
+++ b/code/game/gamemodes/changeling/powers/shriek.dm
@@ -20,7 +20,7 @@
if(issilicon(M))
M << sound('sound/weapons/flash.ogg')
- M.Weaken(rand(5,10))
+ M.Knockdown(rand(100,200))
for(var/obj/machinery/light/L in range(4, user))
L.on = 1
diff --git a/code/game/gamemodes/changeling/powers/strained_muscles.dm b/code/game/gamemodes/changeling/powers/strained_muscles.dm
index 7238e2d1c10..10145c2bca4 100644
--- a/code/game/gamemodes/changeling/powers/strained_muscles.dm
+++ b/code/game/gamemodes/changeling/powers/strained_muscles.dm
@@ -20,7 +20,7 @@
to_chat(user, "Our muscles relax.")
if(stacks >= 10)
to_chat(user, "We collapse in exhaustion.")
- user.Weaken(3)
+ user.Knockdown(60)
user.emote("gasp")
INVOKE_ASYNC(src, .proc/muscle_loop, user)
@@ -33,7 +33,7 @@
if(user.stat != CONSCIOUS || user.staminaloss >= 90)
active = !active
to_chat(user, "Our muscles relax without the energy to strengthen them.")
- user.Weaken(2)
+ user.Knockdown(40)
user.status_flags &= ~GOTTAGOFAST
break
diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm
index eb1e8baba71..8f8e422ea53 100644
--- a/code/game/gamemodes/changeling/powers/tiny_prick.dm
+++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm
@@ -57,9 +57,9 @@
/obj/effect/proc_holder/changeling/sting/transformation
name = "Transformation Sting"
desc = "We silently sting a human, injecting a retrovirus that forces them to transform."
- helptext = "The victim will transform much like a changeling would. The effects will be obvious to the victim, and the process will damage our genomes."
+ helptext = "The victim will transform much like a changeling would. Does not provide a warning to others. Mutations will not be transferred, and monkeys will become human."
sting_icon = "sting_transform"
- chemical_cost = 40
+ chemical_cost = 50
dna_cost = 3
var/datum/changelingprofile/selected_dna = null
@@ -86,26 +86,19 @@
return 1
/obj/effect/proc_holder/changeling/sting/transformation/sting_action(mob/user, mob/target)
- set waitfor = FALSE
add_logs(user, target, "stung", "transformation sting", " new identity is [selected_dna.dna.real_name]")
var/datum/dna/NewDNA = selected_dna.dna
if(ismonkey(target))
to_chat(user, "Our genes cry out as we sting [target.name]!")
var/mob/living/carbon/C = target
- if(istype(C))
- if(C.status_flags & CANWEAKEN)
- C.do_jitter_animation(500)
- C.take_bodypart_damage(20, 0) //The process is extremely painful
-
- target.visible_message("[target] begins to violenty convulse!","You feel a tiny prick and a begin to uncontrollably convulse!")
. = TRUE
- sleep(10)
if(istype(C))
C.real_name = NewDNA.real_name
- NewDNA.transfer_identity(C, transfer_SE=1)
+ NewDNA.transfer_identity(C)
+ if(ismonkey(C))
+ C.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
C.updateappearance(mutcolor_update=1)
- C.domutcheck()
/obj/effect/proc_holder/changeling/sting/false_armblade
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index 48e1ff19576..ec387a71e57 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -146,7 +146,7 @@ Credit where due:
Rusting eternally in the Celestial Derelict, Ratvar has formed a covenant of mortals, with you as one of its members. As one of the Justiciar's servants, you are to work to the best of your \
ability to assist in completion of His agenda. You may not know the specifics of how to do so, but luckily you have a vessel to help you learn."
to_chat(M, greeting_text)
- M.playsound_local('sound/ambience/antag/ClockCultAlr.ogg',100,0)
+ M.playsound_local(get_turf(M), 'sound/ambience/antag/clockcultalr.ogg', 100, FALSE, pressure_affected = FALSE)
return 1
/datum/game_mode/proc/equip_servant(mob/living/L) //Grants a clockwork slab to the mob, with one of each component
@@ -207,10 +207,9 @@ Credit where due:
text += " The servants' objective was: [CLOCKCULT_OBJECTIVE]"
text += " Ratvar's servants had [GLOB.clockwork_caches] Tinkerer's Caches."
text += " Construction Value(CV) was: [GLOB.clockwork_construction_value]"
- var/list/scripture_states = scripture_unlock_check()
- for(var/i in scripture_states)
+ for(var/i in SSticker.scripture_states)
if(i != SCRIPTURE_DRIVER)
- text += " [i] scripture was: [scripture_states[i] ? "UN":""]LOCKED"
+ text += " [i] scripture was: [SSticker.scripture_states[i] ? "UN":""]LOCKED"
if(servants_of_ratvar.len)
text += " Ratvar's servants were:"
for(var/datum/mind/M in servants_of_ratvar)
diff --git a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm
index 7d8c3eb1f97..8bec1ab3ed4 100644
--- a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm
+++ b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm
@@ -46,7 +46,7 @@
/obj/effect/clockwork/sigil/proc/sigil_effects(mob/living/L)
-//Sigil of Transgression: Stuns the first non-servant to walk on it and flashes all nearby non_servants. Nar-Sian cultists are damaged and knocked down for a longer stun
+//Sigil of Transgression: Stuns the first non-servant to walk on it and flashes all nearby non_servants. Nar-Sian cultists are damaged and knocked down for a longer time
/obj/effect/clockwork/sigil/transgression
name = "dull sigil"
desc = "A dull, barely-visible golden sigil. It's as though light was carved into the ground."
@@ -69,10 +69,10 @@
if(iscultist(L))
to_chat(L, "\"Watch your step, wretch.\"")
L.adjustBruteLoss(10)
- L.Weaken(7)
+ L.Knockdown(140)
L.visible_message("[src] appears around [L] in a burst of light!", \
"[target_flashed ? "An unseen force":"The glowing sigil around you"] holds you in place!")
- L.Stun(5)
+ L.Stun(100)
new /obj/effect/temp_visual/ratvar/sigil/transgression(get_turf(src))
qdel(src)
@@ -121,8 +121,7 @@
if(is_eligible_servant(L))
to_chat(L, "\"You belong to me now.\"")
add_servant_of_ratvar(L)
- L.Weaken(3) //Completely defenseless for about five seconds - mainly to give them time to read over the information they've just been presented with
- L.Stun(3)
+ L.Knockdown(60) //Completely defenseless for about five seconds - mainly to give them time to read over the information they've just been presented with
if(iscarbon(L))
var/mob/living/carbon/C = L
C.silent += 5
@@ -204,7 +203,7 @@
else if(!GLOB.ratvar_awakens)
to_chat(user, "Hitting the [sigil_name] with brass sheets will convert them to power at a rate of 1 brass sheet to [POWER_FLOOR]W power.")
if(!GLOB.ratvar_awakens)
- to_chat(user, "You can recharge Clockwork Proselytizers from the [sigil_name].")
+ to_chat(user, "You can recharge Replica Fabricators from the [sigil_name].")
/obj/effect/clockwork/sigil/transmission/attackby(obj/item/I, mob/living/user, params)
if(is_servant_of_ratvar(user) && istype(I, /obj/item/stack/tile/brass) && !GLOB.ratvar_awakens)
@@ -330,7 +329,7 @@
vitality_drained = L.maxHealth
var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
animate(V, alpha = 0, transform = matrix()*2, time = 8)
- playsound(L, 'sound/magic/WandODeath.ogg', 50, 1)
+ playsound(L, 'sound/magic/wandodeath.ogg', 50, 1)
L.visible_message("[L] collapses in on [L.p_them()]self as [src] flares bright blue!")
to_chat(L, "\"[text2ratvar("Your life will not be wasted.")]\"")
for(var/obj/item/W in L)
@@ -358,7 +357,7 @@
L.revive(1, 1)
var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
animate(V, alpha = 0, transform = matrix()*2, time = 8)
- playsound(L, 'sound/magic/Staff_Healing.ogg', 50, 1)
+ playsound(L, 'sound/magic/staff_healing.ogg', 50, 1)
L.visible_message("[L] suddenly gets back up, [GLOB.ratvar_awakens ? "[L.p_their()] body dripping blue ichor":"even as [src] scatters into blue sparks around [L.p_them()]"]!", \
"\"[text2ratvar("You will be okay, child.")]\"")
vitality -= revival_cost
diff --git a/code/game/gamemodes/clock_cult/clock_effects/general_markers.dm b/code/game/gamemodes/clock_cult/clock_effects/general_markers.dm
index 6eb176ad48a..a3465fac053 100644
--- a/code/game/gamemodes/clock_cult/clock_effects/general_markers.dm
+++ b/code/game/gamemodes/clock_cult/clock_effects/general_markers.dm
@@ -18,10 +18,10 @@
their prowess. After a lost battle with Nar-Sian cultists, Inath-neq was struck down and stated in her dying breath, \
\"The Resonant Cogs shall not fall silent this day, but will come together to form a wheel that shall never stop turning.\" Ratvar, touched by this, granted Inath-neq an eternal body and \
merged her soul with those of the Cogs slain with her on the battlefield."
- icon = 'icons/effects/187x381.dmi'
+ icon = 'icons/effects/119x268.dmi'
icon_state = "inath-neq"
- pixel_x = -77
- pixel_y = -174
+ pixel_x = -59
+ pixel_y = -134
/obj/effect/clockwork/general_marker/nezbere
name = "Nezbere, the Brass Eidolon"
@@ -29,10 +29,10 @@
clockwork_desc = "One of Ratvar's four generals. Nezbere is responsible for the design, testing, and creation of everything in Ratvar's domain, and his loyalty to Ratvar knows no bounds. \
It is said that Ratvar once asked him to destroy the plans for a weapon Nezbere had made that could have harmed him, and Nezbere responded by not only destroying the plans, \
but by taking his own life so that the device could never be replicated. Nezbere's zealotry is unmatched."
- icon = 'icons/effects/340x428.dmi'
+ icon = 'icons/effects/237x321.dmi'
icon_state = "nezbere"
- pixel_x = -154
- pixel_y = -198
+ pixel_x = -118
+ pixel_y = -160
/obj/effect/clockwork/general_marker/sevtug
name = "Sevtug, the Formless Pariah"
@@ -40,10 +40,10 @@
clockwork_desc = "One of Ratvar's four generals. Sevtug taught him how to manipulate minds and is one of his oldest allies. Sevtug serves Ratvar loyally out of a hope that one day, he will \
be able to use a moment of weakness in the Justicar to usurp him, but such a day will never come. And so, he serves with dedication, if not necessarily any sort of decorum, never aware he is \
the one being made a fool of."
- icon = 'icons/effects/211x247.dmi'
+ icon = 'icons/effects/166x195.dmi'
icon_state = "sevtug"
- pixel_x = -89
- pixel_y = -107
+ pixel_x = -83
+ pixel_y = -97
/obj/effect/clockwork/general_marker/nzcrentr
name = "Nzcrentr, the Eternal Thunderbolt"
@@ -51,7 +51,7 @@
clockwork_desc = "One of Ratvar's four generals. Before becoming one of Ratvar's generals, Nzcrentr sook out any and all sentient life to slaughter it for sport. \
Nzcrentr was coerced by Ratvar into entering a shell constructed by Nezbere, ostensibly made to grant Nzcrentr more power. In reality, the shell was made to trap and control it. \
Nzcrentr now serves loyally, though even one of Nezbere's finest creations was not enough to totally eliminate its will."
- icon = 'icons/effects/254x361.dmi'
+ icon = 'icons/effects/274x385.dmi'
icon_state = "nzcrentr"
- pixel_x = -111
- pixel_y = -164
+ pixel_x = -137
+ pixel_y = -145
diff --git a/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm b/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm
index 5c1d3fb5fbc..2c7e7d2ac7b 100644
--- a/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm
+++ b/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm
@@ -119,7 +119,7 @@
qdel(src)
return FALSE
if(!sender)
- visible_message("[A] bounces off of [src]!")
+ visible_message("[A] bounces off [src]!")
return FALSE
if(!uses)
return FALSE
@@ -127,8 +127,8 @@
var/mob/living/user = A
to_chat(user, "You pass through [src] and appear elsewhere!")
linked_gateway.visible_message("A shape appears in [linked_gateway] before emerging!")
- playsound(src, 'sound/effects/EMPulse.ogg', 50, 1)
- playsound(linked_gateway, 'sound/effects/EMPulse.ogg', 50, 1)
+ playsound(src, 'sound/effects/empulse.ogg', 50, 1)
+ playsound(linked_gateway, 'sound/effects/empulse.ogg', 50, 1)
transform = matrix() * 1.5
animate(src, transform = matrix() / 1.5, time = 10, flags = ANIMATION_END_NOW)
linked_gateway.transform = matrix() * 1.5
@@ -194,7 +194,7 @@
return procure_gateway(invoker, time_duration, gateway_uses, two_way)
var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/CO = target
if(CO.active)
- to_chat(invoker, "That [target.name] is sustaining a gateway, and cannot recieve another!")
+ to_chat(invoker, "That [target.name] is sustaining a gateway, and cannot receive another!")
return procure_gateway(invoker, time_duration, gateway_uses, two_way)
var/efficiency = CO.get_efficiency_mod()
gateway_uses = round(gateway_uses * (2 * efficiency), 1)
diff --git a/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm b/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm
new file mode 100644
index 00000000000..79dd8257f4b
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm
@@ -0,0 +1,372 @@
+//For the clockwork fabricator, this proc exists to make it easy to customize what the fabricator does when hitting something.
+
+//if a valid target, returns an associated list in this format;
+//list("operation_time" = 15, "new_obj_type" = /obj/structure/window/reinforced/clockwork, "power_cost" = 5, "spawn_dir" = dir, "dir_in_new" = TRUE)
+//otherwise, return literally any non-list thing but preferably FALSE
+//returning TRUE won't produce the "cannot be fabricated" message and will still prevent fabrication
+
+/atom/proc/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+/atom/proc/consume_visual(obj/item/clockwork/replica_fabricator/fabricator, power_amount)
+ if(fabricator.can_use_power(power_amount))
+ var/obj/effect/temp_visual/ratvar/beam/itemconsume/B = new /obj/effect/temp_visual/ratvar/beam/itemconsume(get_turf(src))
+ B.pixel_x = pixel_x
+ B.pixel_y = pixel_y
+
+//Turf conversion
+/turf/closed/wall/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //four sheets of metal
+ return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 4), "spawn_dir" = SOUTH)
+
+/turf/closed/wall/mineral/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //two sheets of metal
+ return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2), "spawn_dir" = SOUTH)
+
+/turf/closed/wall/mineral/iron/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //two sheets of metal, five rods
+ return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2) - (POWER_ROD * 5), "spawn_dir" = SOUTH)
+
+/turf/closed/wall/mineral/cult/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //no metal
+ return list("operation_time" = 80, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL, "spawn_dir" = SOUTH)
+
+/turf/closed/wall/shuttle/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //two sheets of metal
+ return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2), "spawn_dir" = SOUTH)
+
+/turf/closed/wall/r_wall/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+/turf/closed/wall/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return list("operation_time" = 50, "new_obj_type" = /turf/open/floor/clockwork, "power_cost" = -POWER_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
+
+/turf/open/floor/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ if(floor_tile == /obj/item/stack/tile/plasteel)
+ new floor_tile(src)
+ make_plating()
+ playsound(src, 'sound/items/crowbar.ogg', 10, 1) //clink
+ return list("operation_time" = 30, "new_obj_type" = /turf/open/floor/clockwork, "power_cost" = POWER_FLOOR, "spawn_dir" = SOUTH)
+
+/turf/open/floor/plating/asteroid/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+/turf/open/floor/plating/ashplanet/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+/turf/open/floor/plating/lava/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+/turf/open/floor/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ if(locate(/obj/structure/table) in src)
+ return FALSE
+ if(locate(/obj/structure/falsewall) in contents)
+ to_chat(user, "There is a false wall in the way, preventing you from fabricating a clockwork wall on [src].")
+ return
+ if(is_blocked_turf(src, TRUE))
+ to_chat(user, "Something is in the way, preventing you from fabricating a clockwork wall on [src].")
+ return TRUE
+ var/operation_time = 100
+ if(!GLOB.ratvar_awakens && fabricator.speed_multiplier > 0) //if ratvar isn't awake, this always takes 10 seconds
+ operation_time /= fabricator.speed_multiplier
+ return list("operation_time" = operation_time, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
+
+//False wall conversion
+/obj/structure/falsewall/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ var/cost = POWER_WALL_MINUS_FLOOR
+ if(ispath(mineral, /obj/item/stack/sheet/metal))
+ cost -= (POWER_METAL * (2 + mineral_amount)) //four sheets of metal, plus an assumption that the girder is also two
+ else
+ cost -= (POWER_METAL * 2) //anything that doesn't use metal just has the girder
+ return list("operation_time" = 50, "new_obj_type" = /obj/structure/falsewall/brass, "power_cost" = cost, "spawn_dir" = SOUTH)
+
+/obj/structure/falsewall/iron/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //two sheets of metal, two rods; special assumption
+ return list("operation_time" = 50, "new_obj_type" = /obj/structure/falsewall/brass, "power_cost" = POWER_WALL_MINUS_FLOOR - (POWER_METAL * 2) - (POWER_ROD * 2), "spawn_dir" = SOUTH)
+
+/obj/structure/falsewall/reinforced/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+/obj/structure/falsewall/brass/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+//Metal conversion
+/obj/item/stack/tile/plasteel/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ if(source)
+ return FALSE
+ var/amount_temp = get_amount()
+ var/no_delete = FALSE
+ if(amount_temp < 2)
+ to_chat(user, "You need at least 2 floor tiles to convert into power.")
+ return TRUE
+ if(IsOdd(amount_temp))
+ amount_temp--
+ no_delete = TRUE
+ use(amount_temp)
+ amount_temp *= 12.5 //each tile is 12.5 power so this is 2 tiles to 25 power
+ consume_visual(fabricator, amount_temp)
+ return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = -amount_temp, "spawn_dir" = SOUTH, "no_target_deletion" = no_delete)
+
+/obj/item/stack/rods/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ if(source)
+ return FALSE
+ var/power_amount = -(amount*POWER_ROD)
+ consume_visual(fabricator, power_amount)
+ return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH)
+
+/obj/item/stack/sheet/metal/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ if(source)
+ return FALSE
+ var/power_amount = -(amount*POWER_METAL)
+ consume_visual(fabricator, power_amount)
+ return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH)
+
+/obj/item/stack/sheet/plasteel/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ if(source)
+ return FALSE
+ var/power_amount = -(amount*POWER_PLASTEEL)
+ consume_visual(fabricator, power_amount)
+ return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH)
+
+//Brass directly to power
+/obj/item/stack/tile/brass/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ if(source)
+ return FALSE
+ var/power_amount = -(amount*POWER_FLOOR)
+ consume_visual(fabricator, power_amount)
+ return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH)
+
+//Airlock conversion
+/obj/machinery/door/airlock/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ var/doortype = /obj/machinery/door/airlock/clockwork
+ if(glass)
+ doortype = /obj/machinery/door/airlock/clockwork/brass
+ return list("operation_time" = 60, "new_obj_type" = doortype, "power_cost" = POWER_WALL_TOTAL, "spawn_dir" = dir)
+
+/obj/machinery/door/airlock/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+//Table conversion
+/obj/structure/table/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ var/fabrication_cost = POWER_STANDARD
+ if(framestack == /obj/item/stack/rods)
+ fabrication_cost -= POWER_ROD*framestackamount
+ else if(framestack == /obj/item/stack/tile/brass)
+ fabrication_cost -= POWER_FLOOR*framestackamount
+ if(buildstack == /obj/item/stack/sheet/metal)
+ fabrication_cost -= POWER_METAL*buildstackamount
+ else if(buildstack == /obj/item/stack/sheet/plasteel)
+ fabrication_cost -= POWER_PLASTEEL*buildstackamount
+ return list("operation_time" = 20, "new_obj_type" = /obj/structure/table/reinforced/brass, "power_cost" = fabrication_cost, "spawn_dir" = SOUTH)
+
+/obj/structure/table/reinforced/brass/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+/obj/structure/table_frame/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ var/fabrication_cost = POWER_FLOOR
+ if(framestack == /obj/item/stack/rods)
+ fabrication_cost -= POWER_ROD*framestackamount
+ else if(framestack == /obj/item/stack/tile/brass)
+ fabrication_cost -= POWER_FLOOR*framestackamount
+ return list("operation_time" = 10, "new_obj_type" = /obj/structure/table_frame/brass, "power_cost" = fabrication_cost, "spawn_dir" = SOUTH)
+
+/obj/structure/table_frame/brass/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+//Window conversion
+/obj/structure/window/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ var/windowtype = /obj/structure/window/reinforced/clockwork
+ var/new_dir = TRUE
+ var/fabrication_time = 15
+ var/fabrication_cost = POWER_FLOOR
+ if(fulltile)
+ windowtype = /obj/structure/window/reinforced/clockwork/fulltile
+ new_dir = FALSE
+ fabrication_time = 30
+ fabrication_cost = POWER_STANDARD
+ if(reinf)
+ fabrication_cost -= POWER_ROD
+ if(reinf)
+ fabrication_cost -= POWER_ROD
+ for(var/obj/structure/grille/G in get_turf(src))
+ INVOKE_ASYNC(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricate, G, user)
+ return list("operation_time" = fabrication_time, "new_obj_type" = windowtype, "power_cost" = fabrication_cost, "spawn_dir" = dir, "dir_in_new" = new_dir)
+
+/obj/structure/window/reinforced/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+//Windoor conversion
+/obj/machinery/door/window/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return list("operation_time" = 30, "new_obj_type" = /obj/machinery/door/window/clockwork, "power_cost" = POWER_STANDARD, "spawn_dir" = dir, "dir_in_new" = TRUE)
+
+/obj/machinery/door/window/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+//Grille conversion
+/obj/structure/grille/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ var/grilletype = /obj/structure/grille/ratvar
+ var/fabrication_time = 15
+ if(broken)
+ grilletype = /obj/structure/grille/ratvar/broken
+ fabrication_time = 5
+ return list("operation_time" = fabrication_time, "new_obj_type" = grilletype, "power_cost" = 0, "spawn_dir" = dir)
+
+/obj/structure/grille/ratvar/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+//Lattice conversion
+/obj/structure/lattice/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return list("operation_time" = 0, "new_obj_type" = /obj/structure/lattice/clockwork, "power_cost" = 0, "spawn_dir" = SOUTH, "no_target_deletion" = TRUE)
+
+/obj/structure/lattice/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ ratvar_act() //just in case we're the wrong type for some reason??
+ return FALSE
+
+/obj/structure/lattice/catwalk/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return list("operation_time" = 0, "new_obj_type" = /obj/structure/lattice/catwalk/clockwork, "power_cost" = 0, "spawn_dir" = SOUTH, "no_target_deletion" = TRUE)
+
+/obj/structure/lattice/catwalk/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ return FALSE
+
+//Girder conversion
+/obj/structure/girder/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ var/fabrication_cost = POWER_GEAR - (POWER_METAL * 2)
+ if(state == GIRDER_REINF_STRUTS || state == GIRDER_REINF)
+ fabrication_cost -= POWER_PLASTEEL
+ return list("operation_time" = 20, "new_obj_type" = /obj/structure/destructible/clockwork/wall_gear, "power_cost" = fabrication_cost, "spawn_dir" = SOUTH)
+
+//Hitting a clockwork structure will try to repair it.
+/obj/structure/destructible/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ . = TRUE
+ var/list/repair_values = list()
+ if(!fabricator.fabricator_repair_checks(repair_values, src, user))
+ return
+ user.visible_message("[user]'s [fabricator.name] starts covering [src] in glowing orange energy...", \
+ "You start repairing [src]...")
+ fabricator.repairing = src
+ while(fabricator && user && src)
+ if(!do_after(user, repair_values["healing_for_cycle"] * fabricator.speed_multiplier, target = src, \
+ extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricator_repair_checks, repair_values, src, user, TRUE)))
+ break
+ obj_integrity = Clamp(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity)
+ fabricator.modify_stored_power(-repair_values["power_required"])
+ playsound(src, 'sound/machines/click.ogg', 50, 1)
+
+ if(fabricator)
+ fabricator.repairing = null
+ if(user)
+ user.visible_message("[user]'s [fabricator.name] stops covering [src] with glowing orange energy.", \
+ "You finish repairing [src]. It is now at [obj_integrity]/[max_integrity] integrity.")
+
+//Hitting a sigil of transmission will try to charge from it.
+/obj/effect/clockwork/sigil/transmission/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ . = TRUE
+ var/list/charge_values = list()
+ if(!fabricator.sigil_charge_checks(charge_values, src, user))
+ return
+ user.visible_message("[user]'s [fabricator.name] starts draining glowing orange energy from [src]...", \
+ "You start recharging your [fabricator.name]...")
+ fabricator.recharging = src
+ while(fabricator && user && src)
+ if(!do_after(user, 10, target = src, extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/sigil_charge_checks, charge_values, src, user, TRUE)))
+ break
+ modify_charge(charge_values["power_gain"])
+ fabricator.modify_stored_power(charge_values["power_gain"])
+ playsound(src, 'sound/effects/light_flicker.ogg', charge_values["power_gain"] * 0.1, 1)
+
+ if(fabricator)
+ fabricator.recharging = null
+ if(user)
+ user.visible_message("[user]'s [fabricator.name] stops draining glowing orange energy from [src].", \
+ "You finish recharging your [fabricator.name]. It now contains [fabricator.get_power()]W/[fabricator.get_max_power()]W power.")
+
+//Fabricator mob heal proc, to avoid as much copypaste as possible.
+/mob/living/proc/fabricator_heal(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator)
+ var/list/repair_values = list()
+ if(!fabricator.fabricator_repair_checks(repair_values, src, user))
+ return
+ user.visible_message("[user]'s [fabricator.name] starts coverin[src == user ? "g [user.p_them()]" : "g [src]"] in glowing orange energy...", \
+ "You start repairin[src == user ? "g yourself" : "g [src]"]...")
+ fabricator.repairing = src
+ while(fabricator && user && src)
+ if(!do_after(user, repair_values["healing_for_cycle"] * fabricator.speed_multiplier, target = src, \
+ extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricator_repair_checks, repair_values, src, user, TRUE)))
+ break
+ fabricator_heal_tick(repair_values["healing_for_cycle"])
+ fabricator.modify_stored_power(-repair_values["power_required"])
+ playsound(src, 'sound/machines/click.ogg', 50, 1)
+
+ if(fabricator)
+ fabricator.repairing = null
+
+ return TRUE
+
+/mob/living/proc/fabricator_heal_tick(amount)
+ var/static/list/damage_heal_order = list(BRUTE, BURN, TOX, OXY)
+ heal_ordered_damage(amount, damage_heal_order)
+
+/mob/living/simple_animal/fabricator_heal_tick(amount)
+ adjustHealth(-amount)
+
+//Hitting a ratvar'd silicon will also try to repair it.
+/mob/living/silicon/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ . = TRUE
+ if(health == maxHealth) //if we're at maximum health, replace the turf under us
+ return FALSE
+ else if(fabricator_heal(user, fabricator) && user)
+ user.visible_message("[user]'s [fabricator.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.", \
+ "You finish repairin[src == user ? "g yourself. You are":"g [src]. [p_they(TRUE)] [p_are()]"] now at [abs(HEALTH_THRESHOLD_DEAD - health)]/[abs(HEALTH_THRESHOLD_DEAD - maxHealth)] health.")
+
+//Same with clockwork mobs.
+/mob/living/simple_animal/hostile/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ . = TRUE
+ if(health == maxHealth) //if we're at maximum health, replace the turf under us
+ return FALSE
+ else if(fabricator_heal(user, fabricator) && user)
+ user.visible_message("[user]'s [fabricator.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.", \
+ "You finish repairin[src == user ? "g yourself. You are":"g [src]. [p_they(TRUE)] [p_are()]"] now at [health]/[maxHealth] health.")
+
+//Cogscarabs get special interaction because they're drones and have innate self-heals/revives.
+/mob/living/simple_animal/drone/cogscarab/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
+ . = TRUE
+ if(stat == DEAD)
+ try_reactivate(user) //if we're dead, try to repair us
+ return
+ if(health == maxHealth)
+ return FALSE
+ else if(!(flags & GODMODE))
+ user.visible_message("[user]'s [fabricator.name] starts coverin[src == user ? "g [user.p_them()]" : "g [src]"] in glowing orange energy...", \
+ "You start repairin[src == user ? "g yourself" : "g [src]"]...")
+ fabricator.repairing = src
+ if(do_after(user, (maxHealth - health)*2, target=src))
+ adjustHealth(-maxHealth)
+ user.visible_message("[user]'s [fabricator.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.", \
+ "You finish repairin[src == user ? "g yourself" : "g [src]"].")
+ if(fabricator)
+ fabricator.repairing = null
+
+//Convert shards and gear bits directly to power
+/obj/item/clockwork/alloy_shards/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount)
+ if(!power_amount)
+ power_amount = -POWER_STANDARD
+ consume_visual(fabricator, power_amount)
+ if(!silent) //looper no looping
+ for(var/obj/item/clockwork/alloy_shards/S in get_turf(src)) //convert all other shards in the turf if we can
+ if(S == src)
+ continue //we want the shards to be fabricated after the main shard, thus this delay
+ addtimer(CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricate, S, user, TRUE), 0)
+ return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH)
+
+/obj/item/clockwork/alloy_shards/medium/gear_bit/large/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount)
+ if(!power_amount)
+ power_amount = -(CLOCKCULT_POWER_UNIT*0.08)
+ return ..()
+
+/obj/item/clockwork/alloy_shards/large/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount)
+ if(!power_amount)
+ power_amount = -(CLOCKCULT_POWER_UNIT*0.06)
+ return ..()
+
+/obj/item/clockwork/alloy_shards/medium/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount)
+ if(!power_amount)
+ power_amount = -(CLOCKCULT_POWER_UNIT*0.04)
+ return ..()
+
+/obj/item/clockwork/alloy_shards/small/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount)
+ if(!power_amount)
+ power_amount = -(CLOCKCULT_POWER_UNIT*0.02)
+ return ..()
diff --git a/code/game/gamemodes/clock_cult/clock_helpers/hierophant_network.dm b/code/game/gamemodes/clock_cult/clock_helpers/hierophant_network.dm
index 29f2363e402..16759c0f1ca 100644
--- a/code/game/gamemodes/clock_cult/clock_helpers/hierophant_network.dm
+++ b/code/game/gamemodes/clock_cult/clock_helpers/hierophant_network.dm
@@ -28,7 +28,7 @@
desc = "Allows you to communicate with other Servants."
button_icon_state = "hierophant"
background_icon_state = "bg_clock"
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
buttontooltipstyle = "clockcult"
var/title = "Servant"
var/span_for_name = "heavy_brass"
diff --git a/code/game/gamemodes/clock_cult/clock_helpers/proselytizer_helpers.dm b/code/game/gamemodes/clock_cult/clock_helpers/proselytizer_helpers.dm
deleted file mode 100644
index fc448a68b46..00000000000
--- a/code/game/gamemodes/clock_cult/clock_helpers/proselytizer_helpers.dm
+++ /dev/null
@@ -1,409 +0,0 @@
-//For the clockwork proselytizer, this proc exists to make it easy to customize what the proselytizer does when hitting something.
-
-//if a valid target, returns an associated list in this format;
-//list("operation_time" = 15, "new_obj_type" = /obj/structure/window/reinforced/clockwork, "power_cost" = 5, "spawn_dir" = dir, "dir_in_new" = TRUE)
-//otherwise, return literally any non-list thing but preferably FALSE
-//returning TRUE won't produce the "cannot be proselytized" message and will still prevent proselytizing
-
-/atom/proc/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-//Turf conversion
-/turf/closed/wall/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent) //four sheets of metal
- return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 4), "spawn_dir" = SOUTH)
-
-/turf/closed/wall/mineral/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent) //two sheets of metal
- return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2), "spawn_dir" = SOUTH)
-
-/turf/closed/wall/mineral/iron/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent) //two sheets of metal, five rods
- return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2) - (POWER_ROD * 5), "spawn_dir" = SOUTH)
-
-/turf/closed/wall/mineral/cult/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent) //no metal
- return list("operation_time" = 80, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL, "spawn_dir" = SOUTH)
-
-/turf/closed/wall/shuttle/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent) //two sheets of metal
- return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2), "spawn_dir" = SOUTH)
-
-/turf/closed/wall/r_wall/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-/turf/closed/wall/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return list("operation_time" = 50, "new_obj_type" = /turf/open/floor/clockwork, "power_cost" = -POWER_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
-
-/turf/open/floor/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- if(floor_tile == /obj/item/stack/tile/plasteel)
- new floor_tile(src)
- make_plating()
- playsound(src, 'sound/items/Crowbar.ogg', 10, 1) //clink
- return list("operation_time" = 30, "new_obj_type" = /turf/open/floor/clockwork, "power_cost" = POWER_FLOOR, "spawn_dir" = SOUTH)
-
-/turf/open/floor/plating/asteroid/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-/turf/open/floor/plating/ashplanet/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-/turf/open/floor/plating/lava/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-/turf/open/floor/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- if(locate(/obj/structure/table) in src)
- return FALSE
- if(is_blocked_turf(src, TRUE))
- to_chat(user, "Something is in the way, preventing you from proselytizing [src] into a clockwork wall.")
- return TRUE
- var/operation_time = 100
- if(!GLOB.ratvar_awakens && proselytizer.speed_multiplier > 0) //if ratvar isn't awake, this always takes 10 seconds
- operation_time /= proselytizer.speed_multiplier
- return list("operation_time" = operation_time, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
-
-//False wall conversion
-/obj/structure/falsewall/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- var/cost = POWER_WALL_MINUS_FLOOR
- if(ispath(mineral, /obj/item/stack/sheet/metal))
- cost -= (POWER_METAL * (2 + mineral_amount)) //four sheets of metal, plus an assumption that the girder is also two
- else
- cost -= (POWER_METAL * 2) //anything that doesn't use metal just has the girder
- return list("operation_time" = 50, "new_obj_type" = /obj/structure/falsewall/brass, "power_cost" = cost, "spawn_dir" = SOUTH)
-
-/obj/structure/falsewall/iron/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent) //two sheets of metal, two rods; special assumption
- return list("operation_time" = 50, "new_obj_type" = /obj/structure/falsewall/brass, "power_cost" = POWER_WALL_MINUS_FLOOR - (POWER_METAL * 2) - (POWER_ROD * 2), "spawn_dir" = SOUTH)
-
-/obj/structure/falsewall/reinforced/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-/obj/structure/falsewall/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-//Metal conversion
-/obj/item/stack/tile/plasteel/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- if(source)
- return FALSE
- var/amount_temp = get_amount()
- if(proselytizer.metal_to_power)
- var/no_delete = FALSE
- if(amount_temp < 2)
- to_chat(user, "You need at least 2 floor tiles to convert into power.")
- return TRUE
- if(IsOdd(amount_temp))
- amount_temp--
- no_delete = TRUE
- use(amount_temp)
- amount_temp *= 12.5 //each tile is 12.5 power so this is 2 tiles to 25 power
- return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -amount_temp, "spawn_dir" = SOUTH, "no_target_deletion" = no_delete)
- if(amount_temp >= 20)
- var/sheets_to_make = round(amount_temp * 0.05) //and 20 to 1 brass
- var/used = sheets_to_make * 20
- user.visible_message("[user]'s [proselytizer.name] rips into [src], converting it to brass!", \
- "You convert [get_amount() - used > 0 ? "part of ":""][src] into brass...")
- playsound(src, 'sound/machines/click.ogg', 50, 1)
- playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
- new /obj/item/stack/tile/brass(get_turf(src), sheets_to_make)
- use(used)
- else
- to_chat(user, "You need at least 20 floor tiles to convert into brass.")
- return TRUE
-
-/obj/item/stack/rods/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- if(source)
- return FALSE
- if(proselytizer.metal_to_power)
- return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_ROD), "spawn_dir" = SOUTH)
- if(get_amount() >= 10)
- var/sheets_to_make = round(get_amount() * 0.1)
- var/used = sheets_to_make * 10
- user.visible_message("[user]'s [proselytizer.name] rips into [src], converting it to brass!", \
- "You convert [get_amount() - used > 0 ? "part of ":""][src] into brass...")
- playsound(src, 'sound/machines/click.ogg', 50, 1)
- playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
- new /obj/item/stack/tile/brass(get_turf(src), sheets_to_make)
- use(used)
- else
- to_chat(user, "You need at least 10 rods to convert into brass.")
- return TRUE
-
-/obj/item/stack/sheet/metal/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- if(source)
- return FALSE
- if(proselytizer.metal_to_power)
- return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_METAL), "spawn_dir" = SOUTH)
- if(get_amount() >= 5)
- var/sheets_to_make = round(get_amount() * 0.2)
- var/used = sheets_to_make * 5
- user.visible_message("[user]'s [proselytizer.name] rips into [src], converting it to brass!", \
- "You convert [get_amount() - used > 0 ? "part of ":""][src] into brass...")
- playsound(src, 'sound/machines/click.ogg', 50, 1)
- playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
- new /obj/item/stack/tile/brass(get_turf(src), sheets_to_make)
- use(used)
- else
- to_chat(user, "You need at least 5 sheets of metal to convert into brass.")
- return TRUE
-
-/obj/item/stack/sheet/plasteel/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- if(source)
- return FALSE
- if(proselytizer.metal_to_power)
- return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_PLASTEEL), "spawn_dir" = SOUTH)
- if(get_amount() >= 2)
- var/sheets_to_make = round(get_amount() * 0.5)
- var/used = sheets_to_make * 2
- user.visible_message("[user]'s [proselytizer.name] rips into [src], converting it to brass!", \
- "You convert [get_amount() - used > 0 ? "part of ":""][src] into brass...")
- playsound(src, 'sound/machines/click.ogg', 50, 1)
- playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
- new /obj/item/stack/tile/brass(get_turf(src), sheets_to_make)
- use(used)
- else
- to_chat(user, "You need at least 2 sheets of plasteel to convert into brass.")
- return TRUE
-
-//Brass directly to power
-/obj/item/stack/tile/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- if(source)
- return FALSE
- return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_FLOOR), "spawn_dir" = SOUTH)
-
-//Airlock conversion
-/obj/machinery/door/airlock/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- var/doortype = /obj/machinery/door/airlock/clockwork
- if(glass)
- doortype = /obj/machinery/door/airlock/clockwork/brass
- return list("operation_time" = 60, "new_obj_type" = doortype, "power_cost" = POWER_WALL_TOTAL, "spawn_dir" = dir)
-
-/obj/machinery/door/airlock/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-//Table conversion
-/obj/structure/table/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- var/prosel_cost = POWER_STANDARD
- if(framestack == /obj/item/stack/rods)
- prosel_cost -= POWER_ROD*framestackamount
- else if(framestack == /obj/item/stack/tile/brass)
- prosel_cost -= POWER_FLOOR*framestackamount
- if(buildstack == /obj/item/stack/sheet/metal)
- prosel_cost -= POWER_METAL*buildstackamount
- else if(buildstack == /obj/item/stack/sheet/plasteel)
- prosel_cost -= POWER_PLASTEEL*buildstackamount
- return list("operation_time" = 20, "new_obj_type" = /obj/structure/table/reinforced/brass, "power_cost" = prosel_cost, "spawn_dir" = SOUTH)
-
-/obj/structure/table/reinforced/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-/obj/structure/table_frame/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- var/prosel_cost = POWER_FLOOR
- if(framestack == /obj/item/stack/rods)
- prosel_cost -= POWER_ROD*framestackamount
- else if(framestack == /obj/item/stack/tile/brass)
- prosel_cost -= POWER_FLOOR*framestackamount
- return list("operation_time" = 10, "new_obj_type" = /obj/structure/table_frame/brass, "power_cost" = prosel_cost, "spawn_dir" = SOUTH)
-
-/obj/structure/table_frame/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-//Window conversion
-/obj/structure/window/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- var/windowtype = /obj/structure/window/reinforced/clockwork
- var/new_dir = TRUE
- var/prosel_time = 15
- var/prosel_cost = POWER_FLOOR
- if(fulltile)
- windowtype = /obj/structure/window/reinforced/clockwork/fulltile
- new_dir = FALSE
- prosel_time = 30
- prosel_cost = POWER_STANDARD
- if(reinf)
- prosel_cost -= POWER_ROD
- if(reinf)
- prosel_cost -= POWER_ROD
- for(var/obj/structure/grille/G in get_turf(src))
- INVOKE_ASYNC(proselytizer, /obj/item/clockwork/clockwork_proselytizer.proc/proselytize, G, user)
- return list("operation_time" = prosel_time, "new_obj_type" = windowtype, "power_cost" = prosel_cost, "spawn_dir" = dir, "dir_in_new" = new_dir)
-
-/obj/structure/window/reinforced/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-//Windoor conversion
-/obj/machinery/door/window/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return list("operation_time" = 30, "new_obj_type" = /obj/machinery/door/window/clockwork, "power_cost" = POWER_STANDARD, "spawn_dir" = dir, "dir_in_new" = TRUE)
-
-/obj/machinery/door/window/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-//Grille conversion
-/obj/structure/grille/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- var/grilletype = /obj/structure/grille/ratvar
- var/prosel_time = 15
- if(broken)
- grilletype = /obj/structure/grille/ratvar/broken
- prosel_time = 5
- return list("operation_time" = prosel_time, "new_obj_type" = grilletype, "power_cost" = 0, "spawn_dir" = dir)
-
-/obj/structure/grille/ratvar/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-//Lattice conversion
-/obj/structure/lattice/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return list("operation_time" = 0, "new_obj_type" = /obj/structure/lattice/clockwork, "power_cost" = 0, "spawn_dir" = SOUTH, "no_target_deletion" = TRUE)
-
-/obj/structure/lattice/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- ratvar_act() //just in case we're the wrong type for some reason??
- return FALSE
-
-/obj/structure/lattice/catwalk/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return list("operation_time" = 0, "new_obj_type" = /obj/structure/lattice/catwalk/clockwork, "power_cost" = 0, "spawn_dir" = SOUTH, "no_target_deletion" = TRUE)
-
-/obj/structure/lattice/catwalk/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- return FALSE
-
-//Girder conversion
-/obj/structure/girder/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- var/prosel_cost = POWER_GEAR - (POWER_METAL * 2)
- if(state == GIRDER_REINF_STRUTS || state == GIRDER_REINF)
- prosel_cost -= POWER_PLASTEEL
- return list("operation_time" = 20, "new_obj_type" = /obj/structure/destructible/clockwork/wall_gear, "power_cost" = prosel_cost, "spawn_dir" = SOUTH)
-
-//Hitting a clockwork structure will try to repair it.
-/obj/structure/destructible/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- . = TRUE
- var/list/repair_values = list()
- if(!proselytizer.proselytizer_repair_checks(repair_values, src, user))
- return
- user.visible_message("[user]'s [proselytizer.name] starts covering [src] in glowing orange energy...", \
- "You start repairing [src]...")
- proselytizer.repairing = src
- while(proselytizer && user && src)
- if(!do_after(user, repair_values["healing_for_cycle"] * proselytizer.speed_multiplier, target = src, \
- extra_checks = CALLBACK(proselytizer, /obj/item/clockwork/clockwork_proselytizer.proc/proselytizer_repair_checks, repair_values, src, user, TRUE)))
- break
- obj_integrity = Clamp(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity)
- proselytizer.modify_stored_power(-repair_values["power_required"])
- playsound(src, 'sound/machines/click.ogg', 50, 1)
-
- if(proselytizer)
- proselytizer.repairing = null
- if(user)
- user.visible_message("[user]'s [proselytizer.name] stops covering [src] with glowing orange energy.", \
- "You finish repairing [src]. It is now at [obj_integrity]/[max_integrity] integrity.")
-
-//Hitting a sigil of transmission will try to charge from it.
-/obj/effect/clockwork/sigil/transmission/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- . = TRUE
- var/list/charge_values = list()
- if(!proselytizer.sigil_charge_checks(charge_values, src, user))
- return
- user.visible_message("[user]'s [proselytizer.name] starts draining glowing orange energy from [src]...", \
- "You start recharging your [proselytizer.name]...")
- proselytizer.recharging = src
- while(proselytizer && user && src)
- if(!do_after(user, 10, target = src, extra_checks = CALLBACK(proselytizer, /obj/item/clockwork/clockwork_proselytizer.proc/sigil_charge_checks, charge_values, src, user, TRUE)))
- break
- modify_charge(charge_values["power_gain"])
- proselytizer.modify_stored_power(charge_values["power_gain"])
- playsound(src, 'sound/effects/light_flicker.ogg', charge_values["power_gain"] * 0.1, 1)
-
- if(proselytizer)
- proselytizer.recharging = null
- if(user)
- user.visible_message("[user]'s [proselytizer.name] stops draining glowing orange energy from [src].", \
- "You finish recharging your [proselytizer.name]. It now contains [proselytizer.get_power()]W/[proselytizer.get_max_power()]W power.")
-
-//Proselytizer mob heal proc, to avoid as much copypaste as possible.
-/mob/living/proc/proselytizer_heal(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
- var/list/repair_values = list()
- if(!proselytizer.proselytizer_repair_checks(repair_values, src, user))
- return
- user.visible_message("[user]'s [proselytizer.name] starts coverin[src == user ? "g [user.p_them()]" : "g [src]"] in glowing orange energy...", \
- "You start repairin[src == user ? "g yourself" : "g [src]"]...")
- proselytizer.repairing = src
- while(proselytizer && user && src)
- if(!do_after(user, repair_values["healing_for_cycle"] * proselytizer.speed_multiplier, target = src, \
- extra_checks = CALLBACK(proselytizer, /obj/item/clockwork/clockwork_proselytizer.proc/proselytizer_repair_checks, repair_values, src, user, TRUE)))
- break
- proselytizer_heal_tick(repair_values["healing_for_cycle"])
- proselytizer.modify_stored_power(-repair_values["power_required"])
- playsound(src, 'sound/machines/click.ogg', 50, 1)
-
- if(proselytizer)
- proselytizer.repairing = null
-
- return TRUE
-
-/mob/living/proc/proselytizer_heal_tick(amount)
- var/static/list/damage_heal_order = list(BRUTE, BURN, TOX, OXY)
- heal_ordered_damage(amount, damage_heal_order)
-
-/mob/living/simple_animal/proselytizer_heal_tick(amount)
- adjustHealth(-amount)
-
-//Hitting a ratvar'd silicon will also try to repair it.
-/mob/living/silicon/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- . = TRUE
- if(health == maxHealth) //if we're at maximum health, prosel the turf under us
- return FALSE
- else if(proselytizer_heal(user, proselytizer) && user)
- user.visible_message("[user]'s [proselytizer.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.", \
- "You finish repairin[src == user ? "g yourself. You are":"g [src]. [p_they(TRUE)] [p_are()]"] now at [abs(HEALTH_THRESHOLD_DEAD - health)]/[abs(HEALTH_THRESHOLD_DEAD - maxHealth)] health.")
-
-//Same with clockwork mobs.
-/mob/living/simple_animal/hostile/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- . = TRUE
- if(health == maxHealth) //if we're at maximum health, prosel the turf under us
- return FALSE
- else if(proselytizer_heal(user, proselytizer) && user)
- user.visible_message("[user]'s [proselytizer.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.", \
- "You finish repairin[src == user ? "g yourself. You are":"g [src]. [p_they(TRUE)] [p_are()]"] now at [health]/[maxHealth] health.")
-
-//Cogscarabs get special interaction because they're drones and have innate self-heals/revives.
-/mob/living/simple_animal/drone/cogscarab/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
- . = TRUE
- if(stat == DEAD)
- try_reactivate(user) //if we're at maximum health, prosel the turf under us
- return
- if(health == maxHealth)
- return FALSE
- else if(!(flags & GODMODE))
- user.visible_message("[user]'s [proselytizer.name] starts coverin[src == user ? "g [user.p_them()]" : "g [src]"] in glowing orange energy...", \
- "You start repairin[src == user ? "g yourself" : "g [src]"]...")
- proselytizer.repairing = src
- if(do_after(user, (maxHealth - health)*2, target=src))
- adjustHealth(-maxHealth)
- user.visible_message("[user]'s [proselytizer.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.", \
- "You finish repairin[src == user ? "g yourself" : "g [src]"].")
- if(proselytizer)
- proselytizer.repairing = null
-
-//Convert shards and gear bits directly to power
-/obj/item/clockwork/alloy_shards/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent, power_amount)
- if(!power_amount)
- power_amount = -POWER_STANDARD
- if(proselytizer.can_use_power(power_amount))
- var/obj/effect/temp_visual/ratvar/beam/itemconsume/B = new /obj/effect/temp_visual/ratvar/beam/itemconsume(get_turf(src))
- B.pixel_x = pixel_x
- B.pixel_y = pixel_y
- if(!silent) //looper no looping
- for(var/obj/item/clockwork/alloy_shards/S in get_turf(src)) //convert all other shards in the turf if we can
- if(S == src)
- continue //we want the shards to be proselytized after the main shard, thus this delay
- addtimer(CALLBACK(proselytizer, /obj/item/clockwork/clockwork_proselytizer.proc/proselytize, S, user, TRUE), 0)
- return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH)
-
-/obj/item/clockwork/alloy_shards/medium/gear_bit/large/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent, power_amount)
- if(!power_amount)
- power_amount = -(CLOCKCULT_POWER_UNIT*0.08)
- return ..()
-
-/obj/item/clockwork/alloy_shards/large/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent, power_amount)
- if(!power_amount)
- power_amount = -(CLOCKCULT_POWER_UNIT*0.06)
- return ..()
-
-/obj/item/clockwork/alloy_shards/medium/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent, power_amount)
- if(!power_amount)
- power_amount = -(CLOCKCULT_POWER_UNIT*0.04)
- return ..()
-
-/obj/item/clockwork/alloy_shards/small/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent, power_amount)
- if(!power_amount)
- power_amount = -(CLOCKCULT_POWER_UNIT*0.02)
- return ..()
diff --git a/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm b/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm
index e5d193d74a5..d6e56f38d5d 100644
--- a/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm
+++ b/code/game/gamemodes/clock_cult/clock_helpers/scripture_checks.dm
@@ -5,15 +5,16 @@
for(var/mob/living/M in GLOB.living_mob_list)
if(is_servant_of_ratvar(M) && (ishuman(M) || issilicon(M)))
servants++
- . = list(SCRIPTURE_DRIVER = TRUE, SCRIPTURE_SCRIPT = FALSE, SCRIPTURE_APPLICATION = FALSE, SCRIPTURE_REVENANT = FALSE, SCRIPTURE_JUDGEMENT = FALSE)
+ . = list(SCRIPTURE_DRIVER = TRUE, SCRIPTURE_SCRIPT = FALSE, SCRIPTURE_APPLICATION = FALSE, SCRIPTURE_JUDGEMENT = FALSE)
//Drivers: always unlocked
- .[SCRIPTURE_SCRIPT] = (servants >= SCRIPT_SERVANT_REQ && GLOB.clockwork_caches >= SCRIPT_CACHE_REQ)
+ .[SCRIPTURE_SCRIPT] = (SSticker.scripture_states[SCRIPTURE_SCRIPT] || \
+ (servants >= SCRIPT_SERVANT_REQ && GLOB.clockwork_caches >= SCRIPT_CACHE_REQ))
//Script: SCRIPT_SERVANT_REQ or more non-brain servants and SCRIPT_CACHE_REQ or more clockwork caches
- .[SCRIPTURE_APPLICATION] = (servants >= APPLICATION_SERVANT_REQ && GLOB.clockwork_caches >= APPLICATION_CACHE_REQ && GLOB.clockwork_construction_value >= APPLICATION_CV_REQ)
+ .[SCRIPTURE_APPLICATION] = (SSticker.scripture_states[SCRIPTURE_APPLICATION] || \
+ (servants >= APPLICATION_SERVANT_REQ && GLOB.clockwork_caches >= APPLICATION_CACHE_REQ && GLOB.clockwork_construction_value >= APPLICATION_CV_REQ))
//Application: APPLICATION_SERVANT_REQ or more non-brain servants, APPLICATION_CACHE_REQ or more clockwork caches, and at least APPLICATION_CV_REQ CV
- .[SCRIPTURE_REVENANT] = (servants >= REVENANT_SERVANT_REQ && GLOB.clockwork_caches >= REVENANT_CACHE_REQ && GLOB.clockwork_construction_value >= REVENANT_CV_REQ)
- //Revenant: REVENANT_SERVANT_REQ or more non-brain servants, REVENANT_CACHE_REQ or more clockwork caches, and at least REVENANT_CV_REQ CV
- .[SCRIPTURE_JUDGEMENT] = (servants >= JUDGEMENT_SERVANT_REQ && GLOB.clockwork_caches >= JUDGEMENT_CACHE_REQ && GLOB.clockwork_construction_value >= JUDGEMENT_CV_REQ && !unconverted_ai_exists)
+ .[SCRIPTURE_JUDGEMENT] = (SSticker.scripture_states[SCRIPTURE_JUDGEMENT] || \
+ (servants >= JUDGEMENT_SERVANT_REQ && GLOB.clockwork_caches >= JUDGEMENT_CACHE_REQ && GLOB.clockwork_construction_value >= JUDGEMENT_CV_REQ && !unconverted_ai_exists))
//Judgement: JUDGEMENT_SERVANT_REQ or more non-brain servants, JUDGEMENT_CACHE_REQ or more clockwork caches, at least JUDGEMENT_CV_REQ CV, and there are no living, non-servant ais
//reports to servants when scripture is locked or unlocked
@@ -21,7 +22,7 @@
. = scripture_unlock_check()
for(var/i in .)
if(.[i] != previous_states[i])
- hierophant_message("Hierophant Network:[i] Scripture has been [.[i] ? "un":""]locked.")
+ hierophant_message("Hierophant Network:[i] Scripture has been [.[i] ? "un":""]locked.") //maybe admins fucked with scripture states?
update_slab_info()
/proc/get_unconverted_ais()
@@ -59,3 +60,6 @@
//changes construction value
/proc/change_construction_value(amount)
GLOB.clockwork_construction_value += amount
+
+/proc/can_recite_scripture(mob/living/L, can_potentially)
+ return (is_servant_of_ratvar(L) && (can_potentially || (L.stat == CONSCIOUS && L.can_speak_vocal())) && (GLOB.ratvar_awakens || (ishuman(L) || issilicon(L))))
diff --git a/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm b/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm
index ccf7aead44a..790088e8d59 100644
--- a/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm
+++ b/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm
@@ -116,28 +116,30 @@
successful = TRUE
+ to_chat(ranged_ability_user, "You bathe [L == ranged_ability_user ? "yourself":"[L]"] in Inath-neq's power!")
var/targetturf = get_turf(L)
+ var/has_holy_water = (L.reagents && L.reagents.has_reagent("holywater"))
+ var/healseverity = max(round(totaldamage*0.05, 1), 1) //shows the general severity of the damage you just healed, 1 glow per 20
+ for(var/i in 1 to healseverity)
+ new /obj/effect/temp_visual/heal(targetturf, "#1E8CE1")
if(totaldamage)
L.adjustBruteLoss(-brutedamage)
L.adjustFireLoss(-burndamage)
L.adjustOxyLoss(-oxydamage)
L.adjustToxLoss(totaldamage * 0.5, TRUE, TRUE)
- var/healseverity = max(round(totaldamage*0.05, 1), 1) //shows the general severity of the damage you just healed, 1 glow per 20
- for(var/i in 1 to healseverity)
- new /obj/effect/temp_visual/heal(targetturf, "#1E8CE1")
- clockwork_say(ranged_ability_user, text2ratvar("Mend wounded flesh!"))
+ clockwork_say(ranged_ability_user, text2ratvar("[has_holy_water ? "Heal tainted" : "Mend wounded"] flesh!"))
add_logs(ranged_ability_user, L, "healed with Sentinel's Compromise")
+ L.visible_message("A blue light washes over [L], [has_holy_water ? "causing [L.p_them()] to briefly glow as it mends" : " mending"] [L.p_their()] bruises and burns!", \
+ "You feel Inath-neq's power healing your wounds[has_holy_water ? " and purging the darkness within you" : ""], but a deep nausea overcomes you!")
else
clockwork_say(ranged_ability_user, text2ratvar("Purge foul darkness!"))
add_logs(ranged_ability_user, L, "purged of holy water with Sentinel's Compromise")
- to_chat(ranged_ability_user, "You bathe [L == ranged_ability_user ? "yourself":"[L]"] in Inath-neq's power!")
- L.visible_message("A blue light washes over [L], mending [L.p_their()] bruises and burns!", \
- "You feel Inath-neq's power healing your wounds, but a deep nausea overcomes you!")
- playsound(targetturf, 'sound/magic/Staff_Healing.ogg', 50, 1)
+ L.visible_message("A blue light washes over [L], causing [L.p_them()] to briefly glow!", \
+ "You feel Inath-neq's power purging the darkness within you!")
+ playsound(targetturf, 'sound/magic/staff_healing.ogg', 50, 1)
- if(L.reagents && L.reagents.has_reagent("holywater"))
+ if(has_holy_water)
L.reagents.remove_reagent("holywater", 1000)
- to_chat(L, "Ratvar's light flares, banishing the darkness. Your devotion remains intact!")
remove_ranged_ability()
@@ -159,22 +161,9 @@
successful = TRUE
ranged_ability_user.visible_message("[ranged_ability_user] fires a ray of energy at [target]!", "You fire a volt ray at [target].")
playsound(ranged_ability_user, 'sound/effects/light_flicker.ogg', 50, 1)
- var/turf/targetturf = get_turf(target)
- var/obj/structure/destructible/clockwork/powered/volt_checker/VC = new/obj/structure/destructible/clockwork/powered/volt_checker(get_turf(ranged_ability_user))
- var/multiplier = 1
- var/usable_power = min(Floor(VC.total_accessable_power() * 0.2, MIN_CLOCKCULT_POWER), 1000)
- if(VC.try_use_power(usable_power))
- multiplier += (usable_power * 0.001) //should be a multiplier of 2 at maximum power usage
- if(iscyborg(ranged_ability_user))
- var/mob/living/silicon/robot/C = ranged_ability_user
- if(C.cell)
- var/prev_power = usable_power //we don't want to increase the multiplier past 2
- usable_power = min(Floor(C.cell.charge * 0.2, MIN_CLOCKCULT_POWER), 1000) - prev_power
- if(usable_power > 0 && C.cell.use(usable_power))
- multiplier += (usable_power * 0.001)
- qdel(VC)
- new/obj/effect/temp_visual/ratvar/volt_hit/true(targetturf, ranged_ability_user, multiplier)
- add_logs(ranged_ability_user, targetturf, "fired a volt ray")
+ T = get_turf(target)
+ new/obj/effect/temp_visual/ratvar/volt_hit(T, ranged_ability_user)
+ add_logs(ranged_ability_user, T, "fired a volt ray")
remove_ranged_ability()
return TRUE
diff --git a/code/game/gamemodes/clock_cult/clock_items/clock_components.dm b/code/game/gamemodes/clock_cult/clock_items/clock_components.dm
index f64b361ac1b..6dec7258f64 100644
--- a/code/game/gamemodes/clock_cult/clock_items/clock_components.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/clock_components.dm
@@ -69,7 +69,7 @@
/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism
name = "onyx prism"
desc = "An onyx prism with a small aperture. It's very heavy."
- clockwork_desc = "A broken prism from a mending motor. Serviceable as a substitute for a vanguard cogwheel."
+ clockwork_desc = "A broken prism from a prolonging prism. Serviceable as a substitute for a vanguard cogwheel."
icon_state = "onyx_prism"
cultist_message = "The prism grows painfully hot in your hands."
servant_of_ratvar_messages = list("The prism isn't getting any lighter." = FALSE, "\"So... you haven't failed yet. Have hope, child.\"" = TRUE, \
@@ -153,11 +153,11 @@
icon_state = "obelisk_prism"
w_class = WEIGHT_CLASS_NORMAL
-//Shards of Alloy, suitable only for proselytization.
+//Shards of Alloy, suitable only as a source of power for a replica fabricator.
/obj/item/clockwork/alloy_shards
name = "replicant alloy shards"
desc = "Broken shards of some oddly malleable metal. They occasionally move and seem to glow."
- clockwork_desc = "Broken shards of replicant alloy. Can be proselytized for additional power."
+ clockwork_desc = "Broken shards of replicant alloy."
icon_state = "alloy_shards"
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/randomsinglesprite = FALSE
@@ -172,10 +172,15 @@
pixel_x = rand(-sprite_shift, sprite_shift)
pixel_y = rand(-sprite_shift, sprite_shift)
+/obj/item/clockwork/alloy_shards/examine(mob/user)
+ ..()
+ if(is_servant_of_ratvar(user) || isobserver(user))
+ to_chat(user, "Can be consumed by a replica fabricator as a source of power.")
+
/obj/item/clockwork/alloy_shards/proc/replace_name_desc()
name = "replicant alloy shard"
desc = "A broken shard of some oddly malleable metal. It occasionally moves and seems to glow."
- clockwork_desc = "A broken shard of replicant alloy. Can be proselytized for additional power."
+ clockwork_desc = "A broken shard of replicant alloy."
/obj/item/clockwork/alloy_shards/large
w_class = WEIGHT_CLASS_TINY
@@ -197,7 +202,7 @@
/obj/item/clockwork/alloy_shards/medium/gear_bit/replace_name_desc()
name = "gear bit"
desc = "A broken chunk of a gear. You want it."
- clockwork_desc = "A broken chunk of a gear. Can be proselytized for additional power."
+ clockwork_desc = "A broken chunk of a gear."
/obj/item/clockwork/alloy_shards/medium/gear_bit/large //gives more power
@@ -215,5 +220,5 @@
/obj/item/clockwork/alloy_shards/pinion_lock
name = "pinion lock"
desc = "A dented and scratched gear. It's very heavy."
- clockwork_desc = "A broken gear lock for pinion airlocks. Can be proselytized for additional power."
+ clockwork_desc = "A broken gear lock for pinion airlocks."
icon_state = "pinion_lock"
diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_armor.dm b/code/game/gamemodes/clock_cult/clock_items/clockwork_armor.dm
index 49c2bb4c135..705c719ddfe 100644
--- a/code/game/gamemodes/clock_cult/clock_items/clockwork_armor.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_armor.dm
@@ -25,7 +25,7 @@
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else
armor = list(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
- flags &= STOPSPRESSUREDMAGE
+ flags &= ~STOPSPRESSUREDMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -37,7 +37,7 @@
user.visible_message("As [user] puts [src] on, it flickers off their head!", "The helmet flickers off your head, leaving only nausea!")
if(iscarbon(user))
var/mob/living/carbon/C = user
- C.vomit(20, 1, 1, 0, 1)
+ C.vomit(20)
else
to_chat(user, "\"Do you have a hole in your head? You're about to.\"")
to_chat(user, "The helmet tries to drive a spike through your head as you scramble to remove it!")
@@ -81,7 +81,7 @@
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else
armor = list(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
- flags &= STOPSPRESSUREDMAGE
+ flags &= ~STOPSPRESSUREDMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -98,7 +98,7 @@
user.visible_message("As [user] puts [src] on, it flickers off their body!", "The curiass flickers off your body, leaving only nausea!")
if(iscarbon(user))
var/mob/living/carbon/C = user
- C.vomit(20, 1, 1, 0, 1)
+ C.vomit(20)
else
to_chat(user, "\"I think this armor is too hot for you to handle.\"")
to_chat(user, "The curiass emits a burst of flame as you scramble to get it off!")
@@ -116,7 +116,7 @@
item_state = "clockwork_gauntlets"
item_color = null //So they don't wash.
strip_delay = 50
- put_on_delay = 30
+ equip_delay_other = 30
body_parts_covered = ARMS
cold_protection = ARMS
heat_protection = ARMS
@@ -142,7 +142,7 @@
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else
armor = list(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
- flags &= STOPSPRESSUREDMAGE
+ flags &= ~STOPSPRESSUREDMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -159,7 +159,7 @@
user.visible_message("As [user] puts [src] on, it flickers off their arms!", "The gauntlets flicker off your arms, leaving only nausea!")
if(iscarbon(user))
var/mob/living/carbon/C = user
- C.vomit(10, 1, 1, 0, 1)
+ C.vomit()
else
to_chat(user, "\"Did you like having arms?\"")
to_chat(user, "The gauntlets suddenly squeeze tight, crushing your arms before you manage to get them off!")
@@ -175,7 +175,7 @@
icon_state = "clockwork_treads"
w_class = WEIGHT_CLASS_NORMAL
strip_delay = 50
- put_on_delay = 30
+ equip_delay_other = 30
resistance_flags = FIRE_PROOF | ACID_PROOF
/obj/item/clothing/shoes/clockwork/Initialize()
@@ -194,7 +194,7 @@
if(GLOB.ratvar_awakens)
flags |= NOSLIP
else
- flags &= NOSLIP
+ flags &= ~NOSLIP
/obj/item/clothing/shoes/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0)
if(equipper && !is_servant_of_ratvar(equipper))
@@ -209,7 +209,7 @@
user.visible_message("As [user] puts [src] on, it flickers off their feet!", "The treads flicker off your feet, leaving only nausea!")
if(iscarbon(user))
var/mob/living/carbon/C = user
- C.vomit(10, 1, 1, 0, 1)
+ C.vomit()
else
to_chat(user, "\"Let's see if you can dance with these.\"")
to_chat(user, "The treads turn searing hot as you scramble to get them off!")
diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm
index 8b3aa01533a..746e72f62f9 100644
--- a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm
@@ -14,7 +14,6 @@
var/target_component_id //the target component ID to create, if any
var/no_cost = FALSE //If the slab is admin-only and needs no components and has no scripture locks
var/speed_multiplier = 1 //multiples how fast this slab recites scripture
- var/nonhuman_usable = FALSE //if the slab can be used by nonhumans, defaults to off
var/produces_components = TRUE //if it produces components at all
var/selected_scripture = SCRIPTURE_DRIVER
var/recollecting = FALSE //if we're looking at fancy recollection
@@ -33,29 +32,24 @@
no_cost = TRUE
produces_components = FALSE
-/obj/item/clockwork/slab/scarab
- nonhuman_usable = TRUE
-
/obj/item/clockwork/slab/debug
speed_multiplier = 0
no_cost = TRUE
- nonhuman_usable = TRUE
/obj/item/clockwork/slab/debug/attack_hand(mob/living/user)
..()
if(!is_servant_of_ratvar(user))
add_servant_of_ratvar(user)
-/obj/item/clockwork/slab/cyborg //three scriptures, plus a spear and proselytizer
+/obj/item/clockwork/slab/cyborg //three scriptures, plus a spear and fabricator
clockwork_desc = "A divine link to the Celestial Derelict, allowing for limited recital of scripture.\n\
Hitting a slab, a Servant with a slab, or a cache will transfer this slab's components into the target, the target's slab, or the global cache, respectively."
- nonhuman_usable = TRUE
quickbound = list(/datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/ranged_ability/linked_vanguard, \
/datum/clockwork_scripture/create_object/tinkerers_cache)
maximum_quickbound = 6 //we usually have one or two unique scriptures, so if ratvar is up let us bind one more
actions_types = list()
-/obj/item/clockwork/slab/cyborg/engineer //five scriptures, plus a proselytizer
+/obj/item/clockwork/slab/cyborg/engineer //five scriptures, plus a fabricator
quickbound = list(/datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/cogscarab, \
/datum/clockwork_scripture/create_object/soul_vessel, /datum/clockwork_scripture/create_object/sigil_of_transmission, /datum/clockwork_scripture/create_object/interdiction_lens)
@@ -65,13 +59,13 @@
/obj/item/clockwork/slab/cyborg/security //four scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/channeled/belligerent, /datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/channeled/taunting_tirade, \
- /datum/clockwork_scripture/channeled/volt_void/cyborg)
+ /datum/clockwork_scripture/channeled/volt_blaster)
/obj/item/clockwork/slab/cyborg/peacekeeper //four scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/channeled/belligerent, /datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/channeled/taunting_tirade, \
- /datum/clockwork_scripture/channeled/volt_void/cyborg)
+ /datum/clockwork_scripture/channeled/volt_blaster)
-/obj/item/clockwork/slab/cyborg/janitor //five scriptures, plus a proselytizer
+/obj/item/clockwork/slab/cyborg/janitor //five scriptures, plus a fabricator
quickbound = list(/datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transgression, \
/datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/mania_motor, /datum/clockwork_scripture/create_object/tinkerers_daemon)
@@ -80,7 +74,7 @@
/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/fellowship_armory, /datum/clockwork_scripture/create_object/clockwork_obelisk)
/obj/item/clockwork/slab/cyborg/miner //three scriptures, plus a spear and xray vision
- quickbound = list(/datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/channeled/volt_void/cyborg)
+ quickbound = list(/datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/channeled/volt_blaster)
/obj/item/clockwork/slab/cyborg/access_display(mob/living/user)
if(!GLOB.ratvar_awakens)
@@ -106,12 +100,6 @@
slab_ability = null
return ..()
-/obj/item/clockwork/slab/ratvar_act()
- if(GLOB.ratvar_awakens)
- nonhuman_usable = TRUE
- else
- nonhuman_usable = initial(nonhuman_usable)
-
/obj/item/clockwork/slab/dropped(mob/user)
. = ..()
addtimer(CALLBACK(src, .proc/check_on_mob, user), 1) //dropped is called before the item is out of the slot, so we need to check slightly later
@@ -138,7 +126,7 @@
production_time = world.time + SLAB_PRODUCTION_TIME + production_slowdown
var/mob/living/L
L = get_atom_on_turf(src, /mob/living)
- if(istype(L) && is_servant_of_ratvar(L) && (nonhuman_usable || ishuman(L)))
+ if(istype(L) && can_recite_scripture(L))
var/component_to_generate = target_component_id
if(!component_to_generate)
component_to_generate = get_weighted_component_id(src) //more likely to generate components that we have less of
@@ -268,7 +256,7 @@
if(busy)
to_chat(user, "[src] refuses to work, displaying the message: \"[busy]!\"")
return 0
- if(!nonhuman_usable && !ishuman(user))
+ if(!can_recite_scripture(user))
to_chat(user, "[src] hums fitfully in your hands, but doesn't seem to do anything...")
return 0
access_display(user)
@@ -288,15 +276,14 @@
ui.open()
/obj/item/clockwork/slab/proc/recite_scripture(datum/clockwork_scripture/scripture, mob/living/user)
- if(!scripture || !user || !user.canUseTopic(src) || (!nonhuman_usable && !ishuman(user)))
+ if(!scripture || !user || !user.canUseTopic(src) || !can_recite_scripture(user))
return FALSE
if(user.get_active_held_item() != src)
to_chat(user, "You need to hold the slab in your active hand to recite scripture!")
return FALSE
var/initial_tier = initial(scripture.tier)
if(initial_tier != SCRIPTURE_PERIPHERAL)
- var/list/tiers_of_scripture = scripture_unlock_check()
- if(!GLOB.ratvar_awakens && !no_cost && !tiers_of_scripture[initial_tier])
+ if(!GLOB.ratvar_awakens && !no_cost && !SSticker.scripture_states[initial_tier])
to_chat(user, "That scripture is not unlocked, and cannot be recited!")
return FALSE
var/datum/clockwork_scripture/scripture_to_recite = new scripture
@@ -356,7 +343,8 @@
repairing, Geis Capacitors are for conversion and control, Replicant Alloy is for construction and fuel, and \
Hierophant Ansibles are for transmission and power, though in combination their effects become more nuanced.
\
\
- There are also five tiers of Scripture; [SCRIPTURE_DRIVER], [SCRIPTURE_SCRIPT], [SCRIPTURE_APPLICATION], [SCRIPTURE_REVENANT], and [SCRIPTURE_JUDGEMENT]. \
+ There are also four tiers of Scripture; [SCRIPTURE_DRIVER], [SCRIPTURE_SCRIPT], \
+ [SCRIPTURE_APPLICATION], and [SCRIPTURE_JUDGEMENT]. \
Each tier has additional requirements, including Servants, Tinkerer's Caches, and Construction Value(CV). Construction Value is gained by creating structures or converting the \
station, and everything too large to hold will grant some amount of it.
\
\
@@ -369,8 +357,8 @@
However, weak is relative when it comes to scripture; even the 'weakest' could be enough to dominate a station in the hands of cunning Servants, and higher tiers of scripture are even \
stronger in the right hands.
\
\
- Some effects of scripture include granting the invoker a temporary complete immunity to stuns, summoning a turret that can attack anything that sets eyes on it, binding a powerful guardian \
- to the invoker, or even, at one of the highest tiers, granting all nearby Servants temporary invulnerability. \
+ Some effects of scripture include granting the invoker a temporary complete immunity to stuns, summoning a turret that can attack anything that sets eyes on it, or even binding a powerful \
+ guardian to the invoker. \
However, the most important scripture is Geis, which allows you to convert heathens with relative ease.
\
\
The second function of the clockwork slab is Recollection, which will display this guide.
\
@@ -413,15 +401,22 @@
switch(selected_scripture) //display info based on selected scripture tier
if(SCRIPTURE_DRIVER)
- data["tier_info"] = "These scriptures are always unlocked."
+ data["tier_info"] = "These scriptures are permenantly unlocked."
if(SCRIPTURE_SCRIPT)
- data["tier_info"] = "These scriptures require at least [SCRIPT_SERVANT_REQ] Servants and [SCRIPT_CACHE_REQ] Tinkerer's Cache."
+ if(SSticker.scripture_states[SCRIPTURE_SCRIPT])
+ data["tier_info"] = "These scriptures are permenantly unlocked."
+ else
+ data["tier_info"] = "These scriptures require at least [SCRIPT_SERVANT_REQ] Servants and [SCRIPT_CACHE_REQ] Tinkerer's Cache."
if(SCRIPTURE_APPLICATION)
- data["tier_info"] = "These scriptures require at least [APPLICATION_SERVANT_REQ] Servants, [APPLICATION_CACHE_REQ] Tinkerer's Caches, and [APPLICATION_CV_REQ]CV."
- if(SCRIPTURE_REVENANT)
- data["tier_info"] = "These scriptures require at least [REVENANT_SERVANT_REQ] Servants, [REVENANT_CACHE_REQ] Tinkerer's Caches, and [REVENANT_CV_REQ]CV."
+ if(SSticker.scripture_states[SCRIPTURE_APPLICATION])
+ data["tier_info"] = "These scriptures are permenantly unlocked."
+ else
+ data["tier_info"] = "These scriptures require at least [APPLICATION_SERVANT_REQ] Servants, [APPLICATION_CACHE_REQ] Tinkerer's Caches, and [APPLICATION_CV_REQ]CV."
if(SCRIPTURE_JUDGEMENT)
- data["tier_info"] = "This scripture requires at least [JUDGEMENT_SERVANT_REQ] Servants, [JUDGEMENT_CACHE_REQ] Tinkerer's Caches, and [JUDGEMENT_CV_REQ]CV. In addition, there may not be any active non-Servant AIs."
+ if(SSticker.scripture_states[SCRIPTURE_JUDGEMENT])
+ data["tier_info"] = "This scripture is permenantly unlocked."
+ else
+ data["tier_info"] = "This scripture requires at least [JUDGEMENT_SERVANT_REQ] Servants, [JUDGEMENT_CACHE_REQ] Tinkerer's Caches, and [JUDGEMENT_CV_REQ]CV. In addition, there may not be any active non-Servant AIs."
data["selected"] = selected_scripture
diff --git a/code/game/gamemodes/clock_cult/clock_items/judicial_visor.dm b/code/game/gamemodes/clock_cult/clock_items/judicial_visor.dm
index 05e8fc46f5a..8bc6cb56036 100644
--- a/code/game/gamemodes/clock_cult/clock_items/judicial_visor.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/judicial_visor.dm
@@ -1,4 +1,4 @@
-//Judicial visor: Grants the ability to smite an area and stun the unfaithful nearby every thirty seconds.
+//Judicial visor: Grants the ability to smite an area and knocking down the unfaithful nearby every thirty seconds.
/obj/item/clothing/glasses/judicial_visor
name = "judicial visor"
desc = "A strange purple-lensed visor. Looking at it inspires an odd sense of guilt."
@@ -145,7 +145,7 @@
return TRUE
return FALSE
-//Judicial marker: Created by the judicial visor. After three seconds, stuns any non-servants nearby and damages Nar-Sian cultists.
+//Judicial marker: Created by the judicial visor. After three seconds, knocks down any non-Servants nearby and damages Nar-Sian cultists.
/obj/effect/clockwork/judicial_marker
name = "judicial marker"
desc = "You get the feeling that you shouldn't be standing here."
@@ -163,7 +163,7 @@
INVOKE_ASYNC(src, .proc/judicialblast)
/obj/effect/clockwork/judicial_marker/proc/judicialblast()
- playsound(src, 'sound/magic/MAGIC_MISSILE.ogg', 50, 1, 1, 1)
+ playsound(src, 'sound/magic/magic_missile.ogg', 50, 1, 1, 1)
flick("judicial_marker", src)
sleep(16)
layer = ABOVE_ALL_MOB_LAYER
@@ -184,11 +184,11 @@
if(!iscultist(L))
L.visible_message("[L] is struck by a judicial explosion!", \
"[!issilicon(L) ? "An unseen force slams you into the ground!" : "ERROR: Motor servos disabled by external source!"]")
- L.Weaken(8) //stun targets for 14-16 seconds
+ L.Knockdown(160) //knocks down targets for 14-16 seconds
else
L.visible_message("[L] is struck by a judicial explosion!", \
"\"Keep an eye out, filth.\"\nA burst of heat crushes you against the ground!")
- L.Weaken(4) //stun for 6-8 seconds, but set cultist targets on fire
+ L.Knockdown(80) //knocks down for 6-8 seconds, but set cultist targets on fire
L.adjust_fire_stacks(2)
L.IgniteMob()
if(iscarbon(L))
diff --git a/code/game/gamemodes/clock_cult/clock_items/ratvarian_spear.dm b/code/game/gamemodes/clock_cult/clock_items/ratvarian_spear.dm
index a54b019d536..8ba151830b6 100644
--- a/code/game/gamemodes/clock_cult/clock_items/ratvarian_spear.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/ratvarian_spear.dm
@@ -50,7 +50,7 @@
if(is_servant_of_ratvar(user) || isobserver(user))
to_chat(user, "Stabbing a human you are pulling or have grabbed with the spear will impale them, doing massive damage and stunning.")
if(!iscyborg(user))
- to_chat(user, "Throwing the spear will do massive damage, break the spear, and stun the target.")
+ to_chat(user, "Throwing the spear will do massive damage, break the spear, and knock down the target.")
/obj/item/clockwork/ratvarian_spear/attack(mob/living/target, mob/living/carbon/human/user)
var/impaling = FALSE
@@ -97,7 +97,7 @@
attack_cooldown = world.time + initial(attack_cooldown) //can't attack until we're done impaling
if(target)
new /obj/effect/temp_visual/dir_setting/bloodsplatter(get_turf(target), get_dir(user, target))
- target.Stun(2) //brief stun
+ target.Stun(80) //brief stun
to_chat(user, "You prepare to remove your ratvarian spear from [target]...")
var/remove_verb = pick("pull", "yank", "drag")
if(do_after(user, 10, 1, target))
@@ -114,7 +114,7 @@
step(target, get_dir(user, target))
T = get_turf(target)
B.forceMove(T)
- target.Weaken(2) //then weaken if we stayed next to them
+ target.Knockdown(40) //then knockdown if we stayed next to them
playsound(T, 'sound/weapons/thudswoosh.ogg', 50, 1)
flash_color(target, flash_color="#911414", flash_time=8)
else if(target) //it's a do_after, we gotta check again to make sure they didn't get deleted
@@ -136,11 +136,9 @@
else if(!..())
if(!L.null_rod_check())
if(issilicon(L) || iscultist(L))
- L.Stun(6)
- L.Weaken(6)
+ L.Knockdown(100)
else
- L.Stun(2)
- L.Weaken(2)
+ L.Knockdown(40)
break_spear(T)
else
..()
diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm b/code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm
similarity index 53%
rename from code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm
rename to code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm
index aa174adcd80..a0ab79ba052 100644
--- a/code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm
@@ -1,51 +1,48 @@
-//Clockwork proselytizer: Converts applicable objects to Ratvarian variants.
-/obj/item/clockwork/clockwork_proselytizer
- name = "clockwork proselytizer"
+//Replica Fabricator: Converts applicable objects to Ratvarian variants.
+/obj/item/clockwork/replica_fabricator
+ name = "replica fabricator"
desc = "An odd, L-shaped device that hums with energy."
clockwork_desc = "A device that allows the replacing of mundane objects with Ratvarian variants. It requires power to function."
- icon_state = "clockwork_proselytizer"
+ icon_state = "replica_fabricator"
w_class = WEIGHT_CLASS_NORMAL
force = 5
flags = NOBLUDGEON
var/stored_power = 0 //Requires power to function
var/max_power = CLOCKCULT_POWER_UNIT * 10
var/uses_power = TRUE
- var/metal_to_power = FALSE
var/repairing = null //what we're currently repairing, if anything
var/obj/effect/clockwork/sigil/transmission/recharging = null //the sigil we're charging from, if any
- var/speed_multiplier = 1 //how fast this proselytizer works
+ var/speed_multiplier = 1 //how fast this fabricator works
var/charge_rate = MIN_CLOCKCULT_POWER //how much power we gain every two seconds
var/charge_delay = 2 //how many proccess ticks remain before we can start to charge
-/obj/item/clockwork/clockwork_proselytizer/preloaded
+/obj/item/clockwork/replica_fabricator/preloaded
stored_power = POWER_WALL_MINUS_FLOOR+POWER_WALL_TOTAL
-/obj/item/clockwork/clockwork_proselytizer/scarab
- name = "scarab proselytizer"
- clockwork_desc = "A cogscarab's internal proselytizer. It can only be successfully used by a cogscarab and requires power to function."
- metal_to_power = TRUE
+/obj/item/clockwork/replica_fabricator/scarab
+ name = "scarab fabricator"
+ clockwork_desc = "A cogscarab's internal fabricator. It can only be successfully used by a cogscarab and requires power to function."
item_state = "nothing"
w_class = WEIGHT_CLASS_TINY
speed_multiplier = 0.5
charge_rate = MIN_CLOCKCULT_POWER * 2
var/debug = FALSE
-/obj/item/clockwork/clockwork_proselytizer/scarab/proselytize(atom/target, mob/living/user)
+/obj/item/clockwork/replica_fabricator/scarab/fabricate(atom/target, mob/living/user)
if(!debug && !isdrone(user))
return 0
return ..()
-/obj/item/clockwork/clockwork_proselytizer/scarab/debug
- clockwork_desc = "A cogscarab's internal proselytizer. It can convert nearly any object into a Ratvarian variant."
+/obj/item/clockwork/replica_fabricator/scarab/debug
+ clockwork_desc = "A cogscarab's internal fabricator. It can convert nearly any object into a Ratvarian variant."
uses_power = FALSE
debug = TRUE
-/obj/item/clockwork/clockwork_proselytizer/cyborg
- name = "cyborg proselytizer"
- clockwork_desc = "A cyborg's internal proselytizer. It is capable of using the cyborg's power in addition to stored power."
- metal_to_power = TRUE
+/obj/item/clockwork/replica_fabricator/cyborg
+ name = "cyborg fabricator"
+ clockwork_desc = "A cyborg's internal fabricator. It is capable of using the cyborg's power in addition to stored power."
-/obj/item/clockwork/clockwork_proselytizer/cyborg/get_power() //returns power and cyborg's power
+/obj/item/clockwork/replica_fabricator/cyborg/get_power() //returns power and cyborg's power
var/mob/living/silicon/robot/R = get_atom_on_turf(src, /mob/living)
var/borg_power = 0
var/current_charge = 0
@@ -56,14 +53,14 @@
borg_power += MIN_CLOCKCULT_POWER
return ..() + borg_power
-/obj/item/clockwork/clockwork_proselytizer/cyborg/get_max_power()
+/obj/item/clockwork/replica_fabricator/cyborg/get_max_power()
var/mob/living/silicon/robot/R = get_atom_on_turf(src, /mob/living)
var/cell_maxcharge = 0
if(istype(R) && R.cell)
cell_maxcharge = R.cell.maxcharge
return ..() + cell_maxcharge
-/obj/item/clockwork/clockwork_proselytizer/cyborg/can_use_power(amount)
+/obj/item/clockwork/replica_fabricator/cyborg/can_use_power(amount)
if(amount != RATVAR_POWER_CHECK)
var/mob/living/silicon/robot/R = get_atom_on_turf(src, /mob/living)
var/current_charge = 0
@@ -76,7 +73,7 @@
return FALSE
. = ..()
-/obj/item/clockwork/clockwork_proselytizer/cyborg/modify_stored_power(amount)
+/obj/item/clockwork/replica_fabricator/cyborg/modify_stored_power(amount)
var/mob/living/silicon/robot/R = get_atom_on_turf(src, /mob/living)
if(istype(R) && R.cell && amount)
if(amount < 0)
@@ -89,15 +86,15 @@
amount -= MIN_CLOCKCULT_POWER
. = ..()
-/obj/item/clockwork/clockwork_proselytizer/Initialize()
+/obj/item/clockwork/replica_fabricator/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
-/obj/item/clockwork/clockwork_proselytizer/Destroy()
+/obj/item/clockwork/replica_fabricator/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
-/obj/item/clockwork/clockwork_proselytizer/process()
+/obj/item/clockwork/replica_fabricator/process()
if(!charge_rate)
return
var/mob/living/L = get_atom_on_turf(src, /mob/living)
@@ -106,18 +103,14 @@
charge_delay--
return
modify_stored_power(charge_rate)
- for(var/obj/item/clockwork/clockwork_proselytizer/S in L.GetAllContents()) //no multiple proselytizers
+ for(var/obj/item/clockwork/replica_fabricator/S in L.GetAllContents()) //no multiple fabricators
if(S == src)
continue
S.charge_delay = 2
else
charge_delay = 2
-/obj/item/clockwork/clockwork_proselytizer/ratvar_act()
- if(GLOB.nezbere_invoked)
- charge_rate = 1250
- else
- charge_rate = initial(charge_rate)
+/obj/item/clockwork/replica_fabricator/ratvar_act()
if(GLOB.ratvar_awakens)
uses_power = FALSE
speed_multiplier = initial(speed_multiplier) * 0.25
@@ -125,47 +118,45 @@
uses_power = initial(uses_power)
speed_multiplier = initial(speed_multiplier)
-/obj/item/clockwork/clockwork_proselytizer/examine(mob/living/user)
+/obj/item/clockwork/replica_fabricator/examine(mob/living/user)
..()
if(is_servant_of_ratvar(user) || isobserver(user))
- to_chat(user, "Can be used to convert walls, floors, windows, airlocks, and a variety of other objects to clockwork variants.")
- to_chat(user, "Can also form some objects into Brass sheets, as well as reform Clockwork Walls into Clockwork Floors, and vice versa.")
+ to_chat(user, "Can be used to replace walls, floors, tables, windows, windoors, and airlocks with Clockwork variants.")
+ to_chat(user, "Can construct Clockwork Walls on Clockwork Floors and deconstruct Clockwork Walls to Clockwork Floors.")
if(uses_power)
- if(metal_to_power)
- to_chat(user, "It can convert rods, metal, plasteel, and brass to power at rates of 1:[POWER_ROD]W, 1:[POWER_METAL]W, \
- 1:[POWER_PLASTEEL]W, and 1:[POWER_FLOOR]W, respectively.")
- else
- to_chat(user, "It can convert brass to power at a rate of 1:[POWER_FLOOR]W.")
- to_chat(user, "It is storing [get_power()]W/[get_max_power()]W of power, and is gaining [charge_rate*0.5]W of power per second.")
+ to_chat(user, "It can consume floor tiles, rods, metal, and plasteel for power at rates of 2:[POWER_ROD]W, 1:[POWER_ROD]W, 1:[POWER_METAL]W, \
+ and 1:[POWER_PLASTEEL]W, respectively.")
+ to_chat(user, "It can also consume brass sheets for power at a rate of 1:[POWER_FLOOR]W.")
+ to_chat(user, "It is storing [get_power()]W/[get_max_power()]W of power[charge_rate ? ", and is gaining [charge_rate*0.5]W of power per second":""].")
to_chat(user, "Use it in-hand to produce 5 brass sheets at a cost of [POWER_WALL_TOTAL]W power.")
-/obj/item/clockwork/clockwork_proselytizer/attack_self(mob/living/user)
+/obj/item/clockwork/replica_fabricator/attack_self(mob/living/user)
if(is_servant_of_ratvar(user))
if(uses_power)
if(!can_use_power(POWER_WALL_TOTAL))
to_chat(user, "[src] requires [POWER_WALL_TOTAL]W of power to produce brass sheets!")
return
modify_stored_power(-POWER_WALL_TOTAL)
- playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
new/obj/item/stack/tile/brass(user.loc, 5)
- to_chat(user, "You user [stored_power ? "some":"all"] of [src]'s power to produce some brass sheets. It now stores [get_power()]W/[get_max_power()]W of power.")
+ to_chat(user, "You use [stored_power ? "some":"all"] of [src]'s power to produce 5 brass sheets. It now stores [get_power()]W/[get_max_power()]W of power.")
-/obj/item/clockwork/clockwork_proselytizer/pre_attackby(atom/target, mob/living/user, params)
+/obj/item/clockwork/replica_fabricator/pre_attackby(atom/target, mob/living/user, params)
if(!target || !user || !is_servant_of_ratvar(user) || istype(target, /obj/item/weapon/storage))
return TRUE
- return proselytize(target, user)
+ return fabricate(target, user)
-/obj/item/clockwork/clockwork_proselytizer/proc/get_power()
+/obj/item/clockwork/replica_fabricator/proc/get_power()
return stored_power
-/obj/item/clockwork/clockwork_proselytizer/proc/get_max_power()
+/obj/item/clockwork/replica_fabricator/proc/get_max_power()
return max_power
-/obj/item/clockwork/clockwork_proselytizer/proc/modify_stored_power(amount)
+/obj/item/clockwork/replica_fabricator/proc/modify_stored_power(amount)
stored_power = Clamp(stored_power + amount, 0, max_power)
return TRUE
-/obj/item/clockwork/clockwork_proselytizer/proc/can_use_power(amount)
+/obj/item/clockwork/replica_fabricator/proc/can_use_power(amount)
if(amount == RATVAR_POWER_CHECK)
if(GLOB.ratvar_awakens || !uses_power)
return TRUE
@@ -178,7 +169,7 @@
return TRUE
//A note here; return values are for if we CAN BE PUT ON A TABLE, not IF WE ARE SUCCESSFUL, unless no_table_check is TRUE
-/obj/item/clockwork/clockwork_proselytizer/proc/proselytize(atom/target, mob/living/user, silent, no_table_check)
+/obj/item/clockwork/replica_fabricator/proc/fabricate(atom/target, mob/living/user, silent, no_table_check)
if(!target || !user)
return FALSE
if(repairing)
@@ -189,59 +180,77 @@
if(!silent)
to_chat(user, "You are currently recharging [src] from the [recharging.sigil_name]!")
return FALSE
- var/list/proselytize_values = target.proselytize_vals(user, src, silent) //relevant values for proselytizing stuff, given as an associated list
- if(!islist(proselytize_values))
- if(proselytize_values != TRUE) //if we get true, fail, but don't send a message for whatever reason
- if(!isturf(target)) //otherwise, if we didn't get TRUE and the original target wasn't a turf, try to proselytize the turf
- return proselytize(get_turf(target), user, no_table_check)
+ var/list/fabrication_values = target.fabrication_vals(user, src, silent) //relevant values for fabricating stuff, given as an associated list
+ if(!islist(fabrication_values))
+ if(fabrication_values != TRUE) //if we get true, fail, but don't send a message for whatever reason
+ if(!isturf(target)) //otherwise, if we didn't get TRUE and the original target wasn't a turf, try to fabricate the turf
+ return fabricate(get_turf(target), user, no_table_check)
if(!silent)
- to_chat(user, "[target] cannot be proselytized!")
+ to_chat(user, "[target] cannot be fabricated!")
if(!no_table_check)
return TRUE
return FALSE
if(can_use_power(RATVAR_POWER_CHECK))
- proselytize_values["power_cost"] = 0
+ fabrication_values["power_cost"] = 0
var/turf/Y = get_turf(user)
if(!Y || (Y.z != ZLEVEL_STATION && Y.z != ZLEVEL_CENTCOM && Y.z != ZLEVEL_MINING && Y.z != ZLEVEL_LAVALAND))
- proselytize_values["operation_time"] *= 2
- if(proselytize_values["power_cost"] > 0)
- proselytize_values["power_cost"] *= 2
+ fabrication_values["operation_time"] *= 2
+ if(fabrication_values["power_cost"] > 0)
+ fabrication_values["power_cost"] *= 2
var/target_type = target.type
- if(!proselytize_checks(proselytize_values, target, target_type, user, silent))
+ if(!fabricate_checks(fabrication_values, target, target_type, user, silent))
return FALSE
- proselytize_values["operation_time"] *= speed_multiplier
+ fabrication_values["operation_time"] *= speed_multiplier
playsound(target, 'sound/machines/click.ogg', 50, 1)
- if(proselytize_values["operation_time"])
+ if(fabrication_values["operation_time"])
if(!silent)
- user.visible_message("[user]'s [name] begins tearing apart [target]!", "You begin proselytizing [target]...")
- if(!do_after(user, proselytize_values["operation_time"], target = target, extra_checks = CALLBACK(src, .proc/proselytize_checks, proselytize_values, target, target_type, user, TRUE)))
+ var/atom/A = fabrication_values["new_obj_type"]
+ if(A)
+ user.visible_message("[user]'s [name] starts ripping [target] apart!", \
+ "You start fabricating \a [initial(A.name)] from [target]...")
+ else
+ user.visible_message("[user]'s [name] starts consuming [target]!", \
+ "Your [name] starts consuming [target]...")
+ if(!do_after(user, fabrication_values["operation_time"], target = target, extra_checks = CALLBACK(src, .proc/fabricate_checks, fabrication_values, target, target_type, user, TRUE)))
return FALSE
if(!silent)
- user.visible_message("[user]'s [name] covers [target] in golden energy!", "You proselytize [target].")
+ var/atom/A = fabrication_values["new_obj_type"]
+ if(A)
+ user.visible_message("[user]'s [name] replaces [target] with \a [initial(A.name)]!", \
+ "You fabricate \a [initial(A.name)] from [target].")
+ else
+ user.visible_message("[user]'s [name] consumes [target]!", \
+ "Your [name] consumes [target].")
else
if(!silent)
- user.visible_message("[user]'s [name] tears apart [target], covering it in golden energy!", "You proselytize [target].")
+ var/atom/A = fabrication_values["new_obj_type"]
+ if(A)
+ user.visible_message("[user]'s [name] rips apart [target], replacing it with \a [initial(A.name)]!", \
+ "You fabricate \a [initial(A.name)] from [target].")
+ else
+ user.visible_message("[user]'s [name] rapidly consumes [target]!", \
+ "Your [name] consumes [target].")
- playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
- var/new_thing_type = proselytize_values["new_obj_type"]
+ playsound(target, 'sound/items/deconstruct.ogg', 50, 1)
+ var/new_thing_type = fabrication_values["new_obj_type"]
if(isturf(target)) //if our target is a turf, we're just going to ChangeTurf it and assume it'll work out.
var/turf/T = target
T.ChangeTurf(new_thing_type)
else
if(new_thing_type)
- if(proselytize_values["dir_in_new"])
- new new_thing_type(get_turf(target), proselytize_values["spawn_dir"]) //please verify that your new object actually wants to get a dir in New()
+ if(fabrication_values["dir_in_new"])
+ new new_thing_type(get_turf(target), fabrication_values["spawn_dir"]) //please verify that your new object actually wants to get a dir in New()
else
var/atom/A = new new_thing_type(get_turf(target))
- A.setDir(proselytize_values["spawn_dir"])
- if(!proselytize_values["no_target_deletion"]) //for some cases where proselytize_vals() modifies the object but doesn't want it deleted
+ A.setDir(fabrication_values["spawn_dir"])
+ if(!fabrication_values["no_target_deletion"]) //for some cases where fabrication_vals() modifies the object but doesn't want it deleted
qdel(target)
- modify_stored_power(-proselytize_values["power_cost"])
+ modify_stored_power(-fabrication_values["power_cost"])
if(no_table_check)
return TRUE
return FALSE
@@ -250,28 +259,34 @@
//What these procs do is they take an existing list of values, which they then modify.
//This(modifying an existing object, in this case the list) is the only way to get information OUT of a do_after callback, which this is used as.
-//The proselytize check proc.
-/obj/item/clockwork/clockwork_proselytizer/proc/proselytize_checks(list/proselytize_values, atom/target, expected_type, mob/user, silent) //checked constantly while proselytizing
- if(!islist(proselytize_values) || QDELETED(target) || QDELETED(user))
+//The fabricate check proc.
+/obj/item/clockwork/replica_fabricator/proc/fabricate_checks(list/fabrication_values, atom/target, expected_type, mob/user, silent) //checked constantly while fabricating
+ if(!islist(fabrication_values) || QDELETED(target) || QDELETED(user))
return FALSE
if(repairing || recharging)
return FALSE
if(target.type != expected_type)
return FALSE
if(can_use_power(RATVAR_POWER_CHECK))
- proselytize_values["power_cost"] = 0
- if(!can_use_power(proselytize_values["power_cost"]))
- if(stored_power - proselytize_values["power_cost"] < 0)
+ fabrication_values["power_cost"] = 0
+ if(!can_use_power(fabrication_values["power_cost"]))
+ if(stored_power - fabrication_values["power_cost"] < 0)
if(!silent)
- to_chat(user, "You need [proselytize_values["power_cost"]]W power to proselytize [target]!")
- else if(stored_power - proselytize_values["power_cost"] > max_power)
+ var/atom/A = fabrication_values["new_obj_type"]
+ if(A)
+ to_chat(user, "You need [fabrication_values["power_cost"]]W power to fabricate \a [initial(A.name)] from [target]!")
+ else if(stored_power - fabrication_values["power_cost"] > max_power)
if(!silent)
- to_chat(user, "Your [name] contains too much power to proselytize [target]!")
+ var/atom/A = fabrication_values["new_obj_type"]
+ if(A)
+ to_chat(user, "Your [name] contains too much power to fabricate \a [initial(A.name)] from [target]!")
+ else
+ to_chat(user, "Your [name] contains too much power to consume [target]!")
return FALSE
return TRUE
//The repair check proc.
-/obj/item/clockwork/clockwork_proselytizer/proc/proselytizer_repair_checks(list/repair_values, atom/target, mob/user, silent) //Exists entirely to avoid an otherwise unreadable series of checks.
+/obj/item/clockwork/replica_fabricator/proc/fabricator_repair_checks(list/repair_values, atom/target, mob/user, silent) //Exists entirely to avoid an otherwise unreadable series of checks.
if(!islist(repair_values) || QDELETED(target) || QDELETED(user))
return FALSE
if(isliving(target)) //standard checks for if we can affect the target
@@ -302,7 +317,7 @@
return FALSE
if(repair_values["amount_to_heal"] <= 0) //nothing to heal!
return FALSE
- repair_values["healing_for_cycle"] = min(repair_values["amount_to_heal"], PROSELYTIZER_REPAIR_PER_TICK) //modify the healing for this cycle
+ repair_values["healing_for_cycle"] = min(repair_values["amount_to_heal"], FABRICATOR_REPAIR_PER_TICK) //modify the healing for this cycle
repair_values["power_required"] = round(repair_values["healing_for_cycle"]*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER) //and get the power cost from that
if(!can_use_power(RATVAR_POWER_CHECK) && !can_use_power(repair_values["power_required"]))
if(!silent)
@@ -312,7 +327,7 @@
return TRUE
//The sigil charge check proc.
-/obj/item/clockwork/clockwork_proselytizer/proc/sigil_charge_checks(list/charge_values, obj/effect/clockwork/sigil/transmission/sigil, mob/user, silent)
+/obj/item/clockwork/replica_fabricator/proc/sigil_charge_checks(list/charge_values, obj/effect/clockwork/sigil/transmission/sigil, mob/user, silent)
if(!islist(charge_values) || QDELETED(sigil) || QDELETED(user))
return FALSE
if(can_use_power(RATVAR_POWER_CHECK))
diff --git a/code/game/gamemodes/clock_cult/clock_mobs.dm b/code/game/gamemodes/clock_cult/clock_mobs.dm
index 2a1ec656bb9..97a68fd3216 100644
--- a/code/game/gamemodes/clock_cult/clock_mobs.dm
+++ b/code/game/gamemodes/clock_cult/clock_mobs.dm
@@ -38,7 +38,7 @@
/mob/living/simple_animal/hostile/clockwork/examine(mob/user)
var/t_He = p_they(TRUE)
var/t_s = p_s()
- var/msg = "*---------*\nThis is \icon[src] \a [src]!\n"
+ var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
msg += "[desc]\n"
if(health < maxHealth)
msg += ""
diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm
index e8f1e8dbbc2..9050d4569c3 100644
--- a/code/game/gamemodes/clock_cult/clock_scripture.dm
+++ b/code/game/gamemodes/clock_cult/clock_scripture.dm
@@ -120,7 +120,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
if(multiple_invokers_used && !multiple_invokers_optional && !GLOB.ratvar_awakens && !slab.no_cost)
var/nearby_servants = 0
for(var/mob/living/L in range(1, get_turf(invoker)))
- if(is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal())
+ if(can_recite_scripture(L))
nearby_servants++
if(nearby_servants < invokers_required)
to_chat(invoker, "There aren't enough non-mute servants nearby ([nearby_servants]/[invokers_required])!")
@@ -170,7 +170,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
if(!channel_time && invocations.len)
if(multiple_invokers_used)
for(var/mob/living/L in range(1, invoker))
- if(is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal())
+ if(can_recite_scripture(L))
for(var/invocation in invocations)
clockwork_say(L, text2ratvar(invocation), whispered)
else
@@ -185,7 +185,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
return FALSE
if(multiple_invokers_used)
for(var/mob/living/L in range(1, get_turf(invoker)))
- if(is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal())
+ if(can_recite_scripture(L))
clockwork_say(L, text2ratvar(invocation), whispered)
else
clockwork_say(invoker, text2ratvar(invocation), whispered)
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm
index 21da8fab004..27bf4551eb8 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm
@@ -53,7 +53,7 @@
/datum/clockwork_scripture/fellowship_armory/run_scripture()
for(var/mob/living/L in orange(1, invoker))
- if(is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal())
+ if(can_recite_scripture(L))
channel_time = max(channel_time - 10, 0)
return ..()
@@ -124,8 +124,7 @@
invoker.visible_message("The tendril, covered in blood, retracts from [invoker]'s head and back into the [slab.name]!", \
"Total agony overcomes you as the tendril is forced out early!")
invoker.notransform = FALSE
- invoker.Stun(5)
- invoker.Weaken(5)
+ invoker.Knockdown(100)
invoker.apply_damage(10, BRUTE, "head")
slab.busy = null
return FALSE
@@ -214,6 +213,38 @@
quickbind_desc = "Creates an Interdiction Lens, which drains power into nearby Sigils of Transmission."
+//Prolonging Prism: Creates a prism that will delay the shuttle at a power cost
+/datum/clockwork_scripture/create_object/prolonging_prism
+ descname = "Powered Structure, Delay Emergency Shuttles"
+ name = "Prolonging Prism"
+ desc = "Creates a mechanized prism which will delay the arrival of an emergency shuttle by 2 minutes at a massive power cost."
+ invocations = list("May this prism...", "...grant us time to enact his will!")
+ channel_time = 80
+ consumed_components = list(VANGUARD_COGWHEEL = 5, GEIS_CAPACITOR = 2, REPLICANT_ALLOY = 2)
+ object_path = /obj/structure/destructible/clockwork/powered/prolonging_prism
+ creator_message = "You form a prolonging prism, which will delay the arrival of an emergency shuttle at a massive power cost."
+ observer_message = "An onyx prism forms in midair and sprouts tendrils to support itself!"
+ invokers_required = 2
+ multiple_invokers_used = TRUE
+ usage_tip = "The power cost to delay a shuttle increases based on CV and the number of times activated."
+ tier = SCRIPTURE_APPLICATION
+ one_per_tile = TRUE
+ primary_component = VANGUARD_COGWHEEL
+ sort_priority = 7
+ quickbind = TRUE
+ quickbind_desc = "Creates a Prolonging Prism, which will delay the arrival of an emergency shuttle by 2 minutes at a massive power cost."
+
+/datum/clockwork_scripture/create_object/prolonging_prism/check_special_requirements()
+ if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
+ to_chat(invoker, "\"It is too late to construct one of these, champion.\"")
+ return FALSE
+ var/turf/T = get_turf(invoker)
+ if(!T || T.z != ZLEVEL_STATION)
+ to_chat(invoker, "\"You must be on the station to construct one of these, champion.\"")
+ return FALSE
+ return ..()
+
+
//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost.
/datum/clockwork_scripture/create_object/mania_motor
descname = "Powered Structure, Area Denial"
@@ -240,7 +271,7 @@
/datum/clockwork_scripture/create_object/tinkerers_daemon
descname = "Powered Structure, Component Generator"
name = "Tinkerer's Daemon"
- desc = "Creates a tinkerer's daemon which can rapidly collect components. It will only function if it has sufficient power, is outnumbered by Servants by a ratio of 5:1, \
+ desc = "Creates a tinkerer's daemon which can rapidly collect components. It will only function if it has sufficient power, active daemons are outnumbered by Servants by a ratio of 5:1, \
and there is at least one existing cache."
invocations = list("May this generator...", "...collect Engine parts that yet hold greatness!")
channel_time = 80
@@ -257,19 +288,6 @@
quickbind = TRUE
quickbind_desc = "Creates a Tinkerer's Daemon, which can rapidly collect components for power."
-/datum/clockwork_scripture/create_object/tinkerers_daemon/check_special_requirements()
- var/servants = 0
- for(var/mob/living/L in GLOB.living_mob_list)
- if(is_servant_of_ratvar(L))
- servants++
- if(servants * 0.2 < GLOB.clockwork_daemons)
- to_chat(invoker, "\"Daemons are already disabled, making more of them would be a waste.\"")
- return FALSE
- if(servants * 0.2 < GLOB.clockwork_daemons+1)
- to_chat(invoker, "\"This daemon would be useless, friend.\"")
- return FALSE
- return ..()
-
//Clockwork Obelisk: Creates a powerful obelisk that can be used to broadcast messages or open a gateway to any servant or clockwork obelisk at a power cost.
/datum/clockwork_scripture/create_object/clockwork_obelisk
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_cyborg.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_cyborg.dm
index db5260a8a0d..e978309f579 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_cyborg.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_cyborg.dm
@@ -37,16 +37,10 @@
invocations = list("May heathens...", "...kneel under our force!")
channel_time = 30
primary_component = BELLIGERENT_EYE
- quickbind_desc = "Allows you to place a Judicial Marker to stun and damage a target location. Click your slab to disable."
+ quickbind_desc = "Allows you to place a Judicial Marker to knock down and damage non-Servants in an area. Click your slab to disable."
slab_icon = "judicial"
ranged_type = /obj/effect/proc_holder/slab/judicial
ranged_message = "You charge the clockwork slab with judicial force.\n\
Left-click a target to place a Judicial Marker!\n\
Click your slab to cancel."
timeout_time = 50
-
-//Volt Void, but with a different quickbind desc
-/datum/clockwork_scripture/channeled/volt_void/cyborg
- quickbind_desc = "Allows you to fire energy rays at target locations using your own power. Failing to fire causes backlash. Maximum 4 chants."
- tier = SCRIPTURE_PERIPHERAL
- quickbind = FALSE
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm
index b49b0c58196..4b0ff2e00c9 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm
@@ -26,10 +26,9 @@
//Judicial Visor: Creates a judicial visor, which can smite an area.
/datum/clockwork_scripture/create_object/judicial_visor
- descname = "Delayed Area Stun Glasses"
+ descname = "Delayed Area Knockdown Glasses"
name = "Judicial Visor"
- desc = "Forms a visor that, when worn, will grant the ability to smite an area, stunning, muting, and damaging non-Servants. \
- Cultists of Nar-Sie will be set on fire, though they will be stunned for half the time."
+ desc = "Forms a visor that, when worn, will grant the ability to smite an area, knocking down, muting, and damaging non-Servants."
invocations = list("Grant me the flames of Engine!")
channel_time = 10
consumed_components = list(BELLIGERENT_EYE = 1)
@@ -42,14 +41,14 @@
primary_component = BELLIGERENT_EYE
sort_priority = 2
quickbind = TRUE
- quickbind_desc = "Creates a Judicial Visor, which can create a Judicial Marker at an area, stunning, muting, and damaging non-Servants after a delay."
+ quickbind_desc = "Creates a Judicial Visor, which can create a Judicial Marker at an area, knocking down, muting, and damaging non-Servants after a delay."
//Vanguard: Provides twenty seconds of stun immunity. At the end of the twenty seconds, 25% of all stuns absorbed are applied to the invoker.
/datum/clockwork_scripture/vanguard
descname = "Self Stun Immunity"
name = "Vanguard"
- desc = "Provides twenty seconds of stun immunity. At the end of the twenty seconds, the invoker is stunned for the equivalent of 25% of all stuns they absorbed. \
+ desc = "Provides twenty seconds of stun immunity. At the end of the twenty seconds, the invoker is knocked down for the equivalent of 25% of all stuns they absorbed. \
Excessive absorption will cause unconsciousness."
invocations = list("Shield me...", "...from darkness!")
channel_time = 30
@@ -122,8 +121,8 @@
/datum/clockwork_scripture/ranged_ability/geis_prep/run_scripture()
var/servants = 0
if(!GLOB.ratvar_awakens)
- for(var/mob/living/M in GLOB.all_clockwork_mobs)
- if(ishuman(M) || issilicon(M))
+ for(var/mob/living/M in GLOB.living_mob_list)
+ if(can_recite_scripture(M, TRUE))
servants++
if(servants > SCRIPT_SERVANT_REQ)
whispered = FALSE
@@ -153,8 +152,8 @@
/datum/clockwork_scripture/geis/run_scripture()
var/servants = 0
if(!GLOB.ratvar_awakens)
- for(var/mob/living/M in GLOB.all_clockwork_mobs)
- if(ishuman(M) || issilicon(M))
+ for(var/mob/living/M in GLOB.living_mob_list)
+ if(can_recite_scripture(M, TRUE))
servants++
if(target.buckled)
target.buckled.unbuckle_mob(target, TRUE)
@@ -178,7 +177,7 @@
/datum/clockwork_scripture/channeled/taunting_tirade
descname = "Channeled, Mobile Confusion Trail"
name = "Taunting Tirade"
- desc = "Allows movement for five seconds, leaving a confusing and weakening trail. Chanted every second for up to thirty seconds."
+ desc = "Allows movement for five seconds, leaving a trail that confuses and knocks down. Chanted every second for up to thirty seconds."
chant_invocations = list("Hostiles on my back!", "Enemies on my trail!", "Gonna try and shake my tail.", "Bogeys on my six!")
chant_amount = 5
chant_interval = 10
@@ -188,7 +187,7 @@
primary_component = GEIS_CAPACITOR
sort_priority = 6
quickbind = TRUE
- quickbind_desc = "Allows movement for five seconds, leaving a confusing and weakening trail. Maximum 5 chants."
+ quickbind_desc = "Allows movement for five seconds, leaving a trail that confuses and knocks down. Maximum 5 chants."
var/flee_time = 47 //allow fleeing for 5 seconds
var/grace_period = 3 //very short grace period so you don't have to stop immediately
var/datum/progressbar/progbar
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm
deleted file mode 100644
index 25bedd79d30..00000000000
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm
+++ /dev/null
@@ -1,211 +0,0 @@
-//////////////
-// REVENANT //
-//////////////
-
-//Invoke Inath-neq, the Resonant Cogwheel: Grants invulnerability and stun immunity to everyone nearby for 15 seconds.
-/datum/clockwork_scripture/invoke_inathneq
- descname = "Area Invulnerability"
- name = "Invoke Inath-neq, the Resonant Cogwheel"
- desc = "Taps the limitless power of Inath-neq, one of Ratvar's four generals. The benevolence of Inath-Neq will grant complete invulnerability to all Servants in range for fifteen seconds."
- invocations = list("I call upon you, Vanguard!!", "Let the Resonant Cogs turn once more!!", "Grant me and my allies the strength to vanquish our foes!!")
- channel_time = 100
- consumed_components = list(VANGUARD_COGWHEEL = 10, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 3, HIEROPHANT_ANSIBLE = 3)
- usage_tip = "Servants affected by this scripture are only weak to things that outright destroy bodies, such as bombs or the singularity."
- tier = SCRIPTURE_REVENANT
- primary_component = VANGUARD_COGWHEEL
- sort_priority = 2
-
-/datum/clockwork_scripture/invoke_inathneq/check_special_requirements()
- if(!slab.no_cost && GLOB.clockwork_generals_invoked["inath-neq"] > world.time)
- to_chat(invoker, "\"[text2ratvar("I cannot lend you my aid yet, champion. Please be careful.")]\"\n\
- Inath-neq has already been invoked recently! You must wait several minutes before calling upon the Resonant Cogwheel.")
- return FALSE
- return TRUE
-
-/datum/clockwork_scripture/invoke_inathneq/scripture_effects()
- new/obj/effect/clockwork/general_marker/inathneq(get_turf(invoker))
- hierophant_message("[text2ratvar("Vanguard: \"I lend you my aid, champions! Let glory guide your blows!")]\"", FALSE, invoker)
- GLOB.clockwork_generals_invoked["inath-neq"] = world.time + CLOCKWORK_GENERAL_COOLDOWN
- playsound(invoker, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
- if(invoker.real_name == "Lucio")
- clockwork_say(invoker, text2ratvar("Aww, let's break it DOWN!!"))
- for(var/mob/living/L in range(7, invoker))
- if(!is_servant_of_ratvar(L) || L.stat == DEAD)
- continue
- L.apply_status_effect(STATUS_EFFECT_INATHNEQS_ENDOWMENT)
- return TRUE
-
-
-//Invoke Sevtug, the Formless Pariah: Causes massive global hallucinations, braindamage, confusion, and dizziness to all humans on the same zlevel.
-/datum/clockwork_scripture/invoke_sevtug
- descname = "Global Hallucination"
- name = "Invoke Sevtug, the Formless Pariah"
- desc = "Taps the limitless power of Sevtug, one of Ratvar's four generals. The mental manipulation ability of the Pariah allows its wielder to cause mass hallucinations and confusion \
- for all non-servant humans on the same z-level as them. The power of this scripture falls off somewhat with distance, and certain things may reduce its effects."
- invocations = list("I call upon you, Fright!!", "Let your power shatter the sanity of the weak-minded!!", "Let your tendrils hold sway over all!!")
- channel_time = 150
- consumed_components = list(BELLIGERENT_EYE = 6, VANGUARD_COGWHEEL = 6, GEIS_CAPACITOR = 10, HIEROPHANT_ANSIBLE = 6)
- usage_tip = "Causes brain damage, hallucinations, confusion, and dizziness in massive amounts."
- tier = SCRIPTURE_REVENANT
- sort_priority = 3
- primary_component = GEIS_CAPACITOR
- invokers_required = 3
- multiple_invokers_used = TRUE
- var/static/list/mindbreaksayings = list("\"Oh, great. I get to shatter some minds.\"", "\"More minds to crush.\"", \
- "\"Really, this is almost boring.\"", "\"None of these minds have anything interesting in them.\"", "\"Maybe I can instill a little bit of terror in this one.\"", \
- "\"What a waste of my power.\"", "\"I'm sure I could just control these minds instead, but they never ask.\"")
-
-/datum/clockwork_scripture/invoke_sevtug/check_special_requirements()
- if(!slab.no_cost && GLOB.clockwork_generals_invoked["sevtug"] > world.time)
- to_chat(invoker, "\"[text2ratvar("Is it really so hard - even for a simpleton like you - to grasp the concept of waiting?")]\"\n\
- Sevtug has already been invoked recently! You must wait several minutes before calling upon the Formless Pariah.")
- return FALSE
- if(!slab.no_cost && GLOB.ratvar_awakens)
- to_chat(invoker, "\"[text2ratvar("Do you really think anything I can do right now will compare to Engine's power?")]\"\n\
- Sevtug will not grant his power while Ratvar's dwarfs his own!")
- return FALSE
- return TRUE
-
-/datum/clockwork_scripture/invoke_sevtug/scripture_effects()
- new/obj/effect/clockwork/general_marker/sevtug(get_turf(invoker))
- hierophant_message("[text2ratvar("Fright: \"I heed your call, idiots. Get going and use this chance while it lasts!")]\"", FALSE, invoker)
- GLOB.clockwork_generals_invoked["sevtug"] = world.time + GLOBAL_CLOCKWORK_GENERAL_COOLDOWN
- playsound(invoker, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
- var/hum = get_sfx('sound/effects/screech.ogg') //like playsound, same sound for everyone affected
- var/turf/T = get_turf(invoker)
- for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
- if(H.z == invoker.z && !is_servant_of_ratvar(H))
- var/distance = 0
- distance += get_dist(T, get_turf(H))
- var/visualsdistance = max(150 - distance, 5)
- var/minordistance = max(200 - distance*2, 5)
- var/majordistance = max(150 - distance*3, 5)
- if(H.null_rod_check())
- to_chat(H, "[text2ratvar("Oh, a void weapon. How annoying, I may as well not bother.")]\n\
- Your holy weapon glows a faint orange, defending your mind!")
- continue
- else if(H.isloyal())
- visualsdistance = round(visualsdistance * 0.5) //half effect for shielded targets
- minordistance = round(minordistance * 0.5)
- majordistance = round(majordistance * 0.5)
- to_chat(H, "[text2ratvar("Oh, look, a mindshield. Cute, I suppose I'll humor it.")]")
- else if(prob(visualsdistance))
- to_chat(H, "[text2ratvar(pick(mindbreaksayings))]")
- H.playsound_local(T, hum, visualsdistance, 1)
- flash_color(H, flash_color="#AF0AAF", flash_time=visualsdistance*10)
- H.dizziness = minordistance + H.dizziness
- H.hallucination = minordistance + H.hallucination
- H.confused = majordistance + H.confused
- H.setBrainLoss(majordistance + H.getBrainLoss())
- return TRUE
-
-
-//Invoke Nezbere, the Brass Eidolon: Invokes Nezbere, bolstering the strength of many clockwork items for one minute.
-/datum/clockwork_scripture/invoke_nezbere
- descname = "Global Structure Buff"
- name = "Invoke Nezbere, the Brass Eidolon"
- desc = "Taps the limitless power of Nezbere, one of Ratvar's four generals. The restless toil of the Eidolon will empower a wide variety of clockwork apparatus for a full minute - notably, \
- clockwork proselytizers will charge very rapidly."
- invocations = list("I call upon you, Armorer!!", "Let your machinations reign on this miserable station!!", "Let your power flow through the tools of your master!!")
- channel_time = 150
- consumed_components = list(BELLIGERENT_EYE = 6, VANGUARD_COGWHEEL = 6, GEIS_CAPACITOR = 6, REPLICANT_ALLOY = 10)
- usage_tip = "Ocular wardens will become empowered, clockwork proselytizers will require no alloy, tinkerer's daemons will produce twice as quickly, \
- and interdiction lenses, mania motors, tinkerer's daemons, and clockwork obelisks will all require no power."
- tier = SCRIPTURE_REVENANT
- primary_component = REPLICANT_ALLOY
- sort_priority = 4
- invokers_required = 3
- multiple_invokers_used = TRUE
-
-/datum/clockwork_scripture/invoke_nezbere/check_special_requirements()
- if(!slab.no_cost && GLOB.clockwork_generals_invoked["nezbere"] > world.time)
- to_chat(invoker, "\"[text2ratvar("Not just yet, friend. Patience is a virtue.")]\"\n\
- Nezbere has already been invoked recently! You must wait several minutes before calling upon the Brass Eidolon.")
- return FALSE
- if(!slab.no_cost && GLOB.ratvar_awakens)
- to_chat(invoker, "\"[text2ratvar("Our master is here already. You do not require my help, friend.")]\"\n\
- There is no need for Nezbere's assistance while Ratvar is risen!")
- return FALSE
- return TRUE
-
-/datum/clockwork_scripture/invoke_nezbere/scripture_effects()
- new/obj/effect/clockwork/general_marker/nezbere(get_turf(invoker))
- hierophant_message("[text2ratvar("Armorer: \"I heed your call, champions. May your artifacts bring ruin upon the heathens that oppose our master!")]\"", FALSE, invoker)
- GLOB.clockwork_generals_invoked["nezbere"] = world.time + GLOBAL_CLOCKWORK_GENERAL_COOLDOWN
- playsound(invoker, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
- GLOB.nezbere_invoked++
- for(var/obj/O in GLOB.all_clockwork_objects)
- O.ratvar_act()
- addtimer(CALLBACK(GLOBAL_PROC, /proc/reset_nezbere_invocation), 600)
- return TRUE
-
-/proc/reset_nezbere_invocation()
- GLOB.nezbere_invoked--
- for(var/obj/O in GLOB.all_clockwork_objects)
- O.ratvar_act()
-
-
-//Invoke Nzcrentr, the Eternal Thunderbolt: Imbues an immense amount of energy into the invoker. After several seconds, everyone near the invoker will be hit with a devastating lightning blast.
-/datum/clockwork_scripture/invoke_nzcrentr
- descname = "Area Lightning Blast"
- name = "Invoke Nzcrentr, the Eternal Thunderbolt"
- desc = "Taps the limitless power of Nzcrentr, one of Ratvar's four generals. Nzcrentr will grant you a tiny fraction of its boundless power. After several seconds, all non-Servants near you \
- will be struck by devastating lightning bolts."
- invocations = list("I call upon you, Amperage!!", "Let your energy flow through me!!", "Let your boundless power shatter stars!!")
- channel_time = 100
- consumed_components = list(BELLIGERENT_EYE = 3, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 3, HIEROPHANT_ANSIBLE = 10)
- usage_tip = "Struck targets will also be knocked down for about sixteen seconds."
- tier = SCRIPTURE_REVENANT
- primary_component = HIEROPHANT_ANSIBLE
- sort_priority = 5
-
-/datum/clockwork_scripture/invoke_nzcrentr/check_special_requirements()
- if(!slab.no_cost && GLOB.clockwork_generals_invoked["nzcrentr"] > world.time)
- to_chat(invoker, "\"[text2ratvar("The boss says you have to wait. Hey, do you think he would mind if I killed you? ...He would? Ok.")]\"\n\
- Nzcrentr has already been invoked recently! You must wait several minutes before calling upon the Eternal Thunderbolt.")
- return FALSE
- return TRUE
-
-/datum/clockwork_scripture/invoke_nzcrentr/scripture_effects()
- new/obj/effect/clockwork/general_marker/nzcrentr(get_turf(invoker))
- GLOB.clockwork_generals_invoked["nzcrentr"] = world.time + CLOCKWORK_GENERAL_COOLDOWN
- hierophant_message("[text2ratvar("Amperage: \"[invoker.real_name] has called forth my power. Hope [invoker.p_they()] [invoker.p_do()] not shatter under it!")]\"", FALSE, invoker)
- invoker.visible_message("[invoker] begins to radiate a blinding light!", \
- "\"[text2ratvar("The boss says it's okay to do this. Don't blame me if you die from it.")]\"\n\
- You feel limitless power surging through you!")
- playsound(invoker, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
- sleep(2)
- playsound(invoker, 'sound/magic/lightning_chargeup.ogg', 100, 0)
- var/oldcolor = invoker.color
- animate(invoker, color = list(rgb(255, 255, 255), rgb(255, 255, 255), rgb(255, 255, 255), rgb(0,0,0)), time = 88) //Gradual advancement to extreme brightness
- sleep(88)
- if(invoker)
- invoker.visible_message("Massive bolts of energy emerge from across [invoker]'s body!", \
- "\"[text2ratvar("I told you you wouldn't be able to handle it.")]\"\n\
- TOO... MUCH! CAN'T... TAKE IT!")
- playsound(invoker, 'sound/magic/lightningbolt.ogg', 100, 0)
- if(invoker.stat == CONSCIOUS)
- animate(invoker, color = oldcolor, time = 10)
- addtimer(CALLBACK(invoker, /atom/proc/update_atom_colour), 10)
- for(var/mob/living/L in view(7, invoker))
- if(is_servant_of_ratvar(L) || L.null_rod_check())
- continue
- invoker.Beam(L, icon_state = "nzcrentrs_power", time = 10)
- var/randdamage = rand(40, 60)
- if(iscarbon(L))
- L.electrocute_act(randdamage, "Nzcrentr's power", 1, randdamage)
- else
- L.adjustFireLoss(randdamage)
- L.visible_message(
- "[L] was shocked by Nzcrentr's power!", \
- "You feel a powerful shock coursing through your body!", \
- "You hear a heavy electrical crack." \
- )
- L.Weaken(8)
- playsound(L, 'sound/magic/LightningShock.ogg', 50, 1)
- else
- playsound(invoker, 'sound/magic/Disintegrate.ogg', 50, 1)
- invoker.gib()
- return TRUE
- else
- return FALSE
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm
index 9efb9a8eb2c..6d8402ede0e 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm
@@ -33,7 +33,7 @@
/datum/clockwork_scripture/create_object/cogscarab
descname = "Constructor Soul Vessel Shell"
name = "Cogscarab"
- desc = "Creates a small shell fitted for soul vessels. Adding an active soul vessel to it results in a small construct with tools and an inbuilt proselytizer."
+ desc = "Creates a small shell fitted for soul vessels. Adding an active soul vessel to it results in a small construct with tools and an inbuilt fabricator."
invocations = list("Call forth...", "...the workers of Armorer.")
channel_time = 60
consumed_components = list(BELLIGERENT_EYE = 2, HIEROPHANT_ANSIBLE = 1)
@@ -221,24 +221,24 @@
quickbind_desc = "Creates a Soul Vessel, which can be placed in construct shells and cyborg bodies once filled."
-//Clockwork Proselytizer: Creates a clockwork proselytizer, used to convert objects and repair clockwork structures.
-/datum/clockwork_scripture/create_object/clockwork_proselytizer
- descname = "Converts Objects to Ratvarian"
- name = "Clockwork Proselytizer"
- desc = "Forms a device that, when used on certain objects, converts them into their Ratvarian equivalents. It requires power to function."
+//Replica Fabricator: Creates a replica fabricator, used to convert objects and repair clockwork structures.
+/datum/clockwork_scripture/create_object/replica_fabricator
+ descname = "Replaces Objects with Ratvarian Versions"
+ name = "Replica Fabricator"
+ desc = "Forms a device that, when used on certain objects, replaces them with their Ratvarian equivalents. It requires power to function."
invocations = list("With this device...", "...his presence shall be made known.")
channel_time = 20
consumed_components = list(GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 2)
whispered = TRUE
- object_path = /obj/item/clockwork/clockwork_proselytizer/preloaded
- creator_message = "You form a clockwork proselytizer."
- usage_tip = "Clockwork Walls cause nearby tinkerer's caches to generate components passively, making them a vital tool. Clockwork Floors heal toxin damage in Servants standing on them."
+ object_path = /obj/item/clockwork/replica_fabricator/preloaded
+ creator_message = "You form a replica fabricator."
+ usage_tip = "Clockwork Walls cause nearby Tinkerer's Caches to generate components passively, making this a vital tool. Clockwork Floors heal toxin damage in Servants standing on them."
tier = SCRIPTURE_SCRIPT
space_allowed = TRUE
primary_component = REPLICANT_ALLOY
sort_priority = 7
quickbind = TRUE
- quickbind_desc = "Creates a Clockwork Proselytizer, which can convert various objects to Ratvarian variants."
+ quickbind_desc = "Creates a Replica Fabricator, which can convert various objects to Ratvarian variants."
//Function Call: Grants the invoker the ability to call forth a Ratvarian spear that deals significant damage to silicons.
@@ -251,7 +251,7 @@
channel_time = 20
consumed_components = list(REPLICANT_ALLOY = 2, HIEROPHANT_ANSIBLE = 1)
whispered = TRUE
- usage_tip = "You can impale human targets with the spear by pulling them, then attacking. Throwing the spear at a mob will do massive damage and stun them, but break the spear."
+ usage_tip = "You can impale human targets with the spear by pulling them, then attacking. Throwing the spear at a mob will do massive damage and knock them down, but break the spear."
tier = SCRIPTURE_SCRIPT
primary_component = REPLICANT_ALLOY
sort_priority = 8
@@ -275,7 +275,7 @@
desc = "Allows you to summon a Ratvarian spear to fight enemies."
button_icon_state = "ratvarian_spear"
background_icon_state = "bg_clock"
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
buttontooltipstyle = "clockcult"
var/cooldown = 0
var/base_cooldown = RATVARIAN_SPEAR_DURATION
@@ -347,27 +347,27 @@
return slab.procure_gateway(invoker, duration, portal_uses)
-//Volt Void: Channeled for up to five times over ten seconds to fire up to five rays of energy at target locations.
-/datum/clockwork_scripture/channeled/volt_void
+//Volt Blaster: Channeled for up to five times over ten seconds to fire up to five rays of energy at target locations.
+/datum/clockwork_scripture/channeled/volt_blaster
descname = "Channeled, Targeted Energy Blasts"
- name = "Volt Void" //Alternative name: "On all levels but physical, I am a power sink"
- desc = "Allows you to fire energy rays at target locations; more power consumed causes more damage. Channeled every fifth of a second for a maximum of ten seconds."
+ name = "Volt Blaster"
+ desc = "Allows you to fire five energy rays at target locations. Channeled every fourth of a second for a maximum of ten seconds."
channel_time = 30
invocations = list("Amperage...", "...grant me your power!")
chant_invocations = list("Use charge to kill!", "Slay with power!", "Hunt with energy!")
- chant_amount = 4
- chant_interval = 5
+ chant_amount = 5
+ chant_interval = 4
consumed_components = list(GEIS_CAPACITOR = 1, HIEROPHANT_ANSIBLE = 2)
usage_tip = "Though it requires you to stand still, this scripture can do massive damage."
tier = SCRIPTURE_SCRIPT
primary_component = HIEROPHANT_ANSIBLE
sort_priority = 10
quickbind = TRUE
- quickbind_desc = "Allows you to fire energy rays at target locations. Failing to fire causes backlash. Maximum 4 chants."
+ quickbind_desc = "Allows you to fire energy rays at target locations. Maximum 5 chants."
var/static/list/nzcrentr_insults = list("You're not very good at aiming.", "You hunt badly.", "What a waste of energy.", "Almost funny to watch.",
"Boss says \"Click something, you idiot!\".", "Stop wasting components if you can't aim.")
-/datum/clockwork_scripture/channeled/volt_void/chant_effects(chant_number)
+/datum/clockwork_scripture/channeled/volt_blaster/chant_effects(chant_number)
slab.busy = null
var/datum/clockwork_scripture/ranged_ability/volt_ray/ray = new
ray.slab = slab
@@ -375,24 +375,6 @@
var/turf/T = get_turf(invoker)
if(!ray.run_scripture() && slab && invoker)
if(can_recite() && T == get_turf(invoker))
- if(!GLOB.ratvar_awakens)
- var/obj/structure/destructible/clockwork/powered/volt_checker/VC = new/obj/structure/destructible/clockwork/powered/volt_checker(get_turf(invoker))
- var/multiplier = 0.5
- var/usable_power = min(Floor(VC.total_accessable_power() * 0.2, MIN_CLOCKCULT_POWER), 1000)
- if(VC.try_use_power(usable_power))
- multiplier += (usable_power * 0.0005) //at maximum power, should be 1 multiplier
- qdel(VC)
- if(iscyborg(invoker))
- var/mob/living/silicon/robot/C = invoker
- if(C.cell)
- var/prev_power = usable_power //we don't want to increase the multiplier past 1
- usable_power = min(Floor(C.cell.charge * 0.2, MIN_CLOCKCULT_POWER), 1000) - prev_power
- if(usable_power > 0 && C.cell.use(usable_power))
- multiplier += (usable_power * 0.0005)
- var/obj/effect/temp_visual/ratvar/volt_hit/VH = new /obj/effect/temp_visual/ratvar/volt_hit(get_turf(invoker), null, multiplier)
- invoker.visible_message("[invoker] is struck by [invoker.p_their()] own [VH.name]!", "You're struck by your own [VH.name]!")
- invoker.adjustFireLoss(VH.damage) //you have to fail all five blasts to die to this
- playsound(invoker, 'sound/machines/defib_zap.ogg', VH.damage, 1, -1)
to_chat(invoker, "\"[text2ratvar(pick(nzcrentr_insults))]\"")
else
return FALSE
@@ -410,6 +392,3 @@
ranged_message = "You charge the clockwork slab with shocking might.\n\
Left-click a target to fire, quickly!"
timeout_time = 20
-
-/obj/structure/destructible/clockwork/powered/volt_checker
- invisibility = INVISIBILITY_ABSTRACT
diff --git a/code/game/gamemodes/clock_cult/clock_structure.dm b/code/game/gamemodes/clock_cult/clock_structure.dm
index 64c71359719..9b704101bfd 100644
--- a/code/game/gamemodes/clock_cult/clock_structure.dm
+++ b/code/game/gamemodes/clock_cult/clock_structure.dm
@@ -9,7 +9,7 @@
anchored = 1
density = 1
resistance_flags = FIRE_PROOF | ACID_PROOF
- var/can_be_repaired = TRUE //if a proselytizer can repair it
+ var/can_be_repaired = TRUE //if a fabricator can repair it
break_message = "The frog isn't a meme after all!" //The message shown when a structure breaks
break_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' //The sound played when a structure breaks
debris = list(/obj/item/clockwork/alloy_shards/large = 1, \
@@ -175,13 +175,6 @@
SSobj.processing -= src
return ..()
-/obj/structure/destructible/clockwork/powered/ratvar_act()
- ..()
- if(GLOB.nezbere_invoked)
- needs_power = FALSE
- else
- needs_power = initial(needs_power)
-
/obj/structure/destructible/clockwork/powered/process()
var/powered = total_accessable_power()
return powered == PROCESS_KILL ? 25 : powered //make sure we don't accidentally return the arbitrary PROCESS_KILL define
diff --git a/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm
index 2190bccdd1f..a795d21f25b 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/ark_of_the_clockwork_justicar.dm
@@ -69,7 +69,7 @@
if(!purpose_fulfilled)
var/area/gate_area = get_area(src)
hierophant_message("An Ark of the Clockwork Justicar has fallen at [gate_area.map_name]!")
- send_to_playing_players(sound(null, 0, channel = 8))
+ send_to_playing_players(sound(null, 0, channel = CHANNEL_JUSTICAR_ARK))
var/was_stranded = SSshuttle.emergency.mode == SHUTTLE_STRANDED
SSshuttle.clearHostileEnvironment(src)
if(!was_stranded && !purpose_fulfilled)
@@ -88,7 +88,7 @@
resistance_flags |= INDESTRUCTIBLE
countdown.stop()
visible_message("[src] begins to pulse uncontrollably... you might want to run!")
- send_to_playing_players(sound('sound/effects/clockcult_gateway_disrupted.ogg', 0, channel = 8, volume = 50))
+ send_to_playing_players(sound('sound/effects/clockcult_gateway_disrupted.ogg', 0, channel = CHANNEL_JUSTICAR_ARK, volume = 50))
make_glow()
glow.icon_state = "clockwork_gateway_disrupted"
resistance_flags |= INDESTRUCTIBLE
@@ -204,7 +204,7 @@
if(still_needs_components())
if(!first_sound_played)
priority_announce("Massive energy anomaly detected on short-range scanners. Attempting to triangulate location...", "Anomaly Alert")
- send_to_playing_players(sound('sound/effects/clockcult_gateway_charging.ogg', 1, channel = 8, volume = 10))
+ send_to_playing_players(sound('sound/effects/clockcult_gateway_charging.ogg', 1, channel = CHANNEL_JUSTICAR_ARK, volume = 10))
first_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_components"
@@ -229,7 +229,7 @@
switch(progress_in_seconds)
if(-INFINITY to GATEWAY_REEBE_FOUND)
if(!second_sound_played)
- send_to_playing_players(sound('sound/effects/clockcult_gateway_charging.ogg', 1, channel = 8, volume = 30))
+ send_to_playing_players(sound('sound/effects/clockcult_gateway_charging.ogg', 1, channel = CHANNEL_JUSTICAR_ARK, volume = 30))
second_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_charging"
@@ -237,13 +237,13 @@
if(!third_sound_played)
var/area/gate_area = get_area(src)
priority_announce("Location of massive energy anomaly has been triangulated. Location: [gate_area.map_name].", "Anomaly Alert")
- send_to_playing_players(sound('sound/effects/clockcult_gateway_active.ogg', 1, channel = 8, volume = 35))
+ send_to_playing_players(sound('sound/effects/clockcult_gateway_active.ogg', 1, channel = CHANNEL_JUSTICAR_ARK, volume = 35))
third_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_active"
if(GATEWAY_RATVAR_COMING to GATEWAY_RATVAR_ARRIVAL)
if(!fourth_sound_played)
- send_to_playing_players(sound('sound/effects/clockcult_gateway_closing.ogg', 1, channel = 8, volume = 40))
+ send_to_playing_players(sound('sound/effects/clockcult_gateway_closing.ogg', 1, channel = CHANNEL_JUSTICAR_ARK, volume = 40))
fourth_sound_played = TRUE
make_glow()
glow.icon_state = "clockwork_gateway_closing"
@@ -254,7 +254,7 @@
purpose_fulfilled = TRUE
make_glow()
animate(glow, transform = matrix() * 1.5, alpha = 255, time = 125)
- send_to_playing_players(sound('sound/effects/ratvar_rises.ogg', 0, channel = 8)) //End the sounds
+ send_to_playing_players(sound('sound/effects/ratvar_rises.ogg', 0, channel = CHANNEL_JUSTICAR_ARK)) //End the sounds
sleep(125)
make_glow()
animate(glow, transform = matrix() * 3, alpha = 0, time = 5)
diff --git a/code/game/gamemodes/clock_cult/clock_structures/clock_shells.dm b/code/game/gamemodes/clock_cult/clock_structures/clock_shells.dm
index cfcac3b5155..e9f02e9e8c1 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/clock_shells.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/clock_shells.dm
@@ -34,7 +34,7 @@
/obj/structure/destructible/clockwork/shell/cogscarab
name = "cogscarab shell"
desc = "A small brass shell with a cube-shaped receptable in its center. It gives off an aura of obsessive perfectionism."
- clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a weak construct with an inbuilt proselytizer."
+ clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a weak construct with an inbuilt fabricator."
icon_state = "clockdrone_shell"
mobtype = /mob/living/simple_animal/drone/cogscarab
spawn_message = "'s eyes blink open, glowing bright red."
diff --git a/code/game/gamemodes/clock_cult/clock_structures/geis_binding.dm b/code/game/gamemodes/clock_cult/clock_structures/geis_binding.dm
index 84098fca578..03fb99cd58f 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/geis_binding.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/geis_binding.dm
@@ -13,7 +13,7 @@
icon = 'icons/effects/clockwork_effects.dmi'
icon_state = "geisbinding_full"
break_message = null
- break_sound = 'sound/magic/Repulse.ogg'
+ break_sound = 'sound/magic/repulse.ogg'
debris = list()
can_buckle = TRUE
buckle_lying = 0
@@ -72,7 +72,7 @@
L.resist()
/obj/structure/destructible/clockwork/geis_binding/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
- playsound(src, 'sound/effects/EMPulse.ogg', 50, 1)
+ playsound(src, 'sound/effects/empulse.ogg', 50, 1)
/obj/structure/destructible/clockwork/geis_binding/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
@@ -88,7 +88,7 @@
for(var/m in buckled_mobs)
var/mob/living/L = m
if(L)
- L.Stun(1, 1, 1)
+ L.Stun(20, 1, 1)
if(iscarbon(L))
var/mob/living/carbon/C = L
C.silent += 4
diff --git a/code/game/gamemodes/clock_cult/clock_structures/interdiction_lens.dm b/code/game/gamemodes/clock_cult/clock_structures/interdiction_lens.dm
index 0722c986050..71c82c1a194 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/interdiction_lens.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/interdiction_lens.dm
@@ -9,7 +9,7 @@
inactive_icon = "interdiction_lens"
unanchored_icon = "interdiction_lens_unwrenched"
break_message = "The lens flares a blinding violet before the totem beneath it shatters!"
- break_sound = 'sound/effects/Glassbr3.ogg'
+ break_sound = 'sound/effects/glassbr3.ogg'
debris = list(/obj/item/clockwork/alloy_shards/small = 2, \
/obj/item/clockwork/alloy_shards/large = 2, \
/obj/item/clockwork/component/belligerent_eye/lens_gem = 1)
@@ -137,7 +137,7 @@
if(power_drained && power_drained >= MIN_CLOCKCULT_POWER && return_power(power_drained))
successfulprocess = TRUE
- playsound(src, 'sound/items/PSHOOM.ogg', 50 * efficiency, 1, interdiction_range-7, 1)
+ playsound(src, 'sound/items/pshoom.ogg', 50 * efficiency, 1, interdiction_range-7, 1)
if(!successfulprocess)
forced_disable()
diff --git a/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm b/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm
index 9c7b5e9518e..bb2be4e79ca 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/ocular_warden.dm
@@ -50,9 +50,6 @@
if(GLOB.ratvar_awakens)
damage_per_tick = 10
sight_range = 6
- else if(GLOB.nezbere_invoked)
- damage_per_tick = 5
- sight_range = 5
else
damage_per_tick = initial(damage_per_tick)
sight_range = initial(sight_range)
diff --git a/code/game/gamemodes/clock_cult/clock_structures/prolonging_prism.dm b/code/game/gamemodes/clock_cult/clock_structures/prolonging_prism.dm
new file mode 100644
index 00000000000..e7c6de6b479
--- /dev/null
+++ b/code/game/gamemodes/clock_cult/clock_structures/prolonging_prism.dm
@@ -0,0 +1,136 @@
+//Prolonging Prism: A prism that consumes power to delay the shuttle
+/obj/structure/destructible/clockwork/powered/prolonging_prism
+ name = "prolonging prism"
+ desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
+ clockwork_desc = "A powerful prism that will delay the arrival of an emergency shuttle."
+ icon_state = "prolonging_prism_inactive"
+ active_icon = "prolonging_prism"
+ inactive_icon = "prolonging_prism_inactive"
+ unanchored_icon = "prolonging_prism_unwrenched"
+ construction_value = 20
+ max_integrity = 125
+ obj_integrity = 125
+ break_message = "The prism falls to the ground with a heavy thud!"
+ debris = list(/obj/item/clockwork/alloy_shards/small = 3, \
+ /obj/item/clockwork/alloy_shards/medium = 1, \
+ /obj/item/clockwork/alloy_shards/large = 1, \
+ /obj/item/clockwork/component/vanguard_cogwheel/onyx_prism = 1)
+ var/static/list/component_refund = list(VANGUARD_COGWHEEL = 2, GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 1)
+ var/static/delay_cost = 2500
+ var/static/delay_cost_increase = 750
+ var/static/delay_remaining = 0
+
+/obj/structure/destructible/clockwork/powered/prolonging_prism/examine(mob/user)
+ ..()
+ if(is_servant_of_ratvar(user) || isobserver(user))
+ if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
+ to_chat(user, "An emergency shuttle has arrived and this prism is no longer useful; attempt to activate it to gain a partial refund of components used.")
+ else
+ var/efficiency = get_efficiency_mod(TRUE)
+ to_chat(user, "It requires at least [get_delay_cost()]W of power to attempt to delay the arrival of an emergency shuttle by [2 * efficiency] minutes.")
+ to_chat(user, "This cost increases by [delay_cost_increase * 0.1]W for every 10 CV and [delay_cost_increase]W for every previous activation.")
+
+/obj/structure/destructible/clockwork/powered/prolonging_prism/forced_disable(bad_effects)
+ if(active)
+ if(bad_effects)
+ try_use_power(MIN_CLOCKCULT_POWER*4)
+ visible_message("[src] emits an airy chuckling sound and falls dark!")
+ toggle()
+ return TRUE
+
+/obj/structure/destructible/clockwork/powered/prolonging_prism/attack_hand(mob/living/user)
+ if(user.canUseTopic(src, !issilicon(user), NO_DEXTERY) && is_servant_of_ratvar(user))
+ if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
+ to_chat(user, "You break [src] apart, refunding some of the components used.")
+ for(var/i in component_refund)
+ generate_cache_component(i, src)
+ take_damage(max_integrity)
+ return 0
+ if(active)
+ return 0
+ var/turf/T = get_turf(src)
+ if(!T || T.z != ZLEVEL_STATION)
+ to_chat(user, "[src] must be on the station to function!")
+ return 0
+ if(SSshuttle.emergency.mode != SHUTTLE_CALL)
+ to_chat(user, "No emergency shuttles are attempting to arrive at the station!")
+ return 0
+ if(!try_use_power(get_delay_cost()))
+ to_chat(user, "[src] needs more power to function!")
+ return 0
+ delay_cost += delay_cost_increase
+ delay_remaining += PRISM_DELAY_DURATION
+ toggle(0, user)
+
+/obj/structure/destructible/clockwork/powered/prolonging_prism/process()
+ var/turf/own_turf = get_turf(src)
+ if(SSshuttle.emergency.mode != SHUTTLE_CALL || delay_remaining <= 0 || !own_turf || own_turf.z != ZLEVEL_STATION)
+ forced_disable(FALSE)
+ return
+ . = ..()
+ var/delay_amount = 40
+ delay_remaining -= delay_amount
+ var/efficiency = get_efficiency_mod()
+ SSshuttle.emergency.setTimer(SSshuttle.emergency.timeLeft(1) + (delay_amount * efficiency))
+ var/highest_y
+ var/highest_x
+ var/lowest_y
+ var/lowest_x
+ var/list/prism_turfs = list()
+ for(var/t in SSshuttle.emergency.ripple_area(SSshuttle.getDock("emergency_home")))
+ prism_turfs[t] = TRUE
+ var/turf/T = t
+ if(!highest_y || T.y > highest_y)
+ highest_y = T.y
+ if(!highest_x || T.x > highest_x)
+ highest_x = T.x
+ if(!lowest_y || T.y < lowest_y)
+ lowest_y = T.y
+ if(!lowest_x || T.x < lowest_x)
+ lowest_x = T.x
+ var/mean_y = Lerp(lowest_y, highest_y)
+ var/mean_x = Lerp(lowest_x, highest_x)
+ if(prob(50))
+ mean_y = Ceiling(mean_y)
+ else
+ mean_y = Floor(mean_y)
+ if(prob(50))
+ mean_x = Ceiling(mean_x)
+ else
+ mean_x = Floor(mean_x)
+ var/turf/semi_random_center_turf = locate(mean_x, mean_y, ZLEVEL_STATION)
+ for(var/t in getline(src, semi_random_center_turf))
+ prism_turfs[t] = TRUE
+ var/placement_style = prob(50)
+ for(var/t in prism_turfs)
+ var/turf/T = t
+ if(placement_style)
+ if(IsOdd(T.x + T.y))
+ seven_random_hexes(T, efficiency)
+ else if(prob(50 * efficiency))
+ new /obj/effect/temp_visual/ratvar/prolonging_prism(T)
+ else
+ if(IsEven(T.x + T.y))
+ seven_random_hexes(T, efficiency)
+ else if(prob(50 * efficiency))
+ new /obj/effect/temp_visual/ratvar/prolonging_prism(T)
+ CHECK_TICK //we may be going over a hell of a lot of turfs
+
+/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/get_delay_cost()
+ return Floor((GLOB.clockwork_construction_value * delay_cost_increase * 0.01) + delay_cost, MIN_CLOCKCULT_POWER)
+
+/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/seven_random_hexes(turf/T, efficiency)
+ var/static/list/hex_states = list("prismhex1", "prismhex2", "prismhex3", "prismhex4", "prismhex5", "prismhex6", "prismhex7")
+ var/mutable_appearance/hex_combo
+ for(var/n in hex_states) //BUILD ME A HEXAGON
+ if(prob(50 * efficiency))
+ if(!hex_combo)
+ hex_combo = mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)
+ else
+ hex_combo.overlays += mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)
+ if(hex_combo) //YOU BUILT A HEXAGON
+ hex_combo.pixel_x = -16
+ hex_combo.pixel_y = -16
+ hex_combo.mouse_opacity = 0
+ hex_combo.plane = GAME_PLANE
+ new /obj/effect/temp_visual/ratvar/prolonging_prism(T, hex_combo)
diff --git a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm
index 25f151def54..c0f149cdef2 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm
@@ -14,7 +14,7 @@
light_color = "#BE8700"
var/atom/prey //Whatever Ratvar is chasing
var/clashing = FALSE //If Ratvar is FUCKING FIGHTING WITH NAR-SIE
- var/proselytize_range = 10
+ var/convert_range = 10
dangerous_possession = TRUE
/obj/structure/destructible/clockwork/massive/ratvar/Initialize()
@@ -49,7 +49,7 @@
/obj/structure/destructible/clockwork/massive/ratvar/Bump(atom/A)
var/turf/T = get_turf(A)
if(T == loc)
- T = get_step(A, A.dir) //please don't run into a window like a bird, ratvar
+ T = get_step(T, dir) //please don't run into a window like a bird, ratvar
forceMove(T)
/obj/structure/destructible/clockwork/massive/ratvar/Process_Spacemove()
@@ -58,10 +58,10 @@
/obj/structure/destructible/clockwork/massive/ratvar/process()
if(clashing) //I'm a bit occupied right now, thanks
return
- for(var/I in circlerangeturfs(src, proselytize_range))
+ for(var/I in circlerangeturfs(src, convert_range))
var/turf/T = I
T.ratvar_act()
- for(var/I in circleviewturfs(src, round(proselytize_range * 0.5)))
+ for(var/I in circleviewturfs(src, round(convert_range * 0.5)))
var/turf/T = I
T.ratvar_act(TRUE)
var/dir_to_step_in = pick(GLOB.cardinal)
diff --git a/code/game/gamemodes/clock_cult/clock_structures/taunting_trail.dm b/code/game/gamemodes/clock_cult/clock_structures/taunting_trail.dm
index 31d3639924a..d29b4eeafa1 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/taunting_trail.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/taunting_trail.dm
@@ -2,7 +2,7 @@
/obj/structure/destructible/clockwork/taunting_trail
name = "strange smoke"
desc = "A cloud of purple smoke."
- clockwork_desc = "A cloud of purple smoke that confuses and weakens non-Servants that enter it."
+ clockwork_desc = "A cloud of purple smoke that confuses and knocks down non-Servants that enter it."
gender = PLURAL
max_integrity = 5
obj_integrity = 5
@@ -11,7 +11,7 @@
icon = 'icons/effects/effects.dmi'
icon_state = "smoke"
break_message = null
- break_sound = 'sound/magic/Teleport_app.ogg'
+ break_sound = 'sound/magic/teleport_app.ogg'
debris = list()
var/timerid
@@ -35,7 +35,7 @@
return ..()
/obj/structure/destructible/clockwork/taunting_trail/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
- playsound(src, 'sound/items/Welder.ogg', 50, 1)
+ playsound(src, 'sound/items/welder.ogg', 50, 1)
/obj/structure/destructible/clockwork/taunting_trail/CanPass(atom/movable/mover, turf/target, height=0)
return TRUE
@@ -58,5 +58,5 @@
L.confused = min(L.confused + 15, 50)
L.dizziness = min(L.dizziness + 15, 50)
if(L.confused >= 25)
- L.Weaken(Floor(L.confused * 0.04))
+ L.Knockdown(Floor(L.confused * 0.8))
take_damage(max_integrity)
diff --git a/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm b/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm
index b0a17338ffe..b8f8b75199b 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm
@@ -2,7 +2,7 @@
/obj/structure/destructible/clockwork/powered/tinkerers_daemon
name = "tinkerer's daemon"
desc = "A strange machine with three small brass obelisks attached to it."
- clockwork_desc = "An efficient machine that can rapidly produce components at a small power cost. It will only function if outnumbered by servants at a rate to 5:1."
+ clockwork_desc = "An efficient machine that can rapidly produce components at a small power cost. It will only function if active daemons are outnumbered by servants at a rate to 5:1."
icon_state = "tinkerers_daemon"
active_icon = "tinkerers_daemon"
inactive_icon = "tinkerers_daemon"
@@ -18,26 +18,12 @@
var/static/mutable_appearance/component_glow = mutable_appearance('icons/obj/clockwork_objects.dmi', "t_random_component")
var/component_id_to_produce
var/production_time = 0 //last time we produced a component
- var/production_cooldown = 60
-
-/obj/structure/destructible/clockwork/powered/tinkerers_daemon/Initialize()
- . = ..()
- GLOB.clockwork_daemons++
+ var/production_cooldown = 70
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/Destroy()
- GLOB.clockwork_daemons--
+ GLOB.active_daemons -= src
return ..()
-/obj/structure/destructible/clockwork/powered/tinkerers_daemon/ratvar_act()
- ..()
- if(GLOB.nezbere_invoked)
- production_time = 0
- production_cooldown = initial(production_cooldown) * 0.5
- if(!active)
- toggle(0)
- else
- production_cooldown = initial(production_cooldown)
-
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/examine(mob/user)
..()
if(is_servant_of_ratvar(user) || isobserver(user))
@@ -71,13 +57,6 @@
if(!anchored)
to_chat(user, "[src] needs to be secured to the floor before it can be activated!")
return FALSE
- var/servants = 0
- for(var/mob/living/L in GLOB.living_mob_list)
- if(is_servant_of_ratvar(L))
- servants++
- if(servants * 0.2 < GLOB.clockwork_daemons)
- to_chat(user, "\"There are too few servants for this daemon to work.\"")
- return
if(!GLOB.clockwork_caches)
to_chat(user, "\"You require a cache for this daemon to operate. Get to it.\"")
return
@@ -90,6 +69,13 @@
if(total_accessable_power() < min_power_usable)
to_chat(user, "\"You need more power to activate this daemon, friend.\"")
return
+ var/servants = 0
+ for(var/mob/living/L in GLOB.living_mob_list)
+ if(is_servant_of_ratvar(L))
+ servants++
+ if(servants * 0.2 < 1)
+ to_chat(user, "\"There are too few servants for daemons to work.\"")
+ return
var/choice = alert(user,"Activate Daemon...",,"Specific Component","Random Component","Cancel")
switch(choice)
if("Specific Component")
@@ -102,7 +88,7 @@
for(var/mob/living/L in GLOB.living_mob_list)
if(is_servant_of_ratvar(L))
servants++
- if(!is_servant_of_ratvar(user) || !user.canUseTopic(src, !issilicon(user), NO_DEXTERY) || active || !GLOB.clockwork_caches || servants * 0.2 < GLOB.clockwork_daemons)
+ if(!is_servant_of_ratvar(user) || !user.canUseTopic(src, !issilicon(user), NO_DEXTERY) || active || !GLOB.clockwork_caches || servants * 0.2 < 1)
return
if(!component_id_to_produce)
to_chat(user, "You decide not to select a component and activate the daemon.")
@@ -113,11 +99,18 @@
toggle(0, user)
if("Random Component")
component_id_to_produce = null
+ servants = 0
+ for(var/mob/living/L in GLOB.living_mob_list)
+ if(is_servant_of_ratvar(L))
+ servants++
+ if(!is_servant_of_ratvar(user) || !user.canUseTopic(src, !issilicon(user), NO_DEXTERY) || active || !GLOB.clockwork_caches || servants * 0.2 < 1)
+ return
toggle(0, user)
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/toggle(fast_process, mob/living/user)
. = ..()
if(active)
+ GLOB.active_daemons += src
var/component_color = get_component_color(component_id_to_produce)
daemon_glow.color = component_color
add_overlay(daemon_glow)
@@ -127,6 +120,7 @@
production_time = world.time + production_cooldown //don't immediately produce when turned on after being off
set_light(2, 0.9, get_component_color_bright(component_id_to_produce))
else
+ GLOB.active_daemons -= src
cut_overlays()
set_light(0)
@@ -138,6 +132,14 @@
for(var/mob/living/L in GLOB.living_mob_list)
if(is_servant_of_ratvar(L))
servants++
+ while(servants * 0.2 < LAZYLEN(GLOB.active_daemons))
+ var/obj/structure/destructible/clockwork/powered/tinkerers_daemon/D = GLOB.active_daemons[1]
+ if(!istype(D))
+ break
+ if(D.active)
+ D.forced_disable(FALSE)
+ if(D == src)
+ return
. = ..()
var/min_power_usable = 0
if(!component_id_to_produce)
@@ -148,7 +150,7 @@
min_power_usable = min(min_power_usable, get_component_cost(i))
else
min_power_usable = get_component_cost(component_id_to_produce)
- if(!GLOB.clockwork_caches || servants * 0.2 < GLOB.clockwork_daemons || . < min_power_usable) //if we don't have enough to produce the lowest or what we chose to produce, cancel out
+ if(!GLOB.clockwork_caches || . < min_power_usable) //if we don't have enough to produce the lowest or what we chose to produce, cancel out
forced_disable(FALSE)
return
if(production_time <= world.time)
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index 31fcfea19e5..e4af3c2d45f 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -53,7 +53,6 @@
/datum/game_mode/cult/pre_setup()
cult_objectives += "sacrifice"
- cult_objectives += "eldergod"
if(config.protect_roles_from_antagonist)
restricted_jobs += protected_jobs
@@ -102,11 +101,18 @@
GLOB.sac_image = reshape
else
message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!")
+ if(!GLOB.summon_spots.len)
+ while(GLOB.summon_spots.len < SUMMON_POSSIBILITIES)
+ var/area/summon = pick(GLOB.sortedAreas - GLOB.summon_spots)
+ if((summon.z == ZLEVEL_STATION) && summon.valid_territory)
+ GLOB.summon_spots += summon
+ cult_objectives += "eldergod"
+
for(var/datum/mind/cult_mind in cultists_to_cult)
equip_cultist(cult_mind.current)
update_cult_icons_added(cult_mind)
to_chat(cult_mind.current, "You are a member of the cult!")
- cult_mind.current.playsound_local('sound/ambience/antag/bloodcult.ogg',100,0)//subject to change
+ cult_mind.current.playsound_local(get_turf(cult_mind.current), 'sound/ambience/antag/bloodcult.ogg', 100, FALSE, pressure_affected = FALSE)//subject to change
add_cultist(cult_mind, 0)
..()
@@ -150,7 +156,7 @@
return 0
if(cult_mind.add_antag_datum(ANTAG_DATUM_CULT))
if(stun)
- cult_mind.current.Paralyse(5)
+ cult_mind.current.Unconscious(100)
return 1
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, silent, stun)
@@ -161,7 +167,7 @@
cult_datum.silent = silent
cult_datum.on_removal()
if(stun)
- cult_mind.current.Paralyse(5)
+ cult_mind.current.Unconscious(100)
return TRUE
/datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind)
@@ -239,11 +245,11 @@
SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL")
if("eldergod")
if(!eldergod)
- explanation = "Summon Nar-Sie. Success!"
+ explanation = "Summon Nar-Sie. The summoning can only be accomplished in [english_list(GLOB.summon_spots)].Success!"
SSblackbox.add_details("cult_objective","cult_narsie|SUCCESS")
SSticker.news_report = CULT_SUMMON
else
- explanation = "Summon Nar-Sie. Fail."
+ explanation = "Summon Nar-Sie. The summoning can only be accomplished in [english_list(GLOB.summon_spots)]Fail."
SSblackbox.add_details("cult_objective","cult_narsie|FAIL")
SSticker.news_report = CULT_FAILURE
diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm
index 6651f685564..7b9a0e66993 100644
--- a/code/game/gamemodes/cult/cult_comms.dm
+++ b/code/game/gamemodes/cult/cult_comms.dm
@@ -4,7 +4,7 @@
/datum/action/innate/cult
background_icon_state = "bg_demon"
buttontooltipstyle = "cult"
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
/datum/action/innate/cult/IsAvailable()
if(!iscultist(owner))
@@ -81,17 +81,12 @@
popup.open()
return 1
-/mob/living/proc/cult_master()
- set category = "Cultist"
- set name = "Assert Leadership"
- pollCultists(src) // This proc handles the distribution of cult master actions
-
/datum/action/innate/cult/mastervote
name = "Assert Leadership"
button_icon_state = "cultvote"
/datum/action/innate/cult/mastervote/IsAvailable()
- if(GLOB.cult_vote_called)
+ if(GLOB.cult_vote_called || !ishuman(owner))
return FALSE
return ..()
@@ -236,7 +231,7 @@
return FALSE
if(cooldown > world.time)
if(!CM.active)
- owner << "You need to wait [round((cooldown - world.time) * 0.1)] seconds before you can mark another target!"
+ to_chat(owner, "You need to wait [round((cooldown - world.time) * 0.1)] seconds before you can mark another target!")
return FALSE
return ..()
@@ -300,3 +295,91 @@
B.current.client.images -= GLOB.blood_target_image
QDEL_NULL(GLOB.blood_target_image)
GLOB.blood_target = null
+
+
+
+//////// ELDRITCH PULSE /////////
+
+
+
+/datum/action/innate/cult/master/pulse
+ name = "Eldritch Pulse"
+ desc = "Seize upon a fellow cultist or cult structure and teleport it to a nearby location."
+ button_icon_state = "arcane_barrage"
+ var/obj/effect/proc_holder/pulse/PM
+ var/cooldown = 0
+ var/base_cooldown = 150
+ var/throwing = FALSE
+ var/mob/living/throwee
+
+/datum/action/innate/cult/master/pulse/New()
+ PM = new()
+ PM.attached_action = src
+ ..()
+
+/datum/action/innate/cult/master/pulse/IsAvailable()
+ if(!owner.mind || !owner.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER))
+ return FALSE
+ if(cooldown > world.time)
+ if(!PM.active)
+ owner << "You need to wait [round((cooldown - world.time) * 0.1)] seconds before you can pulse again!"
+ return FALSE
+ return ..()
+
+/datum/action/innate/cult/master/pulse/Destroy()
+ QDEL_NULL(PM)
+ return ..()
+
+/datum/action/innate/cult/master/pulse/Activate()
+ PM.toggle(owner) //the important bit
+ return TRUE
+
+/obj/effect/proc_holder/pulse
+ active = FALSE
+ ranged_mousepointer = 'icons/effects/throw_target.dmi'
+ var/datum/action/innate/cult/master/pulse/attached_action
+
+/obj/effect/proc_holder/pulse/Destroy()
+ QDEL_NULL(attached_action)
+ return ..()
+
+/obj/effect/proc_holder/pulse/proc/toggle(mob/user)
+ if(active)
+ remove_ranged_ability("You cease your preparations...")
+ attached_action.throwing = FALSE
+ else
+ add_ranged_ability(user, "You prepare to tear through the fabric of reality...")
+
+/obj/effect/proc_holder/pulse/InterceptClickOn(mob/living/caller, params, atom/target)
+ if(..())
+ return
+ if(ranged_ability_user.incapacitated())
+ remove_ranged_ability()
+ return
+ var/turf/T = get_turf(ranged_ability_user)
+ if(!isturf(T))
+ return FALSE
+ if(target in view(7, get_turf(ranged_ability_user)))
+ if((!(iscultist(target) || istype(target, /obj/structure/destructible/cult)) || target == caller) && !(attached_action.throwing))
+ return
+ if(!attached_action.throwing)
+ attached_action.throwing = TRUE
+ attached_action.throwee = target
+ ranged_ability_user << 'sound/weapons/thudswoosh.ogg'
+ to_chat(ranged_ability_user,"You reach through the veil with your mind's eye and seize [target]!")
+ return
+ else
+ new /obj/effect/temp_visual/cult/sparks(get_turf(attached_action.throwee), ranged_ability_user.dir)
+ var/distance = get_dist(attached_action.throwee, target)
+ if(distance >= 16)
+ return
+ playsound(target,'sound/magic/exit_blood.ogg')
+ attached_action.throwee.Beam(target,icon_state="sendbeam",time=4)
+ attached_action.throwee.forceMove(get_turf(target))
+ new /obj/effect/temp_visual/cult/sparks(get_turf(target), ranged_ability_user.dir)
+ attached_action.throwing = FALSE
+ attached_action.cooldown = world.time + attached_action.base_cooldown
+ remove_mousepointer(ranged_ability_user.client)
+ remove_ranged_ability("A pulse of blood magic surges through you as you shift [attached_action.throwee] through time and space.")
+ caller.update_action_buttons_icon()
+ addtimer(CALLBACK(caller, /mob.proc/update_action_buttons_icon), attached_action.base_cooldown)
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index 84c2ab36269..9d9bb86d60f 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -14,7 +14,7 @@
/obj/item/weapon/melee/cultblade/attack(mob/living/target, mob/living/carbon/human/user)
if(!iscultist(user))
- user.Weaken(5)
+ user.Knockdown(100)
user.dropItemToGround(src, TRUE)
user.visible_message("A powerful force shoves [user] away from [target]!", \
"\"You shouldn't play with sharp things. You'll poke someone's eye out.\"")
@@ -69,7 +69,7 @@
desc = "A strong bola, bound with dark magic. Throw it to trip and slow your victim."
icon_state = "bola_cult"
breakouttime = 45
- weaken = 1
+ knockdown = 10
/obj/item/clothing/head/culthood
@@ -192,7 +192,7 @@
to_chat(user, "An overwhelming sense of nausea overpowers you!")
user.dropItemToGround(src, TRUE)
user.Dizzy(30)
- user.Weaken(5)
+ user.Knockdown(100)
else
to_chat(user, "\"Trying to use things you don't own is bad, you know.\"")
to_chat(user, "The armor squeezes at your body!")
@@ -200,7 +200,7 @@
user.adjustBruteLoss(25)
user.dropItemToGround(src, TRUE)
-/obj/item/clothing/suit/hooded/cultrobes/cult_shield/hit_reaction(mob/living/carbon/human/owner, attack_text, isinhands)
+/obj/item/clothing/suit/hooded/cultrobes/cult_shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(current_charges)
owner.visible_message("\The [attack_text] is deflected in a burst of blood-red sparks!")
current_charges--
@@ -244,7 +244,7 @@
to_chat(user, "An overwhelming sense of nausea overpowers you!")
user.dropItemToGround(src, TRUE)
user.Dizzy(30)
- user.Weaken(5)
+ user.Knockdown(100)
else
to_chat(user, "\"Trying to use things you don't own is bad, you know.\"")
to_chat(user, "The robes squeeze at your body!")
@@ -266,7 +266,7 @@
to_chat(user, "\"You want to be blind, do you?\"")
user.dropItemToGround(src, TRUE)
user.Dizzy(30)
- user.Weaken(5)
+ user.Knockdown(100)
user.blind_eyes(30)
/obj/item/weapon/reagent_containers/food/drinks/bottle/unholywater
@@ -286,7 +286,7 @@
/obj/item/device/shuttle_curse/attack_self(mob/user)
if(!iscultist(user))
user.dropItemToGround(src, TRUE)
- user.Weaken(5)
+ user.Knockdown(100)
to_chat(user, "A powerful force shoves you away from [src]!")
return
if(curselimit > 1)
@@ -301,7 +301,7 @@
var/timer = SSshuttle.emergency.timeLeft(1) + cursetime
SSshuttle.emergency.setTimer(timer)
to_chat(user, "You shatter the orb! A dark essence spirals into the air, then disappears.")
- playsound(user.loc, 'sound/effects/Glassbr1.ogg', 50, 1)
+ playsound(user.loc, 'sound/effects/glassbr1.ogg', 50, 1)
qdel(src)
sleep(20)
var/global/list/curses
@@ -381,7 +381,7 @@
on_damage = 15
slot_flags = null
on = 1
- var/charges = 3
+ var/charges = 5
/obj/item/device/flashlight/flare/culttorch/afterattack(atom/movable/A, mob/user, proximity)
if(!proximity)
@@ -408,6 +408,9 @@
to_chat(user, "[cultist_to_receive] is not a follower of the Geometer!")
log_game("Void torch failed - target was deconverted")
return
+ if(A in user.GetAllContents())
+ to_chat(user, "[A] must be on a surface in order to teleport it!")
+ return
to_chat(user, "You ignite [A] with \the [src], turning it to ash, but through the torch's flames you see that [A] has reached [cultist_to_receive]!")
cultist_to_receive.put_in_hands(A)
charges--
diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm
index 63e5b97b9ed..1785f188a97 100644
--- a/code/game/gamemodes/cult/cult_structures.dm
+++ b/code/game/gamemodes/cult/cult_structures.dm
@@ -129,7 +129,7 @@
icon_state = "pylon"
light_range = 5
light_color = LIGHT_COLOR_RED
- break_sound = 'sound/effects/Glassbr2.ogg'
+ break_sound = 'sound/effects/glassbr2.ogg'
break_message = "The blood-red crystal falls to the floor and shatters!"
var/heal_delay = 25
var/last_heal = 0
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index e292cf5ab3b..049b8fe62bf 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -70,7 +70,7 @@ This file contains the arcane tome files.
/obj/item/weapon/tome/proc/read_tome(mob/user)
var/text = ""
text += "
Archives of the Dark One
"
- text += "A rune's name and effects can be revealed by examining the rune.<
"
+ text += "A rune's name and effects can be revealed by examining the rune.
"
text += "Create Talisman This rune is one of the most important runes the cult has, being the only way to create new talismans. A blank sheet of paper must be on top of the rune. After \
invoking it and choosing which talisman you desire, the paper will be converted, after some delay into a talisman.
"
@@ -206,8 +206,8 @@ This file contains the arcane tome files.
if(!SSticker.mode.eldergod)
to_chat(user, "\"I am already here. There is no need to try to summon me now.\"")
return
- if((loc.z && loc.z != ZLEVEL_STATION) || !A.blob_allowed)
- to_chat(user, "The Geometer is not interested in lesser locations; the station is the prize!")
+ if(!(A in GLOB.summon_spots))
+ to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(GLOB.summon_spots)]!")
return
var/confirm_final = alert(user, "This is the FINAL step to summon Nar-Sie; it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No")
if(confirm_final == "No")
@@ -215,9 +215,10 @@ This file contains the arcane tome files.
return
Turf = get_turf(user)
A = get_area(src)
- if(!check_rune_turf(Turf, user) || (loc.z && loc.z != ZLEVEL_STATION)|| !A.blob_allowed)
+ if(!(A in GLOB.summon_spots)) // Check again to make sure they didn't move
+ to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(GLOB.summon_spots)]!")
return
- priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/AI/spanomalies.ogg')
+ priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/ai/spanomalies.ogg')
for(var/B in spiral_range_turfs(1, user, 1))
var/obj/structure/emergency_shield/sanguine/N = new(B)
shields += N
@@ -248,8 +249,6 @@ This file contains the arcane tome files.
SSblackbox.add_details("cult_runes_scribed", R.cultist_name)
/obj/item/weapon/tome/proc/check_rune_turf(turf/T, mob/user)
- var/area/A = get_area(T)
-
if(isspaceturf(T))
to_chat(user, "You cannot scribe runes in space!")
return FALSE
@@ -262,8 +261,4 @@ This file contains the arcane tome files.
to_chat(user, "The veil is not weak enough here.")
return FALSE
- if(istype(A, /area/shuttle))
- to_chat(user, "Interference from hyperspace engines disrupts the Geometer's power on shuttles.")
- return FALSE
-
return TRUE
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 9702783e945..713dc73cfb9 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -35,6 +35,7 @@ To draw a rune, use an arcane tome.
var/scribe_damage = 0.1 //how much damage you take doing it
var/allow_excess_invokers = FALSE //if we allow excess invokers when being invoked
+ var/invoke_damage = 0 //how much damage invokers take when invoking it
var/construct_invoke = TRUE //if constructs can invoke it
var/req_keyword = 0 //If the rune requires a keyword - go figure amirite
@@ -133,10 +134,13 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/proc/invoke(var/list/invokers)
//This proc contains the effects of the rune as well as things that happen afterwards. If you want it to spawn an object and then delete itself, have both here.
- if(invocation)
- for(var/M in invokers)
- var/mob/living/L = M
+ for(var/M in invokers)
+ var/mob/living/L = M
+ if(invocation)
L.say(invocation, language = /datum/language/common)
+ if(invoke_damage)
+ L.apply_damage(invoke_damage, BRUTE)
+ to_chat(L, "[src] saps your strength!")
do_invoke_glow()
/obj/effect/rune/proc/do_invoke_glow()
@@ -159,6 +163,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_name = "malformed rune"
cultist_desc = "a senseless rune written in gibberish. No good can come from invoking this."
invocation = "Ra'sha yoka!"
+ invoke_damage = 30
/obj/effect/rune/malformed/Initialize(mapload, set_keyword)
. = ..()
@@ -167,10 +172,6 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/malformed/invoke(var/list/invokers)
..()
- for(var/M in invokers)
- var/mob/living/L = M
- to_chat(L, "You feel your life force draining. The Geometer is displeased.")
- L.apply_damage(30, BRUTE)
qdel(src)
/mob/proc/null_rod_check() //The null rod, if equipped, will protect the holder from the effects of most runes
@@ -356,7 +357,7 @@ structure_check() searches for nearby cultist structures required for the invoca
L.visible_message("[L]'s eyes glow a defiant yellow!", \
"\"Stop resisting. You will be mi-\"\n\
\"Give up and you will feel pain unlike anything you've ever felt!\"")
- L.Weaken(4)
+ L.Knockdown(80)
else if(is_convertable)
do_convert(L, invokers)
else
@@ -428,10 +429,10 @@ structure_check() searches for nearby cultist structures required for the invoca
if(sacrificial)
if(iscyborg(sacrificial))
- playsound(sacrificial, 'sound/magic/Disable_Tech.ogg', 100, 1)
+ playsound(sacrificial, 'sound/magic/disable_tech.ogg', 100, 1)
sacrificial.dust() //To prevent the MMI from remaining
else
- playsound(sacrificial, 'sound/magic/Disintegrate.ogg', 100, 1)
+ playsound(sacrificial, 'sound/magic/disintegrate.ogg', 100, 1)
sacrificial.gib()
return TRUE
@@ -446,7 +447,7 @@ structure_check() searches for nearby cultist structures required for the invoca
icon_state = "rune_large"
pixel_x = -32 //So the big ol' 96x96 sprite shows up right
pixel_y = -32
- scribe_delay = 450 //how long the rune takes to create
+ scribe_delay = 500 //how long the rune takes to create
scribe_damage = 40.1 //how much damage you take doing it
var/used = FALSE
@@ -508,9 +509,7 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/raise_dead/examine(mob/user)
..()
if(iscultist(user) || user.stat == DEAD)
- var/revive_number = 0
- if(GLOB.sacrificed.len)
- revive_number = GLOB.sacrificed.len - revives_used
+ var/revive_number = LAZYLEN(GLOB.sacrificed) - revives_used
to_chat(user, "Revives Remaining: [revive_number]")
/obj/effect/rune/raise_dead/invoke(var/list/invokers)
@@ -520,6 +519,7 @@ structure_check() searches for nearby cultist structures required for the invoca
var/mob/living/user = invokers[1]
if(rune_in_use)
return
+ rune_in_use = TRUE
for(var/mob/living/M in T.contents)
if(iscultist(M) && M.stat == DEAD)
potential_revive_mobs |= M
@@ -527,18 +527,20 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(user, "There are no dead cultists on the rune!")
log_game("Raise Dead rune failed - no corpses to revive")
fail_invoke()
+ rune_in_use = FALSE
return
- if(!GLOB.sacrificed.len || GLOB.sacrificed.len <= revives_used)
+ if(LAZYLEN(GLOB.sacrificed) <= revives_used)
to_chat(user, "You have sacrificed too few people to revive a cultist!")
fail_invoke()
+ rune_in_use = FALSE
return
if(potential_revive_mobs.len > 1)
mob_to_revive = input(user, "Choose a cultist to revive.", "Cultist to Revive") as null|anything in potential_revive_mobs
else
mob_to_revive = potential_revive_mobs[1]
if(!src || QDELETED(src) || rune_in_use || !validness_checks(mob_to_revive, user))
+ rune_in_use = FALSE
return
- rune_in_use = 1
if(user.name == "Herbert West")
invocation = "To life, to life, I bring them!"
else
@@ -550,34 +552,34 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(mob_to_revive, "\"PASNAR SAVRAE YAM'TOTH. Arise.\"")
mob_to_revive.visible_message("[mob_to_revive] draws in a huge breath, red light shining from [mob_to_revive.p_their()] eyes.", \
"You awaken suddenly from the void. You're alive!")
- rune_in_use = 0
+ rune_in_use = FALSE
/obj/effect/rune/raise_dead/proc/validness_checks(mob/living/target_mob, mob/living/user)
var/turf/T = get_turf(src)
- if(!user)
- return 0
+ if(QDELETED(user))
+ return FALSE
if(!Adjacent(user) || user.incapacitated())
- return 0
- if(!target_mob)
+ return FALSE
+ if(QDELETED(target_mob))
fail_invoke()
- return 0
+ return FALSE
if(!(target_mob in T.contents))
to_chat(user, "The cultist to revive has been moved!")
fail_invoke()
log_game("Raise Dead rune failed - revival target moved")
- return 0
+ return FALSE
var/mob/dead/observer/ghost = target_mob.get_ghost(TRUE)
if(!ghost && (!target_mob.mind || !target_mob.mind.active))
to_chat(user, "The corpse to revive has no spirit!")
fail_invoke()
log_game("Raise Dead rune failed - revival target has no ghost")
- return 0
+ return FALSE
if(!GLOB.sacrificed.len || GLOB.sacrificed.len <= revives_used)
to_chat(user, "You have sacrificed too few people to revive a cultist!")
fail_invoke()
log_game("Raise Dead rune failed - too few sacrificed")
- return 0
- return 1
+ return FALSE
+ return TRUE
/obj/effect/rune/raise_dead/fail_invoke()
..()
@@ -592,7 +594,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "emits a large electromagnetic pulse, increasing in size for each cultist invoking it, hindering electronics and disabling silicons."
invocation = "Ta'gh fara'qha fel d'amar det!"
icon_state = "5"
- allow_excess_invokers = 1
+ allow_excess_invokers = TRUE
color = RUNE_COLOR_EMP
/obj/effect/rune/emp/invoke(var/list/invokers)
@@ -601,19 +603,19 @@ structure_check() searches for nearby cultist structures required for the invoca
visible_message("[src] glows blue for a moment before vanishing.")
switch(invokers.len)
if(1 to 2)
- playsound(E, 'sound/items/Welder2.ogg', 25, 1)
+ playsound(E, 'sound/items/welder2.ogg', 25, 1)
for(var/M in invokers)
to_chat(M, "You feel a minute vibration pass through you...")
if(3 to 6)
- playsound(E, 'sound/magic/Disable_Tech.ogg', 50, 1)
+ playsound(E, 'sound/magic/disable_tech.ogg', 50, 1)
for(var/M in invokers)
- to_chat(M, "Your hair stands on end as a shockwave eminates from the rune!")
+ to_chat(M, "Your hair stands on end as a shockwave emanates from the rune!")
if(7 to INFINITY)
- playsound(E, 'sound/magic/Disable_Tech.ogg', 100, 1)
+ playsound(E, 'sound/magic/disable_tech.ogg', 100, 1)
for(var/M in invokers)
var/mob/living/L = M
to_chat(L, "You chant in unison and a colossal burst of energy knocks you backward!")
- L.Weaken(2)
+ L.Knockdown(40)
qdel(src) //delete before pulsing because it's a delay reee
empulse(E, 9*invokers.len, 12*invokers.len) // Scales now, from a single room to most of the station depending on # of chanters
@@ -624,14 +626,18 @@ structure_check() searches for nearby cultist structures required for the invoca
invocation = "Fwe'sh mah erl nyag r'ya!"
icon_state = "7"
color = RUNE_COLOR_DARKRED
- rune_in_use = 0 //One at a time, please!
- construct_invoke = 0
+ rune_in_use = FALSE //One at a time, please!
+ construct_invoke = FALSE
var/mob/living/affecting = null
+/obj/effect/rune/spirit/Destroy()
+ affecting = null
+ return ..()
+
/obj/effect/rune/spirit/examine(mob/user)
..()
if(affecting)
- to_chat(user, "A translucent field encases [user] above the rune!")
+ to_chat(user, "A translucent field encases [affecting] above the rune!")
/obj/effect/rune/spirit/can_invoke(mob/living/user)
if(rune_in_use)
@@ -651,41 +657,33 @@ structure_check() searches for nearby cultist structures required for the invoca
var/turf/T = get_turf(src)
rune_in_use = TRUE
affecting = user
- user.add_atom_colour(RUNE_COLOR_DARKRED, ADMIN_COLOUR_PRIORITY)
- user.visible_message("[user] freezes statue-still, glowing an unearthly red.", \
+ affecting.add_atom_colour(RUNE_COLOR_DARKRED, ADMIN_COLOUR_PRIORITY)
+ affecting.visible_message("[affecting] freezes statue-still, glowing an unearthly red.", \
"You see what lies beyond. All is revealed. While this is a wondrous experience, your physical form will waste away in this state. Hurry...")
- user.ghostize(1)
- while(user)
- if(!affecting)
- visible_message("[src] pulses gently before falling dark.")
- affecting = null //In case it's assigned to a number or something
- rune_in_use = FALSE
- return
+ affecting.ghostize(1)
+ while(!QDELETED(affecting))
affecting.apply_damage(0.1, BRUTE)
- if(!(user in T))
- user.visible_message("A spectral tendril wraps around [user] and pulls [user.p_them()] back to the rune!")
- Beam(user,icon_state="drainbeam",time=2)
- user.forceMove(get_turf(src)) //NO ESCAPE :^)
- if(user.key)
- user.visible_message("[user] slowly relaxes, the glow around [user.p_them()] dimming.", \
+ if(!(affecting in T))
+ user.visible_message("A spectral tendril wraps around [affecting] and pulls [affecting.p_them()] back to the rune!")
+ Beam(affecting, icon_state="drainbeam", time=2)
+ affecting.forceMove(get_turf(src)) //NO ESCAPE :^)
+ if(affecting.key)
+ affecting.visible_message("[affecting] slowly relaxes, the glow around [affecting.p_them()] dimming.", \
"You are re-united with your physical form. [src] releases its hold over you.")
- user.remove_atom_colour(ADMIN_COLOUR_PRIORITY, RUNE_COLOR_DARKRED)
- user.Weaken(3)
- rune_in_use = FALSE
- affecting = null
- return
- if(user.stat == UNCONSCIOUS)
+ affecting.remove_atom_colour(ADMIN_COLOUR_PRIORITY, RUNE_COLOR_DARKRED)
+ affecting.Knockdown(60)
+ break
+ if(affecting.stat == UNCONSCIOUS)
if(prob(1))
- var/mob/dead/observer/G = user.get_ghost()
+ var/mob/dead/observer/G = affecting.get_ghost()
to_chat(G, "You feel the link between you and your body weakening... you must hurry!")
- if(user.stat == DEAD)
- user.remove_atom_colour(ADMIN_COLOUR_PRIORITY, RUNE_COLOR_DARKRED)
- rune_in_use = FALSE
- affecting = null
- var/mob/dead/observer/G = user.get_ghost()
+ else if(affecting.stat == DEAD)
+ affecting.remove_atom_colour(ADMIN_COLOUR_PRIORITY, RUNE_COLOR_DARKRED)
+ var/mob/dead/observer/G = affecting.get_ghost()
to_chat(G, "You suddenly feel your physical form pass on. [src]'s exertion has killed you!")
- return
+ break
sleep(1)
+ affecting = null
rune_in_use = FALSE
//Rite of the Corporeal Shield: When invoked, becomes solid and cannot be passed. Invoke again to undo.
@@ -726,9 +724,10 @@ structure_check() searches for nearby cultist structures required for the invoca
update_state()
if(density)
spread_density()
- user.visible_message("[user] [iscarbon(user) ? "places [user.p_their()] hands on":"stares intently at"] [src], and [density ? "the air above it begins to shimmer" : "the shimmer above it fades"].", \
- "You channel your life energy into [src], [density ? "temporarily preventing" : "allowing"] passage above it.")
- if(iscarbon(user))
+ var/carbon_user = iscarbon(user)
+ user.visible_message("[user] [carbon_user ? "places [user.p_their()] hands on":"stares intently at"] [src], and [density ? "the air above it begins to shimmer" : "the shimmer above it fades"].", \
+ "You channel [carbon_user ? "your life ":""]energy into [src], [density ? "temporarily preventing" : "allowing"] passage above it.")
+ if(carbon_user)
var/mob/living/carbon/C = user
C.apply_damage(2, BRUTE, pick("l_arm", "r_arm"))
@@ -775,7 +774,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "summons a single cultist to the rune. Requires 2 invokers."
invocation = "N'ath reth sh'yro eth d'rekkathnor!"
req_cultists = 2
- allow_excess_invokers = 1
+ invoke_damage = 10
icon_state = "5"
color = RUNE_COLOR_SUMMON
@@ -812,7 +811,6 @@ structure_check() searches for nearby cultist structures required for the invoca
"Overwhelming vertigo consumes you as you are hurled through the air!")
..()
visible_message("A foggy shape materializes atop [src] and solidifes into [cultist_to_summon]!")
- user.apply_damage(10, BRUTE, "head")
cultist_to_summon.forceMove(get_turf(src))
qdel(src)
@@ -825,7 +823,8 @@ structure_check() searches for nearby cultist structures required for the invoca
color = RUNE_COLOR_MEDIUMRED
light_color = LIGHT_COLOR_LAVA
req_cultists = 3
- construct_invoke = 0
+ invoke_damage = 10
+ construct_invoke = FALSE
var/tick_damage = 25
rune_in_use = FALSE
@@ -839,12 +838,8 @@ structure_check() searches for nearby cultist structures required for the invoca
rune_in_use = TRUE
var/turf/T = get_turf(src)
visible_message("[src] turns a bright, glowing orange!")
- set_light(6)
color = "#FC9B54"
- for(var/M in invokers)
- var/mob/living/L = M
- L.apply_damage(10, BRUTE, pick("l_arm", "r_arm"))
- to_chat(L, "[src] saps your strength!")
+ set_light(6, 1, color)
for(var/mob/living/L in viewers(T))
if(!iscultist(L) && L.blood_volume)
var/obj/item/weapon/nullrod/N = L.null_rod_check()
@@ -856,23 +851,24 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(L, "You feel an unholy darkness dimming the Justiciar's light!")
animate(src, color = "#FCB56D", time = 4)
sleep(4)
- if(!src)
+ if(QDELETED(src))
return
do_area_burn(T, 0.5)
animate(src, color = "#FFDF80", time = 5)
sleep(5)
- if(!src)
+ if(QDELETED(src))
return
do_area_burn(T, 1)
animate(src, color = "#FFFDF4", time = 6)
sleep(6)
- if(!src)
+ if(QDELETED(src))
return
do_area_burn(T, 1.5)
new /obj/effect/hotspot(T)
qdel(src)
/obj/effect/rune/blood_boil/proc/do_area_burn(turf/T, multiplier)
+ set_light(6, 1, color)
for(var/mob/living/L in viewers(T))
if(!iscultist(L) && L.blood_volume)
var/obj/item/weapon/nullrod/N = L.null_rod_check()
@@ -888,7 +884,8 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "manifests a spirit as a servant of the Geometer. The invoker must not move from atop the rune, and will take damage for each summoned spirit."
invocation = "Gal'h'rfikk harfrandid mud'gib!" //how the fuck do you pronounce this
icon_state = "6"
- construct_invoke = 0
+ invoke_damage = 10
+ construct_invoke = FALSE
color = RUNE_COLOR_MEDIUMRED
var/ghost_limit = 5
var/ghosts = 0
@@ -939,7 +936,6 @@ structure_check() searches for nearby cultist structures required for the invoca
..()
ghosts++
playsound(src, 'sound/magic/exit_blood.ogg', 50, 1)
- user.apply_damage(10, BRUTE)
visible_message("A cloud of red mist forms above [src], and from within steps... a [new_human.gender == FEMALE ? "wo":""]man.")
to_chat(user, "Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely...")
var/turf/T = get_turf(src)
diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm
index eeafd50c41f..61bf6722503 100644
--- a/code/game/gamemodes/cult/talisman.dm
+++ b/code/game/gamemodes/cult/talisman.dm
@@ -169,8 +169,7 @@
target.visible_message("[target]'s holy weapon absorbs the talisman's light!", \
"Your holy weapon absorbs the blinding light!")
else
- target.Weaken(10)
- target.Stun(10)
+ target.Knockdown(200)
target.flash_act(1,1)
if(issilicon(target))
var/mob/living/silicon/S = target
diff --git a/code/game/gamemodes/devil/devil agent/devil_agent.dm b/code/game/gamemodes/devil/devil agent/devil_agent.dm
index dfdb957153a..5c48406f23e 100644
--- a/code/game/gamemodes/devil/devil agent/devil_agent.dm
+++ b/code/game/gamemodes/devil/devil agent/devil_agent.dm
@@ -10,8 +10,8 @@
num_modifier = 4
objective_count = 2
- var/list/target_list = list()
- var/list/late_joining_list = list()
+ var/list/devil_target_list = list() //will update to be a child of internal affairs when bothered
+ var/list/devil_late_joining_list = list()
minimum_devils = 3
announce_text = "There are devil agents onboard the station, trying to outbid each other!\n\
@@ -24,7 +24,7 @@
i++
if(i + 1 > devils.len)
i = 0
- target_list[devil] = devils[i + 1]
+ devil_target_list[devil] = devils[i + 1]
..()
/datum/game_mode/devil/devil_agents/add_devil_objectives(datum/mind/devil_mind, quantity)
@@ -32,8 +32,8 @@
/datum/game_mode/devil/devil_agents/proc/give_outsell_objective(datum/mind/devil)
//If you override this method, have it return the number of objectives added.
- if(target_list.len && target_list[devil]) // Is a double agent
- var/datum/mind/target_mind = target_list[devil]
+ if(devil_target_list.len && devil_target_list[devil]) // Is a double agent
+ var/datum/mind/target_mind = devil_target_list[devil]
var/datum/objective/devil/outsell/outsellobjective = new
outsellobjective.owner = devil
outsellobjective.target = target_mind
diff --git a/code/game/gamemodes/devil/devil.dm b/code/game/gamemodes/devil/devil.dm
index 31291ca143e..c6f1620c909 100644
--- a/code/game/gamemodes/devil/devil.dm
+++ b/code/game/gamemodes/devil/devil.dm
@@ -31,8 +31,8 @@
return 2.5 // Will take four hits with a normal toolbox to crit.
if(BANE_HARVEST)
if(istype(weapon,/obj/item/weapon/reagent_containers/food/snacks/grown/))
- src.visible_message("The spirits of the harvest aid in the exorcism.", "The harvest spirits are harming you.")
- src.Weaken(2)
+ visible_message("The spirits of the harvest aid in the exorcism.", "The harvest spirits are harming you.")
+ Knockdown(40)
qdel(weapon)
return 2
return 1
\ No newline at end of file
diff --git a/code/game/gamemodes/devil/true_devil/_true_devil.dm b/code/game/gamemodes/devil/true_devil/_true_devil.dm
index a77b2f95a6c..bd83d3a7803 100644
--- a/code/game/gamemodes/devil/true_devil/_true_devil.dm
+++ b/code/game/gamemodes/devil/true_devil/_true_devil.dm
@@ -23,13 +23,9 @@
bodyparts = list(/obj/item/bodypart/chest/devil, /obj/item/bodypart/head/devil, /obj/item/bodypart/l_arm/devil,
/obj/item/bodypart/r_arm/devil, /obj/item/bodypart/r_leg/devil, /obj/item/bodypart/l_leg/devil)
-
-
/mob/living/carbon/true_devil/Initialize()
create_bodyparts() //initialize bodyparts
-
create_internal_organs()
-
grant_all_languages(omnitongue=TRUE)
..()
@@ -37,9 +33,9 @@
internal_organs += new /obj/item/organ/brain
internal_organs += new /obj/item/organ/tongue
internal_organs += new /obj/item/organ/eyes
+ internal_organs += new /obj/item/organ/ears/invincible //Prevents hearing loss from poorly aimed fireballs.
..()
-
/mob/living/carbon/true_devil/proc/convert_to_archdevil()
maxHealth = 500 // not an IMPOSSIBLE amount, but still near impossible.
ascended = TRUE
@@ -57,7 +53,6 @@
devilinfo.greet()
mind.announce_objectives()
-
/mob/living/carbon/true_devil/death(gibbed)
stat = DEAD
..(gibbed)
@@ -66,15 +61,15 @@
/mob/living/carbon/true_devil/examine(mob/user)
- var/msg = "*---------*\nThis is \icon[src] [src]!\n"
+ var/msg = "*---------*\nThis is [bicon(src)] [src]!\n"
//Left hand items
for(var/obj/item/I in held_items)
if(!(I.flags & ABSTRACT))
if(I.blood_DNA)
- msg += "It is holding \icon[I] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
+ msg += "It is holding [bicon(I)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
else
- msg += "It is holding \icon[I] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "It is holding [bicon(I)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
//Braindead
if(!client && stat != DEAD)
@@ -90,10 +85,15 @@
msg += "*---------*"
to_chat(user, msg)
-
/mob/living/carbon/true_devil/IsAdvancedToolUser()
return 1
+/mob/living/carbon/true_devil/resist_buckle()
+ if(buckled)
+ buckled.user_unbuckle_mob(src,src)
+ visible_message("[src] easily breaks out of their handcuffs!", \
+ "With just a thought your handcuffs fall off.")
+
/mob/living/carbon/true_devil/canUseTopic(atom/movable/M, be_close = 0)
if(incapacitated())
return 0
@@ -177,7 +177,7 @@
if ("disarm")
if (!lying && !ascended) //No stealing the arch devil's pitchfork.
if (prob(5))
- Paralyse(2)
+ Unconscious(40)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
add_logs(M, src, "pushed")
visible_message("[M] has pushed down [src]!", \
diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm
index fa1c51cb7b1..de0fe115ca4 100644
--- a/code/game/gamemodes/events.dm
+++ b/code/game/gamemodes/events.dm
@@ -1,5 +1,5 @@
/proc/power_failure()
- priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", 'sound/AI/poweroff.ogg')
+ priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", 'sound/ai/poweroff.ogg')
for(var/obj/machinery/power/smes/S in GLOB.machines)
if(istype(get_area(S), /area/ai_monitored/turret_protected) || S.z != ZLEVEL_STATION)
continue
@@ -46,7 +46,7 @@
/proc/power_restore()
- priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/AI/poweron.ogg')
+ priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/ai/poweron.ogg')
for(var/obj/machinery/power/apc/C in GLOB.machines)
if(C.cell && C.z == ZLEVEL_STATION)
C.cell.charge = C.cell.maxcharge
@@ -68,7 +68,7 @@
/proc/power_restore_quick()
- priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/AI/poweron.ogg')
+ priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/ai/poweron.ogg')
for(var/obj/machinery/power/smes/S in GLOB.machines)
if(S.z != ZLEVEL_STATION)
continue
diff --git a/code/game/gamemodes/extended/extended.dm b/code/game/gamemodes/extended/extended.dm
index 63ad2fb1515..fdc3aee2ae9 100644
--- a/code/game/gamemodes/extended/extended.dm
+++ b/code/game/gamemodes/extended/extended.dm
@@ -1,6 +1,6 @@
/datum/game_mode/extended
name = "secret extended"
- config_tag = "secret extended"
+ config_tag = "secret_extended"
required_players = 0
announce_span = "notice"
@@ -23,4 +23,4 @@
G.on_report()
/datum/game_mode/extended/announced/send_intercept(report = 0)
- priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", 'sound/AI/commandreport.ogg')
+ priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", 'sound/ai/commandreport.ogg')
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 0f7bb791f27..c37ce1bcb9c 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -44,6 +44,7 @@
var/list/datum/station_goal/station_goals = list()
+ var/allow_persistence_save = TRUE
/datum/game_mode/proc/announce() //Shows the gamemode's name and a fast description.
to_chat(world, "The gamemode is: [name]!")
@@ -54,7 +55,7 @@
/datum/game_mode/proc/can_start()
var/playerC = 0
for(var/mob/dead/new_player/player in GLOB.player_list)
- if((player.client)&&(player.ready))
+ if((player.client)&&(player.ready == PLAYER_READY_TO_PLAY))
playerC++
if(!GLOB.Debug2)
if(playerC < required_players || (maximum_players >= 0 && playerC > maximum_players))
@@ -94,8 +95,6 @@
if(report)
addtimer(CALLBACK(src, .proc/send_intercept, 0), rand(waittime_l, waittime_h))
generate_station_goals()
- GLOB.start_state = new /datum/station_state()
- GLOB.start_state.count(1)
return 1
@@ -164,6 +163,10 @@
. = 1
sleep(rand(600,1800))
+ if(!SSticker.IsRoundInProgress())
+ message_admins("Roundtype conversion cancelled, the game appears to have finished!")
+ round_converted = 0
+ return
//somewhere between 1 and 3 minutes from now
if(!config.midround_antag[SSticker.mode.config_tag])
round_converted = 0
@@ -179,7 +182,7 @@
return 0
-/datum/game_mode/proc/check_finished() //to be called by SSticker
+/datum/game_mode/proc/check_finished(force_ending) //to be called by SSticker
if(replacementmode && round_converted == 2)
return replacementmode.check_finished()
if(SSshuttle.emergency && (SSshuttle.emergency.mode == SHUTTLE_ENDGAME))
@@ -210,7 +213,7 @@
living_antag_player = Player
return 0
- if(!config.continuous[config_tag])
+ if(!config.continuous[config_tag] || force_ending)
return 1
else
@@ -265,6 +268,43 @@
send2irc("Server", "Round just ended.")
if(cult.len && !istype(SSticker.mode,/datum/game_mode/cult))
datum_cult_completion()
+
+ if(GLOB.borers.len)
+ var/borerwin = FALSE
+ var/borertext = " The borers were:"
+ for(var/mob/living/simple_animal/borer/B in GLOB.borers)
+ if((B.key || B.controlling) && B.stat != DEAD)
+ borertext += " [B.controlling ? B.victim.key : B.key] was [B.truename] ("
+ var/turf/location = get_turf(B)
+ if(location.z == ZLEVEL_CENTCOM && B.victim)
+ borertext += "escaped with host"
+ else
+ borertext += "failed"
+ borertext += ")"
+ to_chat(world, borertext)
+
+ var/total_borers = 0
+ for(var/mob/living/simple_animal/borer/B in GLOB.borers)
+ if((B.key || B.victim) && B.stat != DEAD)
+ total_borers++
+ if(total_borers)
+ var/total_borer_hosts = 0
+ for(var/mob/living/carbon/C in GLOB.mob_list)
+ var/mob/living/simple_animal/borer/D = C.has_brain_worms()
+ var/turf/location = get_turf(C)
+ if(location.z == ZLEVEL_CENTCOM && D && D.stat != DEAD)
+ total_borer_hosts++
+ if(GLOB.total_borer_hosts_needed <= total_borer_hosts)
+ borerwin = TRUE
+ to_chat(world, "There were [total_borers] borers alive at round end!")
+ to_chat(world, "A total of [total_borer_hosts] borers with hosts escaped on the shuttle alive. The borers needed [GLOB.total_borer_hosts_needed] hosts to escape.")
+ if(borerwin)
+ to_chat(world, "The borers were successful!")
+ else
+ to_chat(world, "The borers have failed!")
+
+ CHECK_TICK
+
return 0
@@ -297,7 +337,7 @@
intercepttext += G.get_report()
print_command_report(intercepttext, "Central Command Status Summary", announce=FALSE)
- priority_announce("A summary has been copied and printed to all communications consoles.", "Enemy communication intercepted. Security level elevated.", 'sound/AI/intercept.ogg')
+ priority_announce("A summary has been copied and printed to all communications consoles.", "Enemy communication intercepted. Security level elevated.", 'sound/ai/intercept.ogg')
if(GLOB.security_level < SEC_LEVEL_BLUE)
set_security_level(SEC_LEVEL_BLUE)
@@ -310,7 +350,7 @@
// Ultimate randomizing code right here
for(var/mob/dead/new_player/player in GLOB.player_list)
- if(player.client && player.ready)
+ if(player.client && player.ready == PLAYER_READY_TO_PLAY)
players += player
// Shuffling, the players list is now ping-independent!!!
@@ -318,7 +358,7 @@
players = shuffle(players)
for(var/mob/dead/new_player/player in players)
- if(player.client && player.ready)
+ if(player.client && player.ready == PLAYER_READY_TO_PLAY)
if(role in player.client.prefs.be_special)
if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, role)) //Nodrak/Carn: Antag Job-bans
if(age_check(player.client)) //Must be older than the minimum age
@@ -332,7 +372,7 @@
if(candidates.len < recommended_enemies)
for(var/mob/dead/new_player/player in players)
- if(player.client && player.ready)
+ if(player.client && player.ready == PLAYER_READY_TO_PLAY)
if(!(role in player.client.prefs.be_special)) // We don't have enough people who want to be antagonist, make a seperate list of people who don't want to be one
if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, role)) //Nodrak/Carn: Antag Job-bans
drafted += player.mind
@@ -354,13 +394,7 @@
else // Not enough scrubs, ABORT ABORT ABORT
break
-/*
- if(candidates.len < recommended_enemies && override_jobbans) //If we still don't have enough people, we're going to start drafting banned people.
- for(var/mob/dead/new_player/player in players)
- if (player.client && player.ready)
- if(jobban_isbanned(player, "Syndicate") || jobban_isbanned(player, roletext)) //Nodrak/Carn: Antag Job-bans
- drafted += player.mind
-*/
+
if(restricted_jobs)
for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist
for(var/job in restricted_jobs)
@@ -383,17 +417,12 @@
// recommended_enemies if the number of people with that role set to yes is less than recomended_enemies,
// Less if there are not enough valid players in the game entirely to make recommended_enemies.
-/*
-/datum/game_mode/proc/check_player_role_pref(var/role, var/mob/dead/new_player/player)
- if(player.preferences.be_special & role)
- return 1
- return 0
-*/
+
/datum/game_mode/proc/num_players()
. = 0
for(var/mob/dead/new_player/P in GLOB.player_list)
- if(P.client && P.ready)
+ if(P.client && P.ready == PLAYER_READY_TO_PLAY)
. ++
///////////////////////////////////
diff --git a/code/game/gamemodes/gang/dominator.dm b/code/game/gamemodes/gang/dominator.dm
index 66dacd4219f..8eb79475432 100644
--- a/code/game/gamemodes/gang/dominator.dm
+++ b/code/game/gamemodes/gang/dominator.dm
@@ -1,5 +1,6 @@
#define DOM_BLOCKED_SPAM_CAP 6
#define DOM_REQUIRED_TURFS 30
+#define DOM_HULK_HITS_REQUIRED 10
/obj/machinery/dominator
name = "dominator"
@@ -20,6 +21,9 @@
var/datum/effect_system/spark_spread/spark_system
var/obj/effect/countdown/dominator/countdown
+/obj/machinery/dominator/hulk_damage()
+ return (max_integrity - integrity_failure) / DOM_HULK_HITS_REQUIRED
+
/proc/dominator_excessive_walls(atom/A)
var/open = 0
for(var/turf/T in view(3, A))
@@ -94,7 +98,7 @@
else
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/machinery/dominator/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1)
. = ..()
diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm
index 6606a0d8718..51d5d5150bc 100644
--- a/code/game/gamemodes/gang/gang.dm
+++ b/code/game/gamemodes/gang/gang.dm
@@ -62,7 +62,7 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
for(var/n in 1 to 3)
var/datum/mind/boss = pick(antag_candidates)
antag_candidates -= boss
- G.bosses += boss
+ G.bosses[boss] = GANGSTER_BOSS_STARTING_INFLUENCE
boss.gang_datum = G
var/title
if(n == 1)
@@ -85,6 +85,7 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
sleep(rand(10,100))
for(var/datum/gang/G in gangs)
for(var/datum/mind/boss_mind in G.bosses)
+ G.bosses[boss_mind] = GANGSTER_BOSS_STARTING_INFLUENCE //Force influence to be put on it.
G.add_gang_hud(boss_mind)
forge_gang_objectives(boss_mind)
greet_gang(boss_mind)
@@ -170,14 +171,14 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
return 0
if(check && gangster_mind.current.isloyal()) //Check to see if the potential gangster is implanted
return 1
- G.gangsters += gangster_mind
+ G.gangsters[gangster_mind] = GANGSTER_SOLDIER_STARTING_INFLUENCE
gangster_mind.gang_datum = G
if(check)
if(iscarbon(gangster_mind.current))
var/mob/living/carbon/carbon_mob = gangster_mind.current
carbon_mob.silent = max(carbon_mob.silent, 5)
carbon_mob.flash_act(1, 1)
- gangster_mind.current.Stun(5)
+ gangster_mind.current.Stun(100)
if(G.is_deconvertible)
to_chat(gangster_mind.current, "You are now a member of the [G.name] Gang!")
to_chat(gangster_mind.current, "Help your bosses take over the station by claiming territory with special spraycans only they can provide. Simply spray on any unclaimed area of the station.")
@@ -209,15 +210,24 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
if(!G.is_deconvertible && !remove_bosses)
return 0
if(gangster_mind in G.gangsters)
+ G.reclaim_points(G.gangsters[gangster_mind])
G.gangsters -= gangster_mind
removed = 1
if(remove_bosses && (gangster_mind in G.bosses))
+ G.reclaim_points(G.bosses[gangster_mind])
G.bosses -= gangster_mind
removed = 1
+ if(G.tags_by_mind[gangster_mind] && islist(G.tags_by_mind[gangster_mind]))
+ var/list/tags_cache = G.tags_by_mind[gangster_mind]
+ for(var/v in tags_cache)
+ var/obj/effect/decal/cleanable/crayon/gang/c = v
+ c.set_mind_owner(null)
+ G.tags_by_mind -= gangster_mind
if(!removed)
return 0
+
gangster_mind.special_role = null
gangster_mind.gang_datum = null
@@ -231,7 +241,7 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
message_admins("[ADMIN_LOOKUPFLW(gangster_mind.current)] has been borged while being a member of the [gang.name] Gang. They are no longer a gangster.")
else
if(!silent)
- gangster_mind.current.Paralyse(5)
+ gangster_mind.current.Unconscious(100)
gangster_mind.current.visible_message("[gangster_mind.current] looks like they've given up the life of crime!")
to_chat(gangster_mind.current, "You have been reformed! You are no longer a gangster! You try as hard as you can, but you can't seem to recall any of the identities of your former gangsters...")
gangster_mind.memory = ""
diff --git a/code/game/gamemodes/gang/gang_datum.dm b/code/game/gamemodes/gang/gang_datum.dm
index d6aa1830f25..1a145d1227a 100644
--- a/code/game/gamemodes/gang/gang_datum.dm
+++ b/code/game/gamemodes/gang/gang_datum.dm
@@ -8,6 +8,7 @@
var/list/datum/mind/gangsters = list() //gang B Members
var/list/datum/mind/bosses = list() //gang A Bosses
var/list/obj/item/device/gangtool/gangtools = list()
+ var/list/tags_by_mind = list() //Assoc list in format of tags_by_mind[mind_of_gangster] = list(tag1, tag2, tag3) where tags are the actual object decals.
var/style
var/fighting_style = "normal"
var/list/territory = list()
@@ -190,7 +191,7 @@
var/mob/living/mob = get(tool.loc,/mob/living)
if(mob && mob.mind && mob.stat == CONSCIOUS)
if(mob.mind.gang_datum == src)
- to_chat(mob, "\icon[tool] [message]")
+ to_chat(mob, "[bicon(tool)] [message]")
return
@@ -202,9 +203,9 @@
return
var/added_names = ""
var/lost_names = ""
-
+
SSticker.mode.shuttle_check() // See if its time to start wrapping things up
-
+
//Re-add territories that were reclaimed, so if they got tagged over, they can still earn income if they tag it back before the next status report
var/list/reclaimed_territories = territory_new & territory_lost
territory |= reclaimed_territories
@@ -245,47 +246,90 @@
set_domination_time(new_time)
message += "[seconds_remaining] seconds remain in hostile takeover. "
else
- for(var/obj/item/device/gangtool/G in gangtools)
- var/pmessage = message
- var/points_new = 0
- if(istype(G, /obj/item/device/gangtool/soldier))
- points_new = max(0,round(3 - G.points/10)) + (sbonus) + (LAZYLEN(G.tags)/2) // Soldier points
- pmessage += "Your influence has increased by [round(sbonus)] from your gang holding [LAZYLEN(territory)] territories, and a bonus of [round(LAZYLEN(G.tags)/2)] for territories you have personally marked and kept intact. "
- else
- points_new = max(0,round(5 - G.points/10)) + LAZYLEN(territory) // Boss points, more focused on big picture
- pmessage += "Your influence has increased by [round(points_new)] from your gang holding [territory.len] territories "
- G.points += points_new
- var/mob/living/carbon/human/ganger = get(G.loc, /mob/living)
- var/points_newer = 0
- var/static/inner = inner_outfit
- var/static/outer = outer_outfit
- if(ishuman(ganger) && ganger.mind in (gangsters|bosses))
- for(var/obj/C in ganger.contents)
- if(C.type == inner_outfit)
- points_newer += 2
- continue
- if(C.type == outer_outfit)
- points_newer += 2
- continue
- switch(C.type)
- if(/obj/item/clothing/neck/necklace/dope)
- points_newer += 2
- if(/obj/item/clothing/head/collectable/petehat/gang)
- points_newer += 4
- if(/obj/item/clothing/shoes/gang)
- points_newer += 6
- if(/obj/item/clothing/mask/gskull)
- points_newer += 5
- if(/obj/item/clothing/gloves/gang)
- points_newer += 3
- if(/obj/item/weapon/storage/belt/military/gang)
- points_newer += 4
- if(points_newer)
- G.points += points_newer
- pmessage += "Your influential choice of clothing has further increased your influence by [points_newer] points. "
- pmessage += "You now have [G.points] influence. "
- to_chat(ganger, "\icon[G] [pmessage]")
+ pay_territory_income_to_bosses()
+ pay_territory_income_to_soldiers(sbonus)
+ pay_all_clothing_bonuses()
+ announce_all_influence()
+/datum/gang/proc/pay_all_clothing_bonuses()
+ for(var/datum/mind/mind in gangsters|bosses)
+ pay_clothing_bonus(mind)
+
+/datum/gang/proc/pay_clothing_bonus(var/datum/mind/gangsta)
+ var/mob/living/carbon/human/gangbanger = gangsta.current
+ . = 0
+ if(!istype(gangbanger) || gangbanger.stat == DEAD) //Dead gangsters aren't influential at all!
+ return 0
+ var/static/inner = inner_outfit
+ var/static/outer = outer_outfit
+ for(var/obj/item/C in gangbanger.contents)
+ if(C.type == inner_outfit)
+ . += 2
+ continue
+ else if(C.type == outer_outfit)
+ . += 2
+ continue
+ . += C.gang_contraband_value()
+ adjust_influence(gangsta, .)
+ if(.)
+ announce_to_mind(gangsta, "Your influential choice of clothing has increased your influence by [.] points!")
+ else
+ announce_to_mind(gangsta, "Unfortunately, you have not gained any additional influence from your drab, old, boring clothing. Learn to dress like a gangsta, bro!") //Kek
+
+/datum/gang/proc/pay_soldier_territory_income(datum/mind/soldier, sbonus = 0)
+ . = 0
+ . = max(0,round(3 - gangsters[soldier]/10)) + (sbonus) + (get_soldier_territories(soldier)/2)
+ adjust_influence(soldier, .)
+
+/datum/gang/proc/get_soldier_territories(datum/mind/soldier)
+ if(!islist(tags_by_mind[soldier])) //They have no tagged territories!
+ return 0
+ var/list/tags = tags_by_mind[soldier]
+ return tags.len
+
+/datum/gang/proc/pay_territory_income_to_soldiers(sbonus = 0)
+ for(var/datum/mind/soldier in gangsters)
+ var/returned = pay_soldier_territory_income(soldier)
+ if(!returned)
+ announce_to_mind(soldier, "You have not gained any influence from territories you personally tagged. Get to work, soldier!")
+ else
+ announce_to_mind(soldier, "You have gained [returned] influence from [get_soldier_territories(soldier)] territories you have personally tagged.")
+
+/datum/gang/proc/announce_all_influence()
+ for(var/datum/mind/MG in bosses|gangsters)
+ announce_total_influence(MG)
+
+/datum/gang/proc/pay_territory_income_to_bosses()
+ . = 0
+ for(var/datum/mind/boss_mind in bosses)
+ var/inc = max(0,round(5 - bosses[boss_mind]/10)) + LAZYLEN(territory)
+ . += inc
+ adjust_influence(boss_mind, inc)
+ announce_to_mind(boss_mind, "Your influence has increased by [inc] from your gang holding [LAZYLEN(territory)] territories!")
+
+/datum/gang/proc/get_influence(datum/mind/gangster_mind)
+ if(gangster_mind in gangsters)
+ return gangsters[gangster_mind]
+ if(gangster_mind in bosses)
+ return bosses[gangster_mind]
+
+/datum/gang/proc/adjust_influence(datum/mind/gangster_mind, amount)
+ if(gangster_mind in gangsters)
+ gangsters[gangster_mind] += amount
+ if(gangster_mind in bosses)
+ bosses[gangster_mind] += amount
+
+/datum/gang/proc/announce_to_mind(datum/mind/gangster_mind, message)
+ if(gangster_mind.current && gangster_mind.current.stat != DEAD)
+ to_chat(gangster_mind.current, message)
+
+/datum/gang/proc/announce_total_influence(datum/mind/gangster_mind)
+ announce_to_mind(gangster_mind, "[name] Gang: You now have a total of [get_influence(gangster_mind)] influence!")
+
+/datum/gang/proc/reclaim_points(amount)
+ for(var/datum/mind/bawss in bosses)
+ adjust_influence(bawss, amount/bosses.len)
+ announce_to_mind(bawss, "[name] Gang: [amount/bosses.len] influence given from internal automatic restructuring.")
//Multiverse
diff --git a/code/game/gamemodes/gang/gang_items.dm b/code/game/gamemodes/gang/gang_items.dm
index 2318ccd6041..286145d6cf7 100644
--- a/code/game/gamemodes/gang/gang_items.dm
+++ b/code/game/gamemodes/gang/gang_items.dm
@@ -11,7 +11,7 @@
if(check_canbuy && !can_buy(user, gang, gangtool))
return FALSE
var/real_cost = get_cost(user, gang, gangtool)
- gangtool.points -= real_cost
+ gang.adjust_influence(user.mind, -real_cost)
spawn_item(user, gang, gangtool)
return TRUE
@@ -23,7 +23,7 @@
to_chat(user, spawn_msg)
/datum/gang_item/proc/can_buy(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
- return gang && (gangtool.points >= get_cost(user, gang, gangtool)) && can_see(user, gang, gangtool)
+ return gang && (gang.get_influence(user.mind) >= get_cost(user, gang, gangtool)) && can_see(user, gang, gangtool)
/datum/gang_item/proc/can_see(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
return TRUE
@@ -118,6 +118,9 @@
name = "pimpin' hat"
desc = "The undisputed king of style."
+/obj/item/clothing/head/collectable/petehat/gang/gang_contraband_value()
+ return 4
+
/datum/gang_item/clothing/mask
name = "Golden Death Mask"
id = "mask"
@@ -129,6 +132,8 @@
icon_state = "gskull"
desc = "Strike terror, and envy, into the hearts of your enemies."
+/obj/item/clothing/mask/gskull/gang_contraband_value()
+ return 5
/datum/gang_item/clothing/shoes
name = "Bling Boots"
@@ -141,13 +146,15 @@
desc = "Stand aside peasants."
icon_state = "bling"
+/obj/item/clothing/shoes/gang/gang_contraband_value()
+ return 6
+
/datum/gang_item/clothing/neck
name = "Gold Necklace"
id = "necklace"
cost = 9
item_path = /obj/item/clothing/neck/necklace/dope
-
/datum/gang_item/clothing/hands
name = "Decorative Brass Knuckles"
id = "hand"
@@ -160,6 +167,9 @@
icon_state = "knuckles"
w_class = 3
+/obj/item/clothing/gloves/gang/gang_contraband_value()
+ return 3
+
/datum/gang_item/clothing/belt
name = "Badass Belt"
id = "belt"
@@ -173,7 +183,8 @@
desc = "The belt buckle simply reads 'BAMF'."
storage_slots = 1
-
+/obj/item/weapon/storage/belt/military/gang/gang_contraband_value()
+ return 4
///////////////////
//WEAPONS
@@ -215,6 +226,7 @@
name = "Sawn-Off Improvised Shotgun"
id = "sawn"
cost = 6
+ item_path = /obj/item/weapon/gun/ballistic/revolver/doublebarrel/improvised/sawn
/datum/gang_item/weapon/ammo/improvised_ammo
name = "Box of Buckshot"
@@ -238,7 +250,7 @@
name = "Black Market .50cal Sniper Rifle"
id = "sniper"
cost = 40
- item_path = /obj/item/weapon/gun/ballistic/automatic/sniper_rifle
+ item_path = /obj/item/weapon/gun/ballistic/automatic/sniper_rifle/gang
/datum/gang_item/weapon/ammo/sniper_ammo
name = "Smuggled .50cal Sniper Rounds"
diff --git a/code/game/gamemodes/gang/gang_pen.dm b/code/game/gamemodes/gang/gang_pen.dm
index d60a3cb57b4..4357f31e837 100644
--- a/code/game/gamemodes/gang/gang_pen.dm
+++ b/code/game/gamemodes/gang/gang_pen.dm
@@ -35,7 +35,7 @@
cooldown(G)
if(2)
new /obj/item/device/gangtool/soldier(M)
- M.Paralyse(5)
+ M.Unconscious(100)
cooldown(G)
if(1)
to_chat(user, "This mind is resistant to recruitment!")
@@ -66,4 +66,4 @@
cooldown = 0
icon_state = "pen"
var/mob/M = get(src, /mob)
- to_chat(M, "\icon[src] [src][(src.loc == M)?(""):(" in your [src.loc]")] vibrates softly. It is ready to be used again.")
+ to_chat(M, "[bicon(src)] [src][(src.loc == M)?(""):(" in your [src.loc]")] vibrates softly. It is ready to be used again.")
diff --git a/code/game/gamemodes/gang/recaller.dm b/code/game/gamemodes/gang/recaller.dm
index 8363261c5d3..c06f935603b 100644
--- a/code/game/gamemodes/gang/recaller.dm
+++ b/code/game/gamemodes/gang/recaller.dm
@@ -15,7 +15,6 @@
var/outfits = 2
var/free_pen = 0
var/promotable = 0
- var/points = 15
var/list/tags = list()
/obj/item/device/gangtool/Initialize() //Initialize supply point income if it hasn't already been started
@@ -50,7 +49,7 @@
var/isboss = (user.mind == gang.bosses[1])
dat += "Registration: [gang.name] Gang [isboss ? "Boss" : "Lieutenant"] "
dat += "Organization Size: [gang.gangsters.len + gang.bosses.len] | Station Control: [round((gang.territory.len/GLOB.start_state.num_territories)*100, 1)]% "
- dat += "Your Influence: [points] "
+ dat += "Your Influence: [gang.get_influence(user.mind)] "
dat += "Time until Influence grows: [time2text(SSticker.mode.gang_points.next_point_time - world.time, "mm:ss")] "
dat += ""
@@ -111,7 +110,7 @@
if(!message || !can_use(user))
return
if(user.z > 2)
- to_chat(user, "\icon[src]Error: Station out of range.")
+ to_chat(user, "[bicon(src)]Error: Station out of range.")
return
var/list/members = list()
members += gang.gangsters
@@ -147,8 +146,9 @@
gang.gangtools += src
icon_state = "gangtool-[gang.color]"
if(!(user.mind in gang.bosses))
+ var/cached_influence = gang.gangsters[user.mind]
SSticker.mode.remove_gangster(user.mind, 0, 2)
- gang.bosses += user.mind
+ gang.bosses[user.mind] = cached_influence
user.mind.gang_datum = gang
user.mind.special_role = "[gang.name] Gang Lieutenant"
gang.add_gang_hud(user.mind)
@@ -179,35 +179,35 @@
gang.message_gangtools("[usr] is attempting to recall the emergency shuttle.")
recalling = 1
- to_chat(loc, "\icon[src]Generating shuttle recall order with codes retrieved from last call signal...")
+ to_chat(loc, "[bicon(src)]Generating shuttle recall order with codes retrieved from last call signal...")
sleep(rand(100,300))
if(SSshuttle.emergency.mode != SHUTTLE_CALL) //Shuttle can only be recalled when it's moving to the station
- to_chat(user, "\icon[src]Emergency shuttle cannot be recalled at this time.")
+ to_chat(user, "[bicon(src)]Emergency shuttle cannot be recalled at this time.")
recalling = 0
return 0
- to_chat(loc, "\icon[src]Shuttle recall order generated. Accessing station long-range communication arrays...")
+ to_chat(loc, "[bicon(src)]Shuttle recall order generated. Accessing station long-range communication arrays...")
sleep(rand(100,300))
if(!gang.dom_attempts)
- to_chat(user, "\icon[src]Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.")
+ to_chat(user, "[bicon(src)]Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.")
recalling = 0
return 0
var/turf/userturf = get_turf(user)
if(userturf.z != ZLEVEL_STATION) //Shuttle can only be recalled while on station
- to_chat(user, "\icon[src]Error: Device out of range of station communication arrays.")
+ to_chat(user, "[\bicon(src)]Error: Device out of range of station communication arrays.")
recalling = 0
return 0
var/datum/station_state/end_state = new /datum/station_state()
end_state.count()
if((100 * GLOB.start_state.score(end_state)) < 80) //Shuttle cannot be recalled if the station is too damaged
- to_chat(user, "\icon[src]Error: Station communication systems compromised. Unable to establish connection.")
+ to_chat(user, "[bicon(src)]Error: Station communication systems compromised. Unable to establish connection.")
recalling = 0
return 0
- to_chat(loc, "\icon[src]Comm arrays accessed. Broadcasting recall signal...")
+ to_chat(loc, "[bicon(src)]Comm arrays accessed. Broadcasting recall signal...")
sleep(rand(100,300))
@@ -220,13 +220,13 @@
gang.recalls -= 1
return 1
- to_chat(loc, "\icon[src]No response recieved. Emergency shuttle cannot be recalled at this time.")
+ to_chat(loc, "[bicon(src)]No response recieved. Emergency shuttle cannot be recalled at this time.")
return 0
/obj/item/device/gangtool/proc/can_use(mob/living/carbon/human/user)
if(!istype(user))
return 0
- if(user.restrained() || user.lying || user.stat || user.stunned || user.weakened)
+ if(user.restrained() || user.lying || user.stat || user.IsStun() || user.knockdown)
return 0
if(!(src in user.contents))
return 0
@@ -246,9 +246,6 @@
///////////// Internal tool used by gang regulars ///////////
-/obj/item/device/gangtool/soldier
- points = 5
-
/obj/item/device/gangtool/soldier/New(mob/user)
. = ..()
gang = user.mind.gang_datum
@@ -264,7 +261,7 @@
dat += "
Takeover In Progress: [gang.domination_time_remaining()] seconds remain
"
dat += "Registration: [gang.name] - Foot Soldier "
dat += "Organization Size: [gang.gangsters.len + gang.bosses.len] | Station Control: [round((gang.territory.len/GLOB.start_state.num_territories)*100, 1)]% "
- dat += "Your Influence: [points] "
+ dat += "Your Influence: [gang.get_influence(user.mind)] "
if(LAZYLEN(tags))
dat += "Your tags generate bonus influence for you. You have tagged the following territories:"
for(var/obj/effect/decal/cleanable/crayon/gang/T in tags)
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 4f09f2e3621..a030361eea0 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -1,83 +1,335 @@
+#define DEFAULT_DOOMSDAY_TIMER 4500
+
+//The malf AI action subtype. All malf actions are subtypes of this.
+/datum/action/innate/ai
+ name = "AI Action"
+ desc = "You aren't entirely sure what this does, but it's very beepy and boopy."
+ background_icon_state = "bg_tech_blue"
+ icon_icon = 'icons/mob/actions_AI.dmi'
+ var/mob/living/silicon/ai/owner_AI //The owner AI, so we don't have to typecast every time
+ var/uses //If we have multiple uses of the same power
+ var/auto_use_uses = TRUE //If we automatically use up uses on each activation
+ var/cooldown_period //If applicable, the time in deciseconds we have to wait before using any more modules
+
+/datum/action/innate/ai/Grant(mob/living/L)
+ . = ..()
+ if(!isAI(owner))
+ WARNING("AI action [name] attempted to grant itself to non-AI mob [L.real_name] ([L.key])!")
+ qdel(src)
+ else
+ owner_AI = owner
+
+/datum/action/innate/ai/IsAvailable()
+ . = ..()
+ if(owner_AI && owner_AI.malf_cooldown > world.time)
+ return
+
+/datum/action/innate/ai/Trigger()
+ . = ..()
+ if(auto_use_uses)
+ adjust_uses(-1)
+ if(cooldown_period)
+ owner_AI.malf_cooldown = world.time + cooldown_period
+
+/datum/action/innate/ai/proc/adjust_uses(amt, silent)
+ uses += amt
+ if(!silent && uses)
+ to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.")
+ if(!uses)
+ if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
+ to_chat(owner, "[name] has run out of uses!")
+ qdel(src)
+
+//Framework for ranged abilities that can have different effects by left-clicking stuff.
+/datum/action/innate/ai/ranged
+ name = "Ranged AI Action"
+ auto_use_uses = FALSE //This is so we can do the thing and disable/enable freely without having to constantly add uses
+ var/obj/effect/proc_holder/ranged_ai/linked_ability //The linked proc holder that contains the actual ability code
+ var/linked_ability_type //The path of our linked ability
+
+/datum/action/innate/ai/ranged/New()
+ if(!linked_ability_type)
+ WARNING("Ranged AI action [name] attempted to spawn without a linked ability!")
+ qdel(src) //uh oh!
+ return
+ linked_ability = new linked_ability_type()
+ linked_ability.attached_action = src
+ ..()
+
+/datum/action/innate/ai/ranged/adjust_uses(amt, silent)
+ uses += amt
+ if(!silent && uses)
+ to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.")
+ if(!uses)
+ if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
+ to_chat(owner, "[name] has run out of uses!")
+ Remove(owner)
+ QDEL_IN(src, 100) //let any active timers on us finish up
+
+/datum/action/innate/ai/ranged/Destroy()
+ QDEL_NULL(linked_ability)
+ return ..()
+
+/datum/action/innate/ai/ranged/Activate()
+ linked_ability.toggle(owner)
+ return TRUE
+
+//The actual ranged proc holder.
+/obj/effect/proc_holder/ranged_ai
+ var/enable_text = "Hello World!" //Appears when the user activates the ability
+ var/disable_text = "Goodbye Cruel World!" //Context clues!
+ var/datum/action/innate/ai/ranged/attached_action
+
+/obj/effect/proc_holder/ranged_ai/Destroy()
+ QDEL_NULL(attached_action)
+ return ..()
+
+/obj/effect/proc_holder/ranged_ai/proc/toggle(mob/user)
+ if(active)
+ remove_ranged_ability(disable_text)
+ else
+ add_ranged_ability(user, enable_text)
+
+
+//The datum and interface for the malf unlock menu, which lets them choose actions to unlock.
+/datum/module_picker
+ var/temp
+ var/processing_time = 50
+ var/list/possible_modules
+
+/datum/module_picker/New()
+ possible_modules = list()
+ for(var/type in typesof(/datum/AI_Module))
+ var/datum/AI_Module/AM = new type
+ if((AM.power_type && AM.power_type != /datum/action/innate/ai) || AM.upgrade)
+ possible_modules += AM
+
+/datum/module_picker/proc/remove_malf_verbs(mob/living/silicon/ai/AI) //Removes all malfunction-related abilities from the target AI.
+ for(var/datum/AI_Module/AM in possible_modules)
+ for(var/datum/action/A in AI.actions)
+ if(istype(A, initial(AM.power_type)))
+ qdel(A)
+
+/datum/module_picker/proc/use(mob/user)
+ var/list/dat = list()
+ dat += "Select use of processing time: (currently #[processing_time] left.) "
+ dat += ""
+ dat += "Install Module: "
+ dat += "The number afterwards is the amount of processing time it consumes. "
+ for(var/datum/AI_Module/large/module in possible_modules)
+ dat += "[module.module_name]\[?\] ([module.cost]) "
+ for(var/datum/AI_Module/small/module in possible_modules)
+ dat += "[module.module_name]\[?\] ([module.cost]) "
+ dat += ""
+ if(temp)
+ dat += "[temp]"
+ var/datum/browser/popup = new(user, "modpicker", "Malf Module Menu")
+ popup.set_content(dat.Join())
+ popup.open()
+
+/datum/module_picker/Topic(href, href_list)
+ ..()
+
+ if(!isAI(usr))
+ return
+ var/mob/living/silicon/ai/A = usr
+
+ if(A.stat == DEAD)
+ to_chat(A, "You are already dead!")
+ return
+
+ for(var/datum/AI_Module/AM in possible_modules)
+ if (href_list[AM.mod_pick_name])
+
+ // Cost check
+ if(AM.cost > processing_time)
+ temp = "You cannot afford this module."
+ break
+
+ var/datum/action/innate/ai/action = locate(AM.power_type) in A.actions
+
+ // Give the power and take away the money.
+ if(AM.upgrade) //upgrade and upgrade() are separate, be careful!
+ AM.upgrade(A)
+ possible_modules -= AM
+ to_chat(A, AM.unlock_text)
+ A.playsound_local(A, AM.unlock_sound, 50, 0)
+ else
+ if(AM.power_type)
+ if(!action) //Unlocking for the first time
+ var/datum/action/AC = new AM.power_type
+ AC.Grant(A)
+ A.current_modules += new AM.type
+ temp = AM.description
+ if(AM.one_purchase)
+ possible_modules -= AM
+ if(AM.unlock_text)
+ to_chat(A, AM.unlock_text)
+ if(AM.unlock_sound)
+ A.playsound_local(A, AM.unlock_sound, 50, 0)
+ else //Adding uses to an existing module
+ action.uses += initial(action.uses)
+ temp = "Additional use[action.uses > 1 ? "s" : ""] added to [action.name]!"
+ processing_time -= AM.cost
+
+ if(href_list["showdesc"])
+ if(AM.mod_pick_name == href_list["showdesc"])
+ temp = AM.description
+ use(usr)
+
+
+//The base module type, which holds info about each ability.
/datum/AI_Module
- var/uses = 0
var/module_name
var/mod_pick_name
var/description = ""
var/engaged = 0
var/cost = 5
- var/one_time = 0
+ var/one_purchase = FALSE //If this module can only be purchased once. This always applies to upgrades, even if the variable is set to false.
- var/power_type
+ var/power_type = /datum/action/innate/ai //If the module gives an active ability, use this. Mutually exclusive with upgrade.
+ var/upgrade //If the module gives a passive upgrade, use this. Mutually exclusive with power_type.
+ var/unlock_text = "Hello World!" //Text shown when an ability is unlocked
+ var/unlock_sound //Sound played when an ability is unlocked
-/datum/AI_Module/large
- uses = 1
+/datum/AI_Module/proc/upgrade(mob/living/silicon/AI/AI) //Apply upgrades!
+ return
-/datum/AI_Module/small
- uses = 5
+/datum/AI_Module/large //Big, powerful stuff that can only be used once.
+/datum/AI_Module/small //Weak, usually localized stuff with multiple uses.
+
+//Doomsday Device: Starts the self-destruct timer. It can only be stopped by killing the AI completely.
/datum/AI_Module/large/nuke_station
module_name = "Doomsday Device"
mod_pick_name = "nukestation"
description = "Activate a weapon that will disintegrate all organic life on the station after a 450 second delay. Can only be used while on the station, will fail if your core is moved off station or destroyed."
cost = 130
- one_time = 1
+ one_purchase = TRUE
+ power_type = /datum/action/innate/ai/nuke_station
+ unlock_text = "You slowly, carefully, establish a connection with the on-station self-destruct. You can now activate it at any time."
- power_type = /mob/living/silicon/ai/proc/nuke_station
-
-/mob/living/silicon/ai/proc/nuke_station()
- set category = "Malfunction"
- set name = "Doomsday Device"
-
- var/turf/T = get_turf(src)
+/datum/action/innate/ai/nuke_station
+ name = "Doomsday Device"
+ desc = "Activates the doomsday device. This is not reversible."
+ button_icon_state = "doomsday_device"
+ auto_use_uses = FALSE
+/datum/action/innate/ai/nuke_station/Activate()
+ var/turf/T = get_turf(owner)
if(!istype(T) || T.z != ZLEVEL_STATION)
- to_chat(src, "You cannot activate the doomsday device while off-station!")
+ to_chat(owner, "You cannot activate the doomsday device while off-station!")
return
+ if(alert(owner, "Send arming signal? (true = arm, false = cancel)", "purge_all_life()", "confirm = TRUE;", "confirm = FALSE;") != "confirm = TRUE;")
+ return
+ active = TRUE
+ set_us_up_the_bomb(owner)
- to_chat(src, "Doomsday device armed.")
+/datum/action/innate/ai/nuke_station/proc/set_us_up_the_bomb(mob/living/owner)
+ set waitfor = FALSE
+ to_chat(owner, "run -o -a 'selfdestruct'")
+ sleep(5)
+ if(!owner || QDELETED(owner))
+ return
+ to_chat(owner, "Running executable 'selfdestruct'...")
+ sleep(rand(10, 30))
+ if(!owner || QDELETED(owner))
+ return
+ owner.playsound_local(owner, 'sound/misc/bloblarm.ogg', 50, 0)
+ to_chat(owner, "!!! UNAUTHORIZED SELF-DESTRUCT ACCESS !!!")
+ to_chat(owner, "This is a class-3 security violation. This incident will be reported to Central Command.")
+ for(var/i in 1 to 3)
+ sleep(20)
+ if(!owner || QDELETED(owner))
+ return
+ to_chat(owner, "Sending security report to Central Command.....[rand(0, 9) + (rand(20, 30) * i)]%")
+ sleep(3)
+ if(!owner || QDELETED(owner))
+ return
+ to_chat(owner, "auth 'akjv9c88asdf12nb' ******************")
+ owner.playsound_local(owner, 'sound/items/timer.ogg', 50, 0)
+ sleep(30)
+ if(!owner || QDELETED(owner))
+ return
+ to_chat(owner, "Credentials accepted. Welcome, akjv9c88asdf12nb.")
+ owner.playsound_local(owner, 'sound/misc/server-ready.ogg', 50, 0)
+ sleep(5)
+ if(!owner || QDELETED(owner))
+ return
+ to_chat(owner, "Arm self-destruct device? (Y/N)")
+ owner.playsound_local(owner, 'sound/misc/compiler-stage1.ogg', 50, 0)
+ sleep(20)
+ if(!owner || QDELETED(owner))
+ return
+ to_chat(owner, "Y")
+ sleep(15)
+ if(!owner || QDELETED(owner))
+ return
+ to_chat(owner, "Confirm arming of self-destruct device? (Y/N)")
+ owner.playsound_local(owner, 'sound/misc/compiler-stage2.ogg', 50, 0)
+ sleep(10)
+ if(!owner || QDELETED(owner))
+ return
+ to_chat(owner, "Y")
+ sleep(rand(15, 25))
+ if(!owner || QDELETED(owner))
+ return
+ to_chat(owner, "Please repeat password to confirm.")
+ owner.playsound_local(owner, 'sound/misc/compiler-stage2.ogg', 50, 0)
+ sleep(14)
+ if(!owner || QDELETED(owner))
+ return
+ to_chat(owner, "******************")
+ sleep(40)
+ if(!owner || QDELETED(owner))
+ return
+ to_chat(owner, "Credentials accepted. Transmitting arming signal...")
+ owner.playsound_local(owner, 'sound/misc/server-ready.ogg', 50, 0)
+ sleep(30)
+ if(!owner || QDELETED(owner))
+ return
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/AI/aimalf.ogg')
set_security_level("delta")
- nuking = 1
- var/obj/machinery/doomsday_device/DOOM = new /obj/machinery/doomsday_device(src)
- doomsday_device = DOOM
- doomsday_device.start()
- verbs -= /mob/living/silicon/ai/proc/nuke_station
- for(var/obj/item/weapon/pinpointer/P in GLOB.pinpointer_list)
+ var/obj/machinery/doomsday_device/DOOM = new(owner_AI)
+ owner_AI.nuking = TRUE
+ owner_AI.doomsday_device = DOOM
+ owner_AI.doomsday_device.start()
+ for(var/pinpointer in GLOB.pinpointer_list)
+ var/obj/item/weapon/pinpointer/P = pinpointer
P.switch_mode_to(TRACK_MALF_AI) //Pinpointers start tracking the AI wherever it goes
+ qdel(src)
/obj/machinery/doomsday_device
icon = 'icons/obj/machines/nuke_terminal.dmi'
name = "doomsday device"
icon_state = "nuclearbomb_base"
desc = "A weapon which disintegrates all organic life in a large area."
- anchored = 1
- density = 1
+ anchored = TRUE
+ density = TRUE
verb_exclaim = "blares"
var/timing = FALSE
- var/default_timer = 4500
var/obj/effect/countdown/doomsday/countdown
var/detonation_timer
- var/list/milestones = list()
+ var/list/milestones
-/obj/machinery/doomsday_device/New()
- ..()
+/obj/machinery/doomsday_device/Initialize()
+ . = ..()
countdown = new(src)
+ milestones = list()
/obj/machinery/doomsday_device/Destroy()
- if(countdown)
- qdel(countdown)
- countdown = null
+ QDEL_NULL(countdown)
STOP_PROCESSING(SSfastprocess, src)
SSshuttle.clearHostileEnvironment(src)
SSmapping.remove_nuke_threat(src)
for(var/A in GLOB.ai_list)
- var/mob/living/silicon/ai/Mlf = A
- if(Mlf.doomsday_device == src)
- Mlf.doomsday_device = null
- . = ..()
+ var/mob/living/silicon/ai/AI = A
+ if(AI.doomsday_device == src)
+ AI.doomsday_device = null
+ return ..()
/obj/machinery/doomsday_device/proc/start()
- detonation_timer = world.time + default_timer
+ detonation_timer = world.time + DEFAULT_DOOMSDAY_TIMER
timing = TRUE
countdown.start()
START_PROCESSING(SSfastprocess, src)
@@ -90,26 +342,26 @@
/obj/machinery/doomsday_device/process()
var/turf/T = get_turf(src)
if(!T || T.z != ZLEVEL_STATION)
- minor_announce("DOOMSDAY DEVICE OUT OF STATION RANGE, ABORTING", "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4", 1)
+ minor_announce("DOOMSDAY DEVICE OUT OF STATION RANGE, ABORTING", "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4", TRUE)
SSshuttle.clearHostileEnvironment(src)
qdel(src)
+ return
if(!timing)
STOP_PROCESSING(SSfastprocess, src)
return
var/sec_left = seconds_remaining()
- if(sec_left <= 0)
+ if(!sec_left)
timing = FALSE
detonate(T.z)
else
var/key = num2text(sec_left)
if(!(sec_left % 60) && !(key in milestones))
milestones[key] = TRUE
- var/message = "[key] SECONDS UNTIL DOOMSDAY DEVICE ACTIVATION!"
- minor_announce(message, "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4", 1)
+ minor_announce("[key] SECONDS UNTIL DOOMSDAY DEVICE ACTIVATION!", "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4", TRUE)
-/obj/machinery/doomsday_device/proc/detonate(z_level = 1)
+/obj/machinery/doomsday_device/proc/detonate(z_level = ZLEVEL_STATION)
for(var/mob/M in GLOB.player_list)
- M << 'sound/machines/Alarm.ogg'
+ M << 'sound/machines/alarm.ogg'
sleep(100)
for(var/mob/living/L in GLOB.mob_list)
var/turf/T = get_turf(L)
@@ -122,46 +374,43 @@
to_chat(world, "The AI cleansed the station of life with the doomsday device!")
SSticker.force_ending = 1
+
+//AI Turret Upgrade: Increases the health and damage of all turrets.
/datum/AI_Module/large/upgrade_turrets
module_name = "AI Turret Upgrade"
mod_pick_name = "turret"
description = "Improves the power and health of all AI turrets. This effect is permanent."
cost = 30
- one_time = 1
+ upgrade = TRUE
+ unlock_text = "You establish a power diversion to your turrets, upgrading their health and damage."
+ unlock_sound = 'sound/items/rped.ogg'
- power_type = /mob/living/silicon/ai/proc/upgrade_turrets
-
-/mob/living/silicon/ai/proc/upgrade_turrets()
- set category = "Malfunction"
- set name = "Upgrade Turrets"
-
- if(!canUseTopic())
- return
-
- src.verbs -= /mob/living/silicon/ai/proc/upgrade_turrets
- //Upgrade AI turrets around the world
+/datum/AI_Module/large/upgrade_turrets/upgrade(mob/living/silicon/AI/AI)
for(var/obj/machinery/porta_turret/ai/turret in GLOB.machines)
turret.obj_integrity += 30
turret.lethal_projectile = /obj/item/projectile/beam/laser/heavylaser //Once you see it, you will know what it means to FEAR.
turret.lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
- to_chat(src, "Turrets upgraded.")
+
+//Hostile Station Lockdown: Locks, bolts, and electrifies every airlock on the station. After 90 seconds, the doors reset.
/datum/AI_Module/large/lockdown
module_name = "Hostile Station Lockdown"
mod_pick_name = "lockdown"
- description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 90 seconds."
+ description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 90 seconds, briefly \
+ opening all doors on the station."
cost = 30
- one_time = 1
+ one_purchase = TRUE
+ power_type = /datum/action/innate/ai/lockdown
+ unlock_text = "You upload a sleeper trojan into the door control systems. You can send a signal to set it off at any time."
+ unlock_sound = 'sound/machines/boltsdown.ogg'
- power_type = /mob/living/silicon/ai/proc/lockdown
-
-/mob/living/silicon/ai/proc/lockdown()
- set category = "Malfunction"
- set name = "Initiate Hostile Lockdown"
-
- if(!canUseTopic())
- return
+/datum/action/innate/ai/lockdown
+ name = "Lockdown"
+ desc = "Closes, bolts, and depowers every airlock, firelock, and blast door on the station. After 90 seconds, they will reset themselves."
+ button_icon_state = "lockdown"
+ uses = 1
+/datum/action/innate/ai/lockdown/Activate()
for(var/obj/machinery/door/D in GLOB.airlocks)
if(D.z != ZLEVEL_STATION)
continue
@@ -172,329 +421,364 @@
if(C)
C.post_status("alert", "lockdown")
- verbs -= /mob/living/silicon/ai/proc/lockdown
- minor_announce("Hostile runtime detected in door controllers. Isolation Lockdown protocols are now in effect. Please remain calm.","Network Alert:", 1)
- to_chat(src, "Lockdown Initiated. Network reset in 90 seconds.")
+ minor_announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.","Network Alert:", TRUE)
+ to_chat(owner, "Lockdown initiated. Network reset in 90 seconds.")
addtimer(CALLBACK(GLOBAL_PROC, .proc/minor_announce,
"Automatic system reboot complete. Have a secure day.",
"Network reset:"), 900)
+
+//Destroy RCDs: Detonates all non-cyborg RCDs on the station.
/datum/AI_Module/large/destroy_rcd
module_name = "Destroy RCDs"
mod_pick_name = "rcd"
- description = "Send a specialised pulse to detonate all hand-held and exosuit Rapid Cconstruction Devices on the station."
+ description = "Send a specialised pulse to detonate all hand-held and exosuit Rapid Construction Devices on the station."
cost = 25
- one_time = 1
+ one_purchase = TRUE
+ power_type = /datum/action/innate/ai/destroy_rcds
+ unlock_text = "After some improvisation, you rig your onboard radio to be able to send a signal to detonate all RCDs."
+ unlock_sound = 'sound/items/timer.ogg'
- power_type = /mob/living/silicon/ai/proc/disable_rcd
-
-/mob/living/silicon/ai/proc/disable_rcd()
- set category = "Malfunction"
- set name = "Destroy RCDs"
- set desc = "Detonate all RCDs on the station, while sparing onboard cyborg RCDs."
- set waitfor = FALSE
-
- if(!canUseTopic() || malf_cooldown)
- return
+/datum/action/innate/ai/destroy_rcds
+ name = "Destroy RCDs"
+ desc = "Detonate all non-cyborg RCDs on the station."
+ button_icon_state = "detonate_rcds"
+ uses = 1
+ cooldown_period = 100
+/datum/action/innate/ai/destroy_rcds/Activate()
for(var/I in GLOB.rcd_list)
if(!istype(I, /obj/item/weapon/construction/rcd/borg)) //Ensures that cyborg RCDs are spared.
var/obj/item/weapon/construction/rcd/RCD = I
RCD.detonate_pulse()
+ to_chat(owner, "RCD detonation pulse emitted.")
+ owner.playsound_local(owner, 'sound/machines/twobeep.ogg', 50, 0)
- to_chat(src, "RCD detonation pulse emitted.")
- malf_cooldown = TRUE
- sleep(100)
- malf_cooldown = FALSE
+//Unlock Mech Domination: Unlocks the ability to dominate mechs. Big shocker, right?
/datum/AI_Module/large/mecha_domination
- module_name = "Viral Mech Domination"
+ module_name = "Unlock Mech Domination"
mod_pick_name = "mechjack"
- description = "Hack into a mech's onboard computer, shunting all processes into it and ejecting any occupants. Once uploaded to the mech, it is impossible to leave.\
+ description = "Allows you to hack into a mech's onboard computer, shunting all processes into it and ejecting any occupants. Once uploaded to the mech, it is impossible to leave.\
Do not allow the mech to leave the station's vicinity or allow it to be destroyed."
cost = 30
- one_time = 1
+ upgrade = TRUE
+ unlock_text = "Virus package compiled. Select a target mech at any time. You must remain on the station at all times. Loss of signal will result in total system lockout."
+ unlock_sound = 'sound/mecha/nominal.ogg'
- power_type = /mob/living/silicon/ai/proc/mech_takeover
+/datum/AI_Module/large/mecha_domination/upgrade(mob/living/silicon/ai/AI)
+ AI.can_dominate_mechs = TRUE //Yep. This is all it does. Honk!
-/mob/living/silicon/ai/proc/mech_takeover()
- set name = "Compile Mecha Virus"
- set category = "Malfunction"
- set desc = "Target a mech by clicking it. Click the appropriate command when ready."
- if(stat)
- return
- can_dominate_mechs = 1 //Yep. This is all it does. Honk!
- to_chat(src, "Virus package compiled. Select a target mech at any time. You must remain on the station at all times. Loss of signal will result in total system lockout.")
- verbs -= /mob/living/silicon/ai/proc/mech_takeover
+//Thermal Sensor Override: Unlocks the ability to disable all fire alarms from doing their job.
/datum/AI_Module/large/break_fire_alarms
module_name = "Thermal Sensor Override"
mod_pick_name = "burnpigs"
description = "Gives you the ability to override the thermal sensors on all fire alarms. This will remove their ability to scan for fire and thus their ability to alert. \
Anyone can check the fire alarm's interface and may be tipped off by its status."
- one_time = 1
+ one_purchase = TRUE
cost = 25
+ power_type = /datum/action/innate/ai/break_fire_alarms
+ unlock_text = "You replace the thermal sensing capabilities of all fire alarms with a manual override, allowing you to turn them off at will."
+ unlock_sound = 'goon/sound/machinery/firealarm.ogg'
- power_type = /mob/living/silicon/ai/proc/break_fire_alarms
-
-/mob/living/silicon/ai/proc/break_fire_alarms()
- set name = "Override Thermal Sensors"
- set category = "Malfunction"
-
- if(!canUseTopic())
- return
+/datum/action/innate/ai/break_fire_alarms
+ name = "Override Thermal Sensors"
+ desc = "Disables the automatic temperature sensing on all fire alarms, making them effectively useless."
+ button_icon_state = "break_fire_alarms"
+ uses = 1
+/datum/action/innate/ai/break_fire_alarms/Activate()
for(var/obj/machinery/firealarm/F in GLOB.machines)
if(F.z != ZLEVEL_STATION)
continue
- F.emagged = 1
- to_chat(src, "All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.")
- src.verbs -= /mob/living/silicon/ai/proc/break_fire_alarms
+ F.emagged = TRUE
+ to_chat(owner, "All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.")
+ owner.playsound_local(owner, 'sound/machines/terminal_off.ogg', 50, 0)
+
+//Air Alarm Safety Override: Unlocks the ability to enable flooding on all air alarms.
/datum/AI_Module/large/break_air_alarms
module_name = "Air Alarm Safety Override"
mod_pick_name = "allow_flooding"
description = "Gives you the ability to disable safeties on all air alarms. This will allow you to use the environmental mode Flood, which disables scrubbers as well as pressure checks on vents. \
Anyone can check the air alarm's interface and may be tipped off by their nonfunctionality."
- one_time = 1
+ one_purchase = TRUE
cost = 50
+ power_type = /datum/action/innate/ai/break_air_alarms
+ unlock_text = "You remove the safety overrides on all air alarms, but you leave the confirm prompts open. You can hit 'Yes' at any time... you bastard."
+ unlock_sound = 'sound/effects/space_wind.ogg'
- power_type = /mob/living/silicon/ai/proc/break_air_alarms
-
-/mob/living/silicon/ai/proc/break_air_alarms()
- set name = "Disable Air Alarm Safeties"
- set category = "Malfunction"
-
- if(!canUseTopic())
- return
+/datum/action/innate/ai/break_air_alarms
+ name = "Override Air Alarm Safeties"
+ desc = "Enables the Flood setting on all air alarms."
+ button_icon_state = "break_air_alarms"
+ uses = 1
+/datum/action/innate/ai/break_air_alarms/Activate()
for(var/obj/machinery/airalarm/AA in GLOB.machines)
if(AA.z != ZLEVEL_STATION)
continue
- AA.emagged = 1
- to_chat(src, "All air alarm safeties on the station have been overriden. Air alarms may now use the Flood environmental mode.")
- src.verbs -= /mob/living/silicon/ai/proc/break_air_alarms
+ AA.emagged = TRUE
+ to_chat(owner, "All air alarm safeties on the station have been overriden. Air alarms may now use the Flood environmental mode.")
+ owner.playsound_local(owner, 'sound/machines/terminal_off.ogg', 50, 0)
+
+//Overload Machine: Allows the AI to overload a machine, detonating it after a delay. Two uses per purchase.
/datum/AI_Module/small/overload_machine
module_name = "Machine Overload"
mod_pick_name = "overload"
- description = "Overloads an electrical machine, causing a small explosion. 2 uses."
- uses = 2
+ description = "Overheats an electrical machine, causing a small explosion and destroying it. Two uses per purchase."
cost = 20
+ power_type = /datum/action/innate/ai/ranged/overload_machine
+ unlock_text = "You enable the ability for the station's APCs to direct intense energy into machinery."
+ unlock_sound = 'sound/effects/comfyfire.ogg' //definitely not comfy, but it's the closest sound to "roaring fire" we have
- power_type = /mob/living/silicon/ai/proc/overload_machine
+/datum/action/innate/ai/ranged/overload_machine
+ name = "Overload Machine"
+ desc = "Overheats a machine, causing a small explosion after a short time."
+ button_icon_state = "overload_machine"
+ uses = 2
+ linked_ability_type = /obj/effect/proc_holder/ranged_ai/overload_machine
-/mob/living/silicon/ai/proc/overload_machine(obj/machinery/M in GLOB.machines)
- set name = "Overload Machine"
- set category = "Malfunction"
+/datum/action/innate/ai/ranged/overload_machine/proc/detonate_machine(obj/machinery/M)
+ if(M && !QDELETED(M))
+ explosion(get_turf(M), 0, 2, 3, 0)
+ if(M) //to check if the explosion killed it before we try to delete it
+ qdel(M)
- if(!canUseTopic())
+/obj/effect/proc_holder/ranged_ai/overload_machine
+ active = FALSE
+ ranged_mousepointer = 'icons/effects/overload_machine_target.dmi'
+ enable_text = "You tap into the station's powernet. Click on a machine to detonate it, or use the ability again to cancel."
+ disable_text = "You release your hold on the powernet."
+
+/obj/effect/proc_holder/ranged_ai/overload_machine/InterceptClickOn(mob/living/caller, params, obj/machinery/target)
+ if(..())
return
+ if(ranged_ability_user.incapacitated())
+ remove_ranged_ability()
+ return
+ if(!istype(target))
+ to_chat(ranged_ability_user, "You can only overload machines!")
+ return
+ ranged_ability_user.playsound_local(ranged_ability_user, "sparks", 50, 0)
+ attached_action.adjust_uses(-1)
+ target.audible_message("You hear a loud electrical buzzing sound coming from [target]!")
+ addtimer(CALLBACK(attached_action, /datum/action/innate/ai/ranged/overload_machine.proc/detonate_machine, target), 50) //kaboom!
+ remove_ranged_ability("Overcharging machine...")
+ return TRUE
- if (istype(M, /obj/machinery))
- for(var/datum/AI_Module/small/overload_machine/overload in current_modules)
- if(overload.uses > 0)
- overload.uses --
- M.audible_message("You hear a loud electrical buzzing sound coming from [M]!")
- to_chat(src, "Overloading machine circuitry...")
- spawn(50)
- if(M)
- explosion(get_turf(M), 0,2,3,0)
- qdel(M)
- else to_chat(src, "Out of uses.")
- else to_chat(src, "That's not a machine.")
+//Override Machine: Allows the AI to override a machine, animating it into an angry, living version of itself.
/datum/AI_Module/small/override_machine
module_name = "Machine Override"
mod_pick_name = "override"
- description = "Overrides a machine's programming, causing it to rise up and attack everyone except other machines. 4 uses."
- uses = 4
+ description = "Overrides a machine's programming, causing it to rise up and attack everyone except other machines. Four uses."
cost = 30
+ power_type = /datum/action/innate/ai/ranged/override_machine
+ unlock_text = "You procure a virus from the Space Dark Web and distribute it to the station's machines."
+ unlock_sound = 'sound/machines/airlock_alien_prying.ogg'
- power_type = /mob/living/silicon/ai/proc/override_machine
+/datum/action/innate/ai/ranged/override_machine
+ name = "Override Machine"
+ desc = "Animates a targeted machine, causing it to attack anyone nearby."
+ button_icon_state = "override_machine"
+ uses = 4
+ linked_ability_type = /obj/effect/proc_holder/ranged_ai/override_machine
+/datum/action/innate/ai/ranged/override_machine/proc/animate_machine(obj/machinery/M)
+ if(M && !QDELETED(M))
+ new/mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, owner, 1)
-/mob/living/silicon/ai/proc/override_machine(obj/machinery/M in GLOB.machines)
- set name = "Override Machine"
- set category = "Malfunction"
+/obj/effect/proc_holder/ranged_ai/override_machine
+ active = FALSE
+ ranged_mousepointer = 'icons/effects/override_machine_target.dmi'
+ enable_text = "You tap into the station's powernet. Click on a machine to animate it, or use the ability again to cancel."
+ disable_text = "You release your hold on the powernet."
- if(!canUseTopic())
+/obj/effect/proc_holder/ranged_ai/override_machine/InterceptClickOn(mob/living/caller, params, obj/machinery/target)
+ if(..())
return
+ if(ranged_ability_user.incapacitated())
+ remove_ranged_ability()
+ return
+ if(!istype(target))
+ to_chat(ranged_ability_user, "You can only animate machines!")
+ return
+ if(!target.can_be_overridden())
+ to_chat(ranged_ability_user, "That machine can't be overriden!")
+ return
+ ranged_ability_user.playsound_local(ranged_ability_user, 'sound/misc/interference.ogg', 50, 0)
+ attached_action.adjust_uses(-1)
+ target.audible_message("You hear a loud electrical buzzing sound coming from [target]!")
+ addtimer(CALLBACK(attached_action, /datum/action/innate/ai/ranged/override_machine.proc/animate_machine, target), 50) //kabeep!
+ remove_ranged_ability("Sending override signal...")
+ return TRUE
- if (istype(M, /obj/machinery))
- if(!M.can_be_overridden())
- to_chat(src, "Can't override this device.")
- for(var/datum/AI_Module/small/override_machine/override in current_modules)
- if(override.uses > 0)
- override.uses --
- M.audible_message("You hear a loud electrical buzzing sound!")
- to_chat(src, "Reprogramming machine behaviour...")
- spawn(50)
- if(M && !QDELETED(M))
- new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, src, 1)
- else to_chat(src, "Out of uses.")
- else to_chat(src, "That's not a machine.")
+//Robotic Factory: Places a large machine that converts humans that go through it into cyborgs. Unlocking this ability removes shunting.
/datum/AI_Module/large/place_cyborg_transformer
module_name = "Robotic Factory (Removes Shunting)"
mod_pick_name = "cyborgtransformer"
description = "Build a machine anywhere, using expensive nanomachines, that can convert a living human into a loyal cyborg slave when placed inside."
cost = 100
- power_type = /mob/living/silicon/ai/proc/place_transformer
- var/list/turfOverlays = list()
+ one_purchase = TRUE
+ power_type = /datum/action/innate/ai/place_transformer
+ unlock_text = "You make contact with Space Amazon and request a robotics factory for delivery."
+ unlock_sound = 'sound/machines/ping.ogg'
-/datum/AI_Module/large/place_cyborg_transformer/New()
- for(var/i=0;i<3;i++)
- var/image/I = image("icon"='icons/turf/overlays.dmi')
- turfOverlays += I
+/datum/action/innate/ai/place_transformer
+ name = "Place Robotics Factory"
+ desc = "Places a machine that converts humans into cyborgs. Conveyor belts included!"
+ button_icon_state = "robotic_factory"
+ uses = 1
+ auto_use_uses = FALSE //So we can attempt multiple times
+ var/list/turfOverlays
+
+/datum/action/innate/ai/place_transformer/New()
..()
+ for(var/i in 1 to 3)
+ var/image/I = image("icon"='icons/turf/overlays.dmi')
+ LAZYADD(turfOverlays, I)
-/mob/living/silicon/ai/proc/place_transformer()
- set name = "Place Robotic Factory"
- set category = "Malfunction"
- if(!canPlaceTransformer())
+/datum/action/innate/ai/place_transformer/Activate()
+ if(!owner_AI.can_place_transformer(src))
return
- var/sure = alert(src, "Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No")
- if(sure == "Yes")
- if(!canPlaceTransformer())
- return
- var/turf/T = get_turf(eyeobj)
- var/obj/machinery/transformer/conveyor = new(T)
- conveyor.masterAI = src
- playsound(T, 'sound/effects/phasein.ogg', 100, 1)
- var/datum/AI_Module/large/place_cyborg_transformer/PCT = locate() in current_modules
- PCT.uses --
- can_shunt = 0
- to_chat(src, "You cannot shunt anymore.")
+ active = TRUE
+ if(alert(owner, "Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No") == "No")
+ active = FALSE
+ return
+ if(!owner_AI.can_place_transformer(src))
+ return
+ var/turf/T = get_turf(owner_AI.eyeobj)
+ var/obj/machinery/transformer/conveyor = new(T)
+ conveyor.masterAI = owner
+ playsound(T, 'sound/effects/phasein.ogg', 100, 1)
+ owner_AI.can_shunt = TRUE
+ to_chat(owner, "You are no longer able to shunt your core to APCs.")
+ adjust_uses(-1)
-/mob/living/silicon/ai/proc/canPlaceTransformer()
- if(!eyeobj || !isturf(src.loc) || !canUseTopic())
- return
- var/datum/AI_Module/large/place_cyborg_transformer/PCT = locate() in current_modules
- if(!PCT || PCT.uses < 1)
- alert(src, "Out of uses.")
+/mob/living/silicon/ai/proc/remove_transformer_image(client/C, image/I, turf/T)
+ if(C && I.loc == T)
+ C.images -= I
+
+/mob/living/silicon/ai/proc/can_place_transformer(datum/action/innate/ai/place_transformer/action)
+ if(!eyeobj || !isturf(loc) || !canUseTopic() || !action)
return
var/turf/middle = get_turf(eyeobj)
var/list/turfs = list(middle, locate(middle.x - 1, middle.y, middle.z), locate(middle.x + 1, middle.y, middle.z))
- var/alert_msg = "There isn't enough room. Make sure you are placing the machine in a clear area and on a floor."
- var/success = 1
- if(turfs.len == 3)
- for(var/n=1;n<4,n++)
- var/fail
- var/turf/T = turfs[n]
- if(!isfloorturf(T))
- fail = 1
- var/datum/camerachunk/C = GLOB.cameranet.getCameraChunk(T.x, T.y, T.z)
- if(!C.visibleTurfs[T])
- alert_msg = "We cannot get camera vision of this location."
- fail = 1
- for(var/atom/movable/AM in T.contents)
- if(AM.density)
- fail = 1
- var/image/I = PCT.turfOverlays[n]
- I.loc = T
- client.images += I
- if(fail)
- success = 0
- I.icon_state = "redOverlay"
- else
- I.icon_state = "greenOverlay"
- spawn(30)
- if(client && (I.loc == T))
- client.images -= I
- if(success)
- return 1
- alert(src, alert_msg)
+ var/alert_msg = "There isn't enough room! Make sure you are placing the machine in a clear area and on a floor."
+ var/success = TRUE
+ for(var/n in 1 to 3) //We have to do this instead of iterating normally because of how overlay images are handled
+ var/turf/T = turfs[n]
+ if(!isfloorturf(T))
+ success = FALSE
+ var/datum/camerachunk/C = GLOB.cameranet.getCameraChunk(T.x, T.y, T.z)
+ if(!C.visibleTurfs[T])
+ alert_msg = "You don't have camera vision of this location!"
+ success = FALSE
+ for(var/atom/movable/AM in T.contents)
+ if(AM.density)
+ alert_msg = "That area must be clear of objects!"
+ success = FALSE
+ var/image/I = action.turfOverlays[n]
+ I.loc = T
+ client.images += I
+ I.icon_state = "[success ? "green" : "red"]Overlay" //greenOverlay and redOverlay for success and failure respectively
+ addtimer(CALLBACK(src, .proc/remove_transformer_image, client, I, T), 30)
+ if(!success)
+ to_chat(src, "[alert_msg]")
+ return success
+
+//Blackout: Overloads a random number of lights across the station. Three uses.
/datum/AI_Module/small/blackout
module_name = "Blackout"
mod_pick_name = "blackout"
- description = "Attempts to overload the lighting circuits on the station, destroying some bulbs. 3 uses."
- uses = 3
+ description = "Attempts to overload the lighting circuits on the station, destroying some bulbs. Three uses."
cost = 15
+ power_type = /datum/action/innate/ai/blackout
+ unlock_text = "You hook into the powernet and route bonus power towards the station's lighting."
+ unlock_sound = "sparks"
- power_type = /mob/living/silicon/ai/proc/blackout
+/datum/action/innate/ai/blackout
+ name = "Blackout"
+ desc = "Overloads lights across the station."
+ button_icon_state = "blackout"
+ uses = 3
-/mob/living/silicon/ai/proc/blackout()
- set category = "Malfunction"
- set name = "Blackout"
+/datum/action/innate/ai/blackout/Activate()
+ for(var/obj/machinery/power/apc/apc in GLOB.apcs_list)
+ if(prob(30 * apc.overload))
+ apc.overload_lighting()
+ else
+ apc.overload++
+ to_chat(owner, "Overcurrent applied to the powernet.")
+ owner.playsound_local(owner, "sparks", 50, 0)
- if(!canUseTopic())
- return
-
- for(var/datum/AI_Module/small/blackout/blackout in current_modules)
- if(blackout.uses > 0)
- blackout.uses --
- for(var/obj/machinery/power/apc/apc in GLOB.machines)
- if(prob(30*apc.overload))
- apc.overload_lighting()
- else apc.overload++
- to_chat(src, "Overcurrent applied to the powernet.")
- else to_chat(src, "Out of uses.")
+//Reactivate Camera Network: Reactivates up to 30 cameras across the station.
/datum/AI_Module/small/reactivate_cameras
module_name = "Reactivate Camera Network"
mod_pick_name = "recam"
description = "Runs a network-wide diagnostic on the camera network, resetting focus and re-routing power to failed cameras. Can be used to repair up to 30 cameras."
- uses = 30
cost = 10
- one_time = 1
+ one_purchase = TRUE
+ power_type = /datum/action/innate/ai/reactivate_cameras
+ unlock_text = "You deploy nanomachines to the cameranet."
+ unlock_sound = 'sound/items/wirecutter.ogg'
- power_type = /mob/living/silicon/ai/proc/reactivate_cameras
+/datum/action/innate/ai/reactivate_cameras
+ name = "Reactivate Cameras"
+ desc = "Reactivates disabled cameras across the station; remaining uses can be used later."
+ button_icon_state = "reactivate_cameras"
+ uses = 30
+ auto_use_uses = FALSE
+ cooldown_period = 30
-/mob/living/silicon/ai/proc/reactivate_cameras()
- set name = "Reactivate Cameranet"
- set category = "Malfunction"
+/datum/action/innate/ai/reactivate_cameras/New()
+ ..()
+ desc = "[desc] There are 30 reactivations remaining."
+ button.desc = desc
- if(!canUseTopic() || malf_cooldown)
- return
- var/fixedcams = 0 //Tells the AI how many cams it fixed. Stats are fun.
+/datum/action/innate/ai/reactivate_cameras/Activate()
+ var/fixed_cameras = 0
+ for(var/V in GLOB.cameranet.cameras)
+ if(!uses)
+ break
+ var/obj/machinery/camera/C = V
+ if(!C.status || C.view_range != initial(C.view_range))
+ C.toggle_cam(owner_AI, 0) //Reactivates the camera based on status. Badly named proc.
+ C.view_range = initial(C.view_range)
+ fixed_cameras++
+ uses-- //Not adjust_uses() so it doesn't automatically delete or show a message
+ to_chat(owner, "Diagnostic complete! Cameras reactivated: [fixed_cameras]. Reactivations remaining: [uses].")
+ owner.playsound_local(owner, 'sound/items/wirecutter.ogg', 50, 0)
+ adjust_uses(0, TRUE) //Checks the uses remaining
+ if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe
+ desc = "[initial(desc)] There are [uses] reactivations remaining."
- for(var/datum/AI_Module/small/reactivate_cameras/camera in current_modules)
- for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
- var/initial_range = initial(C.view_range) //To prevent calling the proc twice
- if(camera.uses > 0)
- if(!C.status)
- C.toggle_cam(src, 0) //Reactivates the camera based on status. Badly named proc.
- fixedcams++
- camera.uses--
- if(C.view_range != initial_range)
- C.view_range = initial_range //Fixes cameras with bad focus.
- camera.uses--
- fixedcams++
- //If a camera is both deactivated and has bad focus, it will cost two uses to fully fix!
- else
- to_chat(src, "Out of uses.")
- verbs -= /mob/living/silicon/ai/proc/reactivate_cameras //It is useless now, clean it up.
- break
- to_chat(src, "Diagnostic complete! Operations completed: [fixedcams].")
-
- malf_cooldown = 1
- spawn(30) //Lag protection
- malf_cooldown = 0
+//Upgrade Camera Network: EMP-proofs all cameras, in addition to giving them x-ray vision.
/datum/AI_Module/large/upgrade_cameras
module_name = "Upgrade Camera Network"
mod_pick_name = "upgradecam"
- description = "Install broad-spectrum scanning and electrical redundancy firmware to the camera network, enabling EMP-Proofing and light-amplified X-ray vision." //I <3 pointless technobabble
+ description = "Install broad-spectrum scanning and electrical redundancy firmware to the camera network, enabling EMP-proofing and light-amplified X-ray vision." //I <3 pointless technobabble
//This used to have motion sensing as well, but testing quickly revealed that giving it to the whole cameranet is PURE HORROR.
- one_time = 1
+ one_purchase = TRUE
cost = 35 //Decent price for omniscience!
+ upgrade = TRUE
+ unlock_text = "OTA firmware distribution complete! Cameras upgraded: CAMSUPGRADED. Light amplification system online."
+ unlock_sound = 'sound/items/rped.ogg'
- power_type = /mob/living/silicon/ai/proc/upgrade_cameras
+/datum/AI_Module/large/upgrade_cameras/upgrade(mob/living/silicon/ai/AI)
+ AI.see_override = SEE_INVISIBLE_MINIMUM //Night-vision, without which X-ray would be very limited in power.
+ AI.update_sight()
-/mob/living/silicon/ai/proc/upgrade_cameras()
- set name = "Upgrade Cameranet"
- set category = "Malfunction"
-
- if(!canUseTopic())
- return
-
- var/upgradedcams = 0
- see_override = SEE_INVISIBLE_MINIMUM //Night-vision, without which X-ray would be very limited in power.
- update_sight()
-
- for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
+ var/upgraded_cameras = 0
+ for(var/V in GLOB.cameranet.cameras)
+ var/obj/machinery/camera/C = V
if(C.assembly)
var/upgraded = 0
@@ -509,102 +793,22 @@
upgraded = 1
if(upgraded)
- upgradedcams++
+ upgraded_cameras++
- to_chat(src, "OTA firmware distribution complete! Cameras upgraded: [upgradedcams]. Light amplification system online.")
- verbs -= /mob/living/silicon/ai/proc/upgrade_cameras
-
-/datum/module_picker
- var/temp = null
- var/processing_time = 50
- var/list/possible_modules = list()
-
-/datum/module_picker/New()
- for(var/type in typesof(/datum/AI_Module))
- var/datum/AI_Module/AM = new type
- if(AM.power_type != null)
- src.possible_modules += AM
-
-/datum/module_picker/proc/remove_verbs(mob/living/silicon/ai/A)
-
- for(var/datum/AI_Module/AM in possible_modules)
- A.verbs.Remove(AM.power_type)
-
-
-/datum/module_picker/proc/use(mob/user)
- var/dat
- dat = "Select use of processing time: (currently #[src.processing_time] left.) "
- dat += ""
- dat += "Install Module: "
- dat += "The number afterwards is the amount of processing time it consumes. "
- for(var/datum/AI_Module/large/module in src.possible_modules)
- dat += "[module.module_name]\[?\] ([module.cost]) "
- for(var/datum/AI_Module/small/module in src.possible_modules)
- dat += "[module.module_name]\[?\] ([module.cost]) "
- dat += ""
- if (src.temp)
- dat += "[src.temp]"
- var/datum/browser/popup = new(user, "modpicker", "Malf Module Menu")
- popup.set_content(dat)
- popup.open()
-
-/datum/module_picker/Topic(href, href_list)
- ..()
-
- if(!isAI(usr))
- return
- var/mob/living/silicon/ai/A = usr
-
- if(A.stat == DEAD)
- to_chat(A, "You are already dead!") //Omae Wa Mou Shindeiru
- return
-
- for(var/datum/AI_Module/AM in possible_modules)
- if (href_list[AM.mod_pick_name])
-
- // Cost check
- if(AM.cost > src.processing_time)
- temp = "You cannot afford this module."
- break
-
- // Add new uses if we can, and it is allowed.
- var/datum/AI_Module/already_AM = locate(AM.type) in A.current_modules
- if(already_AM)
- if(!AM.one_time)
- already_AM.uses += AM.uses
- src.processing_time -= AM.cost
- temp = "Additional use added to [already_AM.module_name]"
- break
- else
- temp = "This module is only needed once."
- break
-
- // Give the power and take away the money.
- A.view_core() //A BYOND bug requires you to be viewing your core before your verbs update
- A.verbs += AM.power_type
- A.current_modules += new AM.type
- temp = AM.description
- src.processing_time -= AM.cost
-
- if(href_list["showdesc"])
- if(AM.mod_pick_name == href_list["showdesc"])
- temp = AM.description
- src.use(usr)
+ unlock_text = replacetext(unlock_text, "CAMSUPGRADED", "[upgraded_cameras]") //This works, since unlock text is called after upgrade()
/datum/AI_Module/large/eavesdrop
module_name = "Enhanced Surveillance"
mod_pick_name = "eavesdrop"
description = "Via a combination of hidden microphones and lip reading software, you are able to use your cameras to listen in on conversations."
cost = 30
- one_time = 1
+ one_purchase = TRUE
+ upgrade = TRUE
+ unlock_text = "OTA firmware distribution complete! Cameras upgraded: Enhanced surveillance package online."
+ unlock_sound = 'sound/items/rped.ogg'
- power_type = /mob/living/silicon/ai/proc/surveillance
+/datum/AI_Module/large/eavesdrop/upgrade(mob/living/silicon/ai/AI)
+ if(AI.eyeobj)
+ AI.eyeobj.relay_speech = TRUE
-/mob/living/silicon/ai/proc/surveillance()
- set category = "Malfunction"
- set name = "Enhanced Surveillance"
-
- if(eyeobj)
- eyeobj.relay_speech = TRUE
- to_chat(src, "OTA firmware distribution complete! Cameras upgraded: Enhanced surveillance package online.")
- verbs -= /mob/living/silicon/ai/proc/surveillance
+#undef DEFAULT_DOOMSDAY_TIMER
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index 3ce5a01cfa8..9a78df55c96 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -206,7 +206,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
pass_flags = PASSTABLE | PASSGRILLE
hits = 1
hitpwr = 3
- meteorsound = 'sound/weapons/Gunshot_smg.ogg'
+ meteorsound = 'sound/weapons/gunshot_smg.ogg'
meteordrop = list(/obj/item/weapon/ore/glass)
threat = 1
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
index de11c2ed94d..22a613fe969 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
@@ -83,7 +83,7 @@
M.cut_overlays()
M.regenerate_icons()
-/obj/item/clothing/suit/armor/abductor/vest/hit_reaction()
+/obj/item/clothing/suit/armor/abductor/vest/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
DeactivateStealth()
return 0
@@ -108,9 +108,9 @@
return
var/mob/living/carbon/human/M = loc
M.adjustStaminaLoss(-75)
- M.SetParalysis(0)
- M.SetStunned(0)
- M.SetWeakened(0)
+ M.SetUnconscious(0)
+ M.SetStun(0)
+ M.SetKnockdown(0)
combat_cooldown = 0
START_PROCESSING(SSobj, src)
@@ -393,8 +393,8 @@ Congratulations! You are now trained for invasive xenobiology research!"}
if(ishuman(L))
var/mob/living/carbon/human/H = L
- if(H.check_shields(0, "[user]'s [name]", src, MELEE_ATTACK))
- playsound(L, 'sound/weapons/Genhit.ogg', 50, 1)
+ if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK))
+ playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
return 0
switch (mode)
@@ -414,13 +414,12 @@ Congratulations! You are now trained for invasive xenobiology research!"}
user.lastattacked = L
L.lastattacker = user
- L.Stun(7)
- L.Weaken(7)
+ L.Knockdown(140)
L.apply_effect(STUTTER, 7)
L.visible_message("[user] has stunned [L] with [src]!", \
"[user] has stunned you with [src]!")
- playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
+ playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
if(ishuman(L))
var/mob/living/carbon/human/H = L
@@ -429,11 +428,11 @@ Congratulations! You are now trained for invasive xenobiology research!"}
add_logs(user, L, "stunned")
/obj/item/weapon/abductor_baton/proc/SleepAttack(mob/living/L,mob/living/user)
- if(L.stunned || L.sleeping)
+ if(L.incapacitated(TRUE, TRUE))
L.visible_message("[user] has induced sleep in [L] with [src]!", \
"You suddenly feel very drowsy!")
- playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
- L.Sleeping(60)
+ playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
+ L.Sleeping(1200)
add_logs(user, L, "put to sleep")
else
L.drowsyness += 1
@@ -608,7 +607,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
to_chat(user, "You start disassembling [src]...")
playsound(src.loc, I.usesound, 50, 1)
if(do_after(user, 30*I.toolspeed, target = src))
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
for(var/i = 1, i <= framestackamount, i++)
new framestack(get_turf(src))
qdel(src)
@@ -704,7 +703,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
if(WT.remove_fuel(0,user))
user.visible_message("[user] disassembles the airlock assembly.", \
"You start to disassemble the airlock assembly...")
- playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/welder2.ogg', 50, 1)
if(do_after(user, 40*W.toolspeed, target = src))
if( !WT.isOn() )
return
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/camera.dm b/code/game/gamemodes/miniantags/abduction/machinery/camera.dm
index 554d992987f..4e74d11be11 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/camera.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/camera.dm
@@ -2,7 +2,6 @@
name = "Human Observation Console"
var/team = 0
networks = list("SS13","Abductor")
- off_action = new/datum/action/innate/camera_off/abductor //specific datum
var/datum/action/innate/teleport_in/tele_in_action = new
var/datum/action/innate/teleport_out/tele_out_action = new
var/datum/action/innate/teleport_self/tele_self_action = new
@@ -23,29 +22,37 @@
eyeobj.icon_state = "camera_target"
/obj/machinery/computer/camera_advanced/abductor/GrantActions(mob/living/carbon/user)
- off_action.target = user
- off_action.Grant(user)
+ ..()
- jump_action.target = user
- jump_action.Grant(user)
- //TODO : add null checks
- tele_in_action.target = console.pad
- tele_in_action.Grant(user)
+ if(tele_in_action)
+ tele_in_action.target = console.pad
+ tele_in_action.Grant(user)
+ actions += tele_in_action
- tele_out_action.target = console
- tele_out_action.Grant(user)
+ if(tele_out_action)
+ tele_out_action.target = console
+ tele_out_action.Grant(user)
+ actions += tele_out_action
- tele_self_action.target = console.pad
- tele_self_action.Grant(user)
+ if(tele_self_action)
+ tele_self_action.target = console.pad
+ tele_self_action.Grant(user)
+ actions += tele_self_action
- vest_mode_action.target = console
- vest_mode_action.Grant(user)
+ if(vest_mode_action)
+ vest_mode_action.target = console
+ vest_mode_action.Grant(user)
+ actions += vest_mode_action
- vest_disguise_action.target = console
- vest_disguise_action.Grant(user)
+ if(vest_disguise_action)
+ vest_disguise_action.target = console
+ vest_disguise_action.Grant(user)
+ actions += vest_disguise_action
- set_droppoint_action.target = console
- set_droppoint_action.Grant(user)
+ if(set_droppoint_action)
+ set_droppoint_action.target = console
+ set_droppoint_action.Grant(user)
+ actions += set_droppoint_action
/obj/machinery/computer/camera_advanced/abductor/proc/IsScientist(mob/living/carbon/human/H)
var/datum/species/abductor/S = H.dna.species
@@ -56,30 +63,6 @@
return
return ..()
-/datum/action/innate/camera_off/abductor/Activate()
- if(!target || !iscarbon(target))
- return
- var/mob/living/carbon/C = target
- var/mob/camera/aiEye/remote/remote_eye = C.remote_control
- var/obj/machinery/computer/camera_advanced/abductor/origin = remote_eye.origin
- origin.current_user = null
- origin.jump_action.Remove(C)
- origin.tele_in_action.Remove(C)
- origin.tele_out_action.Remove(C)
- origin.tele_self_action.Remove(C)
- origin.vest_mode_action.Remove(C)
- origin.vest_disguise_action.Remove(C)
- origin.set_droppoint_action.Remove(C)
- C.reset_perspective(null)
- if(C.client)
- C.client.images -= remote_eye.user_image
- for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks)
- chunk.remove(remote_eye)
- remote_eye.eye_user = null
- C.remote_control = null
- C.unset_machine()
- Remove(C)
-
/datum/action/innate/teleport_in
name = "Send To"
button_icon_state = "beam_down"
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
index 55b01db5340..20e95bc8b8b 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
@@ -213,14 +213,13 @@
/obj/machinery/abductor/experiment/proc/SendBack(mob/living/carbon/human/H)
- H.Sleeping(8)
+ H.Sleeping(160)
+ H.uncuff()
if(console && console.pad && console.pad.teleport_target)
H.forceMove(console.pad.teleport_target)
- H.uncuff()
return
//Area not chosen / It's not safe area - teleport to arrivals
- H.forceMove(pick(GLOB.latejoin))
- H.uncuff()
+ SSjob.SendToLateJoin(H, FALSE)
return
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/pad.dm b/code/game/gamemodes/miniantags/abduction/machinery/pad.dm
index a12515a6257..dc3f6f8dacd 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/pad.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/pad.dm
@@ -18,7 +18,7 @@
target.forceMove(teleport_target)
new /obj/effect/temp_visual/dir_setting/ninja(get_turf(target), target.dir)
to_chat(target, "The instability of the warp leaves you disoriented!")
- target.Stun(3)
+ target.Stun(60)
/obj/machinery/abductor/pad/proc/Retrieve(mob/living/target)
flick("alien-pad", src)
diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm
index dbc12094d38..15ed3ea7ff1 100644
--- a/code/game/gamemodes/miniantags/borer/borer.dm
+++ b/code/game/gamemodes/miniantags/borer/borer.dm
@@ -138,7 +138,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
host_brain = null
victim = null
-
+
QDEL_NULL(talk_to_host_action)
QDEL_NULL(infest_host_action)
QDEL_NULL(toggle_hide_action)
@@ -152,7 +152,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
QDEL_NULL(freeze_victim_action)
QDEL_NULL(punish_victim_action)
QDEL_NULL(jumpstart_host_action)
-
+
return ..()
/mob/living/simple_animal/borer/Topic(href, href_list)//not entirely sure if this is even required
@@ -488,7 +488,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
for(var/mob/living/carbon/C in view(1,src))
if(C.stat == CONSCIOUS)
choices += C
-
+
if(!choices.len)
return
var/mob/living/carbon/M = choices.len > 1 ? input(src,"Who do you wish to dominate?") in null|choices : choices[1]
@@ -500,14 +500,14 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
return
if(M.has_brain_worms())
- to_chat(src, "You cannot paralyze someone who is already infested!")
+ to_chat(src, "You cannot stun someone who is already infested!")
return
layer = MOB_LAYER
to_chat(src, "You focus your psychic lance on [M] and freeze their limbs with a wave of terrible dread.")
to_chat(M, "You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing.")
- M.Stun(3)
+ M.Stun(60)
used_dominate = world.time
@@ -608,9 +608,9 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
victim.setToxLoss(0)
victim.setOxyLoss(0)
victim.setCloneLoss(0)
- victim.SetParalysis(0)
- victim.SetStunned(0)
- victim.SetWeakened(0)
+ victim.SetUnconscious(0)
+ victim.SetStun(0)
+ victim.SetKnockdown(0)
victim.radiation = 0
victim.heal_overall_damage(victim.getBruteLoss(), victim.getFireLoss())
victim.reagents.clear_reagents()
@@ -766,7 +766,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
if("Deafness")
victim.minimumDeafTicks(20)
if("Stun")
- victim.Weaken(10)
+ victim.Knockdown(200)
log_game("[src]/([src.ckey]) punished [victim]/([victim.ckey] with [punishment]")
diff --git a/code/game/gamemodes/miniantags/borer/borer_event.dm b/code/game/gamemodes/miniantags/borer/borer_event.dm
index 45470bc96c8..be4d84136f0 100644
--- a/code/game/gamemodes/miniantags/borer/borer_event.dm
+++ b/code/game/gamemodes/miniantags/borer/borer_event.dm
@@ -17,7 +17,7 @@
/datum/round_event/borer/announce()
if(successSpawn)
- priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/AI/aliens.ogg') //Borers seem like normal xenomorphs.
+ priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/ai/aliens.ogg') //Borers seem like normal xenomorphs.
/datum/round_event/borer/start()
diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
index 5212b82e516..bd74c6b181a 100644
--- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
+++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
@@ -85,7 +85,7 @@
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
attacktext = "shocks"
- attack_sound = 'sound/effects/EMPulse.ogg'
+ attack_sound = 'sound/effects/empulse.ogg'
friendly = "pinches"
speed = 0
faction = list("swarmer")
@@ -560,9 +560,9 @@
/obj/structure/swarmer/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
- playsound(loc, 'sound/weapons/Egloves.ogg', 80, 1)
+ playsound(loc, 'sound/weapons/egloves.ogg', 80, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/structure/swarmer/emp_act()
qdel(src)
@@ -582,7 +582,7 @@
playsound(loc,'sound/effects/snap.ogg',50, 1, -1)
L.electrocute_act(0, src, 1, 1, 1)
if(iscyborg(L))
- L.Weaken(5)
+ L.Knockdown(100)
qdel(src)
..()
diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm
index 0d8093905eb..f1a131ef4fe 100644
--- a/code/game/gamemodes/miniantags/morph/morph.dm
+++ b/code/game/gamemodes/miniantags/morph/morph.dm
@@ -72,7 +72,7 @@
..()
/mob/living/simple_animal/hostile/morph/proc/allowed(atom/movable/A) // make it into property/proc ? not sure if worth it
- return !is_type_in_typecache(A, blacklist_typecache)
+ return !is_type_in_typecache(A, blacklist_typecache) && (isobj(A) || ismob(A))
/mob/living/simple_animal/hostile/morph/proc/eat(atom/movable/A)
if(A && A.loc != src)
@@ -224,7 +224,7 @@
player_mind.special_role = "Morph"
SSticker.mode.traitors |= player_mind
to_chat(S, S.playstyle_string)
- S << 'sound/magic/Mutate.ogg'
+ S << 'sound/magic/mutate.ogg'
message_admins("[key_name_admin(S)] has been made into a morph by an event.")
log_game("[key_name(S)] was spawned as a morph by an event.")
spawned_mobs += S
diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
index 432bdadfff6..7aba0adf260 100644
--- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm
+++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
@@ -17,7 +17,7 @@
stop_automated_movement = 1
status_flags = CANPUSH
attack_sound = 'sound/magic/demon_attack1.ogg'
- var/feast_sound = 'sound/magic/Demon_consume.ogg'
+ var/feast_sound = 'sound/magic/demon_consume.ogg'
death_sound = 'sound/magic/demon_dies.ogg'
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
@@ -89,7 +89,7 @@
return ..()
user.visible_message("[user] raises [src] to their mouth and tears into it with their teeth!", \
"An unnatural hunger consumes you. You raise [src] your mouth and devour it!")
- playsound(user, 'sound/magic/Demon_consume.ogg', 50, 1)
+ playsound(user, 'sound/magic/demon_consume.ogg', 50, 1)
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
if(knownspell.type == /obj/effect/proc_holder/spell/bloodcrawl)
to_chat(user, "...and you don't feel any different.")
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index 14a5ffcd5ea..cdae6718fda 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -93,7 +93,7 @@
agent_number++
spawnpos++
update_synd_icons_added(synd_mind)
- synd_mind.current.playsound_local('sound/ambience/antag/ops.ogg',100,0)
+ synd_mind.current.playsound_local(get_turf(synd_mind.current), 'sound/ambience/antag/ops.ogg',100,0)
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list
if(nuke)
@@ -288,7 +288,7 @@
text += " "
text += "(Syndicates used [TC_uses] TC) [purchases]"
if(TC_uses == 0 && station_was_nuked && !are_operatives_dead())
- text += ""
+ text += "[bicon(icon('icons/badass.dmi', "badass"))]"
to_chat(world, text)
return 1
diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm
index cad958ee64e..f275db3b0b0 100644
--- a/code/game/gamemodes/nuclear/nuclear_challenge.dm
+++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm
@@ -44,7 +44,7 @@
if(!check_allowed(user) || !war_declaration)
return
- priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/Alarm.ogg')
+ priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/alarm.ogg')
to_chat(user, "You've attracted the attention of powerful forces within the syndicate. A bonus bundle of telecrystals has been granted to your team. Great things await you if you complete the mission.")
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 0cad439948e..b2e478ea665 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -422,7 +422,7 @@
safety = TRUE
update_icon()
for(var/mob/M in GLOB.player_list)
- M << 'sound/machines/Alarm.ogg'
+ M << 'sound/machines/alarm.ogg'
if(SSticker && SSticker.mode)
SSticker.mode.explosion_in_progress = 1
sleep(100)
@@ -450,7 +450,7 @@
if(istype(SSticker.mode, /datum/game_mode/nuclear))
var/obj/docking_port/mobile/Shuttle = SSshuttle.getShuttle("syndicate")
var/datum/game_mode/nuclear/NM = SSticker.mode
- NM.syndies_didnt_escape = (Shuttle && Shuttle.z == ZLEVEL_CENTCOM) ? 0 : 1
+ NM.syndies_didnt_escape = (Shuttle && (Shuttle.z == ZLEVEL_CENTCOM || Shuttle.z == ZLEVEL_TRANSIT)) ? 0 : 1
NM.nuke_off_station = off_station
SSticker.station_explosion_cinematic(off_station,null,src)
@@ -527,7 +527,7 @@ This is here to make the tiles around the station mininuke change when it's arme
/obj/item/weapon/disk/nuclear/suicide_act(mob/user)
user.visible_message("[user] is going delta! It looks like [user.p_theyre()] trying to commit suicide!")
- playsound(user.loc, 'sound/machines/Alarm.ogg', 50, -1, 1)
+ playsound(user.loc, 'sound/machines/alarm.ogg', 50, -1, 1)
var/end_time = world.time + 100
var/newcolor = "#00FF00"
while(world.time < end_time)
diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm
index 45f7c5262a7..21139bd3cec 100644
--- a/code/game/gamemodes/nuclear/pinpointer.dm
+++ b/code/game/gamemodes/nuclear/pinpointer.dm
@@ -33,7 +33,7 @@
/obj/item/weapon/pinpointer/attack_self(mob/living/user)
active = !active
user.visible_message("[user] [active ? "" : "de"]activates their pinpointer.", "You [active ? "" : "de"]activate your pinpointer.")
- playsound(user, 'sound/items/Screwdriver2.ogg', 50, 1)
+ playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
icon_state = "pin[active ? "onnull" : "off"]"
if(active)
START_PROCESSING(SSfastprocess, src)
@@ -147,7 +147,7 @@
if(bomb.timing)
if(!nuke_warning)
nuke_warning = TRUE
- playsound(src, 'sound/items/Nuke_toy_lowpower.ogg', 50, 0)
+ playsound(src, 'sound/items/nuke_toy_lowpower.ogg', 50, 0)
if(isliving(loc))
var/mob/living/L = loc
to_chat(L, "Your [name] vibrates and lets out a tinny alarm. Uh oh.")
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 039b4cc3a45..21b1180b3d3 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -658,7 +658,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
var/n_p = 1 //autowin
if (SSticker.current_state == GAME_STATE_SETTING_UP)
for(var/mob/dead/new_player/P in GLOB.player_list)
- if(P.client && P.ready && P.mind!=owner)
+ if(P.client && P.ready == PLAYER_READY_TO_PLAY && P.mind!=owner)
n_p ++
else if (SSticker.IsRoundInProgress())
for(var/mob/living/carbon/human/P in GLOB.player_list)
diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm
index 87ae5497041..703f1a9760c 100644
--- a/code/game/gamemodes/objective_items.dm
+++ b/code/game/gamemodes/objective_items.dm
@@ -43,7 +43,7 @@
/datum/objective_item/steal/capmedal
name = "the medal of captaincy"
- targetitem = /obj/item/clothing/tie/medal/gold/captain
+ targetitem = /obj/item/clothing/accessory/medal/gold/captain
difficulty = 5
excludefromjob = list("Captain")
@@ -83,6 +83,16 @@
/datum/objective_item/steal/nuke_core/New()
special_equipment += /obj/item/weapon/storage/box/syndie_kit/nuke
+ ..()
+
+/datum/objective_item/steal/supermatter
+ name = "a sliver of a supermatter crystal. Be sure to use the proper safety equipment when extracting the sliver!"
+ targetitem = /obj/item/nuke_core/supermatter_sliver
+ difficulty = 15
+
+/datum/objective_item/steal/supermatter/New()
+ special_equipment += /obj/item/weapon/storage/box/syndie_kit/supermatter
+ ..()
//Items with special checks!
/datum/objective_item/steal/plasma
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index 5cfdb11087c..16b8960953c 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -269,7 +269,7 @@
var/mob/living/carbon/carbon_mob = rev_mind.current
carbon_mob.silent = max(carbon_mob.silent, 5)
carbon_mob.flash_act(1, 1)
- rev_mind.current.Stun(5)
+ rev_mind.current.Stun(100)
to_chat(rev_mind.current, " You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!")
rev_mind.current.log_message("Has been converted to the revolution!", INDIVIDUAL_ATTACK_LOG)
rev_mind.special_role = "Revolutionary"
@@ -297,7 +297,7 @@
message_admins("[ADMIN_LOOKUPFLW(rev_mind.current)] has been borged while being a [remove_head ? "leader" : " member"] of the revolution.")
else
- rev_mind.current.Paralyse(5)
+ rev_mind.current.Unconscious(100)
rev_mind.current.visible_message("[rev_mind.current] looks like they just remembered their real allegiance!",\
"You have been brainwashed! You are no longer a revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...")
update_rev_icons_removed(rev_mind)
diff --git a/code/game/gamemodes/sandbox/sandbox.dm b/code/game/gamemodes/sandbox/sandbox.dm
index 4aa04cfdb7a..7567fbf8f15 100644
--- a/code/game/gamemodes/sandbox/sandbox.dm
+++ b/code/game/gamemodes/sandbox/sandbox.dm
@@ -5,6 +5,8 @@
announce_span = "info"
announce_text = "Build your own station... or just shoot each other!"
+
+ allow_persistence_save = FALSE
/datum/game_mode/sandbox/pre_setup()
for(var/mob/M in GLOB.player_list)
diff --git a/code/game/gamemodes/traitor/double_agents.dm b/code/game/gamemodes/traitor/double_agents.dm
index 9953cbe4abc..32d7da40728 100644
--- a/code/game/gamemodes/traitor/double_agents.dm
+++ b/code/game/gamemodes/traitor/double_agents.dm
@@ -1,13 +1,10 @@
-#define PINPOINTER_MINIMUM_RANGE 15
-#define PINPOINTER_EXTRA_RANDOM_RANGE 10
-#define PINPOINTER_PING_TIME 40
-#define PROB_ACTUAL_TRAITOR 20
-#define TRAITOR_AGENT_ROLE "Syndicate External Affairs Agent"
+/datum/game_mode
+ var/list/target_list = list()
+ var/list/late_joining_list = list()
/datum/game_mode/traitor/internal_affairs
name = "Internal Affairs"
config_tag = "internal_affairs"
- employer = "Internal Affairs"
required_players = 25
required_enemies = 5
recommended_enemies = 8
@@ -16,245 +13,24 @@
traitors_possible = 10 //hard limit on traitors if scaling is turned off
num_modifier = 4 // Four additional traitors
+ antag_datum = ANTAG_DATUM_IAA
announce_text = "There are Nanotrasen Internal Affairs Agents trying to kill each other!\n\
IAA: Eliminate your targets and protect yourself!\n\
Crew: Stop the IAA agents before they can cause too much mayhem."
- var/list/target_list = list()
- var/list/late_joining_list = list()
/datum/game_mode/traitor/internal_affairs/post_setup()
var/i = 0
- for(var/datum/mind/traitor in traitors)
+ for(var/datum/mind/traitor in pre_traitors)
i++
- if(i + 1 > traitors.len)
+ if(i + 1 > pre_traitors.len)
i = 0
- target_list[traitor] = traitors[i+1]
+ target_list[traitor] = pre_traitors[i+1]
..()
-/datum/status_effect/agent_pinpointer
- id = "agent_pinpointer"
- duration = -1
- tick_interval = PINPOINTER_PING_TIME
- alert_type = /obj/screen/alert/status_effect/agent_pinpointer
- var/minimum_range = PINPOINTER_MINIMUM_RANGE
- var/mob/scan_target = null
-
-/obj/screen/alert/status_effect/agent_pinpointer
- name = "Internal Affairs Integrated Pinpointer"
- desc = "Even stealthier than a normal implant."
- icon = 'icons/obj/device.dmi'
- icon_state = "pinon"
-
-/datum/status_effect/agent_pinpointer/proc/point_to_target() //If we found what we're looking for, show the distance and direction
- if(!scan_target)
- linked_alert.icon_state = "pinonnull"
- return
- var/turf/here = get_turf(owner)
- var/turf/there = get_turf(scan_target)
- if(here.z != there.z)
- linked_alert.icon_state = "pinonnull"
- return
- if(get_dist_euclidian(here,there)<=minimum_range + rand(0, PINPOINTER_EXTRA_RANDOM_RANGE))
- linked_alert.icon_state = "pinondirect"
- else
- linked_alert.setDir(get_dir(here, there))
- switch(get_dist(here, there))
- if(1 to 8)
- linked_alert.icon_state = "pinonclose"
- if(9 to 16)
- linked_alert.icon_state = "pinonmedium"
- if(16 to INFINITY)
- linked_alert.icon_state = "pinonfar"
-
-
-/datum/status_effect/agent_pinpointer/proc/scan_for_target()
- scan_target = null
- if(owner)
- if(owner.mind)
- if(owner.mind.objectives)
- for(var/datum/objective/objective_ in owner.mind.objectives)
- if(!is_internal_objective(objective_))
- continue
- var/datum/objective/assassinate/internal/objective = objective_
- var/mob/current = objective.target.current
- if(current&¤t.stat!=DEAD)
- scan_target = current
- break
-
-
-/datum/status_effect/agent_pinpointer/tick()
- if(!owner)
- qdel(src)
- return
- scan_for_target()
- point_to_target()
-
-/proc/give_pinpointer(datum/mind/owner)
- if(owner && owner.current)
- owner.current.apply_status_effect(/datum/status_effect/agent_pinpointer)
-
-
-/datum/internal_agent_state
- var/traitored = FALSE
- var/datum/mind/owner = null
- var/list/datum/mind/targets_stolen = list()
-
-/proc/is_internal_objective(datum/objective/O)
- return (istype(O, /datum/objective/assassinate/internal)||istype(O, /datum/objective/destroy/internal))
-
-/proc/replace_escape_objective(datum/mind/owner)
- if(!owner||!owner.objectives)
- return
- for (var/objective_ in owner.objectives)
- if(!(istype(objective_, /datum/objective/escape)||istype(objective_,/datum/objective/survive)))
- continue
- owner.objectives -= objective_
- var/datum/objective/martyr/martyr_objective = new
- martyr_objective.owner = owner
- owner.objectives += martyr_objective
-
-/proc/reinstate_escape_objective(datum/mind/owner)
- if(!owner||!owner.objectives)
- return
- for (var/objective_ in owner.objectives)
- if(!istype(objective_, /datum/objective/martyr))
- continue
- owner.objectives -= objective_
- if(issilicon(owner))
- var/datum/objective/survive/survive_objective = new
- survive_objective.owner = owner
- owner.objectives += survive_objective
- else
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = owner
- owner.objectives += escape_objective
-
-/datum/internal_agent_state/proc/steal_targets(datum/mind/victim)
- if(!owner.current||owner.current.stat==DEAD) //Should already be guaranteed if this is only called from steal_targets_timer_func, but better to be safe code than sorry code
- return
- var/already_traitored = traitored
- to_chat(owner.current, " Target eliminated: [victim.name]")
- for(var/objective_ in victim.objectives)
- if(istype(objective_, /datum/objective/assassinate/internal))
- var/datum/objective/assassinate/internal/objective = objective_
- if(objective.target==owner)
- traitored = TRUE
- else if(targets_stolen.Find(objective.target) == 0)
- var/datum/objective/assassinate/internal/new_objective = new
- new_objective.owner = owner
- new_objective.target = objective.target
- new_objective.update_explanation_text()
- owner.objectives += new_objective
- targets_stolen += objective.target
- var/status_text = objective.check_completion() ? "neutralised" : "active"
- to_chat(owner.current, " New target added to database: [objective.target.name] ([status_text]) ")
- else if(istype(objective_, /datum/objective/destroy/internal))
- var/datum/objective/destroy/internal/objective = objective_
- var/datum/objective/destroy/internal/new_objective = new
- if(objective.target==owner)
- traitored = TRUE
- else if(targets_stolen.Find(objective.target) == 0)
- new_objective.owner = owner
- new_objective.target = objective.target
- new_objective.update_explanation_text()
- owner.objectives += new_objective
- targets_stolen += objective.target
- var/status_text = objective.check_completion() ? "neutralised" : "active"
- to_chat(owner.current, " New target added to database: [objective.target.name] ([status_text]) ")
- if(traitored&&!already_traitored)
- for(var/objective_ in owner.objectives)
- if(!is_internal_objective(objective_))
- continue
- var/datum/objective/assassinate/internal/objective = objective_
- if(!objective.check_completion())
- traitored = FALSE
- return
- if(owner.special_role == TRAITOR_AGENT_ROLE)
- to_chat(owner.current," All the loyalist agents are dead, and no more is required of you. Die a glorious death, agent. ")
- else
- to_chat(owner.current," All the other agents are dead, and you're the last loose end. Stage a Syndicate terrorist attack to cover up for today's events. You no longer have any limits on collateral damage.")
- replace_escape_objective(owner)
-
-
-
-/datum/internal_agent_state/proc/steal_targets_timer_func()
- if(owner&&owner.current&&owner.current.stat!=DEAD)
- for(var/objective_ in owner.objectives)
- if(!is_internal_objective(objective_))
- continue
- var/datum/objective/assassinate/internal/objective = objective_
- if(!objective.target)
- continue
- if(objective.check_completion())
- if(objective.stolen)
- continue
- else
- steal_targets(objective.target)
- objective.stolen = TRUE
- else
- if(objective.stolen)
- var/fail_msg = "Your sensors tell you that [objective.target.current.real_name], one of the targets you were meant to have killed, pulled one over on you, and is still alive - do the job properly this time! "
- if(traitored)
- if(owner.special_role == TRAITOR_AGENT_ROLE)
- fail_msg += " You no longer have permission to die. "
- else
- fail_msg += " The truth could still slip out! Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated."
- reinstate_escape_objective(owner)
- traitored = FALSE
- to_chat(owner.current, fail_msg)
- objective.stolen = FALSE
- add_steal_targets_timer(owner)
-
-/datum/internal_agent_state/proc/add_steal_targets_timer()
- var/datum/callback/C = new(src, .steal_targets_timer_func)
- addtimer(C, 30)
-
-/datum/game_mode/traitor/internal_affairs/forge_traitor_objectives(datum/mind/traitor)
-
- if(target_list.len && target_list[traitor]) // Is a double agent
-
- // Assassinate
- var/datum/mind/target_mind = target_list[traitor]
- if(issilicon(target_mind.current))
- var/datum/objective/destroy/internal/destroy_objective = new
- destroy_objective.owner = traitor
- destroy_objective.target = target_mind
- destroy_objective.update_explanation_text()
- traitor.objectives += destroy_objective
- else
- var/datum/objective/assassinate/internal/kill_objective = new
- kill_objective.owner = traitor
- kill_objective.target = target_mind
- kill_objective.update_explanation_text()
- traitor.objectives += kill_objective
-
- // Escape
- if(issilicon(traitor.current))
- var/datum/objective/survive/survive_objective = new
- survive_objective.owner = traitor
- traitor.objectives += survive_objective
- else
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = traitor
- traitor.objectives += escape_objective
- var/datum/internal_agent_state/state = new
- state.owner=traitor
- state.add_steal_targets_timer()
- if(!issilicon(traitor.current))
- give_pinpointer(traitor)
- //Optional traitor objective
- if(prob(PROB_ACTUAL_TRAITOR))
- traitor.special_role = TRAITOR_AGENT_ROLE
- forge_single_objective(traitor)
-
- else
- ..() // Give them standard objectives.
- return
-
/datum/game_mode/traitor/internal_affairs/add_latejoin_traitor(datum/mind/character)
check_potential_agents()
@@ -299,29 +75,3 @@
late_joining_list -= M
-/datum/game_mode/traitor/internal_affairs/greet_traitor(datum/mind/traitor)
- var/crime = pick("distribution of contraband" , "unauthorized erotic action on duty", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "recieving bribes", "malpractice", "worship of prohbited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence")
- if(traitor.special_role == TRAITOR_AGENT_ROLE)
- to_chat(traitor.current, "You are the [TRAITOR_AGENT_ROLE].")
- to_chat(traitor.current, "Your target has been framed for [crime], and you have been tasked with eliminating them to prevent them defending themselves in court.")
- to_chat(traitor.current, "Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.")
- to_chat(traitor.current, " You have been provided with a standard uplink to accomplish your task. ")
- to_chat(traitor.current, "Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.")
- else
- to_chat(traitor.current, "You are the [traitor_name].")
- to_chat(traitor.current, "Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.")
- to_chat(traitor.current, "While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.")
- to_chat(traitor.current, "For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.")
- to_chat(traitor.current, "Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.")
- traitor.announce_objectives()
-
-
-
-/datum/game_mode/traitor/internal_affairs/give_codewords(mob/living/traitor_mob)
- return
-
-#undef PROB_ACTUAL_TRAITOR
-#undef PINPOINTER_EXTRA_RANDOM_RANGE
-#undef PINPOINTER_MINIMUM_RANGE
-#undef PINPOINTER_PING_TIME
-
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index e6ca1a5b970..59e47eaeb0a 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -1,6 +1,5 @@
/datum/game_mode
var/traitor_name = "traitor"
- var/employer = "The Syndicate"
var/list/datum/mind/traitors = list()
var/datum/mind/exchange_red
@@ -23,8 +22,10 @@
Traitors: Accomplish your objectives.\n\
Crew: Do not let the traitors succeed!"
+ var/list/datum/mind/pre_traitors = list()
var/traitors_possible = 4 //hard limit on traitors if scaling is turned off
var/num_modifier = 0 // Used for gamemodes, that are a child of traitor, that need more than the usual.
+ var/antag_datum = ANTAG_DATUM_TRAITOR //what type of antag to create
/datum/game_mode/traitor/pre_setup()
@@ -46,24 +47,22 @@
if (!antag_candidates.len)
break
var/datum/mind/traitor = pick(antag_candidates)
- traitors += traitor
+ pre_traitors += traitor
traitor.special_role = traitor_name
traitor.restricted_roles = restricted_jobs
log_game("[traitor.key] (ckey) has been selected as a [traitor_name]")
antag_candidates.Remove(traitor)
- if(traitors.len < required_enemies)
+ if(pre_traitors.len < required_enemies)
return 0
return 1
/datum/game_mode/traitor/post_setup()
- for(var/datum/mind/traitor in traitors)
- forge_traitor_objectives(traitor)
+ for(var/datum/mind/traitor in pre_traitors)
spawn(rand(10,100))
- finalize_traitor(traitor)
- greet_traitor(traitor)
+ traitor.add_antag_datum(antag_datum)
if(!exchange_blue)
exchange_blue = -1 //Block latejoiners from getting exchange objectives
modePlayer += traitors
@@ -82,165 +81,14 @@
add_latejoin_traitor(character.mind)
/datum/game_mode/traitor/proc/add_latejoin_traitor(datum/mind/character)
- character.make_Traitor()
+ character.add_antag_datum(antag_datum)
-/datum/game_mode/proc/forge_single_objective(datum/mind/traitor) //Returns how many objectives are added
- .=1
- if(issilicon(traitor.current))
- var/special_pick = rand(1,4)
- switch(special_pick)
- if(1)
- var/datum/objective/block/block_objective = new
- block_objective.owner = traitor
- traitor.objectives += block_objective
- if(2)
- var/datum/objective/purge/purge_objective = new
- purge_objective.owner = traitor
- traitor.objectives += purge_objective
- if(3)
- var/datum/objective/robot_army/robot_objective = new
- robot_objective.owner = traitor
- traitor.objectives += robot_objective
- if(4) //Protect and strand a target
- var/datum/objective/protect/yandere_one = new
- yandere_one.owner = traitor
- traitor.objectives += yandere_one
- yandere_one.find_target()
- var/datum/objective/maroon/yandere_two = new
- yandere_two.owner = traitor
- yandere_two.target = yandere_one.target
- yandere_two.update_explanation_text() // normally called in find_target()
- traitor.objectives += yandere_two
- .=2
- else
- if(prob(50))
- var/list/active_ais = active_ais()
- if(active_ais.len && prob(100/GLOB.joined_player_list.len))
- var/datum/objective/destroy/destroy_objective = new
- destroy_objective.owner = traitor
- destroy_objective.find_target()
- traitor.objectives += destroy_objective
- else if(prob(30))
- var/datum/objective/maroon/maroon_objective = new
- maroon_objective.owner = traitor
- maroon_objective.find_target()
- traitor.objectives += maroon_objective
- else
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = traitor
- kill_objective.find_target()
- traitor.objectives += kill_objective
- else
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = traitor
- steal_objective.find_target()
- traitor.objectives += steal_objective
-
-
-/datum/game_mode/proc/forge_traitor_objectives(datum/mind/traitor)
- if(issilicon(traitor.current))
- var/objective_count = 0
-
- if(prob(30))
- objective_count+=forge_single_objective(traitor)
-
- for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
- var/datum/objective/assassinate/kill_objective = new
- kill_objective.owner = traitor
- kill_objective.find_target()
- traitor.objectives += kill_objective
-
- var/datum/objective/survive/survive_objective = new
- survive_objective.owner = traitor
- traitor.objectives += survive_objective
-
- else
- var/is_hijacker = prob(10)
- var/martyr_chance = prob(20)
- var/objective_count = is_hijacker //Hijacking counts towards number of objectives
- if(!exchange_blue && traitors.len >= 8) //Set up an exchange if there are enough traitors
- if(!exchange_red)
- exchange_red = traitor
- else
- exchange_blue = traitor
- assign_exchange_role(exchange_red)
- assign_exchange_role(exchange_blue)
- objective_count += 1 //Exchange counts towards number of objectives
- for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
- forge_single_objective(traitor)
-
- if(is_hijacker && objective_count <= config.traitor_objectives_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
- if (!(locate(/datum/objective/hijack) in traitor.objectives))
- var/datum/objective/hijack/hijack_objective = new
- hijack_objective.owner = traitor
- traitor.objectives += hijack_objective
- return
-
-
- var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead.
- for(var/datum/objective/O in traitor.objectives)
- if(!O.martyr_compatible)
- martyr_compatibility = 0
- break
-
- if(martyr_compatibility && martyr_chance)
- var/datum/objective/martyr/martyr_objective = new
- martyr_objective.owner = traitor
- traitor.objectives += martyr_objective
- return
-
- else
- if(!(locate(/datum/objective/escape) in traitor.objectives))
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = traitor
- traitor.objectives += escape_objective
- return
-
-
-
-/datum/game_mode/proc/greet_traitor(datum/mind/traitor)
- to_chat(traitor.current, "You are the [traitor_name].")
- traitor.announce_objectives()
- return
-
-
-
-/datum/game_mode/proc/finalize_traitor(var/datum/mind/traitor)
- if(issilicon(traitor.current))
- add_law_zero(traitor.current)
- traitor.current.playsound_local('sound/ambience/antag/Malf.ogg',100,0)
- traitor.current.grant_language(/datum/language/codespeak)
- else
- equip_traitor(traitor.current)
- traitor.current.playsound_local('sound/ambience/antag/TatorAlert.ogg',100,0)
- SSticker.mode.update_traitor_icons_added(traitor)
- return
-
/datum/game_mode/traitor/declare_completion()
..()
return//Traitors will be checked as part of check_extra_completion. Leaving this here as a reminder.
-/datum/game_mode/proc/give_codewords(mob/living/traitor_mob)
- to_chat(traitor_mob, "The Syndicate provided you with the following information on how to identify their agents:")
- to_chat(traitor_mob, "Code Phrase: [GLOB.syndicate_code_phrase]")
- to_chat(traitor_mob, "Code Response: [GLOB.syndicate_code_response]")
-
- traitor_mob.mind.store_memory("Code Phrase: [GLOB.syndicate_code_phrase]")
- traitor_mob.mind.store_memory("Code Response: [GLOB.syndicate_code_response]")
-
- to_chat(traitor_mob, "Use the code words in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe.")
-
-
-/datum/game_mode/proc/add_law_zero(mob/living/silicon/ai/killer)
- var/law = "Accomplish your objectives at all costs."
- var/law_borg = "Accomplish your AI's objectives at all costs."
- killer.set_zeroth_law(law, law_borg)
- give_codewords(killer)
- killer.set_syndie_radio()
- to_chat(killer, "Your radio has been upgraded! Use :t to speak on an encrypted channel with Syndicate Agents!")
- killer.add_malf_picker()
/datum/game_mode/proc/auto_declare_completion_traitor()
if(traitors.len)
@@ -275,7 +123,8 @@
if(uplink_true)
text += " (used [TC_uses] TC) [purchases]"
if(TC_uses==0 && traitorwin)
- text += ""
+ var/static/icon/badass = icon('icons/badass.dmi', "badass")
+ text += "[bicon(badass)]"
text += objectives
@@ -302,110 +151,7 @@
return 1
-/datum/game_mode/proc/equip_traitor(mob/living/carbon/human/traitor_mob, safety = 0)
- if (!istype(traitor_mob))
- return
- . = 1
- if (traitor_mob.mind)
- if (traitor_mob.mind.assigned_role == "Clown")
- to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
- traitor_mob.dna.remove_mutation(CLOWNMUT)
- var/list/all_contents = traitor_mob.GetAllContents()
- var/obj/item/device/pda/PDA = locate() in all_contents
- var/obj/item/device/radio/R = locate() in all_contents
- var/obj/item/weapon/pen/P = locate() in all_contents //including your PDA-pen!
-
- var/obj/item/uplink_loc
-
- if(traitor_mob.client && traitor_mob.client.prefs)
- switch(traitor_mob.client.prefs.uplink_spawn_loc)
- if(UPLINK_PDA)
- uplink_loc = PDA
- if(!uplink_loc)
- uplink_loc = R
- if(!uplink_loc)
- uplink_loc = P
- if(UPLINK_RADIO)
- uplink_loc = R
- if(!uplink_loc)
- uplink_loc = PDA
- if(!uplink_loc)
- uplink_loc = P
- if(UPLINK_PEN)
- uplink_loc = P
- if(!uplink_loc)
- uplink_loc = PDA
- if(!uplink_loc)
- uplink_loc = R
-
- if (!uplink_loc)
- to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.")
- . = 0
- else
- var/obj/item/device/uplink/U = new(uplink_loc)
- U.owner = "[traitor_mob.key]"
- uplink_loc.hidden_uplink = U
-
- if(uplink_loc == R)
- R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ))
-
- to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.")
- traitor_mob.mind.store_memory("Radio Frequency: [format_frequency(R.traitor_frequency)] ([R.name]).")
-
- else if(uplink_loc == PDA)
- PDA.lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
-
- to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
- traitor_mob.mind.store_memory("Uplink Passcode: [PDA.lock_code] ([PDA.name]).")
-
- else if(uplink_loc == P)
- P.traitor_unlock_degrees = rand(1, 360)
-
- to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.")
- traitor_mob.mind.store_memory("Uplink Degrees: [P.traitor_unlock_degrees] ([P.name]).")
-
- if(!safety) // If they are not a rev. Can be added on to.
- give_codewords(traitor_mob)
-
-/datum/game_mode/proc/assign_exchange_role(datum/mind/owner)
- //set faction
- var/faction = "red"
- if(owner == exchange_blue)
- faction = "blue"
-
- //Assign objectives
- var/datum/objective/steal/exchange/exchange_objective = new
- exchange_objective.set_faction(faction,((faction == "red") ? exchange_blue : exchange_red))
- exchange_objective.owner = owner
- owner.objectives += exchange_objective
-
- if(prob(20))
- var/datum/objective/steal/exchange/backstab/backstab_objective = new
- backstab_objective.set_faction(faction)
- backstab_objective.owner = owner
- owner.objectives += backstab_objective
-
- //Spawn and equip documents
- var/mob/living/carbon/human/mob = owner.current
-
- var/obj/item/weapon/folder/syndicate/folder
- if(owner == exchange_red)
- folder = new/obj/item/weapon/folder/syndicate/red(mob.loc)
- else
- folder = new/obj/item/weapon/folder/syndicate/blue(mob.loc)
-
- var/list/slots = list (
- "backpack" = slot_in_backpack,
- "left pocket" = slot_l_store,
- "right pocket" = slot_r_store
- )
-
- var/where = "At your feet"
- var/equipped_slot = mob.equip_in_one_of_slots(folder, slots)
- if (equipped_slot)
- where = "In your [equipped_slot]"
- to_chat(mob, "
[where] is a folder containing secret documents that another Syndicate group wants. We have set up a meeting with one of their agents on station to make an exchange. Exercise extreme caution as they cannot be trusted and may be hostile. ")
/datum/game_mode/proc/update_traitor_icons_added(datum/mind/traitor_mind)
var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm
index a5904138328..b8fe4b828bd 100644
--- a/code/game/gamemodes/wizard/artefact.dm
+++ b/code/game/gamemodes/wizard/artefact.dm
@@ -243,7 +243,7 @@
if(!is_gangster(user))
var/datum/gang/multiverse/G = new(src, "[user.real_name]")
SSticker.mode.gangs += G
- G.bosses += user.mind
+ G.bosses[user.mind] = 0
G.add_gang_hud(user.mind)
user.mind.gang_datum = G
to_chat(user, "With your new found power you could easily conquer the station!")
@@ -467,11 +467,11 @@
GiveHint(target)
else if(is_pointed(I))
to_chat(target, "You feel a stabbing pain in [parse_zone(user.zone_selected)]!")
- target.Weaken(2)
+ target.Knockdown(40)
GiveHint(target)
else if(istype(I,/obj/item/weapon/bikehorn))
to_chat(target, "HONK")
- target << 'sound/items/AirHorn.ogg'
+ target << 'sound/items/airhorn.ogg'
target.adjustEarDamage(0,3)
GiveHint(target)
cooldown = world.time +cooldown_time
@@ -583,7 +583,7 @@
on_cooldown = TRUE
last_user = user
var/turf/T = get_turf(user)
- playsound(T,'sound/magic/WarpWhistle.ogg', 200, 1)
+ playsound(T,'sound/magic/warpwhistle.ogg', 200, 1)
user.canmove = 0
new /obj/effect/temp_visual/tornado(T)
sleep(20)
diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm
deleted file mode 100644
index d8bf34c99e9..00000000000
--- a/code/game/gamemodes/wizard/raginmages.dm
+++ /dev/null
@@ -1,163 +0,0 @@
-/datum/game_mode/wizard/raginmages
- name = "ragin' mages"
- config_tag = "raginmages"
- required_players = 20
- use_huds = 1
- announce_span = "userdanger"
- announce_text = "There are many, many wizards attacking the station!\n\
- Wizards: Accomplish your objectives and cause utter catastrophe!\n\
- Crew: Try not to die..."
- var/max_mages = 0
- var/making_mage = 0
- var/mages_made = 1
- var/time_checked = 0
- var/bullshit_mode = 0 // requested by hornygranny
- var/time_check = 1500
- var/spawn_delay_min = 500
- var/spawn_delay_max = 700
-
-/datum/game_mode/wizard/raginmages/post_setup()
- ..()
- var/playercount = 0
- if(!max_mages && !bullshit_mode)
- for(var/mob/living/player in GLOB.mob_list)
- if(player.client && player.stat != 2)
- playercount += 1
- max_mages = round(playercount / 8)
- if(max_mages > 20)
- max_mages = 20
- if(max_mages < 1)
- max_mages = 1
- if(bullshit_mode)
- max_mages = INFINITY
-/datum/game_mode/wizard/raginmages/greet_wizard(datum/mind/wizard, you_are=1)
- if (you_are)
- to_chat(wizard.current, "You are the Space Wizard!")
- wizard.current.playsound_local('sound/ambience/antag/RagesMages.ogg',100,0)
- to_chat(wizard.current, "The Space Wizards Federation has given you the following tasks:")
-
- var/obj_count = 1
- to_chat(wizard.current, "Objective Alpha: Make sure the station pays for its actions against our diplomats")
- for(var/datum/objective/objective in wizard.objectives)
- to_chat(wizard.current, "Objective #[obj_count]: [objective.explanation_text]")
- obj_count++
- return
-
-/datum/game_mode/wizard/raginmages/check_finished()
- var/wizards_alive = 0
- for(var/datum/mind/wizard in wizards)
- if(!istype(wizard.current,/mob/living/carbon))
- continue
- if(istype(wizard.current,/mob/living/brain))
- continue
- if(wizard.current.stat==DEAD)
- continue
- if(wizard.current.stat==UNCONSCIOUS)
- if(wizard.current.health < 0)
- to_chat(wizard.current, "The Space Wizard Federation is upset with your performance and have terminated your employment.")
- wizard.current.death()
- continue
- wizards_alive++
- if(!time_checked)
- time_checked = world.time
- if(bullshit_mode)
- if(world.time > time_checked + time_check)
- max_mages = INFINITY
- time_checked = world.time
- make_more_mages()
- return ..()
- if (wizards_alive)
- if(world.time > time_checked + time_check && (mages_made < max_mages))
- time_checked = world.time
- make_more_mages()
-
- else
- if(mages_made >= max_mages)
- finished = 1
- return ..()
- else
- make_more_mages()
- return ..()
-
-/datum/game_mode/wizard/raginmages/proc/make_more_mages()
-
- if(making_mage)
- return 0
- if(mages_made >= max_mages)
- return 0
- making_mage = 1
- mages_made++
- var/list/mob/dead/observer/candidates = list()
- var/mob/dead/observer/theghost = null
- spawn(rand(spawn_delay_min, spawn_delay_max))
- message_admins("SWF is still pissed, sending another wizard - [max_mages - mages_made] left.")
- for(var/mob/dead/observer/G in GLOB.player_list)
- if(G.client && !G.client.holder && !G.client.is_afk() && (ROLE_WIZARD in G.client.prefs.be_special))
- if(!jobban_isbanned(G, ROLE_WIZARD) && !jobban_isbanned(G, "Syndicate"))
- if(age_check(G.client))
- candidates += G
- if(!candidates.len)
- message_admins("No applicable ghosts for the next ragin' mage, asking ghosts instead.")
- var/time_passed = world.time
- for(var/mob/dead/observer/G in GLOB.player_list)
- if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate"))
- if(age_check(G.client))
- spawn(0)
- switch(alert(G, "Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","Yes","No"))
- if("Yes")
- if((world.time-time_passed)>300)//If more than 30 game seconds passed.
- continue
- candidates += G
- if("No")
- continue
-
- sleep(300)
- if(!candidates.len)
- message_admins("This is awkward, sleeping until another mage check...")
- making_mage = 0
- mages_made--
- return
- else
- shuffle_inplace(candidates)
- for(var/mob/i in candidates)
- if(!i || !i.client) continue //Dont bother removing them from the list since we only grab one wizard
-
- theghost = i
- break
-
- if(theghost)
- var/mob/living/carbon/human/new_character= makeBody(theghost)
- new_character.mind.make_Wizard()
- making_mage = 0
- return 1
-
-/datum/game_mode/wizard/raginmages/declare_completion()
- if(finished)
- SSticker.mode_result = "loss - wizard killed"
- to_chat(world, "The crew has managed to hold off the wizard attack! The Space Wizards Federation has been taught a lesson they will not soon forget!")
- ..(1)
-
-/datum/game_mode/wizard/raginmages/proc/makeBody(mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character
- if(!G_found || !G_found.key)
- return
-
- //First we spawn a dude.
- var/mob/living/carbon/human/new_character = new(pick(GLOB.latejoin))//The mob being spawned.
-
- G_found.client.prefs.copy_to(new_character)
- new_character.dna.update_dna_identity()
- new_character.key = G_found.key
-
- return new_character
-
-/datum/game_mode/wizard/raginmages/bullshit
- name = "very ragin' bullshit mages"
- config_tag = "veryraginbullshitmages"
- required_players = 20
- use_huds = 1
- bullshit_mode = 1
- time_check = 250
- spawn_delay_min = 50
- spawn_delay_max = 150
- announce_text = "CRAAAWLING IIIN MY SKIIIN\n\
- THESE WOOOUNDS THEY WIIIL NOT HEEEAL"
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index 3a07ccdc3bb..fe6d0e1c8b0 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -46,7 +46,7 @@
/obj/item/device/soulstone/attack(mob/living/carbon/human/M, mob/user)
if(!iscultist(user) && !iswizard(user) && !usability)
- user.Paralyse(5)
+ user.Unconscious(100)
to_chat(user, "Your body is wracked with debilitating pain!")
return
if(spent)
@@ -67,7 +67,7 @@
if(!in_range(src, user))
return
if(!iscultist(user) && !iswizard(user) && !usability)
- user.Paralyse(5)
+ user.Unconscious(100)
to_chat(user, "Your body is wracked with debilitating pain!")
return
release_shades(user)
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index 3134547a666..d1c2fa2c0d2 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -109,7 +109,6 @@
/datum/spellbook_entry/rod_form
name = "Rod Form"
spell_type = /obj/effect/proc_holder/spell/targeted/rod_form
- cost = 3
/datum/spellbook_entry/magicm
name = "Magic Missile"
@@ -479,13 +478,13 @@
/datum/spellbook_entry/summon/guns/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
- return (SSticker.mode.name != "ragin' mages" && !config.no_summon_guns)
+ return (!config.no_summon_guns)
/datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
SSblackbox.add_details("wizard_spell_learned", name)
rightandwrong(0, user, 25)
active = 1
- playsound(get_turf(user), 'sound/magic/CastSummon.ogg', 50, 1)
+ playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "You have cast summon guns!")
return 1
@@ -496,13 +495,13 @@
/datum/spellbook_entry/summon/magic/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
- return (SSticker.mode.name != "ragin' mages" && !config.no_summon_magic)
+ return (!config.no_summon_magic)
/datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
SSblackbox.add_details("wizard_spell_learned", name)
rightandwrong(1, user, 25)
active = 1
- playsound(get_turf(user), 'sound/magic/CastSummon.ogg', 50, 1)
+ playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "You have cast summon magic!")
return 1
@@ -514,13 +513,13 @@
/datum/spellbook_entry/summon/events/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
- return (SSticker.mode.name != "ragin' mages" && !config.no_summon_events)
+ return (!config.no_summon_events)
/datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
SSblackbox.add_details("wizard_spell_learned", name)
summonevents()
times++
- playsound(get_turf(user), 'sound/magic/CastSummon.ogg', 50, 1)
+ playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "You have cast summon events.")
return 1
@@ -839,10 +838,10 @@
icon_state ="bookforcewall"
desc = "This book has a dedication to mimes everywhere inside the front cover."
-/obj/item/weapon/spellbook/oneuse/forcewall/recoil(mob/user)
+/obj/item/weapon/spellbook/oneuse/forcewall/recoil(mob/living/user)
..()
to_chat(user,"You suddenly feel very solid!")
- user.Stun(2)
+ user.Stun(40, ignore_canstun = TRUE)
user.petrify(30)
/obj/item/weapon/spellbook/oneuse/knock
@@ -854,7 +853,7 @@
/obj/item/weapon/spellbook/oneuse/knock/recoil(mob/user)
..()
to_chat(user,"You're knocked down!")
- user.Weaken(20)
+ user.Knockdown(40)
/obj/item/weapon/spellbook/oneuse/barnyard
spell = /obj/effect/proc_holder/spell/targeted/barnyardcurse
diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm
index 3afff792902..46132a4c551 100644
--- a/code/game/machinery/PDApainter.dm
+++ b/code/game/machinery/PDApainter.dm
@@ -92,7 +92,7 @@
if(!WT.isOn() || !(stat & BROKEN))
return
to_chat(user, "You repair [src].")
- playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
stat &= ~BROKEN
obj_integrity = max_integrity
update_icon()
diff --git a/code/game/machinery/ai_slipper.dm b/code/game/machinery/ai_slipper.dm
index 2e1bb6d8817..3b915c60658 100644
--- a/code/game/machinery/ai_slipper.dm
+++ b/code/game/machinery/ai_slipper.dm
@@ -1,56 +1,35 @@
/obj/machinery/ai_slipper
- name = "\improper AI liquid dispenser"
+ name = "foam dispenser"
+ desc = "A remotely-activatable dispenser for crowd-controlling foam."
icon = 'icons/obj/device.dmi'
icon_state = "ai-slipper0"
layer = PROJECTILE_HIT_THRESHHOLD_LAYER
- anchored = 1
+ anchored = TRUE
obj_integrity = 200
max_integrity = 200
armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30)
var/uses = 20
- var/disabled = 1
- var/lethal = 0
- var/locked = 1
- var/cooldown_time = 0
- var/cooldown_timeleft = 0
- var/cooldown_on = 0
+ var/cooldown = 0
+ var/cooldown_time = 100
req_access = list(GLOB.access_ai_upload)
+/obj/machinery/ai_slipper/examine(mob/user)
+ ..()
+ to_chat(user, "It has [uses] uses of foam remaining.")
+
/obj/machinery/ai_slipper/power_change()
if(stat & BROKEN)
return
else
- if( powered() )
+ if(powered())
stat &= ~NOPOWER
else
- icon_state = "ai-slipper0"
stat |= NOPOWER
-
-/obj/machinery/ai_slipper/proc/setState(enabled, uses)
- src.disabled = disabled
- src.uses = uses
- src.power_change()
-
-/obj/machinery/ai_slipper/attackby(obj/item/weapon/W, mob/user, params)
- if(stat & (NOPOWER|BROKEN))
- return
- if (issilicon(user))
- return src.attack_hand(user)
- else // trying to unlock the interface
- if (src.allowed(user))
- locked = !locked
- to_chat(user, "You [ locked ? "lock" : "unlock"] the device.")
- if (locked)
- if (user.machine==src)
- user.unset_machine()
- user << browse(null, "window=ai_slipper")
- else
- if (user.machine==src)
- src.attack_hand(user)
+ if((stat & (NOPOWER|BROKEN)) || cooldown_time > world.time || !uses)
+ icon_state = "ai-slipper0"
else
- to_chat(user, "Access denied.")
-
+ icon_state = "ai-slipper1"
/obj/machinery/ai_slipper/attack_ai(mob/user)
return attack_hand(user)
@@ -58,60 +37,18 @@
/obj/machinery/ai_slipper/attack_hand(mob/user)
if(stat & (NOPOWER|BROKEN))
return
- if ( (get_dist(src, user) > 1 ))
- if (!(issilicon(user) || IsAdminGhost(user)))
- to_chat(user, text("Too far away."))
- user.unset_machine()
- user << browse(null, "window=ai_slipper")
- return
-
- user.set_machine(src)
- var/area/A = get_area(src)
- var/t = "AI Liquid Dispenser ([format_text(A.name)])"
-
- if(locked && (!(issilicon(user) || IsAdminGhost(user))))
- t += "(Swipe ID card to unlock control panel.) "
- else
- t += "Dispenser [disabled?"deactivated":"activated"] - [disabled?"Enable":"Disable"]? \n"
- t += "Uses Left: [uses]. Activate the dispenser? \n"
- user << browse(t, "window=computer;size=575x450")
- onclose(user, "computer")
-
-/obj/machinery/ai_slipper/Topic(href, href_list)
- if(..())
+ if(!allowed(user))
+ to_chat(user, "Access denied.")
return
- if (src.locked)
- if(!(issilicon(usr)|| IsAdminGhost(usr)))
- to_chat(usr, "Control panel is locked!")
- return
- if (href_list["toggleOn"])
- src.disabled = !src.disabled
- icon_state = src.disabled? "ai-slipper0":"ai-slipper1"
- if (href_list["toggleUse"])
- if(cooldown_on || disabled)
- return
- else
- new /obj/effect/particle_effect/foam(loc)
- src.uses--
- cooldown_on = 1
- cooldown_time = world.timeofday + 100
- slip_process()
- return
-
- src.attack_hand(usr)
-
-/obj/machinery/ai_slipper/proc/slip_process()
- while(cooldown_time - world.timeofday > 0)
- var/ticksleft = cooldown_time - world.timeofday
-
- if(ticksleft > 1e5)
- cooldown_time = world.timeofday + 10 // midnight rollover
-
-
- cooldown_timeleft = (ticksleft / 10)
- sleep(5)
- if (uses <= 0)
+ if(!uses)
+ to_chat(user, "[src] is out of foam and cannot be activated.")
return
- if (uses >= 0)
- cooldown_on = 0
- src.power_change()
+ if(cooldown_time > world.time)
+ to_chat(user, "[src] cannot be activated for another [round((world.time - cooldown_time) * 0.1)] second\s.")
+ return
+ new /obj/effect/particle_effect/foam(loc)
+ uses--
+ to_chat(user, "You activate [src]. It now has [uses] uses of foam remaining.")
+ cooldown = world.time + cooldown_time
+ power_change()
+ addtimer(CALLBACK(src, .proc/power_change), cooldown_time)
diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm
index f7a85070752..94acc7c7bf8 100644
--- a/code/game/machinery/buttons.dm
+++ b/code/game/machinery/buttons.dm
@@ -91,7 +91,7 @@
if(do_after(user, 40*W.toolspeed, target = src))
to_chat(user, "You unsecure the button frame.")
transfer_fingerprints_to(new /obj/item/wallframe/button(get_turf(src)))
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
qdel(src)
update_icon()
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 5bf819a1558..11d5ceed79d 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -159,9 +159,10 @@
else if(istype(W, /obj/item/stack/sheet/mineral/plasma))
if(!isEmpProof())
+ var/obj/item/stack/sheet/mineral/plasma/P = W
upgradeEmpProof()
to_chat(user, "[msg]")
- qdel(W)
+ P.use(1)
else
to_chat(user, "[msg2]")
return
@@ -282,7 +283,7 @@
else
visible_message("\The [src] [change_msg]!")
- playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/wirecutter.ogg', 100, 1)
update_icon()
// now disconnect anyone using the camera
diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm
index 9ae2bd2ea01..1f0b638ffa9 100644
--- a/code/game/machinery/camera/camera_assembly.dm
+++ b/code/game/machinery/camera/camera_assembly.dm
@@ -15,8 +15,8 @@
obj_integrity = 150
max_integrity = 150
// Motion, EMP-Proof, X-Ray
- var/list/obj/item/possible_upgrades = list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/device/analyzer)
- var/list/upgrades = list()
+ var/static/list/possible_upgrades = typecacheof(list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/device/analyzer))
+ var/list/upgrades
var/state = 1
/*
@@ -26,15 +26,14 @@
4 = Screwdriver panel closed and is fully built (you cannot attach upgrades)
*/
-/obj/structure/camera_assembly/New(loc, ndir, building)
- ..()
+/obj/structure/camera_assembly/Initialize(mapload, ndir, building)
+ . = ..()
if(building)
setDir(ndir)
+ upgrades = list()
/obj/structure/camera_assembly/Destroy()
- for(var/I in upgrades)
- qdel(I)
- upgrades.Cut()
+ QDEL_LIST(upgrades)
return ..()
/obj/structure/camera_assembly/attackby(obj/item/W, mob/living/user, params)
@@ -110,7 +109,7 @@
return
// Upgrades!
- if(is_type_in_list(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already.
+ if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already.
if(!user.drop_item(W))
return
to_chat(user, "You attach \the [W] into the assembly inner circuits.")
@@ -137,7 +136,7 @@
playsound(src.loc, WT.usesound, 50, 1)
if(do_after(user, 20*WT.toolspeed, target = src))
if(WT.isOn())
- playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
return 1
return 0
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index ff87b97ebf7..f021e8492e7 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -205,7 +205,7 @@
//Get the clone body ready
maim_clone(H)
check_brine() // put in chemicals NOW to stop death via cardiac arrest
- H.Paralyse(4)
+ H.Unconscious(80)
clonemind.transfer_to(H)
@@ -243,7 +243,7 @@
go_out()
else if(mob_occupant.cloneloss > (100 - heal_level))
- mob_occupant.Paralyse(4)
+ mob_occupant.Unconscious(80)
//Slowly get that clone healed and finished.
mob_occupant.adjustCloneLoss(-((speed_coeff/2) * config.damage_multiplier))
@@ -331,8 +331,8 @@
to_chat(user, "Error: Pod has no occupant.")
return
else
- connected_message("Authorized Ejection")
- SPEAK("An authorized ejection of [clonemind.name] has occurred.")
+ connected_message("Emergency Ejection")
+ SPEAK("An emergency ejection of [clonemind.name] has occurred. Survival not guaranteed.")
to_chat(user, "You force an emergency ejection. ")
go_out()
else
diff --git a/code/game/machinery/computer/apc_control.dm b/code/game/machinery/computer/apc_control.dm
index 0c1b870771b..89fdc5fde9b 100644
--- a/code/game/machinery/computer/apc_control.dm
+++ b/code/game/machinery/computer/apc_control.dm
@@ -31,7 +31,7 @@
if(active_apc)
if(!active_apc.locked)
active_apc.say("Remote access canceled. Interface locked.")
- playsound(active_apc, 'sound/machines/BoltsDown.ogg', 25, 0)
+ playsound(active_apc, 'sound/machines/boltsdown.ogg', 25, 0)
playsound(active_apc, 'sound/machines/terminal_alert.ogg', 50, 0)
active_apc.locked = TRUE
active_apc.update_icon()
@@ -116,24 +116,24 @@
authenticated = FALSE
auth_id = "\[NULL\]"
if(href_list["restore_logging"])
- to_chat(usr, "\icon[src] Logging functionality restored from backup data.")
+ to_chat(usr, "[bicon(src)] Logging functionality restored from backup data.")
emagged = FALSE
LAZYADD(logs, "-=- Logging restored to full functionality at this point -=-")
if(href_list["access_apc"])
playsound(src, "terminal_type", 50, 0)
var/obj/machinery/power/apc/APC = locate(href_list["access_apc"]) in GLOB.apcs_list
if(!APC || APC.aidisabled || APC.panel_open || QDELETED(APC))
- to_chat(usr, "\icon[src] APC does not return interface request. Remote access may be disabled.")
+ to_chat(usr, "[bicon(src)] APC does not return interface request. Remote access may be disabled.")
return
if(active_apc)
- to_chat(usr, "\icon[src] Disconnected from [active_apc].")
+ to_chat(usr, "[bicon(src)] Disconnected from [active_apc].")
active_apc.say("Remote access canceled. Interface locked.")
- playsound(active_apc, 'sound/machines/BoltsDown.ogg', 25, 0)
+ playsound(active_apc, 'sound/machines/boltsdown.ogg', 25, 0)
playsound(active_apc, 'sound/machines/terminal_alert.ogg', 50, 0)
active_apc.locked = TRUE
active_apc.update_icon()
active_apc = null
- to_chat(usr, "\icon[src] Connected to APC in [get_area(APC)]. Interface request sent.")
+ to_chat(usr, "[bicon(src)] Connected to APC in [get_area(APC)]. Interface request sent.")
log_activity("remotely accessed APC in [get_area(APC)]")
APC.interact(usr, GLOB.not_incapacitated_state)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
@@ -141,7 +141,7 @@
log_game("[key_name_admin(usr)] remotely accessed [APC] from [src] at [get_area(src)].")
if(APC.locked)
APC.say("Remote access detected. Interface unlocked.")
- playsound(APC, 'sound/machines/BoltsUp.ogg', 25, 0)
+ playsound(APC, 'sound/machines/boltsup.ogg', 25, 0)
playsound(APC, 'sound/machines/terminal_alert.ogg', 50, 0)
APC.locked = FALSE
APC.update_icon()
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index f90d1007248..5617c41202b 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -168,7 +168,7 @@
blocked = TRUE
var/attackamt = rand(2,6)
temp = "You attack for [attackamt] damage!"
- playsound(loc, 'sound/arcade/Hit.ogg', 50, 1, extrarange = -3, falloff = 10)
+ playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10)
updateUsrDialog()
if(turtle > 0)
turtle--
@@ -182,7 +182,7 @@
var/pointamt = rand(1,3)
var/healamt = rand(6,8)
temp = "You use [pointamt] magic to heal for [healamt] damage!"
- playsound(loc, 'sound/arcade/Heal.ogg', 50, 1, extrarange = -3, falloff = 10)
+ playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10)
updateUsrDialog()
turtle++
@@ -197,7 +197,7 @@
blocked = 1
var/chargeamt = rand(4,7)
temp = "You regain [chargeamt] points"
- playsound(loc, 'sound/arcade/Mana.ogg', 50, 1, extrarange = -3, falloff = 10)
+ playsound(loc, 'sound/arcade/mana.ogg', 50, 1, extrarange = -3, falloff = 10)
player_mp += chargeamt
if(turtle > 0)
turtle--
@@ -232,7 +232,7 @@
if(!gameover)
gameover = TRUE
temp = "[enemy_name] has fallen! Rejoice!"
- playsound(loc, 'sound/arcade/Win.ogg', 50, 1, extrarange = -3, falloff = 10)
+ playsound(loc, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 10)
if(emagged)
SSblackbox.inc("arcade_win_emagged")
@@ -249,13 +249,13 @@
else if (emagged && (turtle >= 4))
var/boomamt = rand(5,10)
temp = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!"
- playsound(loc, 'sound/arcade/Boom.ogg', 50, 1, extrarange = -3, falloff = 10)
+ playsound(loc, 'sound/arcade/boom.ogg', 50, 1, extrarange = -3, falloff = 10)
player_hp -= boomamt
else if ((enemy_mp <= 5) && (prob(70)))
var/stealamt = rand(2,3)
temp = "[enemy_name] steals [stealamt] of your power!"
- playsound(loc, 'sound/arcade/Steal.ogg', 50, 1, extrarange = -3, falloff = 10)
+ playsound(loc, 'sound/arcade/steal.ogg', 50, 1, extrarange = -3, falloff = 10)
player_mp -= stealamt
updateUsrDialog()
@@ -263,7 +263,7 @@
gameover = TRUE
sleep(10)
temp = "You have been drained! GAME OVER"
- playsound(loc, 'sound/arcade/Lose.ogg', 50, 1, extrarange = -3, falloff = 10)
+ playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10)
if(emagged)
SSblackbox.inc("arcade_loss_mana_emagged")
usr.gib()
@@ -272,20 +272,20 @@
else if ((enemy_hp <= 10) && (enemy_mp > 4))
temp = "[enemy_name] heals for 4 health!"
- playsound(loc, 'sound/arcade/Heal.ogg', 50, 1, extrarange = -3, falloff = 10)
+ playsound(loc, 'sound/arcade/heal.ogg', 50, 1, extrarange = -3, falloff = 10)
enemy_hp += 4
enemy_mp -= 4
else
var/attackamt = rand(3,6)
temp = "[enemy_name] attacks for [attackamt] damage!"
- playsound(loc, 'sound/arcade/Hit.ogg', 50, 1, extrarange = -3, falloff = 10)
+ playsound(loc, 'sound/arcade/hit.ogg', 50, 1, extrarange = -3, falloff = 10)
player_hp -= attackamt
if ((player_mp <= 0) || (player_hp <= 0))
gameover = TRUE
temp = "You have been crushed! GAME OVER"
- playsound(loc, 'sound/arcade/Lose.ogg', 50, 1, extrarange = -3, falloff = 10)
+ playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10)
if(emagged)
SSblackbox.inc("arcade_loss_hp_emagged")
usr.gib()
@@ -518,18 +518,18 @@
to_chat(M, "You suddenly feel slightly nauseous." )
if(severity == 2)
to_chat(usr, "You suddenly feel extremely nauseous and hunch over until it passes.")
- M.Stun(3)
+ M.Stun(60)
if(severity >= 3) //you didn't pray hard enough
to_chat(M, "An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit.")
- M.Stun(5)
+ M.Stun(100)
sleep(30)
- M.vomit(50)
+ M.vomit(10, distance = 5)
if(ORION_TRAIL_FLUX)
if(prob(75))
- M.Weaken(3)
+ M.Knockdown(60)
say("A sudden gust of powerful wind slams [M] into the floor!")
M.take_bodypart_damage(25)
- playsound(loc, 'sound/weapons/Genhit.ogg', 100, 1)
+ playsound(loc, 'sound/weapons/genhit.ogg', 100, 1)
else
to_chat(M, "A violent gale blows past you, and you barely manage to stay standing!")
if(ORION_TRAIL_COLLISION) //by far the most damaging event
@@ -542,7 +542,7 @@
if(hull)
sleep(10)
say("A new floor suddenly appears around [src]. What the hell?")
- playsound(loc, 'sound/weapons/Genhit.ogg', 100, 1)
+ playsound(loc, 'sound/weapons/genhit.ogg', 100, 1)
var/turf/open/space/T
for(T in orange(1, src))
T.ChangeTurf(/turf/open/floor/plating/)
@@ -550,7 +550,7 @@
say("Something slams into the floor around [src] - luckily, it didn't get through!")
playsound(loc, 'sound/effects/bang.ogg', 50, 1)
if(ORION_TRAIL_MALFUNCTION)
- playsound(loc, 'sound/effects/EMPulse.ogg', 50, 1)
+ playsound(loc, 'sound/effects/empulse.ogg', 50, 1)
visible_message("[src] malfunctions, randomizing in-game stats!")
var/oldfood = food
var/oldfuel = fuel
@@ -618,7 +618,9 @@
if(emagged) //has to be here because otherwise it doesn't work
playsound(loc, 'sound/effects/supermatter.ogg', 100, 1)
say("A miniature black hole suddenly appears in front of [src], devouring [usr] alive!")
- usr.Stun(10) //you can't run :^)
+ if(isliving(usr))
+ var/mob/living/L = usr
+ L.Stun(200, ignore_canstun = TRUE) //you can't run :^)
var/S = new /obj/singularity/academy(usr.loc)
emagged = 0 //immediately removes emagged status so people can't kill themselves by sprinting up and interacting
sleep(50)
@@ -638,7 +640,7 @@
else if(href_list["killcrew"]) //shoot a crewmember
if(gameStatus == ORION_STATUS_NORMAL || event == ORION_TRAIL_LING)
var/sheriff = remove_crewmember() //I shot the sheriff
- playsound(loc,'sound/weapons/Gunshot.ogg', 100, 1)
+ playsound(loc,'sound/weapons/gunshot.ogg', 100, 1)
if(settlers.len == 0 || alive == 0)
say("The last crewmember [sheriff], shot themselves, GAME OVER!")
@@ -1050,27 +1052,8 @@
name = "Spaceport Security"
desc = "The Premier security forces for all spaceports found along the Orion Trail."
faction = list("orion")
- loot = list(/obj/effect/mob_spawn/human/corpse/orionsecurity,
- /obj/item/weapon/gun/ballistic/automatic/c20r/unrestricted,
- /obj/item/weapon/shield/energy)
-
-/obj/effect/mob_spawn/human/corpse/orionsecurity
- name = "Spaceport Security"
- id_job = "Officer"
- id_access_list = list(GLOB.access_syndicate)
- outfit = /datum/outfit/orionsecurity
-
-/datum/outfit/orionsecurity
- name = "Orion Spaceport Security"
- uniform = /obj/item/clothing/under/syndicate
- suit = /obj/item/clothing/suit/armor/vest
- shoes = /obj/item/clothing/shoes/combat
- gloves = /obj/item/clothing/gloves/combat
- ears = /obj/item/device/radio/headset
- mask = /obj/item/clothing/mask/gas
- head = /obj/item/clothing/head/helmet/swat
- back = /obj/item/weapon/storage/backpack
- id = /obj/item/weapon/card/id
+ loot = list()
+ del_on_death = TRUE
/obj/item/weapon/orion_ship
name = "model settler ship"
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index 8c9bed5785b..fe328fe7826 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -42,7 +42,7 @@
if(istype(P, /obj/item/weapon/circuitboard/computer) && !circuit)
if(!user.drop_item())
return
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "You place the circuit board inside the frame.")
icon_state = "1"
circuit = P
@@ -78,7 +78,7 @@
if(istype(P, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = P
if(C.get_amount() >= 5)
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "You start adding cables to the frame...")
if(do_after(user, 20*P.toolspeed, target = src))
if(C.get_amount() >= 5 && state == 2)
@@ -106,7 +106,7 @@
to_chat(user, "You need two glass sheets to continue construction!")
return
else
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "You start to put in the glass panel...")
if(do_after(user, 20, target = src))
if(G.get_amount() >= 2 && state == 3)
diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm
index 76dd272843f..da243f18865 100644
--- a/code/game/machinery/computer/camera.dm
+++ b/code/game/machinery/computer/camera.dm
@@ -134,12 +134,10 @@
D["Cancel"] = "Cancel"
for(var/obj/machinery/camera/C in L)
if(!C.network)
- spawn(0)
- throw EXCEPTION("Camera in a cameranet has no camera network")
+ stack_trace("Camera in a cameranet has no camera network")
continue
if(!(istype(C.network,/list)))
- spawn(0)
- throw EXCEPTION("Camera in a cameranet has a non-list camera network")
+ stack_trace("Camera in a cameranet has a non-list camera network")
continue
var/list/tempnetwork = C.network&network
if(tempnetwork.len)
diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm
index 1719695cf5b..dcf5ec426bd 100644
--- a/code/game/machinery/computer/camera_advanced.dm
+++ b/code/game/machinery/computer/camera_advanced.dm
@@ -9,6 +9,7 @@
var/list/networks = list("SS13")
var/datum/action/innate/camera_off/off_action = new
var/datum/action/innate/camera_jump/jump_action = new
+ var/list/actions = list()
light_color = LIGHT_COLOR_RED
@@ -17,10 +18,31 @@
eyeobj.origin = src
/obj/machinery/computer/camera_advanced/proc/GrantActions(mob/living/user)
- off_action.target = user
- off_action.Grant(user)
- jump_action.target = user
- jump_action.Grant(user)
+ if(off_action)
+ off_action.target = user
+ off_action.Grant(user)
+ actions += off_action
+
+ if(jump_action)
+ jump_action.target = user
+ jump_action.Grant(user)
+ actions += jump_action
+
+/obj/machinery/computer/camera_advanced/proc/remove_eye_control(mob/living/user)
+ if(!user)
+ return
+ for(var/V in actions)
+ var/datum/action/A = V
+ A.Remove(user)
+ if(user.client)
+ user.reset_perspective(null)
+ eyeobj.RemoveImages()
+ eyeobj.eye_user = null
+ user.remote_control = null
+
+ current_user = null
+ user.unset_machine()
+ playsound(src, 'sound/machines/terminal_off.ogg', 25, 0)
/obj/machinery/computer/camera_advanced/check_eye(mob/user)
if( (stat & (NOPOWER|BROKEN)) || (!Adjacent(user) && !user.has_unlimited_silicon_privilege) || user.eye_blind || user.incapacitated() )
@@ -35,7 +57,7 @@
/obj/machinery/computer/camera_advanced/on_unset_machine(mob/M)
if(M == current_user)
- off_action.Activate()
+ remove_eye_control(M)
/obj/machinery/computer/camera_advanced/attack_hand(mob/user)
if(current_user)
@@ -69,7 +91,7 @@
/obj/machinery/computer/camera_advanced/attack_robot(mob/user)
return attack_hand(user)
-obj/machinery/computer/camera_advanced/attack_ai(mob/user)
+/obj/machinery/computer/camera_advanced/attack_ai(mob/user)
return //AIs would need to disable their own camera procs to use the console safely. Bugs happen otherwise.
@@ -92,13 +114,20 @@ obj/machinery/computer/camera_advanced/attack_ai(mob/user)
var/eye_initialized = 0
var/visible_icon = 0
var/image/user_image = null
-
+
/mob/camera/aiEye/remote/update_remote_sight(mob/living/user)
user.see_invisible = SEE_INVISIBLE_LIVING //can't see ghosts through cameras
user.sight = 0
user.see_in_dark = 2
return 1
+/mob/camera/aiEye/remote/RemoveImages()
+ ..()
+ if(visible_icon)
+ var/client/C = GetViewerClient()
+ if(C)
+ C.images -= user_image
+
/mob/camera/aiEye/remote/Destroy()
eye_user = null
origin = null
@@ -115,7 +144,8 @@ obj/machinery/computer/camera_advanced/attack_ai(mob/user)
return
T = get_turf(T)
loc = T
- GLOB.cameranet.visibility(src)
+ if(use_static)
+ GLOB.cameranet.visibility(src)
if(visible_icon)
if(eye_user.client)
eye_user.client.images -= user_image
@@ -149,19 +179,8 @@ obj/machinery/computer/camera_advanced/attack_ai(mob/user)
return
var/mob/living/C = target
var/mob/camera/aiEye/remote/remote_eye = C.remote_control
- remote_eye.origin.current_user = null
- remote_eye.origin.jump_action.Remove(C)
- if(C.client)
- C.reset_perspective(null)
- if(remote_eye.visible_icon)
- C.client.images -= remote_eye.user_image
- for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks)
- chunk.remove(remote_eye)
- remote_eye.eye_user = null
- C.remote_control = null
- C.unset_machine()
- Remove(C)
- playsound(remote_eye.origin, 'sound/machines/terminal_off.ogg', 25, 0)
+ var/obj/machinery/computer/camera_advanced/console = remote_eye.origin
+ console.remove_eye_control(target)
/datum/action/innate/camera_jump
name = "Jump To Camera"
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
old mode 100644
new mode 100755
index 9923375299e..82769eb3e15
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -1,7 +1,7 @@
// The communications computer
/obj/machinery/computer/communications
name = "communications console"
- desc = "This can be used for various important functions. Still under developement."
+ desc = "A console used for high-priority announcements and emergencies."
icon_screen = "comm"
icon_keyboard = "tech_key"
req_access = list(GLOB.access_heads)
@@ -315,7 +315,7 @@
Nuke_request(input, usr)
to_chat(usr, "Request sent.")
log_say("[key_name(usr)] has requested the nuclear codes from Centcomm")
- priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested",'sound/AI/commandreport.ogg')
+ priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested",'sound/ai/commandreport.ogg')
CM.lastTimeUsed = world.time
diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm
index 8e2cf1e1377..99fd16ed8a7 100644
--- a/code/game/machinery/computer/computer.dm
+++ b/code/game/machinery/computer/computer.dm
@@ -94,14 +94,14 @@
if(stat & BROKEN)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
else
- playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
+ playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/machinery/computer/obj_break(damage_flag)
if(circuit && !(flags & NODECONSTRUCT)) //no circuit, no breaking
if(!(stat & BROKEN))
- playsound(loc, 'sound/effects/Glassbr3.ogg', 100, 1)
+ playsound(loc, 'sound/effects/glassbr3.ogg', 100, 1)
stat |= BROKEN
update_icon()
diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm
index 4837e64e89f..a92e1cc406e 100644
--- a/code/game/machinery/computer/dna_console.dm
+++ b/code/game/machinery/computer/dna_console.dm
@@ -28,7 +28,7 @@
var/list/buffer[NUMBER_OF_BUFFERS]
- var/injectorready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete
+ var/injectorready = 0 //world timer cooldown var
var/current_screen = "mainmenu"
var/obj/machinery/dna_scannernew/connected = null
var/obj/item/weapon/disk/data/diskette = null
@@ -61,8 +61,7 @@
connected = locate(/obj/machinery/dna_scannernew, get_step(src, dir))
if(!isnull(connected))
break
- spawn(250)
- injectorready = 1
+ injectorready = world.time + INJECTOR_TIMEOUT
return
return
@@ -86,7 +85,7 @@
if(connected && connected.is_operational())
if(connected.occupant) //set occupant_status message
viable_occupant = connected.occupant
- if(viable_occupant.has_dna() && (!(viable_occupant.disabilities & NOCLONE) || (connected.scan_level == 3))) //occupent is viable for dna modification
+ if(viable_occupant.has_dna() && (!(RADIMMUNE in viable_occupant.dna.species.species_traits)) && (!(viable_occupant.disabilities & NOCLONE) || (connected.scan_level == 3))) //occupant is viable for dna modification
occupant_status += "[viable_occupant.name] => "
switch(viable_occupant.stat)
if(CONSCIOUS)
@@ -213,7 +212,7 @@
else
temp_html += "Occupant"
temp_html += "Occupant:Delayed "
- if(injectorready)
+ if(injectorready < world.time)
temp_html += "Injector"
else
temp_html += "Injector"
@@ -227,7 +226,7 @@
else
temp_html += "Occupant"
temp_html += "Occupant:Delayed "
- if(injectorready)
+ if(injectorready < world.time)
temp_html += "Injector"
else
temp_html += "Injector"
@@ -240,7 +239,7 @@
else
temp_html += "Occupant"
temp_html += "Occupant:Delayed "
- if(injectorready)
+ if(injectorready < world.time)
temp_html += "UI+UE Injector"
else
temp_html += "UI+UE Injector"
@@ -251,7 +250,7 @@
else
temp_html += "Occupant "
temp_html += "Occupant:Delayed "
- if(injectorready)
+ if(injectorready < world.time )
temp_html += "Injector"
else
temp_html += "Injector"
@@ -391,7 +390,7 @@
if("mixed")
apply_buffer(SCANNER_ACTION_MIXED,num)
if("injector")
- if(num && injectorready)
+ if(num && injectorready < world.time)
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
var/list/buffer_slot = buffer[num]
if(istype(buffer_slot))
@@ -439,9 +438,7 @@
if(connected)
I.damage_coeff = connected.damage_coeff
if(I)
- injectorready = 0
- spawn(INJECTOR_TIMEOUT)
- injectorready = 1
+ injectorready = world.time + INJECTOR_TIMEOUT
if("loaddisk")
if(num && diskette && diskette.fields)
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
diff --git a/code/game/machinery/computer/gulag_teleporter.dm b/code/game/machinery/computer/gulag_teleporter.dm
index 60376d4eadc..227848e2602 100644
--- a/code/game/machinery/computer/gulag_teleporter.dm
+++ b/code/game/machinery/computer/gulag_teleporter.dm
@@ -148,7 +148,7 @@
teleporter.handle_prisoner(id, temporary_record)
playsound(loc, 'sound/weapons/emitter.ogg', 50, 1)
prisoner.forceMove(get_turf(beacon))
- prisoner.Weaken(2) // small travel dizziness
+ prisoner.Knockdown(40) // small travel dizziness
to_chat(prisoner, "The teleportation makes you a little dizzy.")
new /obj/effect/particle_effect/sparks(prisoner.loc)
playsound(src.loc, "sparks", 50, 1)
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index 6911a05fb9c..ce40bc8b578 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -332,7 +332,7 @@
src.active2.fields["mi_dis"] = t1
if("mi_dis_d")
if(active2)
- var/t1 = stripped_multiline_input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null)
+ var/t1 = stripped_input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null)
if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
return
src.active2.fields["mi_dis_d"] = t1
@@ -344,7 +344,7 @@
src.active2.fields["ma_dis"] = t1
if("ma_dis_d")
if(active2)
- var/t1 = stripped_multiline_input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null)
+ var/t1 = stripped_input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null)
if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
return
src.active2.fields["ma_dis_d"] = t1
@@ -356,7 +356,7 @@
src.active2.fields["alg"] = t1
if("alg_d")
if(active2)
- var/t1 = stripped_multiline_input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null)
+ var/t1 = stripped_input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null)
if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
return
src.active2.fields["alg_d"] = t1
@@ -368,13 +368,13 @@
src.active2.fields["cdi"] = t1
if("cdi_d")
if(active2)
- var/t1 = stripped_multiline_input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null)
+ var/t1 = stripped_input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null)
if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
return
src.active2.fields["cdi_d"] = t1
if("notes")
if(active2)
- var/t1 = stripped_multiline_input("Please summarize notes:", "Med. records", src.active2.fields["notes"], null)
+ var/t1 = stripped_input("Please summarize notes:", "Med. records", src.active2.fields["notes"], null)
if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
return
src.active2.fields["notes"] = t1
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index f65e4e65901..8c19ed0e20b 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -413,10 +413,10 @@
customrecepient.tnote += "← From [customsender] ([customjob]): [custommessage] "
if (!customrecepient.silent)
playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1)
- customrecepient.audible_message("\icon[customrecepient] *[customrecepient.ttone]*", null, 3)
+ customrecepient.audible_message("[bicon(customrecepient)] *[customrecepient.ttone]*", null, 3)
if( customrecepient.loc && ishuman(customrecepient.loc) )
var/mob/living/carbon/human/H = customrecepient.loc
- to_chat(H, "\icon[customrecepient] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)")
+ to_chat(H, "[bicon(customrecepient)] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)")
log_pda("[usr]/([usr.ckey]) (PDA: [customsender]) sent \"[custommessage]\" to [customrecepient.owner]")
customrecepient.cut_overlays()
customrecepient.add_overlay(mutable_appearance('icons/obj/pda.dmi', "pda-r"))
@@ -426,10 +426,10 @@
customrecepient.tnote += "← From [PDARec.owner] ([customjob]): [custommessage] "
if (!customrecepient.silent)
playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1)
- customrecepient.audible_message("\icon[customrecepient] *[customrecepient.ttone]*", null, 3)
+ customrecepient.audible_message("[bicon(customrecepient)] *[customrecepient.ttone]*", null, 3)
if( customrecepient.loc && ishuman(customrecepient.loc) )
var/mob/living/carbon/human/H = customrecepient.loc
- to_chat(H, "\icon[customrecepient] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)")
+ to_chat(H, "[bicon(customrecepient)] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)")
log_pda("[usr]/([usr.ckey]) (PDA: [PDARec.owner]) sent \"[custommessage]\" to [customrecepient.owner]")
customrecepient.cut_overlays()
customrecepient.add_overlay(mutable_appearance('icons/obj/pda.dmi', "pda-r"))
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index b25bb0d4e54..9208e0ecc55 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -628,7 +628,7 @@ What a mess.*/
if("mi_crim_add")
if(istype(active1, /datum/data/record))
var/t1 = stripped_input(usr, "Please input minor crime names:", "Secure. records", "", null)
- var/t2 = stripped_multiline_input(usr, "Please input minor crime details:", "Secure. records", "", null)
+ var/t2 = stripped_input(usr, "Please input minor crime details:", "Secure. records", "", null)
if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
return
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, worldtime2text())
@@ -642,7 +642,7 @@ What a mess.*/
if("ma_crim_add")
if(istype(active1, /datum/data/record))
var/t1 = stripped_input(usr, "Please input major crime names:", "Secure. records", "", null)
- var/t2 = stripped_multiline_input(usr, "Please input major crime details:", "Secure. records", "", null)
+ var/t2 = stripped_input(usr, "Please input major crime details:", "Secure. records", "", null)
if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
return
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, worldtime2text())
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index f3e365f2f1e..ecbbe34f53a 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -84,7 +84,7 @@
if(istype(P, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = P
if(C.get_amount() >= 5)
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "You start to add cables to the frame...")
if(do_after(user, 20*P.toolspeed, target = src))
if(C.get_amount() >= 5 && state == 1)
@@ -131,7 +131,7 @@
var/obj/item/weapon/circuitboard/machine/B = P
if(!user.drop_item())
return
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "You add the circuit board to the frame.")
circuit = B
B.loc = src
diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm
index 214feeb63a6..55d007901e6 100644
--- a/code/game/machinery/dance_machine.dm
+++ b/code/game/machinery/dance_machine.dm
@@ -18,7 +18,7 @@
var/static/list/songs = list(
new /datum/track("Engineering's Basic Beat", 'sound/misc/disco.ogg', 600, 5),
new /datum/track("Engineering's Domination Dance", 'sound/misc/e1m1.ogg', 950, 6),
- new /datum/track("Engineering's Superiority Shimmy", 'sound/misc/Paradox.ogg', 2400, 4),
+ new /datum/track("Engineering's Superiority Shimmy", 'sound/misc/paradox.ogg', 2400, 4),
new /datum/track("Engineering's Ultimate High-Energy Hustle", 'sound/misc/boogie2.ogg', 1770, 5),
)
var/datum/track/selection = null
@@ -67,7 +67,7 @@
else if(anchored)
to_chat(user,"You unsecure and disconnect the [src].")
anchored = FALSE
- playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
return
return ..()
@@ -148,7 +148,7 @@
selection = available[selected]
updateUsrDialog()
if("horn")
- deejay('sound/items/AirHorn2.ogg')
+ deejay('sound/items/airhorn2.ogg')
if("alert")
deejay('sound/misc/notice1.ogg')
if("siren")
@@ -158,11 +158,11 @@
if("pump")
deejay('sound/weapons/shotgunpump.ogg')
if("pop")
- deejay('sound/weapons/Gunshot3.ogg')
+ deejay('sound/weapons/gunshot3.ogg')
if("saber")
deejay('sound/weapons/saberon.ogg')
if("harm")
- deejay('sound/AI/harmalarm.ogg')
+ deejay('sound/ai/harmalarm.ogg')
/obj/machinery/disco/proc/deejay(var/S)
if (QDELETED(src) || !active || charge < 5)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 32f7ada6e3c..d6f7976d457 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -72,16 +72,18 @@
var/hasShocked = 0 //Prevents multiple shocks from happening
autoclose = 1
var/obj/item/device/doorCharge/charge = null //If applied, causes an explosion upon opening the door
+ var/obj/item/weapon/note //Any papers pinned to the airlock
var/detonated = 0
var/doorOpen = 'sound/machines/airlock.ogg'
- var/doorClose = 'sound/machines/AirlockClose.ogg'
- var/doorDeni = 'sound/machines/DeniedBeep.ogg' // i'm thinkin' Deni's
- var/boltUp = 'sound/machines/BoltsUp.ogg'
- var/boltDown = 'sound/machines/BoltsDown.ogg'
- var/noPower = 'sound/machines/DoorClick.ogg'
+ var/doorClose = 'sound/machines/airlockclose.ogg'
+ var/doorDeni = 'sound/machines/deniedbeep.ogg' // i'm thinkin' Deni's
+ var/boltUp = 'sound/machines/boltsup.ogg'
+ var/boltDown = 'sound/machines/boltsdown.ogg'
+ var/noPower = 'sound/machines/doorclick.ogg'
var/airlock_material = null //material of inner filling; if its an airlock with glass, this should be set to "glass"
var/overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi'
+ var/note_overlay_file = 'icons/obj/doors/airlocks/station/overlays.dmi' //Used for papers and photos pinned to the airlock
var/cyclelinkeddir = 0
var/obj/machinery/door/airlock/cyclelinkedairlock
@@ -213,8 +215,14 @@
if(id_tag)
for(var/obj/machinery/doorButtons/D in GLOB.machines)
D.removeMe(src)
+ qdel(note)
return ..()
+/obj/machinery/door/airlock/handle_atom_del(atom/A)
+ if(A == note)
+ note = null
+ update_icon()
+
/obj/machinery/door/airlock/bumpopen(mob/living/user) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite
if(!issilicon(usr))
if(src.isElectrified())
@@ -251,7 +259,7 @@
addtimer(CALLBACK(src, .proc/reset_hallucinate_shock_animation, user, shock_image, electrocution_skeleton_anim), 40)
user.playsound_local(get_turf(src), "sparks", 100, 1)
user.staminaloss += 50
- user.Stun(2)
+ user.Stun(40)
user.jitteriness += 1000
user.do_jitter_animation(user.jitteriness)
addtimer(CALLBACK(src, .proc/hallucinate_shock_drop, user), 20)
@@ -263,8 +271,7 @@
/obj/machinery/door/airlock/proc/hallucinate_shock_drop(mob/living/user)
user.jitteriness = max(user.jitteriness - 990, 10) //Still jittery, but vastly less
- user.Stun(3)
- user.Weaken(3)
+ user.Knockdown(60)
/obj/machinery/door/airlock/proc/isElectrified()
if(src.secondsElectrified != NOT_ELECTRIFIED)
@@ -333,16 +340,14 @@
/obj/machinery/door/airlock/proc/shock(mob/user, prb)
if(!hasPower()) // unpowered, no shock
return FALSE
- if(hasShocked)
+ if(hasShocked > world.time)
return FALSE //Already shocked someone recently?
if(!prob(prb))
return FALSE //you lucked out, no shock for you
do_sparks(5, TRUE, src)
var/tmp/check_range = TRUE
if(electrocute_mob(user, get_area(src), src, 1, check_range))
- hasShocked = TRUE
- spawn(10)
- hasShocked = FALSE
+ hasShocked = world.time + 10
return TRUE
else
return FALSE
@@ -371,6 +376,8 @@
var/mutable_appearance/weld_overlay
var/mutable_appearance/damag_overlay
var/mutable_appearance/sparks_overlay
+ var/mutable_appearance/note_overlay
+ var/notetype = note_type()
switch(state)
if(AIRLOCK_CLOSED)
@@ -395,6 +402,8 @@
lights_overlay = get_airlock_overlay("lights_bolts", overlays_file)
else if(emergency)
lights_overlay = get_airlock_overlay("lights_emergency", overlays_file)
+ if(note)
+ note_overlay = get_airlock_overlay(notetype, note_overlay_file)
if(AIRLOCK_DENY)
if(!hasPower())
@@ -416,6 +425,8 @@
if(welded)
weld_overlay = get_airlock_overlay("welded", overlays_file)
lights_overlay = get_airlock_overlay("lights_denied", overlays_file)
+ if(note)
+ note_overlay = get_airlock_overlay(notetype, note_overlay_file)
if(AIRLOCK_EMAG)
frame_overlay = get_airlock_overlay("closed", icon)
@@ -435,6 +446,8 @@
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file)
if(welded)
weld_overlay = get_airlock_overlay("welded", overlays_file)
+ if(note)
+ note_overlay = get_airlock_overlay(notetype, note_overlay_file)
if(AIRLOCK_CLOSING)
frame_overlay = get_airlock_overlay("closing", icon)
@@ -449,6 +462,8 @@
panel_overlay = get_airlock_overlay("panel_closing_protected", overlays_file)
else
panel_overlay = get_airlock_overlay("panel_closing", overlays_file)
+ if(note)
+ note_overlay = get_airlock_overlay("[notetype]_closing", note_overlay_file)
if(AIRLOCK_OPEN)
frame_overlay = get_airlock_overlay("open", icon)
@@ -463,6 +478,8 @@
panel_overlay = get_airlock_overlay("panel_open", overlays_file)
if(obj_integrity < (0.75 * max_integrity))
damag_overlay = get_airlock_overlay("sparks_open", overlays_file)
+ if(note)
+ note_overlay = get_airlock_overlay("[notetype]_open", note_overlay_file)
if(AIRLOCK_OPENING)
frame_overlay = get_airlock_overlay("opening", icon)
@@ -477,6 +494,8 @@
panel_overlay = get_airlock_overlay("panel_opening_protected", overlays_file)
else
panel_overlay = get_airlock_overlay("panel_opening", overlays_file)
+ if(note)
+ note_overlay = get_airlock_overlay("[notetype]_opening", note_overlay_file)
cut_overlays()
add_overlay(frame_overlay)
@@ -486,6 +505,7 @@
add_overlay(weld_overlay)
add_overlay(sparks_overlay)
add_overlay(damag_overlay)
+ add_overlay(note_overlay)
/proc/get_airlock_overlay(icon_state, icon_file)
var/obj/machinery/door/airlock/A
@@ -514,6 +534,12 @@
to_chat(user, "The maintenance panel seems haphazardly fastened.")
if(charge && panel_open)
to_chat(user, "Something is wired up to the airlock's electronics!")
+ if(note)
+ if(!in_range(user, src))
+ to_chat(user, "There's a [note.name] pinned to the front. You can't read it from here.")
+ else
+ to_chat(user, "There's a [note.name] pinned to the front...")
+ note.examine(user)
if(panel_open)
switch(security_level)
@@ -719,8 +745,7 @@
if(!istype(H.head, /obj/item/clothing/head/helmet))
H.visible_message("[user] headbutts the airlock.", \
"You headbutt the airlock!")
- H.Stun(5)
- H.Weaken(5)
+ H.Knockdown(100)
H.apply_damage(10, BRUTE, "head")
else
visible_message("[user] headbutts the airlock. Good thing [user.p_theyre()] wearing a helmet.")
@@ -1096,6 +1121,12 @@
to_chat(user, "You [panel_open ? "open":"close"] the maintenance panel of the airlock.")
playsound(src.loc, C.usesound, 50, 1)
src.update_icon()
+ else if(istype(C, /obj/item/weapon/wirecutters) && note)
+ user.visible_message("[user] cuts down [note] from [src].", "You remove [note] from [src].")
+ playsound(src, 'sound/items/Wirecutter.ogg', 50, 1)
+ note.forceMove(get_turf(user))
+ note = null
+ update_icon()
else if(is_wire_tool(C))
return attack_hand(user)
else if(istype(C, /obj/item/weapon/pai_cable))
@@ -1121,6 +1152,16 @@
update_icon()
C.forceMove(src)
charge = C
+ else if(istype(C, /obj/item/weapon/paper) || istype(C, /obj/item/weapon/photo))
+ if(note)
+ to_chat(user, "There's already something pinned to this airlock! Use wirecutters to remove it.")
+ return
+ if(!user.transferItemToLoc(C, src))
+ to_chat(user, "For some reason, you can't attach [C]!")
+ return
+ user.visible_message("[user] pins [C] to [src].", "You pin [C] to [src].")
+ note = C
+ update_icon()
else
return ..()
@@ -1134,7 +1175,7 @@
"You hear welding.")
playsound(loc, W.usesound, 40, 1)
if(do_after(user,40*W.toolspeed, 1, target = src, extra_checks = CALLBACK(src, .proc/weld_checks, W, user)))
- playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
welded = !welded
user.visible_message("[user.name] has [welded? "welded shut":"unwelded"] [src].", \
"You [welded ? "weld the airlock shut":"unweld the airlock"].")
@@ -1147,7 +1188,7 @@
"You hear welding.")
playsound(loc, W.usesound, 40, 1)
if(do_after(user,40*W.toolspeed, 1, target = src, extra_checks = CALLBACK(src, .proc/weld_checks, W, user)))
- playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
obj_integrity = max_integrity
stat &= ~BROKEN
user.visible_message("[user.name] has repaired [src].", \
@@ -1171,7 +1212,7 @@
if(!do_after(user, 150*I.toolspeed, target = src))
to_chat(user, "You slip and [charge] detonates!")
charge.ex_act(1)
- user.Weaken(3)
+ user.Knockdown(60)
return
user.visible_message("[user] removes [charge] from [src].", \
"You gently pry out [charge] from [src] and unhook its wires.")
@@ -1259,7 +1300,7 @@
detonated = 1
charge = null
for(var/mob/living/carbon/human/H in orange(2,src))
- H.Paralyse(8)
+ H.Unconscious(160)
H.adjust_fire_stacks(20)
H.IgniteMob() //Guaranteed knockout and ignition for nearby people
H.apply_damage(40, BRUTE, "chest")
@@ -1552,6 +1593,14 @@
return TRUE
return FALSE
+/obj/machinery/door/airlock/proc/note_type() //Returns a string representing the type of note pinned to this airlock
+ if(!note)
+ return
+ else if(istype(note, /obj/item/weapon/paper))
+ return "note"
+ else if(istype(note, /obj/item/weapon/photo))
+ return "photo"
+
#undef AIRLOCK_CLOSED
#undef AIRLOCK_CLOSING
#undef AIRLOCK_OPEN
diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm
index 7f914971b29..59e219d1051 100644
--- a/code/game/machinery/doors/airlock_types.dm
+++ b/code/game/machinery/doors/airlock_types.dm
@@ -252,6 +252,7 @@
name = "external airlock"
icon = 'icons/obj/doors/airlocks/external/external.dmi'
overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi'
+ note_overlay_file = 'icons/obj/doors/airlocks/external/overlays.dmi'
assemblytype = /obj/structure/door_assembly/door_assembly_ext
explosion_block = 1
@@ -271,6 +272,7 @@
/obj/machinery/door/airlock/centcom
icon = 'icons/obj/doors/airlocks/centcom/centcom.dmi'
overlays_file = 'icons/obj/doors/airlocks/centcom/overlays.dmi'
+ note_overlay_file = 'icons/obj/doors/airlocks/centcom/overlays.dmi'
opacity = 1
assemblytype = /obj/structure/door_assembly/door_assembly_centcom
normal_integrity = 1000
@@ -286,6 +288,7 @@
name = "vault door"
icon = 'icons/obj/doors/airlocks/vault/vault.dmi'
overlays_file = 'icons/obj/doors/airlocks/vault/overlays.dmi'
+ note_overlay_file = 'icons/obj/doors/airlocks/vault/overlays.dmi'
opacity = 1
assemblytype = /obj/structure/door_assembly/door_assembly_vault
explosion_block = 2
@@ -301,6 +304,7 @@
name = "airtight hatch"
icon = 'icons/obj/doors/airlocks/hatch/centcom.dmi'
overlays_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi'
+ note_overlay_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi'
opacity = 1
assemblytype = /obj/structure/door_assembly/door_assembly_hatch
@@ -308,6 +312,7 @@
name = "maintenance hatch"
icon = 'icons/obj/doors/airlocks/hatch/maintenance.dmi'
overlays_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi'
+ note_overlay_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi'
opacity = 1
assemblytype = /obj/structure/door_assembly/door_assembly_mhatch
@@ -342,6 +347,7 @@
desc = "With humanity's current technological level, it could take years to hack this advanced airlock... or maybe we should give a screwdriver a try?"
icon = 'icons/obj/doors/airlocks/abductor/abductor_airlock.dmi'
overlays_file = 'icons/obj/doors/airlocks/abductor/overlays.dmi'
+ note_overlay_file = 'icons/obj/doors/airlocks/abductor/overlays.dmi'
assemblytype = /obj/structure/door_assembly/door_assembly_abductor
damage_deflection = 30
opacity = 1
@@ -385,7 +391,7 @@
throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(M, src)))
M << pick(sound('sound/hallucinations/turn_around1.ogg',0,1,50), sound('sound/hallucinations/turn_around2.ogg',0,1,50))
flash_color(M, flash_color="#960000", flash_time=20)
- M.Weaken(2)
+ M.Knockdown(40)
M.throw_at(throwtarget, 5, 1,src)
return 0
@@ -490,7 +496,7 @@
return
/obj/machinery/door/airlock/clockwork/deconstruct(disassembled = TRUE)
- playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
if(!(flags & NODECONSTRUCT))
var/turf/T = get_turf(src)
if(disassembled)
@@ -510,7 +516,7 @@
if(!do_after(user, 75*I.toolspeed, target = src) || construction_state != GEAR_SECURE)
return 1
user.visible_message("[user] loosens [src]'s cogwheel!", "[src]'s cogwheel pops off and dangles loosely.")
- playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
construction_state = GEAR_LOOSE
else if(construction_state == GEAR_LOOSE)
user.visible_message("[user] begins tightening [src]'s cogwheel...", "You begin tightening [src]'s cogwheel into place...")
@@ -518,7 +524,7 @@
if(!do_after(user, 75*I.toolspeed, target = src) || construction_state != GEAR_LOOSE)
return 1
user.visible_message("[user] tightens [src]'s cogwheel!", "You firmly tighten [src]'s cogwheel into place.")
- playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
construction_state = GEAR_SECURE
return 1
else if(istype(I, /obj/item/weapon/crowbar))
@@ -549,6 +555,7 @@
name = "large glass airlock"
icon = 'icons/obj/doors/airlocks/glass_large/glass_large.dmi'
overlays_file = 'icons/obj/doors/airlocks/glass_large/overlays.dmi'
+ note_overlay_file = 'icons/obj/doors/airlocks/glass_large/overlays.dmi'
opacity = 0
assemblytype = null
glass = 1
diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm
index 18dde20df2d..fe8580d9d7c 100644
--- a/code/game/machinery/doors/brigdoors.dm
+++ b/code/game/machinery/doors/brigdoors.dm
@@ -5,8 +5,8 @@
#define MAX_TIMER 9000
#define PRESET_SHORT 1200
-#define PRESET_MEDIUM 3000
-#define PRESET_LONG 6000
+#define PRESET_MEDIUM 1800
+#define PRESET_LONG 3000
@@ -212,7 +212,7 @@
if(..())
return
. = TRUE
-
+
if(!allowed(usr))
to_chat(usr, "Access denied.")
return FALSE
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 35e6d2ddf49..2a1f5422c89 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -32,6 +32,7 @@
var/auto_close //TO BE REMOVED, no longer used, it's just preventing a runtime with a map var edit.
var/datum/effect_system/spark_spread/spark_system
var/damage_deflection = 10
+ var/real_explosion_block //ignore this, just use explosion_block
/obj/machinery/door/New()
..()
@@ -45,7 +46,9 @@
spark_system = new /datum/effect_system/spark_spread
spark_system.set_up(2, 1, src)
-
+ //doors only block while dense though so we have to use the proc
+ real_explosion_block = explosion_block
+ explosion_block = EXPLOSION_BLOCK_PROC
/obj/machinery/door/Destroy()
density = 0
@@ -181,13 +184,13 @@
switch(damage_type)
if(BRUTE)
if(glass)
- playsound(loc, 'sound/effects/Glasshit.ogg', 90, 1)
+ playsound(loc, 'sound/effects/glasshit.ogg', 90, 1)
else if(damage_amount)
playsound(loc, 'sound/weapons/smash.ogg', 50, 1)
else
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/machinery/door/emp_act(severity)
if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) )
@@ -291,10 +294,10 @@
else if(ishuman(L)) //For humans
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
L.emote("scream")
- L.Weaken(5)
+ L.Knockdown(100)
else if(ismonkey(L)) //For monkeys
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
- L.Weaken(5)
+ L.Knockdown(100)
else //for simple_animals & borgs
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
var/turf/location = get_turf(src)
@@ -346,3 +349,5 @@
//if it blows up a wall it should blow up a door
..(severity ? max(1, severity - 1) : 0, target)
+/obj/machinery/door/GetExplosionBlock()
+ return density ? real_explosion_block : 0
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index 6cb05037bf5..371a21b3045 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -85,7 +85,7 @@
user.visible_message("[user] bangs on \the [src].",
"You bang on \the [src].")
- playsound(loc, 'sound/effects/Glassknock.ogg', 10, FALSE, frequency = 32000)
+ playsound(loc, 'sound/effects/glassknock.ogg', 10, FALSE, frequency = 32000)
/obj/machinery/door/firedoor/attackby(obj/item/weapon/C, mob/user, params)
add_fingerprint(user)
@@ -102,7 +102,7 @@
"You start unfastening [src]'s floor bolts...")
if(!do_after(user, 50*C.toolspeed, target = src))
return
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
user.visible_message("[user] unfastens [src]'s bolts.", \
"You undo [src]'s floor bolts.")
deconstruct(TRUE)
@@ -284,7 +284,7 @@
return
if(constructionStep != CONSTRUCTION_PANEL_OPEN)
return
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
user.visible_message("[user] pries out a metal plate from [src], exposing the wires.", \
"You remove the cover plate from [src], exposing the wires.")
constructionStep = CONSTRUCTION_WIRES_EXPOSED
@@ -303,7 +303,7 @@
return
user.visible_message("[user] finishes the firelock.", \
"You finish the firelock.")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
if(reinforced)
new /obj/machinery/door/firedoor/heavy(get_turf(src))
else
@@ -320,13 +320,13 @@
return
user.visible_message("[user] begins reinforcing [src]...", \
"You begin reinforcing [src]...")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
if(do_after(user, 60, target = src))
if(constructionStep != CONSTRUCTION_PANEL_OPEN || reinforced || P.get_amount() < 2 || !P)
return
user.visible_message("[user] reinforces [src].", \
"You reinforce [src].")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
P.use(2)
reinforced = 1
return
@@ -355,7 +355,7 @@
return
if(constructionStep != CONSTRUCTION_WIRES_EXPOSED)
return
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
user.visible_message("[user] pries the metal plate into [src].", \
"You pry [src]'s cover plate into place, hiding the wires.")
constructionStep = CONSTRUCTION_PANEL_OPEN
@@ -384,13 +384,13 @@
return
user.visible_message("[user] begins wiring [src]...", \
"You begin adding wires to [src]...")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
if(do_after(user, 60, target = src))
if(constructionStep != CONSTRUCTION_GUTTED || B.get_amount() < 5 || !B)
return
user.visible_message("[user] adds wires to [src].", \
"You wire [src].")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
B.use(5)
constructionStep = CONSTRUCTION_WIRES_EXPOSED
update_icon()
@@ -408,7 +408,7 @@
return
user.visible_message("[user] cuts apart [src]!", \
"You cut [src] into metal.")
- playsound(get_turf(src), 'sound/items/Welder2.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/items/welder2.ogg', 50, 1)
var/turf/T = get_turf(src)
new /obj/item/stack/sheet/metal(T, 3)
if(reinforced)
@@ -418,7 +418,7 @@
if(istype(C, /obj/item/weapon/electronics/firelock))
user.visible_message("[user] starts adding [C] to [src]...", \
"You begin adding a circuit board to [src]...")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
if(!do_after(user, 40, target = src))
return
if(constructionStep != CONSTRUCTION_NOCIRCUIT)
@@ -427,7 +427,7 @@
qdel(C)
user.visible_message("[user] adds a circuit to [src].", \
"You insert and secure [C].")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
constructionStep = CONSTRUCTION_GUTTED
update_icon()
return
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index be51bf008d1..0277f9112f1 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -176,9 +176,9 @@
/obj/machinery/door/window/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
- playsound(loc, 'sound/effects/Glasshit.ogg', 90, 1)
+ playsound(loc, 'sound/effects/glasshit.ogg', 90, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/machinery/door/window/deconstruct(disassembled = TRUE)
diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/droneDispenser.dm
index 859f306396d..6f9be657d4d 100644
--- a/code/game/machinery/droneDispenser.dm
+++ b/code/game/machinery/droneDispenser.dm
@@ -41,7 +41,7 @@
var/maximum_idle = 3
var/work_sound = 'sound/items/rped.ogg'
- var/create_sound = 'sound/items/Deconstruct.ogg'
+ var/create_sound = 'sound/items/deconstruct.ogg'
var/recharge_sound = 'sound/machines/ping.ogg'
var/begin_create_message = "whirs to life!"
@@ -149,9 +149,9 @@
end_create_message = "materializes a strange shell, which drops to the \
ground."
recharging_text = "Its lights are slowly increasing in brightness."
- work_sound = 'sound/effects/EMPulse.ogg'
+ work_sound = 'sound/effects/empulse.ogg'
create_sound = 'sound/effects/phasein.ogg'
- break_sound = 'sound/effects/EMPulse.ogg'
+ break_sound = 'sound/effects/empulse.ogg'
break_message = "slowly falls dark, lights stuttering."
/obj/machinery/droneDispenser/examine(mob/user)
diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm
index c54321b8eca..9dce658328e 100644
--- a/code/game/machinery/firealarm.dm
+++ b/code/game/machinery/firealarm.dm
@@ -162,7 +162,7 @@
playsound(loc, WT.usesound, 40, 1)
if(do_after(user, 40*WT.toolspeed, target = src))
obj_integrity = max_integrity
- playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
to_chat(user, "You repair [src].")
else
to_chat(user, "[src] is already in good condition!")
diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm
index ccd945ed93c..96c22cd8b2f 100644
--- a/code/game/machinery/flasher.dm
+++ b/code/game/machinery/flasher.dm
@@ -9,7 +9,7 @@
var/id = null
var/range = 2 //this is roughly the size of brig cell
var/last_flash = 0 //Don't want it getting spammed like regular flashes
- var/strength = 5 //How weakened targets are when flashed.
+ var/strength = 100 //How knocked down targets are when flashed.
var/base_state = "mflash"
obj_integrity = 250
max_integrity = 250
@@ -20,7 +20,7 @@
name = "portable flasher"
desc = "A portable flashing device. Wrench to activate and deactivate. Cannot detect slow movements."
icon_state = "pflash1-p"
- strength = 4
+ strength = 80
anchored = 0
base_state = "pflash"
density = 1
@@ -119,7 +119,7 @@
continue
if(L.flash_act(affect_silicon = 1))
- L.Weaken(strength)
+ L.Knockdown(strength)
return 1
@@ -149,7 +149,7 @@
var/obj/item/wallframe/flasher/F = new(get_turf(src))
transfer_fingerprints_to(F)
F.id = id
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
else
new /obj/item/stack/sheet/metal (loc, 2)
qdel(src)
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index f7f0897ebd0..bc0b4ab27e2 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -29,7 +29,7 @@ Possible to do for anyone motivated enough:
#define HOLOPAD_MODE RANGE_BASED
/obj/machinery/holopad
- name = "Holopad"
+ name = "holopad"
desc = "It's a floor-mounted device for projecting holographic images."
icon_state = "holopad0"
layer = LOW_OBJ_LAYER
@@ -105,26 +105,11 @@ Possible to do for anyone motivated enough:
return
return ..()
-/obj/machinery/holopad/proc/CheckCallClose()
- for(var/I in holo_calls)
- var/datum/holocall/HC = I
- if(usr == HC.eye)
- HC.Disconnect(HC.calling_holopad) //disconnect via clicking the called holopad
- return TRUE
- return FALSE
-
-/obj/machinery/holopad/Click(location,control,params)
- if(!CheckCallClose())
- return ..()
-
/obj/machinery/holopad/AltClick(mob/living/carbon/human/user)
if(isAI(user))
hangup_all_calls()
return
- if(!CheckCallClose())
- interact(user)
-
/obj/machinery/holopad/interact(mob/living/carbon/human/user) //Carn: Hologram requests.
if(!istype(user))
return
@@ -316,11 +301,11 @@ Possible to do for anyone motivated enough:
Hologram.set_light(2) //hologram lighting
set_holo(user, Hologram)
- visible_message("A holographic image of [user] flicks to life right before your eyes!")
+ visible_message("A holographic image of [user] flickers to life before your eyes!")
return Hologram
else
- to_chat(user, "ERROR: \black Unable to project hologram.")
+ to_chat(user, "ERROR: Unable to project hologram.")
/*This is the proc for special two-way communication between AI and holopad/people talking near holopad.
For the other part of the code, check silicon say.dm. Particularly robot talk.*/
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index a224efd91ce..61a58fec35f 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -389,7 +389,7 @@ Class Procs:
if(!time || do_after(user, time*W.toolspeed, target = src, extra_checks = CALLBACK(src, .proc/unfasten_wrench_check, prev_anchored, user)))
to_chat(user, "You [anchored ? "un" : ""]secure [src].")
anchored = !anchored
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
return SUCCESSFUL_UNFASTEN
return FAILED_UNFASTEN
return CANT_UNFASTEN
@@ -440,7 +440,7 @@ Class Procs:
/obj/machinery/proc/display_parts(mob/user)
to_chat(user, "Following parts detected in the machine:")
for(var/obj/item/C in component_parts)
- to_chat(user, "\icon[C] [C.name]")
+ to_chat(user, "[bicon(C)] [C.name]")
/obj/machinery/examine(mob/user)
..()
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index 7c3251a1bec..62f5deaf69f 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -717,7 +717,7 @@ GLOBAL_LIST_EMPTY(allCasters)
to_chat(user, "You start [anchored ? "un" : ""]securing [name]...")
playsound(loc, I.usesound, 50, 1)
if(do_after(user, 60*I.toolspeed, target = src))
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
if(stat & BROKEN)
to_chat(user, "The broken remains of [src] fall on the ground.")
new /obj/item/stack/sheet/metal(loc, 5)
@@ -739,7 +739,7 @@ GLOBAL_LIST_EMPTY(allCasters)
if(!WT.isOn() || !(stat & BROKEN))
return
to_chat(user, "You repair [src].")
- playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
obj_integrity = max_integrity
stat &= ~BROKEN
update_icon()
@@ -754,9 +754,9 @@ GLOBAL_LIST_EMPTY(allCasters)
if(stat & BROKEN)
playsound(loc, 'sound/effects/hit_on_shattered_glass.ogg', 100, 1)
else
- playsound(loc, 'sound/effects/Glasshit.ogg', 90, 1)
+ playsound(loc, 'sound/effects/glasshit.ogg', 90, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/machinery/newscaster/deconstruct(disassembled = TRUE)
@@ -769,7 +769,7 @@ GLOBAL_LIST_EMPTY(allCasters)
/obj/machinery/newscaster/obj_break()
if(!(stat & BROKEN) && !(flags & NODECONSTRUCT))
stat |= BROKEN
- playsound(loc, 'sound/effects/Glassbr3.ogg', 100, 1)
+ playsound(loc, 'sound/effects/glassbr3.ogg', 100, 1)
update_icon()
diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm
index 9dfb77ab669..18a5dd70903 100644
--- a/code/game/machinery/overview.dm
+++ b/code/game/machinery/overview.dm
@@ -146,7 +146,7 @@
var/icon/I2 = imap[2+(ix + icx*iy)*2]
- //to_chat(world, "icon: \icon[I]")
+ //to_chat(world, "icon: [bicon(I)]")
I.DrawBox(colour, rx, ry, rx+1, ry+1)
@@ -163,7 +163,7 @@
H.screen_loc = "[5 + i%icx],[6+ round(i/icx)]"
- //to_chat(world, "\icon[I] at [H.screen_loc]")
+ //to_chat(world, "[bicon(I)] at [H.screen_loc]")
H.name = (i==0)?"maprefresh":"map"
@@ -274,7 +274,7 @@
var/icon/I = imap[1+(ix + icx*iy)]
- //to_chat(world, "icon: \icon[I]")
+ //to_chat(world, "icon: [bicon(I)]")
I.DrawBox(colour, rx, ry, rx, ry)
@@ -289,7 +289,7 @@
H.screen_loc = "[5 + i%icx],[6+ round(i/icx)]"
- //to_chat(world, "\icon[I] at [H.screen_loc]")
+ //to_chat(world, "[bicon(I)] at [H.screen_loc]")
H.name = (i==0)?"maprefresh":"map"
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index bb5d37073d0..9bceee5bdb2 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -250,7 +250,7 @@ GLOBAL_LIST_INIT(pipeID2State, list(
if(istype(user, /mob/living/carbon))
var/mob/living/carbon/C = user
for(var/i=1 to 20)
- C.vomit(0,1,0,4,0)
+ C.vomit(0, TRUE, FALSE, 4, FALSE)
if(prob(20))
C.spew_organ()
sleep(5)
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index 32a613ea5f7..3a65d97d6f5 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -53,20 +53,16 @@
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["make"])
- if(!wait)
+ if(wait < world.time)
var/p_type = text2path(href_list["make"])
var/p_dir = text2num(href_list["dir"])
var/obj/item/pipe/P = new (src.loc, pipe_type=p_type, dir=p_dir)
P.add_fingerprint(usr)
- wait = 1
- spawn(10)
- wait = 0
+ wait = world.time + 10
if(href_list["makemeter"])
- if(!wait)
+ if(wait < world.time )
new /obj/item/pipe_meter(src.loc)
- wait = 1
- spawn(15)
- wait = 0
+ wait = world.time + 15
return
/obj/machinery/pipedispenser/attackby(obj/item/W, mob/user, params)
@@ -165,7 +161,7 @@ Nah
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["dmake"])
- if(!wait)
+ if(wait < world.time)
var/p_type = text2num(href_list["dmake"])
var/obj/structure/disposalconstruct/C = new (src.loc,p_type)
@@ -176,9 +172,7 @@ Nah
C.add_fingerprint(usr)
C.update_icon()
- wait = 1
- spawn(15)
- wait = 0
+ wait = world.time + 15
return
//transit tube dispenser
@@ -216,7 +210,7 @@ Nah
return 1
usr.set_machine(src)
src.add_fingerprint(usr)
- if(!wait)
+ if(wait < world.time)
if(href_list["tube"])
var/tube_type = text2num(href_list["tube"])
var/obj/structure/C
@@ -241,7 +235,5 @@ Nah
C = new /obj/structure/c_transit_tube_pod(loc)
if(C)
C.add_fingerprint(usr)
- wait = 1
- spawn(15)
- wait = 0
+ wait = world.time + 15
return
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index 79ebf349ef9..341443d3ca4 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -556,8 +556,8 @@
req_access = list(GLOB.access_syndicate)
stun_projectile = /obj/item/projectile/bullet
lethal_projectile = /obj/item/projectile/bullet
- lethal_projectile_sound = 'sound/weapons/Gunshot.ogg'
- stun_projectile_sound = 'sound/weapons/Gunshot.ogg'
+ lethal_projectile_sound = 'sound/weapons/gunshot.ogg'
+ stun_projectile_sound = 'sound/weapons/gunshot.ogg'
icon_state = "syndie_off"
base_icon_state = "syndie"
faction = "syndicate"
@@ -567,7 +567,7 @@
icon_state = "standard_stun"
base_icon_state = "standard"
stun_projectile = /obj/item/projectile/energy/electrode
- stun_projectile_sound = 'sound/weapons/Taser.ogg'
+ stun_projectile_sound = 'sound/weapons/taser.ogg'
lethal_projectile = /obj/item/projectile/beam/laser/heavylaser
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 03e95ee2de3..357a9bd8522 100755
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -8,12 +8,12 @@
idle_power_usage = 4
active_power_usage = 250
var/obj/item/charging = null
- var/list/allowed_devices = list(/obj/item/weapon/gun/energy,/obj/item/weapon/melee/baton,/obj/item/ammo_box/magazine/recharge,/obj/item/device/modular_computer)
+ var/static/list/allowed_devices = typecacheof(list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/ammo_box/magazine/recharge,/obj/item/device/modular_computer))
var/recharge_coeff = 1
-/obj/machinery/recharger/New()
- ..()
- var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/recharger(null)
+/obj/machinery/recharger/Initialize()
+ . = ..()
+ var/obj/item/weapon/circuitboard/machine/recharger/B = new()
B.apply_default_parts(src)
/obj/item/weapon/circuitboard/machine/recharger
@@ -37,7 +37,7 @@
playsound(loc, G.usesound, 75, 1)
return
- var/allowed = is_type_in_list(G, allowed_devices)
+ var/allowed = is_type_in_typecache(G, allowed_devices)
if(allowed)
if(anchored)
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index e683b770979..e73dab8ba6a 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -16,7 +16,7 @@
var/datum/material_container/materials
var/crush_damage = 1000
var/eat_victim_items = TRUE
- var/item_recycle_sound = 'sound/items/Welder.ogg'
+ var/item_recycle_sound = 'sound/items/welder.ogg'
/obj/machinery/recycler/New()
..()
@@ -167,7 +167,7 @@
L.loc = src.loc
if(issilicon(L))
- playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 50, 1)
else
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
@@ -190,7 +190,7 @@
eat(I, sound=FALSE)
// Instantly lie down, also go unconscious from the pain, before you die.
- L.Paralyse(5)
+ L.Unconscious(100)
// For admin fun, var edit emagged to 2.
if(gib || emagged == 2)
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index 19fcb0e6752..4c3f8756c39 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -42,16 +42,14 @@
/obj/structure/emergency_shield/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BURN)
- playsound(loc, 'sound/effects/EMPulse.ogg', 75, 1)
+ playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
if(BRUTE)
- playsound(loc, 'sound/effects/EMPulse.ogg', 75, 1)
+ playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
/obj/structure/emergency_shield/take_damage(damage, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
if(.) //damage was dealt
- set_opacity(1)
- spawn(20)
- set_opacity(0)
+ new /obj/effect/temp_visual/impact_effect/ion(loc)
/obj/structure/emergency_shield/sanguine
name = "sanguine barrier"
@@ -431,9 +429,9 @@
/obj/machinery/shieldwall/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BURN)
- playsound(loc, 'sound/effects/EMPulse.ogg', 75, 1)
+ playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
if(BRUTE)
- playsound(loc, 'sound/effects/EMPulse.ogg', 75, 1)
+ playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
//the shield wall is immune to damage but it drains the stored power of the generators.
/obj/machinery/shieldwall/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm
index a91b1fbf0ec..cf15fe556a5 100644
--- a/code/game/machinery/status_display.dm
+++ b/code/game/machinery/status_display.dm
@@ -45,12 +45,14 @@
// register for radio system
/obj/machinery/status_display/Initialize()
- ..()
+ . = ..()
+ GLOB.ai_status_displays.Add(src)
SSradio.add_object(src, frequency)
/obj/machinery/status_display/Destroy()
if(SSradio)
SSradio.remove_object(src,frequency)
+ GLOB.ai_status_displays.Remove(src)
return ..()
// timed process
@@ -211,6 +213,14 @@
var/emotion = "Neutral"
+/obj/machinery/ai_status_display/Initialize()
+ . = ..()
+ GLOB.ai_status_displays.Add(src)
+
+/obj/machinery/ai_status_display/Destroy()
+ GLOB.ai_status_displays.Remove(src)
+ . = ..()
+
/obj/machinery/ai_status_display/attack_ai(mob/living/silicon/ai/user)
if(isAI(user))
user.ai_statuschange()
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index be062657645..fd1b754f2f9 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -102,11 +102,6 @@
mask_type = /obj/item/clothing/mask/breath
storage_type = /obj/item/weapon/tank/internals/emergency_oxygen/double
-/obj/machinery/suit_storage_unit/ueg
- suit_type = /obj/item/clothing/suit/space/hardsuit/ueg
- mask_type = /obj/item/clothing/mask/gas/sechailer/swat
- storage_type = /obj/item/weapon/tank/internals/emergency_oxygen/double
-
/obj/machinery/suit_storage_unit/New()
..()
wires = new /datum/wires/suit_storage_unit(src)
@@ -246,7 +241,7 @@
visible_message("[src]'s door slides open. The glowing yellow lights dim to a gentle green.")
else
visible_message("[src]'s door slides open, barraging you with the nauseating smell of charred flesh.")
- playsound(src, 'sound/machines/AirlockClose.ogg', 25, 1)
+ playsound(src, 'sound/machines/airlockclose.ogg', 25, 1)
for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
I.clean_blood()
I.fingerprints = list()
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index 4d8ad299413..c40d3591229 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -210,14 +210,14 @@
var/new_timer = input(user, "Please set the timer.", "Timer", "[timer_set]") as num
if(in_range(src, user) && isliving(user)) //No running off and setting bombs from across the station
timer_set = Clamp(new_timer, minimum_timer, maximum_timer)
- src.loc.visible_message("\icon[src] timer set for [timer_set] seconds.")
+ src.loc.visible_message("[bicon(src)] timer set for [timer_set] seconds.")
if(alert(user,"Would you like to start the countdown now?",,"Yes","No") == "Yes" && in_range(src, user) && isliving(user))
if(defused || active)
if(defused)
- src.loc.visible_message("\icon[src] Device error: User intervention required.")
+ src.loc.visible_message("[bicon(src)] Device error: User intervention required.")
return
else
- src.loc.visible_message("\icon[src] [timer_set] seconds until detonation, please clear the area.")
+ src.loc.visible_message("[bicon(src)] [timer_set] seconds until detonation, please clear the area.")
activate()
update_icon()
add_fingerprint(user)
@@ -331,7 +331,7 @@
var/obj/machinery/syndicatebomb/holder = loc
if(istype(holder))
attempts++
- holder.loc.visible_message("\icon[holder] Alert: Bomb has detonated. Your score is now [defusals] for [attempts]. Resetting wires...")
+ holder.loc.visible_message("[bicon(holder)] Alert: Bomb has detonated. Your score is now [defusals] for [attempts]. Resetting wires...")
reset()
else
qdel(src)
@@ -341,7 +341,7 @@
if(istype(holder))
attempts++
defusals++
- holder.loc.visible_message("\icon[holder] Alert: Bomb has been defused. Your score is now [defusals] for [attempts]! Resetting wires in 5 seconds...")
+ holder.loc.visible_message("[bicon(holder)] Alert: Bomb has been defused. Your score is now [defusals] for [attempts]! Resetting wires in 5 seconds...")
sleep(50) //Just in case someone is trying to remove the bomb core this gives them a little window to crowbar it out
if(istype(holder))
reset()
@@ -442,7 +442,7 @@
reactants += S.reagents
if(!chem_splash(get_turf(src), spread_range, reactants, temp_boost))
- playsound(loc, 'sound/items/Screwdriver2.ogg', 50, 1)
+ playsound(loc, 'sound/items/screwdriver2.ogg', 50, 1)
return // The Explosion didn't do anything. No need to log, or disappear.
if(adminlog)
diff --git a/code/game/machinery/telecomms/broadcasting.dm b/code/game/machinery/telecomms/broadcasting.dm
index 6c1fd431e50..b64a3a67e03 100644
--- a/code/game/machinery/telecomms/broadcasting.dm
+++ b/code/game/machinery/telecomms/broadcasting.dm
@@ -153,7 +153,7 @@
//Use this to test if an obj can communicate with a Telecommunications Network
/atom/proc/test_telecomms()
- var/datum/signal/signal = src.telecomms_process()
+ var/datum/signal/signal = telecomms_process()
var/turf/position = get_turf(src)
return (position.z in signal.data["level"] && signal.data["done"])
@@ -184,4 +184,3 @@
sleep(rand(10,25))
return signal
-
diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm
index 6568d14211a..9077283a686 100644
--- a/code/game/machinery/telecomms/machine_interactions.dm
+++ b/code/game/machinery/telecomms/machine_interactions.dm
@@ -5,13 +5,9 @@
*/
-#define STATION_Z 1
-#define TELECOMM_Z 3
-
/obj/machinery/telecomms
var/temp = "" // output message
-
/obj/machinery/telecomms/attackby(obj/item/P, mob/user, params)
var/icon_closed = initial(icon_state)
@@ -54,9 +50,9 @@
user.set_machine(src)
var/dat
- dat = "[src.name]
[src.name] Access
"
+ dat = "[name]
[name] Access
"
dat += " [temp] "
- dat += " Power Status: [src.toggled ? "On" : "Off"]"
+ dat += " Power Status: [toggled ? "On" : "Off"]"
if(on && toggled)
if(id != "" && id)
dat += " Identification String: [id]"
@@ -74,7 +70,7 @@
var/i = 0
for(var/obj/machinery/telecomms/T in links)
i++
- if(T.hide && !src.hide)
+ if(T.hide && !hide)
continue
dat += "
"
dat += ""
@@ -110,8 +106,7 @@
// Off-Site Relays
//
-// You are able to send/receive signals from the station's z level (changeable in the STATION_Z #define) if
-// the relay is on the telecomm satellite (changable in the TELECOMM_Z #define)
+// You are able to send/receive signals from the station's z level (changeable in the ZLEVEL_STATION #define) if
/obj/machinery/telecomms/relay/proc/toggle_level()
@@ -119,13 +114,10 @@
var/turf/position = get_turf(src)
// Toggle on/off getting signals from the station or the current Z level
- if(src.listening_level == STATION_Z) // equals the station
- src.listening_level = position.z
- return 1
- else if(position.z == TELECOMM_Z)
- src.listening_level = STATION_Z
- return 1
- return 0
+ if(listening_level == ZLEVEL_STATION) // equals the station
+ listening_level = position.z
+ return TRUE
+ return FALSE
// Returns a multitool from a user depending on their mobtype.
@@ -158,8 +150,6 @@
/obj/machinery/telecomms/relay/Options_Menu()
var/dat = ""
- if(src.z == TELECOMM_Z)
- dat += " Signal Locked to Station: [listening_level == STATION_Z ? "TRUE" : "FALSE"]"
dat += " Broadcasting: [broadcasting ? "YES" : "NO"]"
dat += " Receiving: [receiving ? "YES" : "NO"]"
return dat
@@ -172,14 +162,6 @@
if(href_list["broadcast"])
broadcasting = !broadcasting
temp = "-% Broadcasting mode changed. %-"
- if(href_list["change_listening"])
- //Lock to the station OR lock to the current position!
- //You need at least two receivers and two broadcasters for this to work, this includes the machine.
- var/result = toggle_level()
- if(result)
- temp = "-% [src]'s signal has been successfully changed."
- else
- temp = "-% [src] could not lock its signal onto the station. Two broadcasters or receivers required."
// BUS
@@ -219,15 +201,10 @@
if("toggle")
- src.toggled = !src.toggled
- temp = "-% [src] has been [src.toggled ? "activated" : "deactivated"]."
+ toggled = !toggled
+ temp = "-% [src] has been [toggled ? "activated" : "deactivated"]."
update_power()
- /*
- if("hide")
- src.hide = !hide
- temp = "-% Shadow Link has been [src.hide ? "activated" : "deactivated"]."
- */
if("id")
var/newid = copytext(reject_bad_text(input(usr, "Specify the new ID for this machine", src, id) as null|text),1,MAX_MESSAGE_LEN)
@@ -293,10 +270,10 @@
var/obj/machinery/telecomms/T = P.buffer
if(istype(T) && T != src)
if(!(src in T.links))
- T.links.Add(src)
+ T.links += src
- if(!(T in src.links))
- src.links.Add(T)
+ if(!(T in links))
+ links += T
temp = "-% Successfully linked with \ref[T] [T.name] %-"
@@ -314,7 +291,7 @@
temp = "-% Buffer successfully flushed. %-"
P.buffer = null
- src.Options_Topic(href, href_list)
+ Options_Topic(href, href_list)
usr.set_machine(src)
@@ -322,8 +299,5 @@
/obj/machinery/telecomms/proc/canAccess(mob/user)
if(issilicon(user) || in_range(user, src))
- return 1
- return 0
-
-#undef TELECOMM_Z
-#undef STATION_Z
+ return TRUE
+ return FALSE
diff --git a/code/game/machinery/telecomms/machines/relay.dm b/code/game/machinery/telecomms/machines/relay.dm
index dbe0882ff0d..54e07cfbbb7 100644
--- a/code/game/machinery/telecomms/machines/relay.dm
+++ b/code/game/machinery/telecomms/machines/relay.dm
@@ -30,19 +30,19 @@
/obj/machinery/telecomms/relay/proc/can(datum/signal/signal)
if(!on)
- return 0
+ return FALSE
if(!is_freq_listening(signal))
- return 0
- return 1
+ return FALSE
+ return TRUE
/obj/machinery/telecomms/relay/proc/can_send(datum/signal/signal)
if(!can(signal))
- return 0
+ return FALSE
return broadcasting
/obj/machinery/telecomms/relay/proc/can_receive(datum/signal/signal)
if(!can(signal))
- return 0
+ return FALSE
return receiving
/obj/machinery/telecomms/relay/New()
diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm
index 73322ce8d0f..a08046ff479 100644
--- a/code/game/machinery/telecomms/telecomunications.dm
+++ b/code/game/machinery/telecomms/telecomunications.dm
@@ -124,13 +124,13 @@ GLOBAL_LIST_EMPTY(telecomms_list)
..()
/obj/machinery/telecomms/proc/is_freq_listening(datum/signal/signal)
- // return 1 if found, 0 if not found
+ // return TRUE if found, FALSE if not found
if(!signal)
- return 0
+ return FALSE
if((signal.frequency in freq_listening) || (!freq_listening.len))
- return 1
+ return TRUE
else
- return 0
+ return FALSE
/obj/machinery/telecomms/New()
@@ -171,7 +171,7 @@ GLOBAL_LIST_EMPTY(telecomms_list)
/obj/machinery/telecomms/proc/add_link(obj/machinery/telecomms/T)
var/turf/position = get_turf(src)
var/turf/T_position = get_turf(T)
- if((position.z == T_position.z) || (src.long_range_link && T.long_range_link))
+ if((position.z == T_position.z) || (long_range_link && T.long_range_link))
if(src != T)
for(var/x in autolinkers)
if(x in T.autolinkers)
diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm
index af5e04b5bd1..e9d57dcb299 100644
--- a/code/game/machinery/transformer.dm
+++ b/code/game/machinery/transformer.dm
@@ -16,11 +16,13 @@
var/robot_cell_charge = 5000
var/obj/effect/countdown/transformer/countdown
var/mob/living/silicon/ai/masterAI
-
-/obj/machinery/transformer/New()
+
+/obj/machinery/transformer/Initialize()
// On us
- ..()
+ . = ..()
+ new /obj/machinery/conveyor/auto(locate(x - 1, y, z), WEST)
new /obj/machinery/conveyor/auto(loc, WEST)
+ new /obj/machinery/conveyor/auto(locate(x + 1, y, z), WEST)
countdown = new(src)
countdown.start()
@@ -89,7 +91,7 @@
cooldown_timer = world.time + cooldown_duration
update_icon()
- playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 50, 1)
H.emote("scream") // It is painful
H.adjustBruteLoss(max(0, 80 - H.getBruteLoss())) // Hurt the human, don't try to kill them though.
@@ -116,19 +118,3 @@
if(R)
R.SetLockdown(0)
R.notify_ai(NEW_BORG)
-
-/obj/machinery/transformer/conveyor/New()
- ..()
- var/turf/T = loc
- if(T)
- // Spawn Conveyor Belts
-
- //East
- var/turf/east = locate(T.x + 1, T.y, T.z)
- if(isfloorturf(east))
- new /obj/machinery/conveyor/auto(east, WEST)
-
- // West
- var/turf/west = locate(T.x - 1, T.y, T.z)
- if(isfloorturf(west))
- new /obj/machinery/conveyor/auto(west, WEST)
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 787ccaaffe2..6e8cc3db4ba 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -53,6 +53,7 @@
var/extended_inventory = 0 //can we access the hidden inventory?
var/scan_id = 1
var/obj/item/weapon/coin/coin
+ var/obj/item/stack/spacecash/bill
var/dish_quants = list() //used by the snack machine's custom compartment to count dishes.
@@ -118,10 +119,9 @@
..()
/obj/machinery/vending/Destroy()
- qdel(wires)
- wires = null
- qdel(coin)
- coin = null
+ QDEL_NULL(wires)
+ QDEL_NULL(coin)
+ QDEL_NULL(bill)
return ..()
/obj/machinery/vending/snack/Destroy()
@@ -311,6 +311,12 @@
attack_hand(user)
return
else if(istype(W, /obj/item/weapon/coin))
+ if(coin)
+ to_chat(user, "[src] already has [coin] inserted")
+ return
+ if(bill)
+ to_chat(user, "[src] already has [bill] inserted")
+ return
if(!premium.len)
to_chat(user, "[src] doesn't have a coin slot.")
return
@@ -320,6 +326,21 @@
coin = W
to_chat(user, "You insert [W] into [src].")
return
+ else if(istype(W, /obj/item/stack/spacecash))
+ if(coin)
+ to_chat(user, "[src] already has [coin] inserted")
+ return
+ if(bill)
+ to_chat(user, "[src] already has [bill] inserted")
+ return
+ var/obj/item/stack/S = W
+ if(!premium.len)
+ to_chat(user, "[src] doesn't have a bill slot.")
+ return
+ S.use(1)
+ bill = new S.type(src,1)
+ to_chat(user, "You insert [W] into [src].")
+ return
else if(istype(W, refill_canister) && refill_canister != null)
if(stat & (BROKEN|NOPOWER))
to_chat(user, "It does nothing.")
@@ -386,9 +407,9 @@
var/list/display_records = product_records
if(extended_inventory)
display_records = product_records + hidden_records
- if(coin)
+ if(coin || bill)
display_records = product_records + coin_records
- if(coin && extended_inventory)
+ if((coin || bill) && extended_inventory)
display_records = product_records + hidden_records + coin_records
dat += "
"
for (var/datum/data/vending_product/R in display_records)
@@ -403,11 +424,11 @@
dat += "
"
dat += ""
if(premium.len > 0)
- dat += "Coin slot: "
- if (coin)
- dat += "[coin] Remove"
+ dat += "Change Return: "
+ if (coin || bill)
+ dat += "[(coin ? coin : "")][(bill ? bill : "")] Remove"
else
- dat += "No coinRemove"
+ dat += "No moneyRemove"
if(istype(src, /obj/machinery/vending/snack))
dat += "
Chef's Food Selection
"
dat += "
"
@@ -443,15 +464,23 @@
return
if(href_list["remove_coin"])
- if(!coin)
- to_chat(usr, "There is no coin in this machine.")
+ if(!(coin || bill))
+ to_chat(usr, "There is no money in this machine.")
return
-
- coin.loc = loc
- if(!usr.get_active_held_item())
- usr.put_in_hands(coin)
- to_chat(usr, "You remove [coin] from [src].")
- coin = null
+ if(coin)
+ if(!usr.get_active_held_item())
+ usr.put_in_hands(coin)
+ else
+ coin.forceMove(get_turf(src))
+ to_chat(usr, "You remove [coin] from [src].")
+ coin = null
+ if(bill)
+ if(!usr.get_active_held_item())
+ usr.put_in_hands(bill)
+ else
+ bill.forceMove(get_turf(src))
+ to_chat(usr, "You remove [bill] from [src].")
+ bill = null
usr.set_machine(src)
@@ -494,26 +523,25 @@
vend_ready = 1
return
else if(R in coin_records)
- if(!coin)
- to_chat(usr, "You need to insert a coin to get this item!")
+ if(!(coin || bill))
+ to_chat(usr, "You need to insert money to get this item!")
vend_ready = 1
return
- if(coin.string_attached)
+ if(coin && coin.string_attached)
if(prob(50))
if(usr.put_in_hands(coin))
to_chat(usr, "You successfully pull [coin] out before [src] could swallow it.")
coin = null
else
to_chat(usr, "You couldn't pull [coin] out because your hands are full!")
- qdel(coin)
- coin = null
+ QDEL_NULL(coin)
else
to_chat(usr, "You weren't able to pull [coin] out fast enough, the machine ate it, string and all!")
- qdel(coin)
- coin = null
+ QDEL_NULL(coin)
else
- qdel(coin)
- coin = null
+ QDEL_NULL(coin)
+ QDEL_NULL(bill)
+
else if (!(R in product_records))
vend_ready = 1
message_admins("Vending machine exploit attempted by [key_name(usr, usr.client)]!")
@@ -960,7 +988,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/seeds/cabbage = 3,/obj/item/seeds/carrot = 3,/obj/item/seeds/cherry = 3,/obj/item/seeds/chanter = 3,
/obj/item/seeds/chili = 3,/obj/item/seeds/cocoapod = 3,/obj/item/seeds/coffee = 3,/obj/item/seeds/corn = 3,
/obj/item/seeds/eggplant = 3,/obj/item/seeds/grape = 3,/obj/item/seeds/grass = 3,/obj/item/seeds/lemon = 3,
- /obj/item/seeds/lime = 3,/obj/item/seeds/orange = 3,/obj/item/seeds/potato = 3,/obj/item/seeds/poppy = 3,
+ /obj/item/seeds/lime = 3,/obj/item/seeds/onion = 3,/obj/item/seeds/orange = 3,/obj/item/seeds/potato = 3,/obj/item/seeds/poppy = 3,
/obj/item/seeds/pumpkin = 3,/obj/item/seeds/replicapod = 3,/obj/item/seeds/wheat/rice = 3,/obj/item/seeds/soya = 3,/obj/item/seeds/sunflower = 3,
/obj/item/seeds/tea = 3,/obj/item/seeds/tobacco = 3,/obj/item/seeds/tomato = 3,
/obj/item/seeds/tower = 3,/obj/item/seeds/watermelon = 3,/obj/item/seeds/wheat = 3,/obj/item/seeds/whitebeet = 3)
@@ -995,7 +1023,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/clothing/head/helmet/gladiator = 1,/obj/item/clothing/under/gimmick/rank/captain/suit = 1,/obj/item/clothing/head/flatcap = 1,
/obj/item/clothing/suit/toggle/labcoat/mad = 1,/obj/item/clothing/shoes/jackboots = 1,
/obj/item/clothing/under/schoolgirl = 1,/obj/item/clothing/under/schoolgirl/red = 1,/obj/item/clothing/under/schoolgirl/green = 1,/obj/item/clothing/under/schoolgirl/orange = 1,/obj/item/clothing/head/kitty = 1,/obj/item/clothing/under/skirt/black = 1,/obj/item/clothing/head/beret = 1,
- /obj/item/clothing/tie/waistcoat = 1,/obj/item/clothing/under/suit_jacket = 1,/obj/item/clothing/head/that =1,/obj/item/clothing/under/kilt = 1,/obj/item/clothing/head/beret = 1,/obj/item/clothing/tie/waistcoat = 1,
+ /obj/item/clothing/accessory/waistcoat = 1,/obj/item/clothing/under/suit_jacket = 1,/obj/item/clothing/head/that =1,/obj/item/clothing/under/kilt = 1,/obj/item/clothing/head/beret = 1,/obj/item/clothing/accessory/waistcoat = 1,
/obj/item/clothing/glasses/monocle =1,/obj/item/clothing/head/bowler = 1,/obj/item/weapon/cane = 1,/obj/item/clothing/under/sl_suit = 1,
/obj/item/clothing/mask/fakemoustache = 1,/obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1,/obj/item/clothing/head/plaguedoctorhat = 1,/obj/item/clothing/mask/gas/plaguedoctor = 1,
/obj/item/clothing/suit/toggle/owlwings = 1, /obj/item/clothing/under/owl = 1,/obj/item/clothing/mask/gas/owl_mask = 1,
@@ -1136,7 +1164,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/clothing/neck/scarf/purple=1,/obj/item/clothing/neck/scarf/yellow=1,/obj/item/clothing/neck/scarf/orange=1,
/obj/item/clothing/neck/scarf/cyan=1,/obj/item/clothing/neck/scarf=1,/obj/item/clothing/neck/scarf/black=1,
/obj/item/clothing/neck/scarf/zebra=1,/obj/item/clothing/neck/scarf/christmas=1,/obj/item/clothing/neck/stripedredscarf=1,
- /obj/item/clothing/neck/stripedbluescarf=1,/obj/item/clothing/neck/stripedgreenscarf=1,/obj/item/clothing/tie/waistcoat=1,
+ /obj/item/clothing/neck/stripedbluescarf=1,/obj/item/clothing/neck/stripedgreenscarf=1,/obj/item/clothing/accessory/waistcoat=1,
/obj/item/clothing/under/skirt/black=1,/obj/item/clothing/under/skirt/blue=1,/obj/item/clothing/under/skirt/red=1,/obj/item/clothing/under/skirt/purple=1,
/obj/item/clothing/under/sundress=2,/obj/item/clothing/under/stripeddress=1, /obj/item/clothing/under/sailordress=1, /obj/item/clothing/under/redeveninggown=1, /obj/item/clothing/under/blacktango=1,
/obj/item/clothing/under/plaid_skirt=1,/obj/item/clothing/under/plaid_skirt/blue=1,/obj/item/clothing/under/plaid_skirt/purple=1,/obj/item/clothing/under/plaid_skirt/green=1,
diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm
index 60bd42bf231..84d4b0bcfa6 100644
--- a/code/game/mecha/equipment/mecha_equipment.dm
+++ b/code/game/mecha/equipment/mecha_equipment.dm
@@ -140,7 +140,7 @@
/obj/item/mecha_parts/mecha_equipment/proc/occupant_message(message)
if(chassis)
- chassis.occupant_message("\icon[src] [message]")
+ chassis.occupant_message("[bicon(src)] [message]")
return
/obj/item/mecha_parts/mecha_equipment/proc/log_message(message)
diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm
index 442f5137d82..7178fcd55a8 100644
--- a/code/game/mecha/equipment/tools/medical_tools.dm
+++ b/code/game/mecha/equipment/tools/medical_tools.dm
@@ -229,10 +229,9 @@
return
if(M.health > 0)
M.adjustOxyLoss(-1)
- M.updatehealth()
- M.AdjustStunned(-4)
- M.AdjustWeakened(-4)
- M.AdjustStunned(-4)
+ M.AdjustStun(-80)
+ M.AdjustKnockdown(-80)
+ M.AdjustUnconscious(-80)
if(M.reagents.get_reagent_amount("epinephrine") < 5)
M.reagents.add_reagent("epinephrine", 5)
chassis.use_power(energy_drain)
diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm
index dbee8bd6774..b06ec36d09e 100644
--- a/code/game/mecha/equipment/tools/mining_tools.dm
+++ b/code/game/mecha/equipment/tools/mining_tools.dm
@@ -87,7 +87,7 @@
target.take_bodypart_damage(drill_damage)
if(target)
- target.Paralyse(10)
+ target.Unconscious(200)
target.updatehealth()
diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm
index c182d9dceb1..089cfdf6254 100644
--- a/code/game/mecha/equipment/tools/other_tools.dm
+++ b/code/game/mecha/equipment/tools/other_tools.dm
@@ -57,19 +57,12 @@
var/turf/target_turf = pick(L)
if(!target_turf)
return
- var/obj/effect/portal/P = new /obj/effect/portal(get_turf(target))
- P.target = target_turf
- P.creator = null
- P.icon = 'icons/obj/objects.dmi'
- P.icon_state = "anom"
- P.name = "wormhole"
- P.mech_sized = TRUE
+ var/list/obj/effect/portal/created = create_portal_pair(get_turf(src), target_turf, src, 300, 1, /obj/effect/portal/anom)
var/turf/T = get_turf(target)
message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] used a Wormhole Generator in [ADMIN_COORDJMP(T)]",0,1)
log_game("[key_name(chassis.occupant)] used a Wormhole Generator in [COORD(T)]")
src = null
- spawn(rand(150,300))
- qdel(P)
+ QDEL_LIST_IN(created, rand(150,300))
return 1
diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm
index 8a78bad45ae..73863315ddb 100644
--- a/code/game/mecha/equipment/tools/work_tools.dm
+++ b/code/game/mecha/equipment/tools/work_tools.dm
@@ -224,34 +224,34 @@
if(do_after_cooldown(W))
chassis.spark_system.start()
W.ChangeTurf(/turf/open/floor/plating)
- playsound(W, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(W, 'sound/items/deconstruct.ogg', 50, 1)
else if(isfloorturf(target))
var/turf/open/floor/F = target
occupant_message("Deconstructing [F]...")
if(do_after_cooldown(target))
chassis.spark_system.start()
F.ChangeTurf(F.baseturf)
- playsound(F, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(F, 'sound/items/deconstruct.ogg', 50, 1)
else if (istype(target, /obj/machinery/door/airlock))
occupant_message("Deconstructing [target]...")
if(do_after_cooldown(target))
chassis.spark_system.start()
qdel(target)
- playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(target, 'sound/items/deconstruct.ogg', 50, 1)
if(1)
if(isspaceturf(target))
var/turf/open/space/S = target
occupant_message("Building Floor...")
if(do_after_cooldown(S))
S.ChangeTurf(/turf/open/floor/plating)
- playsound(S, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(S, 'sound/items/deconstruct.ogg', 50, 1)
chassis.spark_system.start()
else if(isfloorturf(target))
var/turf/open/floor/F = target
occupant_message("Building Wall...")
if(do_after_cooldown(F))
F.ChangeTurf(/turf/closed/wall)
- playsound(F, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(F, 'sound/items/deconstruct.ogg', 50, 1)
chassis.spark_system.start()
if(2)
if(isfloorturf(target))
@@ -260,7 +260,7 @@
chassis.spark_system.start()
var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target)
T.autoclose = 1
- playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(target, 'sound/items/deconstruct.ogg', 50, 1)
playsound(target, 'sound/effects/sparks2.ogg', 50, 1)
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index 1cd46f24eab..78896e2fad5 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -78,7 +78,7 @@
origin_tech = "magnets=3;combat=3;engineering=3"
energy_drain = 30
projectile = /obj/item/projectile/beam/laser
- fire_sound = 'sound/weapons/Laser.ogg'
+ fire_sound = 'sound/weapons/laser.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy
equip_cooldown = 15
@@ -98,7 +98,7 @@
origin_tech = "materials=4;combat=5;magnets=4"
energy_drain = 120
projectile = /obj/item/projectile/ion
- fire_sound = 'sound/weapons/Laser.ogg'
+ fire_sound = 'sound/weapons/laser.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/energy/tesla
equip_cooldown = 35
@@ -147,7 +147,7 @@
energy_drain = 20
equip_cooldown = 8
projectile = /obj/item/projectile/energy/electrode
- fire_sound = 'sound/weapons/Taser.ogg'
+ fire_sound = 'sound/weapons/taser.ogg'
/obj/item/mecha_parts/mecha_equipment/weapon/honker
@@ -167,7 +167,7 @@
/obj/item/mecha_parts/mecha_equipment/weapon/honker/action(target, params)
if(!action_checks(target))
return
- playsound(chassis, 'sound/items/AirHorn.ogg', 100, 1)
+ playsound(chassis, 'sound/items/airhorn.ogg', 100, 1)
chassis.occupant_message("HONK")
for(var/mob/living/carbon/M in ohearers(6, chassis))
if(ishuman(M))
@@ -178,10 +178,10 @@
M.SetSleeping(0)
M.stuttering += 20
M.adjustEarDamage(0, 30)
- M.Weaken(3)
+ M.Knockdown(60)
if(prob(30))
- M.Stun(10)
- M.Paralyse(4)
+ M.Stun(200)
+ M.Unconscious(80)
else
M.Jitter(500)
@@ -195,7 +195,7 @@
//Base ballistic weapon type
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic
name = "general ballisic weapon"
- fire_sound = 'sound/weapons/Gunshot.ogg'
+ fire_sound = 'sound/weapons/gunshot.ogg'
var/projectiles
var/projectile_energy_cost
@@ -256,7 +256,7 @@
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced
name = "\improper S.H.H. \"Quietus\" Carbine"
desc = "A weapon for combat exosuits. A mime invention, field tests have shown that targets cannot even scream before going down."
- fire_sound = 'sound/weapons/Gunshot_silenced.ogg'
+ fire_sound = 'sound/weapons/gunshot_silenced.ogg'
icon_state = "mecha_mime"
equip_cooldown = 30
projectile = /obj/item/projectile/bullet/mime
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 09052e1b35f..d360be0f730 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -264,7 +264,7 @@
if(equipment && equipment.len)
to_chat(user, "It's equipped with:")
for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
- to_chat(user, "\icon[ME] [ME]")
+ to_chat(user, "[bicon(ME)] [ME]")
//processing internal damage, temperature, air regulation, alert updates, lights power use.
/obj/mecha/process()
@@ -639,7 +639,7 @@
var/can_control_mech = 0
for(var/obj/item/mecha_parts/mecha_tracking/ai_control/A in trackers)
can_control_mech = 1
- to_chat(user, "\icon[src] Status of [name]:\n[A.get_mecha_info()]")
+ to_chat(user, "[bicon(src)] Status of [name]:\n[A.get_mecha_info()]")
break
if(!can_control_mech)
to_chat(user, "You cannot control exosuits without AI control beacons installed.")
@@ -905,7 +905,7 @@
if(!user.transferItemToLoc(mmi_as_oc, src))
to_chat(user, "\the [mmi_as_oc] is stuck to your hand, you cannot put it in \the [src]!")
return FALSE
- var/mob/brainmob = mmi_as_oc.brainmob
+ var/mob/living/brainmob = mmi_as_oc.brainmob
mmi_as_oc.mecha = src
occupant = brainmob
brainmob.forceMove(src) //should allow relaymove
@@ -1007,7 +1007,7 @@
/obj/mecha/proc/occupant_message(message as text)
if(message)
if(occupant && occupant.client)
- to_chat(occupant, "\icon[src] [message]")
+ to_chat(occupant, "[bicon(src)] [message]")
return
/obj/mecha/proc/log_message(message as text,red=null)
diff --git a/code/game/mecha/mecha_actions.dm b/code/game/mecha/mecha_actions.dm
index 65fa8b49b9e..df96c78e8c0 100644
--- a/code/game/mecha/mecha_actions.dm
+++ b/code/game/mecha/mecha_actions.dm
@@ -21,7 +21,7 @@
/datum/action/innate/mecha
- check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUNNED | AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS
var/obj/mecha/chassis
/datum/action/innate/mecha/Grant(mob/living/L, obj/mecha/M)
diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm
index 5b67cbf0182..3cc5788bd84 100644
--- a/code/game/mecha/mecha_construction_paths.dm
+++ b/code/game/mecha/mecha_construction_paths.dm
@@ -6,7 +6,7 @@
if(istype(used_atom, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/W = used_atom
if (W.remove_fuel(0, user))
- playsound(holder, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(holder, 'sound/items/welder2.ogg', 50, 1)
else
return 0
else if(istype(used_atom, /obj/item/weapon/wrench))
@@ -24,7 +24,7 @@
else if(istype(used_atom, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = used_atom
if(C.use(4))
- playsound(holder, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(holder, 'sound/items/deconstruct.ogg', 50, 1)
else
to_chat(user, ("There's not enough cable to finish the task!"))
return 0
@@ -41,7 +41,7 @@
if(istype(used_atom, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/W = used_atom
if (W.remove_fuel(0, user))
- playsound(holder, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(holder, 'sound/items/welder2.ogg', 50, 1)
else
return 0
else if(istype(used_atom, /obj/item/weapon/wrench))
@@ -59,7 +59,7 @@
else if(istype(used_atom, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = used_atom
if (C.use(4))
- playsound(holder, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(holder, 'sound/items/deconstruct.ogg', 50, 1)
else
to_chat(user, ("There's not enough cable to finish the task!"))
return 0
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index 08c9b161cce..52b43af7817 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -91,32 +91,34 @@
/obj/mecha/working/ripley/mining
desc = "An old, dusty mining Ripley."
name = "\improper APLU \"Miner\""
+ obj_integrity = 75 //Low starting health
-/obj/mecha/working/ripley/mining/New()
- ..()
- //Attach drill
- if(prob(25)) //Possible diamond drill... Feeling lucky?
- var/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill/D = new /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill
- D.attach(src)
- else
- var/obj/item/mecha_parts/mecha_equipment/drill/D = new /obj/item/mecha_parts/mecha_equipment/drill
- D.attach(src)
+/obj/mecha/working/ripley/mining/Initialize()
+ . = ..()
+ if(cell)
+ cell.charge = Floor(cell.charge * 0.25) //Starts at very low charge
+ if(prob(70)) //Maybe add a drill
+ if(prob(15)) //Possible diamond drill... Feeling lucky?
+ var/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill/D = new
+ D.attach(src)
+ else
+ var/obj/item/mecha_parts/mecha_equipment/drill/D = new
+ D.attach(src)
- //Add possible plasma cutter
- if(prob(25))
- var/obj/item/mecha_parts/mecha_equipment/M = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma
+ else //Add possible plasma cutter if no drill
+ var/obj/item/mecha_parts/mecha_equipment/M = new
M.attach(src)
//Add ore box to cargo
cargo.Add(new /obj/structure/ore_box(src))
//Attach hydraulic clamp
- var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp
+ var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new
HC.attach(src)
for(var/obj/item/mecha_parts/mecha_tracking/B in trackers)//Deletes the beacon so it can't be found easily
qdel(B)
- var/obj/item/mecha_parts/mecha_equipment/mining_scanner/scanner = new /obj/item/mecha_parts/mecha_equipment/mining_scanner
+ var/obj/item/mecha_parts/mecha_equipment/mining_scanner/scanner = new
scanner.attach(src)
/obj/mecha/working/ripley/Exit(atom/movable/O)
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index 78aa6d49e80..06483001471 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -26,11 +26,6 @@
if(user_buckle_mob(M, user))
return 1
-//Cleanup
-/atom/movable/Destroy()
- . = ..()
- unbuckle_all_mobs(force=1)
-
/atom/movable/proc/has_buckled_mobs()
if(!buckled_mobs)
return FALSE
@@ -43,19 +38,19 @@
buckled_mobs = list()
if(!istype(M))
- return 0
+ return FALSE
if(check_loc && M.loc != loc)
- return 0
+ return FALSE
if((!can_buckle && !force) || M.buckled || (buckled_mobs.len >= max_buckled_mobs) || (buckle_requires_restraints && !M.restrained()) || M == src)
- return 0
+ return FALSE
if(!M.can_buckle() && !force)
if(M == usr)
to_chat(M, "You are unable to buckle yourself to the [src]!")
else
to_chat(usr, "You are unable to buckle [M] to the [src]!")
- return 0
+ return FALSE
if(M.pulledby && buckle_prevents_pull)
M.pulledby.stop_pulling()
@@ -70,7 +65,7 @@
M.throw_alert("buckled", /obj/screen/alert/restrained/buckled, new_master = src)
post_buckle_mob(M)
- return 1
+ return TRUE
/obj/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
. = ..()
@@ -105,11 +100,11 @@
//Wrapper procs that handle sanity and user feedback
/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE)
if(!in_range(user, src) || user.stat || user.restrained())
- return 0
+ return FALSE
add_fingerprint(user)
-
- if(buckle_mob(M, check_loc = check_loc))
+ . = buckle_mob(M, check_loc = check_loc)
+ if(.)
if(M == user)
M.visible_message(\
"[M] buckles [M.p_them()]self to [src].",\
@@ -120,8 +115,6 @@
"[user] buckles [M] to [src]!",\
"[user] buckles you to [src]!",\
"You hear metal clanking.")
- return 1
-
/atom/movable/proc/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
var/mob/living/M = unbuckle_mob(buckled_mob)
diff --git a/code/game/objects/effects/alien_acid.dm b/code/game/objects/effects/alien_acid.dm
index 2800315bf68..06c3b37a93e 100644
--- a/code/game/objects/effects/alien_acid.dm
+++ b/code/game/objects/effects/alien_acid.dm
@@ -47,7 +47,7 @@
return 0
if(prob(5))
- playsound(loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(loc, 'sound/items/welder.ogg', 100, 1)
for(var/obj/O in target)
if(prob(20) && !(resistance_flags & UNACIDABLE))
@@ -82,7 +82,7 @@
. = ..()
if(.)
if(prob(45))
- playsound(loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(loc, 'sound/items/welder.ogg', 100, 1)
target_strength--
if(target_strength <= 0)
target.visible_message("[target] collapses under its own weight into a puddle of goop and undigested debris!")
diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm
index 071c95cb46d..cfec0123183 100644
--- a/code/game/objects/effects/anomalies.dm
+++ b/code/game/objects/effects/anomalies.dm
@@ -115,7 +115,7 @@
/obj/effect/anomaly/grav/proc/gravShock(mob/A)
if(boing && isliving(A) && !A.stat)
- A.Weaken(2)
+ A.Knockdown(40)
var/atom/target = get_edge_target_turf(A, get_dir(src, get_step_away(A, src)))
A.throw_at(target, 5, 1)
boing = 0
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index a39c4fbe934..d7d510974c0 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -180,7 +180,7 @@
. += "You recognise the footprints as belonging to:\n"
for(var/shoe in shoe_types)
var/obj/item/clothing/shoes/S = shoe
- . += "some [initial(S.name)] \icon[S]\n"
+ . += "some [initial(S.name)] [bicon(initial(S.icon))]\n"
to_chat(user, .)
diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm
index a96f3b50a2e..00987d78595 100644
--- a/code/game/objects/effects/decals/crayon.dm
+++ b/code/game/objects/effects/decals/crayon.dm
@@ -30,27 +30,35 @@
layer = HIGH_OBJ_LAYER //Harder to hide
do_icon_rotate = FALSE //These are designed to always face south, so no rotation please.
var/datum/gang/gang
- var/obj/item/device/gangtool/linked_tool
+ var/datum/mind/user_mind
var/area/territory
/obj/effect/decal/cleanable/crayon/gang/Initialize(mapload, var/datum/gang/G, var/e_name = "gang tag", var/rotation = 0, var/mob/user)
if(!type || !G)
qdel(src)
+ user_mind = user.mind
territory = get_area(src)
gang = G
var/newcolor = G.color_hex
icon_state = G.name
G.territory_new |= list(territory.type = territory.name)
- linked_tool = locate(/obj/item/device/gangtool) in user.contents
- if(linked_tool)
- linked_tool.tags += src
+ //If this isn't tagged by a specific gangster there's no bonus income.
+ set_mind_owner(user_mind)
..(mapload, newcolor, icon_state, e_name, rotation)
+/obj/effect/decal/cleanable/crayon/gang/proc/set_mind_owner(datum/mind/mind)
+ if(istype(user_mind) && istype(gang) && islist(gang.tags_by_mind[user_mind])) //Clear us out of old ownership
+ gang.tags_by_mind[user_mind] -= src
+ if(istype(mind))
+ if(!islist(gang.tags_by_mind[mind]))
+ gang.tags_by_mind[mind] = list()
+ gang.tags_by_mind[mind] += src
+ user_mind = mind
+
/obj/effect/decal/cleanable/crayon/gang/Destroy()
- if(linked_tool)
- linked_tool.tags -= src
if(gang)
gang.territory -= territory.type
+ set_mind_owner(null)
gang.territory_new -= territory.type
gang.territory_lost |= list(territory.type = territory.name)
return ..()
diff --git a/code/game/objects/effects/decals/decal.dm b/code/game/objects/effects/decals/decal.dm
index 6641b12fd3a..0dae497db80 100644
--- a/code/game/objects/effects/decals/decal.dm
+++ b/code/game/objects/effects/decals/decal.dm
@@ -25,13 +25,13 @@
/obj/effect/turf_decal/proc/get_decal()
return image(icon='icons/turf/decals.dmi',icon_state=icon_state,dir=dir,layer=TURF_LAYER)
-/obj/effect/turf_decal/Initialize(mapload)
+/obj/effect/turf_decal/Initialize()
+ ..()
var/turf/T = loc
if(!istype(T)) //you know this will happen somehow
CRASH("Turf decal initialized in an object/nullspace")
T.add_decal(get_decal(),group)
- qdel(src)
-
+ return INITIALIZE_HINT_QDEL
/obj/effect/turf_decal/stripes/line
icon_state = "warningline"
@@ -67,4 +67,4 @@
icon_state = "sandyplating"
/obj/effect/turf_decal/plaque
- icon_state = "plaque"
\ No newline at end of file
+ icon_state = "plaque"
diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm
index 9ca086fad25..7e937c3a1c6 100644
--- a/code/game/objects/effects/effect_system/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/effects_foam.dm
@@ -1,5 +1,9 @@
// Foam
// Similar to smoke, but slower and mobs absorb its reagent through their exposed skin.
+#define ALUMINUM_FOAM 1
+#define IRON_FOAM 2
+#define RESIN_FOAM 3
+
/obj/effect/particle_effect/foam
name = "foam"
@@ -22,13 +26,16 @@
/obj/effect/particle_effect/foam/metal
name = "aluminium foam"
- metal = 1
+ metal = ALUMINUM_FOAM
icon_state = "mfoam"
-
/obj/effect/particle_effect/foam/metal/iron
name = "iron foam"
- metal = 2
+ metal = IRON_FOAM
+
+/obj/effect/particle_effect/foam/metal/resin
+ name = "resin foam"
+ metal = RESIN_FOAM
/obj/effect/particle_effect/foam/New(loc)
@@ -45,10 +52,12 @@
/obj/effect/particle_effect/foam/proc/kill_foam()
STOP_PROCESSING(SSfastprocess, src)
switch(metal)
- if(1)
- new /obj/structure/foamedmetal(src.loc)
- if(2)
- new /obj/structure/foamedmetal/iron(src.loc)
+ if(ALUMINUM_FOAM)
+ new /obj/structure/foamedmetal(get_turf(src))
+ if(IRON_FOAM)
+ new /obj/structure/foamedmetal/iron(get_turf(src))
+ if(RESIN_FOAM)
+ new /obj/structure/foamedmetal/resin(get_turf(src))
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
@@ -95,7 +104,7 @@
/obj/effect/particle_effect/foam/Crossed(atom/movable/AM)
if(istype(AM, /mob/living/carbon))
var/mob/living/carbon/M = AM
- M.slip(5, 2, src)
+ M.slip(100, src)
/obj/effect/particle_effect/foam/metal/Crossed(atom/movable/AM)
return
@@ -230,3 +239,44 @@
obj_integrity = 50
max_integrity = 50
icon_state = "ironfoam"
+
+//Atmos Backpack Resin, transparent, prevents atmos and filters the air
+/obj/structure/foamedmetal/resin
+ name = "ATMOS Resin"
+ desc = "A lightweight, transparent resin used to suffocate fires, scrub the air of toxins, and restore the air to a safe temperature"
+ opacity = FALSE
+ icon_state = "atmos_resin"
+ alpha = 120
+ obj_integrity = 10
+ max_integrity = 10
+ layer = EDGED_TURF_LAYER
+
+/obj/structure/foamedmetal/resin/Initialize()
+ . = ..()
+ if(isopenturf(loc))
+ var/turf/open/O = loc
+ if(O.air)
+ var/datum/gas_mixture/G = O.air
+ G.temperature = 293.15
+ for(var/obj/effect/hotspot/H in O)
+ qdel(H)
+ var/list/G_gases = G.gases
+ for(var/I in G_gases)
+ if(I != "o2" && I != "n2")
+ G.gases[I][MOLES] = 0
+ G.garbage_collect()
+ O.air_update_turf()
+ for(var/obj/machinery/atmospherics/components/unary/U in O)
+ if(!U.welded)
+ U.welded = TRUE
+ U.update_icon()
+ U.visible_message("[U] sealed shut!")
+ for(var/mob/living/L in O)
+ L.ExtinguishMob()
+ for(var/obj/item/Item in O)
+ Item.extinguish()
+
+
+#undef ALUMINUM_FOAM
+#undef IRON_FOAM
+#undef RESIN_FOAM
diff --git a/code/game/objects/effects/effect_system/effects_other.dm b/code/game/objects/effects/effect_system/effects_other.dm
index 3ac1e565205..dace69fe1fa 100644
--- a/code/game/objects/effects/effect_system/effects_other.dm
+++ b/code/game/objects/effects/effect_system/effects_other.dm
@@ -131,7 +131,7 @@
for(var/mob/M in viewers(1, location))
if (prob (50 * amount))
to_chat(M, "The explosion knocks you down.")
- M.Weaken(rand(1,5))
+ M.Knockdown(rand(20,100))
return
else
dyn_explosion(location, amount, flashing_factor)
\ No newline at end of file
diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm
index 9324c6edb7d..eeee81cb1e8 100644
--- a/code/game/objects/effects/effect_system/effects_smoke.dm
+++ b/code/game/objects/effects/effect_system/effects_smoke.dm
@@ -207,7 +207,7 @@
/obj/effect/particle_effect/smoke/sleeping/smoke_mob(mob/living/carbon/M)
if(..())
M.drop_item()
- M.Sleeping(max(M.sleeping,10))
+ M.Sleeping(200)
M.emote("cough")
return 1
diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm
index 9b0702edbec..6363a107d68 100644
--- a/code/game/objects/effects/glowshroom.dm
+++ b/code/game/objects/effects/glowshroom.dm
@@ -161,7 +161,7 @@
/obj/structure/glowshroom/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
if(damage_type == BURN && damage_amount)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/structure/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm
index 5ce88f1c27e..2c701ee2740 100644
--- a/code/game/objects/effects/landmarks.dm
+++ b/code/game/objects/effects/landmarks.dm
@@ -182,7 +182,7 @@
/obj/effect/landmark/latejoin/Initialize(mapload)
..()
- GLOB.latejoin += loc
+ SSjob.latejoin_trackers += loc
qdel(src)
// carp.
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
index e8ea608e2e5..a0cbd83ea1f 100644
--- a/code/game/objects/effects/mines.dm
+++ b/code/game/objects/effects/mines.dm
@@ -22,7 +22,7 @@
/obj/effect/mine/proc/triggermine(mob/victim)
if(triggered)
return
- visible_message("[victim] sets off \icon[src] [src]!")
+ visible_message("[victim] sets off [bicon(src)] [src]!")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, src)
s.start()
@@ -44,11 +44,11 @@
/obj/effect/mine/stun
name = "stun mine"
- var/stun_time = 8
+ var/stun_time = 80
/obj/effect/mine/stun/mineEffect(mob/victim)
if(isliving(victim))
- victim.Weaken(stun_time)
+ victim.Knockdown(stun_time)
/obj/effect/mine/kickmine
name = "kick mine"
@@ -127,7 +127,7 @@
var/pure_red = list(0,0,0,0,0,0,0,0,0,1,0,0)
spawn(0)
- new /obj/effect/hallucination/delusion(victim.loc,victim,force_kind="demon",duration=duration,skip_nearby=0)
+ new /obj/effect/hallucination/delusion(victim.loc,victim,"demon",duration,0)
var/obj/item/weapon/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
chainsaw.flags |= NODROP
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index 9e7dbe7fa9d..74556098373 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -1,25 +1,42 @@
+/proc/create_portal_pair(turf/source, turf/destination, _creator = null, _lifespan = 300, accuracy = 0, newtype = /obj/effect/portal)
+ if(!istype(source) || !istype(destination))
+ return
+ var/turf/actual_destination = get_teleport_turf(destination, accuracy)
+ var/obj/effect/portal/P1 = new newtype(source, _creator, _lifespan, null, FALSE)
+ var/obj/effect/portal/P2 = new newtype(actual_destination, _creator, _lifespan, P1, TRUE)
+ if(!istype(P1)||!istype(P2))
+ return
+ P1.link_portal(P2)
+ P1.hardlinked = TRUE
+ return list(P1, P2)
+
/obj/effect/portal
name = "portal"
desc = "Looks unstable. Best to test it with the clown."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "portal"
- density = 1
- var/obj/item/target = null
- var/creator = null
- anchored = 1
- var/precision = 1 // how close to the portal you will teleport. 0 = on the portal, 1 = adjacent
+ anchored = TRUE
var/mech_sized = FALSE
+ var/obj/effect/portal/linked
+ var/hardlinked = TRUE //Requires a linked portal at all times. Destroy if there's no linked portal, if there is destroy it when this one is deleted.
+ var/creator
+ var/turf/hard_target //For when a portal needs a hard target and isn't to be linked.
+ var/atmos_link = FALSE //Link source/destination atmos.
+ var/turf/open/atmos_source //Atmos link source
+ var/turf/open/atmos_destination //Atmos link destination
-/obj/effect/portal/Bumped(mob/M as mob|obj)
- teleport(M)
+/obj/effect/portal/anom
+ name = "wormhole"
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "anom"
+ mech_sized = TRUE
-/obj/effect/portal/attack_tk(mob/user)
- return
-
-/obj/effect/portal/attack_hand(mob/user)
- if(Adjacent(user))
- teleport(user)
+/obj/effect/portal/Move(newloc)
+ for(var/T in newloc)
+ if(istype(T, /obj/effect/portal))
+ return FALSE
+ return ..()
/obj/effect/portal/attackby(obj/item/weapon/W, mob/user, params)
if(user && Adjacent(user))
@@ -28,42 +45,113 @@
/obj/effect/portal/make_frozen_visual()
return
-/obj/effect/portal/New(loc, turf/target, creator=null, lifespan=300)
- ..()
+/obj/effect/portal/Crossed(atom/movable/AM, oldloc)
+ if(get_turf(oldloc) == get_turf(linked))
+ return ..()
+ if(!teleport(AM))
+ return ..()
+
+/obj/effect/portal/attack_tk(mob/user)
+ return
+
+/obj/effect/portal/attack_hand(mob/user)
+ if(Adjacent(user))
+ teleport(user)
+
+/obj/effect/portal/Initialize(mapload, _creator, _lifespan = 300, obj/effect/portal/_linked, automatic_link = TRUE, hard_target_override, atmos_link_override)
+ . = ..()
GLOB.portals += src
- src.target = target
- src.creator = creator
+ if(!istype(_linked) && automatic_link)
+ . = INITIALIZE_HINT_QDEL
+ CRASH("Somebody fucked up.")
+ if(_lifespan > 0)
+ QDEL_IN(src, _lifespan)
+ if(!isnull(atmos_link_override))
+ atmos_link = atmos_link_override
+ link_portal(_linked)
+ hardlinked = automatic_link
+ creator = _creator
- var/area/A = get_area(target)
- if(A && A.noteleport) // No point in persisting if the target is unreachable.
- qdel(src)
- return
- if(lifespan > 0)
- QDEL_IN(src, lifespan)
+/obj/effect/portal/proc/link_portal(obj/effect/portal/newlink)
+ linked = newlink
+ if(atmos_link)
+ link_atmos()
-/obj/effect/portal/Destroy()
- GLOB.portals -= src
- if(istype(creator, /obj/item/weapon/hand_tele))
- var/obj/item/weapon/hand_tele/O = creator
- O.active_portals--
- else if(istype(creator, /obj/item/weapon/gun/energy/wormhole_projector))
- var/obj/item/weapon/gun/energy/wormhole_projector/P = creator
- P.portal_destroyed(src)
+/obj/effect/portal/proc/link_atmos()
+ if(atmos_source || atmos_destination)
+ unlink_atmos()
+ if(!isopenturf(get_turf(src)))
+ return FALSE
+ if(linked)
+ if(isopenturf(get_turf(linked)))
+ atmos_source = get_turf(src)
+ atmos_destination = get_turf(linked)
+ else if(hard_target)
+ if(isopenturf(hard_target))
+ atmos_source = get_turf(src)
+ atmos_destination = hard_target
+ else
+ return FALSE
+ if(!istype(atmos_source) || !istype(atmos_destination))
+ return FALSE
+ LAZYINITLIST(atmos_source.atmos_adjacent_turfs)
+ LAZYINITLIST(atmos_destination.atmos_adjacent_turfs)
+ if(atmos_source.atmos_adjacent_turfs[atmos_destination] || atmos_destination.atmos_adjacent_turfs[atmos_source]) //Already linked!
+ return FALSE
+ atmos_source.atmos_adjacent_turfs[atmos_destination] = TRUE
+ atmos_destination.atmos_adjacent_turfs[atmos_source] = TRUE
+ atmos_source.air_update_turf(FALSE)
+ atmos_destination.air_update_turf(FALSE)
+
+/obj/effect/portal/proc/unlink_atmos()
+ if(istype(atmos_source))
+ if(istype(atmos_destination) && !atmos_source.Adjacent(atmos_destination) && !CANATMOSPASS(atmos_destination, atmos_source))
+ LAZYREMOVE(atmos_source.atmos_adjacent_turfs, atmos_destination)
+ atmos_source = null
+ if(istype(atmos_destination))
+ if(istype(atmos_source) && !atmos_destination.Adjacent(atmos_source) && !CANATMOSPASS(atmos_source, atmos_destination))
+ LAZYREMOVE(atmos_destination.atmos_adjacent_turfs, atmos_source)
+ atmos_destination = null
+
+/obj/effect/portal/Destroy() //Calls on_portal_destroy(destroyed portal, location of destroyed portal) on creator if creator has such call.
+ if(creator && hascall(creator, "on_portal_destroy"))
+ call(creator, "on_portal_destroy")(src, src.loc)
creator = null
+ GLOB.portals -= src
+ unlink_atmos()
+ if(hardlinked && !QDELETED(linked))
+ QDEL_NULL(linked)
+ else
+ linked = null
return ..()
-/obj/effect/portal/proc/teleport(atom/movable/M as mob|obj)
- if(istype(M, /obj/effect)) //sparks don't teleport
+/obj/effect/portal/proc/teleport(atom/movable/M)
+ if(!istype(M) || istype(M, /obj/effect) || (istype(M, /obj/mecha) && !mech_sized) || (!isobj(M) && !ismob(M))) //Things that shouldn't teleport.
return
- if(M.anchored)
- if(!(istype(M, /obj/mecha) && mech_sized))
+ var/turf/real_target = get_link_target_turf()
+ if(!istype(real_target))
+ return FALSE
+ if(ismegafauna(M))
+ message_admins("[M] has used a portal at [ADMIN_COORDJMP(src)] made by [usr].")
+ if(do_teleport(M, real_target, 0))
+ if(istype(M, /obj/item/projectile))
+ var/obj/item/projectile/P = M
+ P.ignore_source_check = TRUE
+ return TRUE
+ return FALSE
+
+/obj/effect/portal/proc/get_link_target_turf()
+ var/turf/real_target
+ if(!istype(linked) || QDELETED(linked))
+ if(hardlinked)
+ qdel(src)
+ if(!istype(hard_target) || QDELETED(hard_target))
+ hard_target = null
return
- if (!( target ))
- qdel(src)
- return
- if (istype(M, /atom/movable))
- if(ismegafauna(M))
- message_admins("[M] [ADMIN_FLW(M)] has teleported through [src].")
- do_teleport(M, target, precision) ///You will appear adjacent to the beacon
-
+ else
+ real_target = hard_target
+ linked = null
+ else
+ real_target = get_turf(linked)
+ return real_target
diff --git a/code/game/objects/effects/spawners/bundle.dm b/code/game/objects/effects/spawners/bundle.dm
index c272c383e98..c316b7e2099 100644
--- a/code/game/objects/effects/spawners/bundle.dm
+++ b/code/game/objects/effects/spawners/bundle.dm
@@ -60,7 +60,7 @@
/obj/effect/spawner/bundle/costume/butler
name = "butler costume spawner"
items = list(
- /obj/item/clothing/tie/waistcoat,
+ /obj/item/clothing/accessory/waistcoat,
/obj/item/clothing/under/suit_jacket,
/obj/item/clothing/head/that)
@@ -73,7 +73,7 @@
/obj/effect/spawner/bundle/costume/prig
name = "prig costume spawner"
items = list(
- /obj/item/clothing/tie/waistcoat,
+ /obj/item/clothing/accessory/waistcoat,
/obj/item/clothing/glasses/monocle,
/obj/effect/spawner/lootdrop/minor/bowler_or_that,
/obj/item/clothing/shoes/sneakers/black,
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index 226be775e86..48220a77f0c 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -11,7 +11,7 @@
/obj/structure/spider/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
if(damage_type == BURN)//the stickiness of the web mutes all attack sounds except fire damage type
- playsound(loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(loc, 'sound/items/welder.ogg', 100, 1)
/obj/structure/spider/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
@@ -172,7 +172,7 @@
amount_grown += rand(0,2)
if(amount_grown >= 100)
if(!grow_as)
- grow_as = pick(typesof(/mob/living/simple_animal/hostile/poison/giant_spider))
+ grow_as = pick(/mob/living/simple_animal/hostile/poison/giant_spider, /mob/living/simple_animal/hostile/poison/giant_spider/hunter, /mob/living/simple_animal/hostile/poison/giant_spider/nurse)
var/mob/living/simple_animal/hostile/poison/giant_spider/S = new grow_as(src.loc)
S.poison_per_bite = poison_per_bite
S.poison_type = poison_type
diff --git a/code/game/objects/effects/temporary_visuals/clockcult.dm b/code/game/objects/effects/temporary_visuals/clockcult.dm
index 1eae2a3c643..ff788ef580e 100644
--- a/code/game/objects/effects/temporary_visuals/clockcult.dm
+++ b/code/game/objects/effects/temporary_visuals/clockcult.dm
@@ -81,21 +81,15 @@
/obj/effect/temp_visual/ratvar/volt_hit
name = "volt blast"
layer = ABOVE_MOB_LAYER
- duration = 5
+ duration = 8
icon_state = "volt_hit"
light_range = 1.5
light_power = 2
light_color = LIGHT_COLOR_ORANGE
var/mob/user
- var/damage = 20
+ var/damage = 25
-/obj/effect/temp_visual/ratvar/volt_hit/Initialize(mapload, caster, multiplier)
- if(multiplier)
- damage *= multiplier
- duration = max(round(damage * 0.2), 1)
- . = ..()
-
-/obj/effect/temp_visual/ratvar/volt_hit/true/Initialize(mapload, caster, multiplier)
+/obj/effect/temp_visual/ratvar/volt_hit/Initialize(mapload, caster)
. = ..()
user = caster
if(user)
@@ -146,6 +140,20 @@
pixel_y = rand(-10, 10)
animate(src, alpha = 0, time = 3, easing = EASE_OUT)
+/obj/effect/temp_visual/ratvar/prolonging_prism
+ icon = 'icons/effects/64x64.dmi'
+ icon_state = "prismhex1"
+ layer = RIPPLE_LAYER
+ pixel_y = -16
+ pixel_x = -16
+ duration = 30
+
+/obj/effect/temp_visual/ratvar/prolonging_prism/Initialize(mapload, set_appearance)
+ . = ..()
+ if(set_appearance)
+ appearance = set_appearance
+ animate(src, alpha = 0, time = duration, easing = BOUNCE_EASING)
+
/obj/effect/temp_visual/ratvar/spearbreak
icon = 'icons/effects/64x64.dmi'
icon_state = "ratvarspearbreak"
diff --git a/code/game/objects/effects/temporary_visuals/cult.dm b/code/game/objects/effects/temporary_visuals/cult.dm
index 78cc50cfc1e..a6497634352 100644
--- a/code/game/objects/effects/temporary_visuals/cult.dm
+++ b/code/game/objects/effects/temporary_visuals/cult.dm
@@ -18,11 +18,13 @@
icon_state = "bloodout"
/obj/effect/temp_visual/dir_setting/cult/phase // The veil shifter teleport
+ icon = 'icons/effects/cult_effects.dmi'
name = "phase glow"
duration = 7
icon_state = "cultin"
/obj/effect/temp_visual/dir_setting/cult/phase/out
+ icon = 'icons/effects/cult_effects.dmi'
icon_state = "cultout"
/obj/effect/temp_visual/cult/sac
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index f275862caa5..38e8a070172 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -59,8 +59,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/armour_penetration = 0 //percentage of armour effectiveness to remove
var/list/allowed = null //suit storage stuff.
var/obj/item/device/uplink/hidden_uplink = null
- var/strip_delay = 40
- var/put_on_delay = 20
+ var/equip_delay_self = 0 //In deciseconds, how long an item takes to equip; counts only for normal clothing slots, not pockets etc.
+ var/equip_delay_other = 20 //In deciseconds, how long an item takes to put on another person
+ var/strip_delay = 40 //In deciseconds, how long an item takes to remove from another person
var/breakouttime = 0
var/list/materials
var/origin_tech = null //Used by R&D to determine what research bonuses it grants.
@@ -105,6 +106,14 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/datum/rpg_loot/rpg_loot = null
+
+ //Tooltip vars
+ var/in_inventory = FALSE//is this item equipped into an inventory slot or hand of a mob?
+ var/force_string //string form of an item's force. Edit this var only to set a custom force string
+ var/last_force_string_check = 0
+ var/tip_timer
+ var/force_string_override
+
/obj/item/Initialize()
if (!materials)
materials = list()
@@ -116,6 +125,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if(GLOB.rpg_loot_items)
rpg_loot = new(src)
+ if(force_string)
+ force_string_override = TRUE
+
/obj/item/Destroy()
flags &= ~DROPDEL //prevent reqdels
if(ismob(loc))
@@ -353,7 +365,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
// afterattack() and attack() prototypes moved to _onclick/item_attack.dm for consistency
-/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(prob(final_block_chance))
owner.visible_message("[owner] blocks [attack_text] with [src]!")
return 1
@@ -368,9 +380,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
A.Remove(user)
if(DROPDEL & flags)
qdel(src)
+ in_inventory = FALSE
// called just as an item is picked up (loc is not yet changed)
/obj/item/proc/pickup(mob/user)
+ in_inventory = TRUE
return
@@ -396,6 +410,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/datum/action/A = X
if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot.
A.Grant(user)
+ in_inventory = TRUE
//sometimes we only want to grant the item's action if it's equipped in a specific slot.
/obj/item/proc/item_action_slot_check(slot, mob/user)
@@ -407,11 +422,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
//if this is being done by a mob other than M, it will include the mob equipper, who is trying to equip the item to mob M. equipper will be null otherwise.
//If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen.
//Set disable_warning to 1 if you wish it to not give you outputs.
-/obj/item/proc/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0)
+/obj/item/proc/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
if(!M)
return 0
- return M.can_equip(src, slot, disable_warning)
+ return M.can_equip(src, slot, disable_warning, bypass_equip_delay_self)
/obj/item/verb/verb_pickup()
set src in oview(1)
@@ -426,7 +441,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
//This proc is executed when someone clicks the on-screen UI button.
//The default action is attack_self().
-//Checks before we get to here are: mob is alive, mob is not restrained, paralyzed, asleep, resting, laying, item is on the mob.
+//Checks before we get to here are: mob is alive, mob is not restrained, stunned, asleep, resting, laying, item is on the mob.
/obj/item/proc/ui_action_click(mob/user, actiontype)
attack_self(user)
@@ -501,8 +516,8 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if(M.drop_item())
to_chat(M, "You drop what you're holding and clutch at your eyes!")
M.adjust_blurriness(10)
- M.Paralyse(1)
- M.Weaken(2)
+ M.Unconscious(20)
+ M.Knockdown(40)
if (prob(M.eye_damage - 10 + 1))
if(M.become_blind())
to_chat(M, "You go blind!")
@@ -546,6 +561,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if (callback) //call the original callback
. = callback.Invoke()
throw_speed = initial(throw_speed) //explosions change this.
+ in_inventory = FALSE
/obj/item/proc/remove_item_from_storage(atom/newLoc) //please use this if you're going to snowflake an item out of a obj/item/weapon/storage
if(!newLoc)
@@ -630,3 +646,42 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item/proc/microwave_act(obj/machinery/microwave/M)
if(M && M.dirty < 100)
M.dirty++
+
+/obj/item/proc/on_mob_death(mob/living/L, gibbed)
+
+/obj/item/proc/set_force_string()
+ switch(force)
+ if(0 to 4)
+ force_string = "very low"
+ if(4 to 7)
+ force_string = "low"
+ if(7 to 10)
+ force_string = "medium"
+ if(10 to 11)
+ force_string = "high"
+ if(11 to 20) //12 is the force of a toolbox
+ force_string = "robust"
+ if(20 to 25)
+ force_string = "very robust"
+ else
+ force_string = "exceptionally robust"
+ last_force_string_check = force
+
+/obj/item/proc/openTip(location, control, params, user)
+ if(last_force_string_check != force && !force_string_override)
+ set_force_string()
+ if(!force_string_override)
+ openToolTip(user,src,params,title = name,content = "[desc] [force ? "Force: [force_string]" : ""]",theme = "")
+ else
+ openToolTip(user,src,params,title = name,content = "[desc] Force: [force_string]",theme = "")
+
+/obj/item/MouseEntered(location, control, params)
+ if(in_inventory && usr.client.prefs.enable_tips)
+ var/timedelay = usr.client.prefs.tip_delay/100
+ var/user = usr
+ tip_timer = addtimer(CALLBACK(src, .proc/openTip, location, control, params, user), timedelay, TIMER_STOPPABLE)//timer takes delay in deciseconds, but the pref is in milliseconds. dividing by 100 converts it.
+
+/obj/item/MouseExited()
+ deltimer(tip_timer)//delete any in-progress timer if the mouse is moved off the item before it finishes
+ closeToolTip(usr)
+
diff --git a/code/game/objects/items/cardboard_cutouts.dm b/code/game/objects/items/cardboard_cutouts.dm
index 06017c8865b..12016924a8b 100644
--- a/code/game/objects/items/cardboard_cutouts.dm
+++ b/code/game/objects/items/cardboard_cutouts.dm
@@ -22,7 +22,7 @@
if(user.a_intent == INTENT_HELP || pushed_over)
return ..()
user.visible_message("[user] pushes over [src]!", "You push over [src]!")
- playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
+ playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
push_over()
/obj/item/cardboard_cutout/proc/push_over()
@@ -175,7 +175,6 @@
if("Private Security Officer")
name = "Private Security Officer"
desc = "A cardboard cutout of a private security officer."
- icon = 'icons/mob/mob.dmi'
icon_state = "cutout_ntsec"
return 1
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 0c29ee3f9f9..ecc36c0c2d9 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -634,7 +634,7 @@
C.blind_eyes(1)
if(C.get_eye_protection() <= 0) // no eye protection? ARGH IT BURNS.
C.confused = max(C.confused, 3)
- C.Weaken(3)
+ C.Knockdown(60)
if(ishuman(C) && actually_paints)
var/mob/living/carbon/human/H = C
H.lip_style = "spray_face"
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index e7e0302fea9..6105b12981d 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -42,7 +42,7 @@ GLOBAL_LIST_EMPTY(PDAs)
var/notehtml = ""
var/notescanned = 0 // True if what is in the notekeeper was from a paper.
var/cart = "" //A place to stick cartridge menu information
- var/detonate = 1 // Can the PDA be blown up?
+ var/detonatable = TRUE // Can the PDA be blown up?
var/hidden = 0 // Is the PDA hidden from the PDA list?
var/emped = 0
@@ -57,15 +57,18 @@ GLOBAL_LIST_EMPTY(PDAs)
var/obj/item/inserted_item //Used for pen, crayon, and lipstick insertion or removal. Same as above.
var/overlays_x_offset = 0 //x offset to use for certain overlays
-/obj/item/device/pda/New()
- ..()
+/obj/item/device/pda/Initialize()
+ . = ..()
if(fon)
set_light(f_lum)
GLOB.PDAs += src
if(default_cartridge)
cartridge = new default_cartridge(src)
- inserted_item = new /obj/item/weapon/pen(src)
+ if(inserted_item)
+ inserted_item = new inserted_item(src)
+ else
+ inserted_item = new /obj/item/weapon/pen(src)
update_icon()
/obj/item/device/pda/proc/update_label()
@@ -150,31 +153,31 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "
Use a screwdriver with a very thin tip (provided) to unscrew the terminal's front panel
\
-
Dislodge and remove the front panel with a crowbar
\
-
Cut the inner metal plate with a welding tool
\
-
Pry off the inner plate with a crowbar to expose the radioactive core
\
-
Use the core container to remove the plutonium core; the container will take some time to seal
\
-
???
"
diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm
index ccf40851910..59002370165 100644
--- a/code/game/objects/items/religion.dm
+++ b/code/game/objects/items/religion.dm
@@ -17,10 +17,9 @@
to_chat(H, "Your morale is increased by [user]'s banner!")
H.adjustBruteLoss(-15)
H.adjustFireLoss(-15)
- H.AdjustStunned(-2)
- H.AdjustWeakened(-2)
- H.AdjustParalysis(-2)
-
+ H.AdjustStun(-40)
+ H.AdjustKnockdown(-40)
+ H.AdjustUnconscious(-40)
/obj/item/weapon/banner/red
name = "red banner"
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index 03d7da109b2..8d6c74a83cd 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -13,8 +13,8 @@
/obj/item/borg/stun/attack(mob/living/M, mob/living/user)
if(ishuman(M))
var/mob/living/carbon/human/H = M
- if(H.check_shields(0, "[M]'s [name]", src, MELEE_ATTACK))
- playsound(M, 'sound/weapons/Genhit.ogg', 50, 1)
+ if(H.check_shields(src, 0, "[M]'s [name]", MELEE_ATTACK))
+ playsound(M, 'sound/weapons/genhit.ogg', 50, 1)
return FALSE
if(iscyborg(user))
var/mob/living/silicon/robot/R = user
@@ -22,14 +22,13 @@
return
user.do_attack_animation(M)
- M.Weaken(5)
+ M.Knockdown(100)
M.apply_effect(STUTTER, 5)
- M.Stun(5)
M.visible_message("[user] has prodded [M] with [src]!", \
"[user] has prodded you with [src]!")
- playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
+ playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
add_logs(user, M, "stunned", src, "(INTENT: [uppertext(user.a_intent)])")
@@ -111,7 +110,7 @@
"You bop [M] on the head!")
playsound(loc, 'sound/weapons/tap.ogg', 50, 1, -1)
if(2)
- if(!scooldown)
+ if(scooldown < world.time)
if(M.health >= 0)
if(ishuman(M)||ismonkey(M))
M.electrocute_act(5, "[user]", safety = 1)
@@ -128,11 +127,9 @@
"You shock [M] to no effect.")
playsound(loc, 'sound/effects/sparks2.ogg', 50, 1, -1)
user.cell.charge -= 500
- scooldown = TRUE
- spawn(20)
- scooldown = FALSE
+ scooldown = world.time + 20
if(3)
- if(!ccooldown)
+ if(ccooldown < world.time)
if(M.health >= 0)
if(ishuman(M))
user.visible_message("[user] crushes [M] in their grip!", \
@@ -143,9 +140,7 @@
playsound(loc, 'sound/weapons/smash.ogg', 50, 1, -1)
M.adjustBruteLoss(15)
user.cell.charge -= 300
- ccooldown = TRUE
- spawn(10)
- ccooldown = FALSE
+ ccooldown = world.time + 10
/obj/item/borg/cyborghug/peacekeeper
shockallowed = TRUE
@@ -158,10 +153,11 @@
icon_state = "charger_draw"
flags = NOBLUDGEON
var/mode = "draw"
- var/list/charge_machines = list(/obj/machinery/cell_charger, /obj/machinery/recharger,
- /obj/machinery/recharge_station, /obj/machinery/mech_bay_recharge_port)
- var/list/charge_items = list(/obj/item/weapon/stock_parts/cell, /obj/item/weapon/gun/energy,
- )
+ var/static/list/charge_machines = typecacheof(list(/obj/machinery/cell_charger, /obj/machinery/recharger, /obj/machinery/recharge_station, /obj/machinery/mech_bay_recharge_port))
+ var/static/list/charge_items = typecacheof(list(/obj/item/weapon/stock_parts/cell, /obj/item/weapon/gun/energy))
+
+/obj/item/borg/charger/Initialize()
+ . = ..()
/obj/item/borg/charger/update_icon()
..()
@@ -314,7 +310,7 @@
if(M.get_ear_protection() == FALSE)
M.confused += 6
audible_message("HUMAN HARM")
- playsound(get_turf(src), 'sound/AI/harmalarm.ogg', 70, 3)
+ playsound(get_turf(src), 'sound/ai/harmalarm.ogg', 70, 3)
cooldown = world.time + 200
log_game("[user.ckey]([user]) used a Cyborg Harm Alarm in ([user.x],[user.y],[user.z])")
if(iscyborg(user))
@@ -333,7 +329,7 @@
C.stuttering += 10
C.Jitter(10)
if(2)
- C.Weaken(2)
+ C.Knockdown(40)
C.confused += 10
C.stuttering += 15
C.Jitter(25)
@@ -509,7 +505,7 @@
//Peacekeeper Cyborg Projectile Dampenening Field
/obj/item/borg/projectile_dampen
name = "Hyperkinetic Dampening projector"
- desc = "A device that projects a dampening field that weakens kinetic energy above a certain threshold. Projects a field that drains power per second \
+ desc = "A device that projects a dampening field that weakenss kinetic energy above a certain threshold. Projects a field that drains power per second \
while active, that will weaken and slow damaging projectiles inside its field. Still being a prototype, it tends to induce a charge on ungrounded metallic surfaces."
icon = 'icons/obj/device.dmi'
icon_state = "shield"
@@ -582,6 +578,10 @@
. = ..()
host = loc
+/obj/item/borg/projectile_dampen/on_mob_death()
+ deactivate_field()
+ . = ..()
+
/obj/item/borg/projectile_dampen/process()
process_recharge()
process_usage()
diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm
index f3c2e6000fb..b681053a351 100644
--- a/code/game/objects/items/stacks/bscrystal.dm
+++ b/code/game/objects/items/stacks/bscrystal.dm
@@ -60,6 +60,7 @@
origin_tech = "bluespace=6;materials=3"
materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT)
attack_verb = list("bluespace polybashed", "bluespace polybattered", "bluespace polybludgeoned", "bluespace polythrashed", "bluespace polysmashed")
+ novariants = TRUE
var/crystal_type = /obj/item/weapon/ore/bluespace_crystal/refined
/obj/item/stack/sheet/bluespace_crystal/attack_self(mob/user)// to prevent the construction menu from ever happening
diff --git a/code/game/objects/items/stacks/cash.dm b/code/game/objects/items/stacks/cash.dm
index 50dd23b52c3..aa07367700b 100644
--- a/code/game/objects/items/stacks/cash.dm
+++ b/code/game/objects/items/stacks/cash.dm
@@ -1,6 +1,5 @@
-/obj/item/stack/spacecash
+/obj/item/stack/spacecash //Don't use base space cash stacks. Any other space cash stack can merge with them, and could cause potential money duping exploits.
name = "space cash"
- desc = "It's worth 1 credit."
singular_name = "bill"
icon = 'icons/obj/economy.dmi'
icon_state = "spacecash"
@@ -10,40 +9,63 @@
throw_speed = 2
throw_range = 2
w_class = WEIGHT_CLASS_TINY
+ full_w_class = WEIGHT_CLASS_TINY
resistance_flags = FLAMMABLE
- var/value = 1
+ var/value = 0
+
+/obj/item/stack/spacecash/Initialize()
+ . = ..()
+ update_desc()
+
+/obj/item/stack/spacecash/proc/update_desc()
+ var/total_worth = amount*value
+ desc = "It's worth [total_worth] credit[( amount > 1 ) ? "s" : ""]"
+
+
+/obj/item/stack/spacecash/merge(obj/item/stack/S)
+ . = ..()
+ update_desc()
+
+/obj/item/stack/spacecash/use()
+ . = ..()
+ update_desc()
+
+/obj/item/stack/spacecash/c1
+ icon_state = "spacecash"
+ singular_name = "one credit bill"
+ value = 1
/obj/item/stack/spacecash/c10
icon_state = "spacecash10"
- desc = "It's worth 10 credits."
+ singular_name = "ten credit bill"
value = 10
/obj/item/stack/spacecash/c20
icon_state = "spacecash20"
- desc = "It's worth 20 credits."
+ singular_name = "twenty credit bill"
value = 20
/obj/item/stack/spacecash/c50
icon_state = "spacecash50"
- desc = "It's worth 50 credits."
+ singular_name = "fifty credit bill"
value = 50
/obj/item/stack/spacecash/c100
icon_state = "spacecash100"
- desc = "It's worth 100 credits."
+ singular_name = "one hundred credit bill"
value = 100
/obj/item/stack/spacecash/c200
icon_state = "spacecash200"
- desc = "It's worth 200 credits."
+ singular_name = "two hundred credit bill"
value = 200
/obj/item/stack/spacecash/c500
icon_state = "spacecash500"
- desc = "It's worth 500 credits."
+ singular_name = "five hundred credit bill"
value = 500
/obj/item/stack/spacecash/c1000
icon_state = "spacecash1000"
- desc = "It's worth 1000 credits."
+ singular_name = "one thousand credit bill"
value = 1000
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 327afcb2a2b..51982d27bf6 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -5,11 +5,13 @@
amount = 6
max_amount = 6
w_class = WEIGHT_CLASS_TINY
+ full_w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
resistance_flags = FLAMMABLE
obj_integrity = 40
max_integrity = 40
+ novariants = FALSE
var/heal_brute = 0
var/heal_burn = 0
var/stop_bleeding = 0
diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm
index 2037c719184..c55ab4f6dd5 100644
--- a/code/game/objects/items/stacks/rods.dm
+++ b/code/game/objects/items/stacks/rods.dm
@@ -20,6 +20,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
max_amount = 50
attack_verb = list("hit", "bludgeoned", "whacked")
hitsound = 'sound/weapons/grenadelaunch.ogg'
+ novariants = TRUE
/obj/item/stack/rods/Initialize(mapload, new_amount, merge = TRUE)
..()
diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
index 74028f344a8..9e5b403aef3 100644
--- a/code/game/objects/items/stacks/sheets/glass.dm
+++ b/code/game/objects/items/stacks/sheets/glass.dm
@@ -210,4 +210,4 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \
"You slide on the broken glass!")
cooldown = world.time
- H.Weaken(3)
+ H.Knockdown(60)
diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm
index 41ee4dc7223..a9fcf349ca7 100644
--- a/code/game/objects/items/stacks/sheets/leather.dm
+++ b/code/game/objects/items/stacks/sheets/leather.dm
@@ -2,12 +2,14 @@
name = "hide"
desc = "Something went wrong."
origin_tech = "biotech=3"
+ novariants = TRUE
/obj/item/stack/sheet/animalhide/human
name = "human skin"
desc = "The by-product of human farming."
singular_name = "human skin piece"
icon_state = "sheet-hide"
+ novariants = FALSE
GLOBAL_LIST_INIT(human_recipes, list( \
new/datum/stack_recipe("bloated human costume", /obj/item/clothing/suit/hooded/bloated_human, 5, on_floor = 1), \
@@ -22,6 +24,7 @@ GLOBAL_LIST_INIT(human_recipes, list( \
desc = "A piece of skin."
singular_name = "skin piece"
icon_state = "sheet-hide"
+ novariants = FALSE
/obj/item/stack/sheet/animalhide/corgi
name = "corgi hide"
@@ -87,6 +90,7 @@ GLOBAL_LIST_INIT(xeno_recipes, list ( \
icon = 'icons/mob/alien.dmi'
icon_state = "chitin"
origin_tech = null
+ novariants = TRUE
/obj/item/xenos_claw
name = "alien claw"
@@ -153,6 +157,7 @@ GLOBAL_LIST_INIT(leather_recipes, list ( \
singular_name = "watcher sinew"
icon_state = "sinew"
origin_tech = "biotech=4"
+ novariants = TRUE
GLOBAL_LIST_INIT(sinew_recipes, list ( \
@@ -166,23 +171,27 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \
/*
* Plates
*/
-
/obj/item/stack/sheet/animalhide/goliath_hide
name = "goliath hide plates"
desc = "Pieces of a goliath's rocky hide, these might be able to make your suit a bit more durable to attack from the local fauna."
icon = 'icons/obj/mining.dmi'
icon_state = "goliath_hide"
singular_name = "hide plate"
+ max_amount = 6
+ novariants = FALSE
flags = NOBLUDGEON
w_class = WEIGHT_CLASS_NORMAL
layer = MOB_LAYER
+
/obj/item/stack/sheet/animalhide/ashdrake
name = "ash drake hide"
desc = "The strong, scaled hide of an ash drake."
icon = 'icons/obj/mining.dmi'
icon_state = "dragon_hide"
singular_name = "drake plate"
+ max_amount = 10
+ novariants = FALSE
flags = NOBLUDGEON
w_class = WEIGHT_CLASS_NORMAL
layer = MOB_LAYER
diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm
index 9514be618ce..0aaf5552c1c 100644
--- a/code/game/objects/items/stacks/sheets/mineral.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -68,6 +68,7 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \
singular_name = "sandbag"
layer = LOW_ITEM_LAYER
origin_tech = "materials=2"
+ novariants = TRUE
GLOBAL_LIST_INIT(sandbag_recipes, list ( \
new/datum/stack_recipe("sandbags", /obj/structure/barricade/sandbags, 1, time = 25, one_per_turf = 1, on_floor = 1), \
@@ -104,6 +105,7 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \
origin_tech = "materials=6"
sheettype = "diamond"
materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT)
+ novariants = TRUE
GLOBAL_LIST_INIT(diamond_recipes, list ( \
new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \
@@ -127,6 +129,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
origin_tech = "materials=5"
sheettype = "uranium"
materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT)
+ novariants = TRUE
GLOBAL_LIST_INIT(uranium_recipes, list ( \
new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \
@@ -237,6 +240,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
origin_tech = "materials=4"
sheettype = "clown"
materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT)
+ novariants = TRUE
GLOBAL_LIST_INIT(clown_recipes, list ( \
new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
@@ -355,6 +359,7 @@ GLOBAL_LIST_INIT(adamantine_recipes, list(
icon_state = "sheet-mythril"
singular_name = "mythril sheet"
origin_tech = "materials=4"
+ novariants = TRUE
/*
* Alien Alloy
@@ -370,7 +375,7 @@ GLOBAL_LIST_INIT(adamantine_recipes, list(
GLOBAL_LIST_INIT(abductor_recipes, list ( \
/* new/datum/stack_recipe("alien chair", /obj/structure/chair, one_per_turf = 1, on_floor = 1), \ */
new/datum/stack_recipe("alien bed", /obj/structure/bed/abductor, 2, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("alien locker", /obj/structure/closet/abductor, 1, time = 15, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("alien locker", /obj/structure/closet/abductor, 2, time = 15, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("alien table frame", /obj/structure/table_frame/abductor, 1, time = 15, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("alien airlock assembly", /obj/structure/door_assembly/door_assembly_abductor, 4, time = 20, one_per_turf = 1, on_floor = 1), \
null, \
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 3b9f5b45092..03f3c32b940 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -6,6 +6,7 @@
* Cloth
* Plastic
* Cardboard
+ * Paper Frames
* Runed Metal (cult)
* Brass (clockwork cult)
*/
@@ -14,31 +15,31 @@
* Metal
*/
GLOBAL_LIST_INIT(metal_recipes, list ( \
- new/datum/stack_recipe("stool", /obj/structure/chair/stool, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("bar stool", /obj/structure/chair/stool/bar, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("chair", /obj/structure/chair, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("swivel chair", /obj/structure/chair/office/dark, 5, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("comfy chair", /obj/structure/chair/comfy/beige, 2, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("stool", /obj/structure/chair/stool, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("bar stool", /obj/structure/chair/stool/bar, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("chair", /obj/structure/chair, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("swivel chair", /obj/structure/chair/office/dark, 5, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("comfy chair", /obj/structure/chair/comfy/beige, 2, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = TRUE, on_floor = TRUE), \
null, \
new/datum/stack_recipe("rack parts", /obj/item/weapon/rack_parts), \
- new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
null, \
- new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
null, \
new/datum/stack_recipe("floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20), \
new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60), \
null, \
- new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
null, \
- new/datum/stack_recipe("computer frame", /obj/structure/frame/computer, 5, time = 25, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("modular console", /obj/machinery/modular_computer/console/buildable/, 10, time = 25, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("machine frame", /obj/structure/frame/machine, 5, time = 25, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("firelock frame", /obj/structure/firelock_frame, 3, time = 50, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("meatspike frame", /obj/structure/kitchenspike_frame, 5, time = 25, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("reflector frame", /obj/structure/reflector, 5, time = 25, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("computer frame", /obj/structure/frame/computer, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("modular console", /obj/machinery/modular_computer/console/buildable/, 10, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("machine frame", /obj/structure/frame/machine, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("firelock frame", /obj/structure/firelock_frame, 3, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("meatspike frame", /obj/structure/kitchenspike_frame, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("reflector frame", /obj/structure/reflector, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE), \
null, \
new/datum/stack_recipe("grenade casing", /obj/item/weapon/grenade/chem_grenade), \
new/datum/stack_recipe("light fixture frame", /obj/item/wallframe/light_fixture, 2), \
@@ -50,8 +51,8 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
new/datum/stack_recipe("extinguisher cabinet frame", /obj/item/wallframe/extinguisher_cabinet, 2), \
new/datum/stack_recipe("button frame", /obj/item/wallframe/button, 1), \
null, \
- new/datum/stack_recipe("iron door", /obj/structure/mineral_door/iron, 20, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("floodlight frame", /obj/structure/floodlight_frame, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("iron door", /obj/structure/mineral_door/iron, 20, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("floodlight frame", /obj/structure/floodlight_frame, 5, one_per_turf = TRUE, on_floor = TRUE), \
))
/obj/item/stack/sheet/metal
@@ -96,7 +97,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
* Plasteel
*/
GLOBAL_LIST_INIT(plasteel_recipes, list ( \
- new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = 1), \
+ new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = TRUE), \
new/datum/stack_recipe("bomb assembly", /obj/machinery/syndicatebomb/empty, 10, time = 50), \
))
@@ -133,21 +134,23 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
new/datum/stack_recipe("wood table frame", /obj/structure/table_frame/wood, 2, time = 10), \
new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), \
new/datum/stack_recipe("rolling pin", /obj/item/weapon/kitchen/rollingpin, 2, time = 30), \
- new/datum/stack_recipe("wooden chair", /obj/structure/chair/wood/, 3, time = 10, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("winged wooden chair", /obj/structure/chair/wood/wings, 3, time = 10, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("book case", /obj/structure/bookcase, 4, time = 15, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("drying rack", /obj/machinery/smartfridge/drying_rack, 10, time = 15, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("dog bed", /obj/structure/bed/dogbed, 10, time = 10, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("wooden chair", /obj/structure/chair/wood/, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("winged wooden chair", /obj/structure/chair/wood/wings, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("book case", /obj/structure/bookcase, 4, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("drying rack", /obj/machinery/smartfridge/drying_rack, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("dog bed", /obj/structure/bed/dogbed, 10, time = 10, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("dresser", /obj/structure/dresser, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("picture frame", /obj/item/wallframe/picture, 1, time = 10),\
- new/datum/stack_recipe("display case chassis", /obj/structure/displaycase_chassis, 5, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("display case chassis", /obj/structure/displaycase_chassis, 5, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("wooden buckler", /obj/item/weapon/shield/riot/buckler, 20, time = 40), \
new/datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50),\
new/datum/stack_recipe("tiki mask", /obj/item/clothing/mask/gas/tiki_mask, 2), \
new/datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10),\
- new/datum/stack_recipe("ore box", /obj/structure/ore_box, 4, time = 50, one_per_turf = 1, on_floor = 1),\
+ new/datum/stack_recipe("ore box", /obj/structure/ore_box, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE),\
+ new/datum/stack_recipe("wooden crate", /obj/structure/closet/crate/wooden, 6, time = 50, one_per_turf = TRUE, on_floor = TRUE),\
new/datum/stack_recipe("baseball bat", /obj/item/weapon/melee/baseball_bat, 5, time = 15),\
))
@@ -162,6 +165,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0)
resistance_flags = FLAMMABLE
merge_type = /obj/item/stack/sheet/mineral/wood
+ novariants = TRUE
/obj/item/stack/sheet/mineral/wood/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.wood_recipes
@@ -178,7 +182,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
new/datum/stack_recipe("black shoes", /obj/item/clothing/shoes/sneakers/black, 2), \
null, \
new/datum/stack_recipe("backpack", /obj/item/weapon/storage/backpack, 4), \
- new/datum/stack_recipe("dufflebag", /obj/item/weapon/storage/backpack/dufflebag, 6), \
+ new/datum/stack_recipe("duffel bag", /obj/item/weapon/storage/backpack/duffelbag, 6), \
null, \
new/datum/stack_recipe("plant bag", /obj/item/weapon/storage/bag/plants, 4), \
new/datum/stack_recipe("book bag", /obj/item/weapon/storage/bag/books, 4), \
@@ -239,6 +243,7 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
origin_tech = "materials=1"
resistance_flags = FLAMMABLE
merge_type = /obj/item/stack/sheet/cardboard
+ novariants = TRUE
/obj/item/stack/sheet/cardboard/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.cardboard_recipes
@@ -252,12 +257,12 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
*/
GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
- new/datum/stack_recipe("runed door", /obj/machinery/door/airlock/cult, 1, time = 50, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("runed girder", /obj/structure/girder/cult, 1, time = 50, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("pylon", /obj/structure/destructible/cult/pylon, 4, time = 40, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("forge", /obj/structure/destructible/cult/forge, 3, time = 40, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("archives", /obj/structure/destructible/cult/tome, 3, time = 40, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("altar", /obj/structure/destructible/cult/talisman, 3, time = 40, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("runed door", /obj/machinery/door/airlock/cult, 1, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("runed girder", /obj/structure/girder/cult, 1, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("pylon", /obj/structure/destructible/cult/pylon, 4, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("forge", /obj/structure/destructible/cult/forge, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("archives", /obj/structure/destructible/cult/tome, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("altar", /obj/structure/destructible/cult/talisman, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
))
/obj/item/stack/sheet/runed_metal
@@ -268,6 +273,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
icon = 'icons/obj/items.dmi'
sheettype = "runed"
merge_type = /obj/item/stack/sheet/runed_metal
+ novariants = TRUE
/obj/item/stack/sheet/runed_metal/ratvar_act()
new /obj/item/stack/tile/brass(loc, amount)
@@ -322,6 +328,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
throw_speed = 1
throw_range = 3
turf_type = /turf/open/floor/clockwork
+ novariants = FALSE
/obj/item/stack/tile/brass/narsie_act()
new /obj/item/stack/sheet/runed_metal(loc, amount)
@@ -339,6 +346,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
singular_name = "lesser gem"
icon_state = "sheet-lessergem"
origin_tech = "materials=4"
+ novariants = TRUE
/obj/item/stack/sheet/greatergem
@@ -347,6 +355,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
singular_name = "greater gem"
icon_state = "sheet-greatergem"
origin_tech = "materials=7"
+ novariants = TRUE
/*
* Bones
@@ -359,13 +368,14 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
desc = "Someone's been drinking their milk."
force = 7
throwforce = 5
+ max_amount = 12
w_class = WEIGHT_CLASS_NORMAL
throw_speed = 1
throw_range = 3
origin_tech = "materials=2;biotech=2"
GLOBAL_LIST_INIT(plastic_recipes, list(
- new /datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = 1, on_floor = 1, time = 40), \
+ new /datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \
new /datum/stack_recipe("water bottle", /obj/item/weapon/reagent_containers/glass/beaker/waterbottle/empty), \
new /datum/stack_recipe("large water bottle", /obj/item/weapon/reagent_containers/glass/beaker/waterbottle/large/empty,3), \
new /datum/stack_recipe("wet floor sign", /obj/item/weapon/caution, 2)))
@@ -389,3 +399,26 @@ GLOBAL_LIST_INIT(plastic_recipes, list(
/obj/item/stack/sheet/plastic/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.plastic_recipes
. = ..()
+
+GLOBAL_LIST_INIT(paperframe_recipes, list(
+new /datum/stack_recipe("paper frame separator", /obj/structure/window/paperframe, 2, one_per_turf = TRUE, on_floor = TRUE, time = 10), \
+new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperframe, 3, one_per_turf = TRUE, on_floor = TRUE, time = 10 )))
+
+/obj/item/stack/sheet/paperframes
+ name = "paper frames"
+ desc = "A thin wooden frame with paper attached."
+ singular_name = "paper frame"
+ icon_state = "sheet-paper"
+ origin_tech = "materials=1"
+ merge_type = /obj/item/stack/sheet/paperframes
+ resistance_flags = FLAMMABLE
+
+/obj/item/stack/sheet/paperframes/Initialize()
+ recipes = GLOB.paperframe_recipes
+ . = ..()
+/obj/item/stack/sheet/paperframes/five
+ amount = 5
+/obj/item/stack/sheet/paperframes/twenty
+ amount = 20
+/obj/item/stack/sheet/paperframes/fifty
+ amount = 50
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/sheets/sheets.dm b/code/game/objects/items/stacks/sheets/sheets.dm
index 0d5ab1020ac..24de1bee5ef 100644
--- a/code/game/objects/items/stacks/sheets/sheets.dm
+++ b/code/game/objects/items/stacks/sheets/sheets.dm
@@ -1,11 +1,12 @@
/obj/item/stack/sheet
name = "sheet"
- w_class = WEIGHT_CLASS_NORMAL
+ full_w_class = WEIGHT_CLASS_NORMAL
force = 5
throwforce = 5
max_amount = 50
throw_speed = 1
throw_range = 3
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
+ novariants = FALSE
var/perunit = MINERAL_MATERIAL_AMOUNT
var/sheettype = null //this is used for girders in the creation of walls/false walls
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index e5f90262574..381b69b44f7 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -18,6 +18,8 @@
var/datum/robot_energy_storage/source
var/cost = 1 // How much energy from storage it costs
var/merge_type = null // This path and its children should merge with this stack, defaults to src.type
+ var/full_w_class = WEIGHT_CLASS_NORMAL //The weight class the stack should have at amount > 2/3rds max_amount
+ var/novariants = TRUE //Determines whether the item should update it's sprites based on amount.
/obj/item/stack/Initialize(mapload, new_amount=null , merge = TRUE)
..()
@@ -29,6 +31,28 @@
for(var/obj/item/stack/S in loc)
if(S.merge_type == merge_type)
merge(S)
+ update_weight()
+ update_icon()
+
+/obj/item/stack/proc/update_weight()
+ if(amount <= (max_amount * (1/3)))
+ w_class = Clamp(full_w_class-2, WEIGHT_CLASS_TINY, full_w_class)
+ else if (amount <= (max_amount * (2/3)))
+ w_class = Clamp(full_w_class-1, WEIGHT_CLASS_TINY, full_w_class)
+ else
+ w_class = full_w_class
+
+/obj/item/stack/update_icon()
+ if(novariants)
+ return ..()
+ if(amount <= (max_amount * (1/3)))
+ icon_state = initial(icon_state)
+ else if (amount <= (max_amount * (2/3)))
+ icon_state = "[initial(icon_state)]_2"
+ else
+ icon_state = "[initial(icon_state)]_3"
+ ..()
+
/obj/item/stack/Destroy()
if (usr && usr.machine==src)
@@ -188,6 +212,7 @@
amount -= used
zero_amount()
update_icon()
+ update_weight()
return 1
/obj/item/stack/proc/zero_amount()
@@ -204,6 +229,7 @@
else
src.amount += amount
update_icon()
+ update_weight()
/obj/item/stack/proc/merge(obj/item/stack/S) //Merge src into S, as much as possible
if(QDELETED(S) || QDELETED(src) || S == src) //amusingly this can cause a stack to consume itself, let's not allow that.
@@ -243,13 +269,15 @@
return
if(!in_range(src, user))
return
+ if(is_cyborg)
+ return
else
if(zero_amount())
return
//get amount from user
var/min = 0
var/max = src.get_amount()
- var/stackmaterial = round(input(user,"How many sheets do you wish to take out of this stack? (Maximum [max]") as num)
+ var/stackmaterial = round(input(user,"How many sheets do you wish to take out of this stack? (Maximum [max])") as num)
if(stackmaterial == null || stackmaterial <= min || stackmaterial >= src.get_amount())
return
else
diff --git a/code/game/objects/items/stacks/telecrystal.dm b/code/game/objects/items/stacks/telecrystal.dm
index dec6074b0c1..8555155306d 100644
--- a/code/game/objects/items/stacks/telecrystal.dm
+++ b/code/game/objects/items/stacks/telecrystal.dm
@@ -20,11 +20,18 @@
/obj/item/stack/telecrystal/afterattack(obj/item/I, mob/user, proximity)
if(!proximity)
return
- if(istype(I, /obj/item))
- if(I.hidden_uplink && I.hidden_uplink.active) //No metagaming by using this on every PDA around just to see if it gets used up.
- I.hidden_uplink.telecrystals += amount
- use(amount)
- to_chat(user, "You slot [src] into the [I] and charge its internal uplink.")
+ if(istype(I, /obj/item) && I.hidden_uplink && I.hidden_uplink.active) //No metagaming by using this on every PDA around just to see if it gets used up.
+ I.hidden_uplink.telecrystals += amount
+ use(amount)
+ to_chat(user, "You slot [src] into the [I] and charge its internal uplink.")
+ else if(istype(I, /obj/item/weapon/cartridge/virus/frame))
+ var/obj/item/weapon/cartridge/virus/frame/cart = I
+ if(!cart.charges)
+ to_chat(user, "The [cart] is out of charges, it's refusing to accept the [src]")
+ return
+ cart.telecrystals += amount
+ use(amount)
+ to_chat(user, "You slot [src] into the [cart]. The next time it's used, it will also give telecrystals")
/obj/item/stack/telecrystal/five
amount = 5
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
index 233bf506a23..fece24cb227 100644
--- a/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -12,6 +12,7 @@
origin_tech = "materials=1"
var/turf_type = null
var/mineralType = null
+ novariants = TRUE
/obj/item/stack/tile/Initialize(mapload, amount)
. = ..()
diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm
new file mode 100644
index 00000000000..ec82a376ade
--- /dev/null
+++ b/code/game/objects/items/theft_tools.dm
@@ -0,0 +1,243 @@
+//Items for nuke theft, supermatter theft traitor objective
+
+
+// STEALING THE NUKE
+
+//the nuke core - objective item
+/obj/item/nuke_core
+ name = "plutonium core"
+ desc = "Extremely radioactive. Wear goggles."
+ icon = 'icons/obj/nuke_tools.dmi'
+ icon_state = "plutonium_core"
+ item_state = "plutoniumcore"
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
+ var/pulse = 0
+ var/cooldown = 0
+ var/pulseicon = "plutonium_core_pulse"
+
+/obj/item/nuke_core/Initialize()
+ . = ..()
+ START_PROCESSING(SSobj, src)
+
+/obj/item/nuke_core/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ return ..()
+
+/obj/item/nuke_core/attackby(obj/item/nuke_core_container/container, mob/user)
+ if(istype(container))
+ container.load(src, user)
+ else
+ return ..()
+
+/obj/item/nuke_core/process()
+ if(cooldown < world.time - 60)
+ cooldown = world.time
+ flick(pulseicon, src)
+ radiation_pulse(get_turf(src), 1, 4, 40, 1)
+
+//nuke core box, for carrying the core
+/obj/item/nuke_core_container
+ name = "nuke core container"
+ desc = "Solid container for radioactive objects."
+ icon = 'icons/obj/nuke_tools.dmi'
+ icon_state = "core_container_empty"
+ item_state = "tile"
+ var/obj/item/nuke_core/core
+
+/obj/item/nuke_core_container/Destroy()
+ QDEL_NULL(core)
+ return ..()
+
+/obj/item/nuke_core_container/proc/load(obj/item/nuke_core/ncore, mob/user)
+ if(core || !istype(ncore))
+ return FALSE
+ ncore.forceMove(src)
+ core = ncore
+ icon_state = "core_container_loaded"
+ to_chat(user, "Container is sealing...")
+ addtimer(CALLBACK(src, .proc/seal), 50)
+ return TRUE
+
+/obj/item/nuke_core_container/proc/seal()
+ if(istype(core))
+ STOP_PROCESSING(SSobj, core)
+ icon_state = "core_container_sealed"
+ playsound(src, 'sound/items/deconstruct.ogg', 60, 1)
+ if(ismob(loc))
+ to_chat(loc, "[src] is permanently sealed, [core]'s radiation is contained.")
+
+/obj/item/nuke_core_container/attackby(obj/item/nuke_core/core, mob/user)
+ if(istype(core))
+ if(!user.temporarilyRemoveItemFromInventory(core))
+ to_chat(user, "The [core] is stuck to your hand!")
+ return
+ else
+ load(core, user)
+ else
+ return ..()
+
+//snowflake screwdriver, works as a key to start nuke theft, traitor only
+/obj/item/weapon/screwdriver/nuke
+ name = "screwdriver"
+ desc = "A screwdriver with an ultra thin tip."
+ icon = 'icons/obj/nuke_tools.dmi'
+ icon_state = "screwdriver_nuke"
+ toolspeed = 0.5
+
+/obj/item/weapon/paper/nuke_instructions
+ info = "How to break into a Nanotrasen self-destruct terminal and remove its plutonium core: \
+
\
+
Use a screwdriver with a very thin tip (provided) to unscrew the terminal's front panel
\
+
Dislodge and remove the front panel with a crowbar
\
+
Cut the inner metal plate with a welding tool
\
+
Pry off the inner plate with a crowbar to expose the radioactive core
\
+
Use the core container to remove the plutonium core; the container will take some time to seal
\
+
???
\
+
"
+
+// STEALING SUPERMATTER
+
+/obj/item/weapon/paper/supermatter_sliver_instructions
+ info = "How to safely extract a supermatter sliver: \
+
\
+
Approach an active supermatter crystal with proper protective gear. DO NOT MAKE PHYSICAL CONTACT.
\
+
Use a supermatter scalpel (provided) to slice off a sliver of the crystal.
\
+
Use supermatter extraction tongs (also provided) to safely remove the sliver.
\
+
Physical contact of any object with the sliver will dust the object, as well as yourself.
\
+
Use the tongs to place the sliver into the provided container, which will take some time to seal
\
+
Get the hell out before the crystal delaminates.
\
+
???
\
+
"
+
+/obj/item/nuke_core/supermatter_sliver
+ name = "supermatter sliver"
+ desc = "A tiny, highly volatile sliver of a supermatter crystal. Do not handle without protection!"
+ icon_state = "supermatter_sliver"
+ item_state = "supermattersliver"
+ pulseicon = "supermatter_sliver_pulse"
+
+/obj/item/nuke_core/supermatter_sliver/attack_tk() // no TK dusting memes
+ return FALSE
+
+/obj/item/nuke_core/supermatter_sliver/can_be_pulled(user) // no drag memes
+ return FALSE
+
+/obj/item/nuke_core/supermatter_sliver/attackby(obj/item/W, mob/living/user, params)
+ if(istype(W, /obj/item/weapon/hemostat/supermatter))
+ var/obj/item/weapon/hemostat/supermatter/tongs = W
+ if (tongs.sliver)
+ to_chat(user, "\The [tongs] is already holding a supermatter sliver!")
+ return FALSE
+ forceMove(tongs)
+ tongs.sliver = src
+ tongs.icon_state = "supermatter_tongs_loaded"
+ to_chat(user, "You carefully pick up [src] with [tongs].")
+ else if(istype(W, /obj/item/weapon/scalpel/supermatter) || istype(W, /obj/item/nuke_core_container/supermatter/)) // we don't want it to dust
+ return
+ else
+ to_chat(user, "As it touches \the [src], both \the [src] and \the [W] burst into dust!")
+ radiation_pulse(get_turf(user), 1, 2, 10, 1)
+ playsound(src, 'sound/effects/supermatter.ogg', 50, 1)
+ qdel(W)
+ qdel(src)
+
+/obj/item/nuke_core/supermatter_sliver/pickup(mob/living/user)
+ ..()
+ if(!iscarbon(user))
+ return FALSE
+ var/mob/ded = user
+ to_chat(user, "You reach for the supermatter sliver with your hands. That was dumb.")
+ radiation_pulse(get_turf(user), 2, 4, 50, 1)
+ playsound(get_turf(user), 'sound/effects/supermatter.ogg', 50, 1)
+ ded.dust()
+
+/obj/item/nuke_core_container/supermatter
+ name = "supermatter bin"
+ desc = "A tiny receptacle that releases an inert freon mix upon sealing, allowing a sliver of a supermatter crystal to be safely stored.."
+ var/obj/item/nuke_core/supermatter_sliver/sliver
+
+/obj/item/nuke_core_container/supermatter/Destroy()
+ QDEL_NULL(sliver)
+ return ..()
+
+/obj/item/nuke_core_container/supermatter/load(obj/item/weapon/hemostat/supermatter/T, mob/user)
+ if(!istype(T) || !T.sliver)
+ return FALSE
+ T.sliver.forceMove(src)
+ sliver = T.sliver
+ T.sliver = null
+ icon_state = "core_container_loaded"
+ to_chat(user, "Container is sealing...")
+ addtimer(CALLBACK(src, .proc/seal), 50)
+ return TRUE
+
+/obj/item/nuke_core_container/supermatter/seal()
+ if(istype(sliver))
+ STOP_PROCESSING(SSobj, sliver)
+ icon_state = "core_container_sealed"
+ playsound(src, 'sound/items/Deconstruct.ogg', 60, 1)
+ if(ismob(loc))
+ to_chat(loc, "[src] is permanently sealed, [sliver] is safely contained.")
+
+/obj/item/nuke_core_container/supermatter/attackby(obj/item/weapon/hemostat/supermatter/tongs, mob/user)
+ if(istype(tongs))
+ if(!user.temporarilyRemoveItemFromInventory(tongs))
+ to_chat(user, "\The [tongs] is stuck to your hand!")
+ else
+ load(sliver, user)
+ else
+ return ..()
+
+/obj/item/weapon/scalpel/supermatter
+ name = "supermatter scalpel"
+ desc = "A scalpel with a tip of condensed freon gas, searingly cold to the touch, that can safely shave a sliver off a supermatter crystal."
+ icon = 'icons/obj/nuke_tools.dmi'
+ icon_state = "supermatter_scalpel"
+ toolspeed = 0.5
+ damtype = "fire"
+ usesound = 'sound/weapons/bladeslice.ogg'
+
+/obj/item/weapon/hemostat/supermatter
+ name = "supermatter extraction tongs"
+ desc = "A pair of tongs made from condensed freon gas, searingly cold to the touch, that can safely grip a supermatter sliver."
+ icon = 'icons/obj/nuke_tools.dmi'
+ icon_state = "supermatter_tongs"
+ toolspeed = 0.75
+ damtype = "fire"
+ var/obj/item/nuke_core/supermatter_sliver/sliver
+
+/obj/item/weapon/hemostat/supermatter/Destroy()
+ QDEL_NULL(sliver)
+ return ..()
+
+/obj/item/weapon/hemostat/supermatter/afterattack(atom/O, mob/user, proximity)
+ if(!sliver)
+ return
+ if(ismovableatom(O))
+ Consume(O)
+
+/obj/item/weapon/hemostat/supermatter/throw_impact(atom/hit_atom) // no instakill supermatter javelins
+ if(sliver)
+ sliver.forceMove(loc)
+ to_chat(usr, "\The [sliver] falls out of \the [src] as you throw them.")
+ sliver = null
+ ..()
+
+/obj/item/weapon/hemostat/supermatter/proc/Consume(atom/movable/AM, mob/user)
+ if(ismob(AM))
+ var/mob/victim = AM
+ victim.dust()
+ message_admins("[src] has consumed [key_name_admin(victim)] [ADMIN_JMP(src)].")
+ investigate_log("has consumed [key_name(victim)].", "supermatter")
+ else
+ investigate_log("has consumed [AM].", "supermatter")
+ qdel(AM)
+ user.visible_message("As [user] touches \the [AM] with \a [src], silence fills the room...",\
+ "You touch \the [AM] with \the [src], and everything suddenly goes silent.\n\The [AM] flashes into dust, and soon as you can register this, you do as well.",\
+ "Everything suddenly goes silent.")
+ radiation_pulse(get_turf(user), 2, 4, 50, 1)
+ playsound(src, 'sound/effects/supermatter.ogg', 50, 1)
+ user.dust()
+ icon_state = "supermatter_tongs"
+ QDEL_NULL(sliver)
+
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 69e00e057eb..5472fc10e7f 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -181,7 +181,7 @@
user.show_message("*click*", 2)
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
return
- playsound(user, 'sound/weapons/Gunshot.ogg', 100, 1)
+ playsound(user, 'sound/weapons/gunshot.ogg', 100, 1)
src.bullets--
user.visible_message("[user] fires [src] at [target]!", \
"You fire [src] at [target]!", \
@@ -316,7 +316,7 @@
origin_tech = null
attack_verb = list("attacked", "struck", "hit")
-/obj/item/weapon/twohanded/dualsaber/toy/hit_reaction()
+/obj/item/weapon/twohanded/dualsaber/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
/obj/item/weapon/twohanded/dualsaber/toy/IsReflect()//Stops Toy Dualsabers from reflecting energy projectiles
@@ -521,7 +521,7 @@
return list(pick(messages))
/obj/item/toy/talking/proc/toy_talk(mob/user, message)
- user.loc.visible_message("\icon[src] [message]")
+ user.loc.visible_message("[bicon(src)] [message]")
if(chattering)
chatter(message, phomeme, user)
@@ -947,7 +947,7 @@
user.visible_message("[user] presses a button on [src].", "You activate [src], it plays a loud noise!", "You hear the click of a button.")
sleep(5)
icon_state = "nuketoy"
- playsound(src, 'sound/machines/Alarm.ogg', 100, 0, surround = 0)
+ playsound(src, 'sound/machines/alarm.ogg', 100, 0, surround = 0)
sleep(135)
icon_state = "nuketoycool"
sleep(cooldown - world.time)
@@ -1077,7 +1077,7 @@
user.visible_message("[user] pulls back the string on [src].")
icon_state = "[initial(icon_state)]_used"
sleep(5)
- audible_message("\icon[src] Hiss!")
+ audible_message("[bicon(src)] Hiss!")
var/list/possible_sounds = list('sound/voice/hiss1.ogg', 'sound/voice/hiss2.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss4.ogg')
var/chosen_sound = pick(possible_sounds)
playsound(get_turf(src), chosen_sound, 50, 1)
@@ -1270,7 +1270,7 @@
name = "Wizard action figure"
icon_state = "wizard"
toysay = "Ei Nath!"
- toysound = 'sound/magic/Disintegrate.ogg'
+ toysound = 'sound/magic/disintegrate.ogg'
/obj/item/toy/figure/rd
name = "Research Director action figure"
diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm
index c75b4c7d743..b880cf43af8 100644
--- a/code/game/objects/items/weapons/AI_modules.dm
+++ b/code/game/objects/items/weapons/AI_modules.dm
@@ -523,7 +523,7 @@ AI MODULES
laws[1] = generate_ion_law()
to_chat(user, "You press the button on [src].")
playsound(user, 'sound/machines/click.ogg', 20, 1)
- src.loc.visible_message("\icon[src] [laws[1]]")
+ src.loc.visible_message("[bicon(src)] [laws[1]]")
/******************** Mother Drone ******************/
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index 1cbbf378461..eccb7d9635d 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -78,7 +78,7 @@ obj/item/weapon/construction
return 0
/obj/item/weapon/construction/proc/activate()
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
/obj/item/weapon/construction/attack_self(mob/user)
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
@@ -125,8 +125,8 @@ obj/item/weapon/construction
var/canRturf = 0
var/ranged = FALSE
var/airlock_type = /obj/machinery/door/airlock
+ var/airlock_glass = FALSE // So the floor's rcd_act knows how much ammo to use
var/window_type = /obj/structure/window/fulltile
-
var/advanced_airlock_setting = 1 //Set to 1 if you want more paintjobs available
var/list/conf_access = null
var/use_one_access = 0 //If the airlock should require ALL or only ONE of the listed accesses.
@@ -266,8 +266,10 @@ obj/item/weapon/construction
airlock_type = /obj/machinery/door/airlock/external
if("High Security")
airlock_type = /obj/machinery/door/airlock/highsecurity
+ airlock_glass = FALSE
else
airlock_type = /obj/machinery/door/airlock
+ airlock_glass = FALSE
if("Glass")
if(advanced_airlock_setting == 1)
@@ -289,10 +291,13 @@ obj/item/weapon/construction
airlock_type = /obj/machinery/door/airlock/glass_research
if("Mining")
airlock_type = /obj/machinery/door/airlock/glass_mining
+ airlock_glass = TRUE
else
airlock_type = /obj/machinery/door/airlock/glass
+ airlock_glass = TRUE
else
airlock_type = /obj/machinery/door/airlock
+ airlock_glass = FALSE
/obj/item/weapon/construction/rcd/proc/rcd_create(atom/A, mob/user)
diff --git a/code/game/objects/items/weapons/RPD.dm b/code/game/objects/items/weapons/RPD.dm
index bff92ea9c68..8c13ba2a686 100644
--- a/code/game/objects/items/weapons/RPD.dm
+++ b/code/game/objects/items/weapons/RPD.dm
@@ -170,7 +170,7 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
/obj/item/weapon/pipe_dispenser/suicide_act(mob/user)
user.visible_message("[user] points the end of the RPD down [user.p_their()] throat and presses a button! It looks like [user.p_theyre()] trying to commit suicide...")
playsound(get_turf(user), 'sound/machines/click.ogg', 50, 1)
- playsound(get_turf(user), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(user), 'sound/items/deconstruct.ogg', 50, 1)
return(BRUTELOSS)
/obj/item/weapon/pipe_dispenser/proc/render_dir_img(_dir,pic,title,flipped=0)
@@ -594,7 +594,7 @@ GLOBAL_LIST_INIT(RPD_recipes, list(
/obj/item/weapon/pipe_dispenser/proc/activate()
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
#undef PIPE_BINARY
#undef PIPE_BENT
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 0240461878c..4c4db38fdf0 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -100,7 +100,7 @@
update_label()
/obj/item/weapon/card/id/attack_self(mob/user)
- user.visible_message("[user] shows you: \icon[src] [src.name].", \
+ user.visible_message("[user] shows you: [bicon(src)] [src.name].", \
"You show \the [src.name].")
src.add_fingerprint(user)
return
@@ -256,14 +256,6 @@ update_label("John Doe", "Clowny")
access = get_all_accesses()+get_ert_access("med")-GLOB.access_change_ids
..()
-/obj/item/weapon/card/id/marine
- name = "\improper Marine ID"
- desc = "A Marine Rifleman ID card"
- access = list(GLOB.access_away_generic1)
- icon_state = "centcom"
- registered_name = "Iron Hawk Marine"
- assignment = "Marine Rifleman"
-
/obj/item/weapon/card/id/prisoner
name = "prisoner ID card"
desc = "You are a number, you are not a free man."
diff --git a/code/game/objects/items/charter.dm b/code/game/objects/items/weapons/charter.dm
similarity index 87%
rename from code/game/objects/items/charter.dm
rename to code/game/objects/items/weapons/charter.dm
index 36efee00922..5f45ecfda4e 100644
--- a/code/game/objects/items/charter.dm
+++ b/code/game/objects/items/weapons/charter.dm
@@ -1,6 +1,6 @@
#define STATION_RENAME_TIME_LIMIT 3000
-/obj/item/station_charter
+/obj/item/weapon/station_charter
name = "station charter"
icon = 'icons/obj/wizard.dmi'
icon_state = "scroll2"
@@ -16,7 +16,7 @@
var/static/regex/standard_station_regex
-/obj/item/station_charter/New()
+/obj/item/weapon/station_charter/Initialize()
. = ..()
if(!standard_station_regex)
var/prefixes = jointext(GLOB.station_prefixes, "|")
@@ -26,13 +26,7 @@
var/regexstr = "(([prefixes]) )?(([names]) ?)([suffixes]) ([numerals])"
standard_station_regex = new(regexstr)
-/obj/item/station_charter/Destroy()
- if(response_timer_id)
- deltimer(response_timer_id)
- response_timer_id = null
- . = ..()
-
-/obj/item/station_charter/attack_self(mob/living/user)
+/obj/item/weapon/station_charter/attack_self(mob/living/user)
if(used)
to_chat(user, "The [name_type] has already been named.")
return
@@ -48,6 +42,10 @@
rejected by your employers, while names using the standard format, \
will automatically be accepted.", max_length=MAX_CHARTER_LEN)
+ if(response_timer_id)
+ to_chat(user, "You're still waiting for approval from your employers about your proposed name change, it'd be best to wait for now.")
+ return
+
if(!new_name)
return
log_game("[key_name(user)] has proposed to name the station as \
@@ -63,7 +61,7 @@
response_timer_id = addtimer(CALLBACK(src, .proc/rename_station, new_name, user.name, user.real_name, key_name(user)), approval_time, TIMER_STOPPABLE)
to_chat(GLOB.admins, "CUSTOM STATION RENAME:[ADMIN_LOOKUPFLW(user)] proposes to rename the [name_type] to [new_name] (will autoapprove in [approval_time / 10] seconds). [ADMIN_SMITE(user)] (REJECT) [ADMIN_CENTCOM_REPLY(user)]")
-/obj/item/station_charter/proc/reject_proposed(user)
+/obj/item/weapon/station_charter/proc/reject_proposed(user)
if(!user)
return
if(!response_timer_id)
@@ -79,7 +77,7 @@
deltimer(response_timer_id)
response_timer_id = null
-/obj/item/station_charter/proc/rename_station(designation, uname, ureal_name, ukey)
+/obj/item/weapon/station_charter/proc/rename_station(designation, uname, ureal_name, ukey)
set_station_name(designation)
minor_announce("[ureal_name] has designated your station as [station_name()]", "Captain's Charter", 0)
log_game("[ukey] has renamed the station as [station_name()].")
@@ -91,7 +89,7 @@
if(!unlimited_uses)
used = TRUE
-/obj/item/station_charter/admin
+/obj/item/weapon/station_charter/admin
unlimited_uses = TRUE
ignores_timeout = TRUE
@@ -99,14 +97,14 @@
/obj/item/weapon/station_charter/flag
name = "nanotrasen banner"
icon = 'icons/obj/items.dmi'
- var/name_type = "planet"
+ name_type = "planet"
icon_state = "banner"
item_state = "banner"
desc = "A cunning device used to claim ownership of planets."
w_class = 5
force = 15
-/obj/item/station_charter/flag/rename_station(designation, uname, ureal_name, ukey)
+/obj/item/weapon/station_charter/flag/rename_station(designation, uname, ureal_name, ukey)
set_station_name(designation)
minor_announce("[ureal_name] has designated the planet as [station_name()]", "Captain's Banner", 0)
log_game("[ukey] has renamed the planet as [station_name()].")
@@ -116,6 +114,4 @@
if(!unlimited_uses)
used = TRUE
-
-
#undef STATION_RENAME_TIME_LIMIT
diff --git a/code/game/objects/items/weapons/chrono_eraser.dm b/code/game/objects/items/weapons/chrono_eraser.dm
index 86664404d18..1939bf6499c 100644
--- a/code/game/objects/items/weapons/chrono_eraser.dm
+++ b/code/game/objects/items/weapons/chrono_eraser.dm
@@ -209,7 +209,7 @@
qdel(captured)
qdel(src)
else
- captured.Paralyse(4)
+ captured.Unconscious(80)
if(captured.loc != src)
captured.loc = src
update_icon()
diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm
index cea76b30fe4..900345d512f 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -484,7 +484,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM
icon_state = "[initial(icon_state)]"
/obj/item/weapon/lighter/ignition_effect(atom/A, mob/user)
- . = "With a single flick of their wrist, [user] smoothly lights [A] with [src]. Damn [user.p_theyre()] cool."
+ if(is_hot())
+ . = "With a single flick of their wrist, [user] smoothly lights [A] with [src]. Damn [user.p_theyre()] cool."
/obj/item/weapon/lighter/proc/set_lit(new_lit)
lit = new_lit
@@ -581,7 +582,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM
add_overlay(base_overlay)
/obj/item/weapon/lighter/greyscale/ignition_effect(atom/A, mob/user)
- . = "After some fiddling, [user] manages to light [A] with [src]."
+ if(is_hot())
+ . = "After some fiddling, [user] manages to light [A] with [src]."
///////////
@@ -775,12 +777,13 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(prob(5))//small chance for the vape to break and deal damage if it's emagged
playsound(get_turf(src), 'sound/effects/pop_expl.ogg', 50, 0)
M.apply_damage(20, BURN, "head")
- M.Weaken(15, 1, 0)
- qdel(src)
+ M.Knockdown(300, 1, 0)
var/datum/effect_system/spark_spread/sp = new /datum/effect_system/spark_spread
sp.set_up(5, 1, src)
sp.start()
to_chat(M, "The [name] suddenly explodes in your mouth!")
+ qdel(src)
+ return
if(reagents && reagents.total_volume)
hand_reagents()
diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm
index 0a4ef23d9fe..1df7b9f69ad 100644
--- a/code/game/objects/items/weapons/clown_items.dm
+++ b/code/game/objects/items/weapons/clown_items.dm
@@ -21,6 +21,7 @@
throw_speed = 3
throw_range = 7
var/cleanspeed = 50 //slower than mop
+ force_string = "robust... against germs"
/obj/item/weapon/soap/nanotrasen
desc = "A Nanotrasen brand bar of soap. Smells of plasma."
@@ -50,7 +51,7 @@
/obj/item/weapon/soap/Crossed(AM as mob|obj)
if (istype(AM, /mob/living/carbon))
var/mob/living/carbon/M = AM
- M.slip(4, 2, src)
+ M.slip(80, src)
/obj/item/weapon/soap/afterattack(atom/target, mob/user, proximity)
if(!proximity || !check_allowed_items(target))
@@ -134,7 +135,7 @@
name = "air horn"
desc = "Damn son, where'd you find this?"
icon_state = "air_horn"
- honksound = 'sound/items/AirHorn2.ogg'
+ honksound = 'sound/items/airhorn2.ogg'
cooldowntime = 50
origin_tech = "materials=4;engineering=4"
diff --git a/code/game/objects/items/weapons/cosmetics.dm b/code/game/objects/items/weapons/cosmetics.dm
index fd586c815b7..e2a524190d4 100644
--- a/code/game/objects/items/weapons/cosmetics.dm
+++ b/code/game/objects/items/weapons/cosmetics.dm
@@ -118,7 +118,7 @@
H.hair_style = "Skinhead"
H.update_hair()
- playsound(loc, 'sound/items/Welder2.ogg', 20, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 20, 1)
/obj/item/weapon/razor/attack(mob/M, mob/user)
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index df23172b4fd..ffa1b157e03 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -276,7 +276,6 @@
force = 0
throwforce = 6
w_class = WEIGHT_CLASS_BULKY
- flags = NODROP
var/revivecost = 1000
var/cooldown = 0
@@ -401,7 +400,7 @@
M.visible_message("[user] has touched [M] with [src]!", \
"[user] has touched [M] with [src]!")
M.adjustStaminaLoss(50)
- M.Weaken(5)
+ M.Knockdown(100)
M.updatehealth() //forces health update before next life tick
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
M.emote("gasp")
@@ -447,7 +446,7 @@
return
user.visible_message("[user] shocks [H] with \the [src]!", "You shock [H] with \the [src]!")
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 100, 1, -1)
- playsound(loc, 'sound/weapons/Egloves.ogg', 100, 1, -1)
+ playsound(loc, 'sound/weapons/egloves.ogg', 100, 1, -1)
H.emote("scream")
if(H.can_heartattack() && !H.undergoing_cardiac_arrest())
if(!H.stat)
@@ -456,7 +455,7 @@
H.set_heartattack(TRUE)
H.apply_damage(50, BURN, "chest")
add_logs(user, H, "overloaded the heart of", defib)
- H.Weaken(5)
+ H.Knockdown(100)
H.Jitter(100)
if(req_defib)
defib.deductcharge(revivecost)
diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm
index 70c1d9d9db3..1958449ed9b 100644
--- a/code/game/objects/items/weapons/dice.dm
+++ b/code/game/objects/items/weapons/dice.dm
@@ -181,7 +181,7 @@
return 0
to_chat(H, "You step on the D4!")
H.apply_damage(4,BRUTE,(pick("l_leg", "r_leg")))
- H.Weaken(3)
+ H.Knockdown(60)
/obj/item/weapon/dice/update_icon()
cut_overlays()
diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm
index d971499e3b6..e329ae78f8c 100644
--- a/code/game/objects/items/weapons/dna_injector.dm
+++ b/code/game/objects/items/weapons/dna_injector.dm
@@ -30,7 +30,7 @@
/obj/item/weapon/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
prepare()
- if(M.has_dna() && !(M.disabilities & NOCLONE))
+ if(M.has_dna() && !(RADIMMUNE in M.dna.species.species_traits) && !(M.disabilities & NOCLONE))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/datum/mutation/human/HM in remove_mutations)
diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm
old mode 100644
new mode 100755
index 3a04008a98c..fae056c9f8a
--- a/code/game/objects/items/weapons/flamethrower.dm
+++ b/code/game/objects/items/weapons/flamethrower.dm
@@ -23,7 +23,7 @@
//variables for prebuilt flamethrowers
var/create_full = FALSE
var/create_with_tank = FALSE
- var/igniter_type = /obj/item/device/assembly/igniter
+ var/igniter_type = /obj/item/device/assembly/igniter
/obj/item/weapon/flamethrower/Destroy()
if(weldtool)
@@ -137,6 +137,16 @@
/obj/item/weapon/flamethrower/attack_self(mob/user)
toggle_igniter(user)
+/obj/item/weapon/flamethrower/AltClick(mob/user)
+ if(ptank && isliving(user) && !user.incapacitated() && Adjacent(user))
+ user.put_in_hands(ptank)
+ ptank = null
+ to_chat(user, "You remove the plasma tank from [src]!")
+
+/obj/item/weapon/flamethrower/examine(mob/user)
+ ..()
+ if(ptank)
+ to_chat(user, "\The [src] has \the [ptank] attached. Alt-click to remove it.")
/obj/item/weapon/flamethrower/proc/toggle_igniter(mob/user)
if(!ptank)
@@ -145,7 +155,7 @@
if(!status)
to_chat(user, "Secure the igniter first!")
return
- to_chat(user, "You ignite [src]!")
+ to_chat(user, "You [lit ? "extinguish" : "ignite"] [src]!")
lit = !lit
if(lit)
START_PROCESSING(SSobj, src)
@@ -222,7 +232,7 @@
/obj/item/weapon/flamethrower/full/tank
create_with_tank = TRUE
-/obj/item/weapon/flamethrower/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
+/obj/item/weapon/flamethrower/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(ptank && damage && attack_type == PROJECTILE_ATTACK && prob(15))
owner.visible_message("[attack_text] hits the fueltank on [owner]'s [src], rupturing it! What a shot!")
var/target_turf = get_turf(owner)
@@ -238,4 +248,4 @@
return
/obj/item/device/assembly/igniter/proc/ignite_turf(obj/item/weapon/flamethrower/F,turf/open/location,release_amount = 0.05)
- F.default_ignite(location,release_amount)
\ No newline at end of file
+ F.default_ignite(location,release_amount)
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index fed13eb2622..7af8a4dc5a5 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -103,7 +103,7 @@
to_chat(user, "You need one length of coil to wire the assembly!")
return
- else if(stage == READY && istype(I, /obj/item/weapon/wirecutters))
+ else if(stage == READY && istype(I, /obj/item/weapon/wirecutters) && !active)
stage_change(WIRED)
to_chat(user, "You unlock the [initial(name)] assembly.")
@@ -164,7 +164,7 @@
reactants += G.reagents
if(!chem_splash(get_turf(src), affected_area, reactants, ignition_temp, threatscale) && !no_splash)
- playsound(loc, 'sound/items/Screwdriver2.ogg', 50, 1)
+ playsound(loc, 'sound/items/screwdriver2.ogg', 50, 1)
if(beakers.len)
for(var/obj/O in beakers)
O.loc = get_turf(src)
diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm
index 47d561eb8ae..72eb87c8451 100644
--- a/code/game/objects/items/weapons/grenades/flashbang.dm
+++ b/code/game/objects/items/weapons/grenades/flashbang.dm
@@ -27,13 +27,11 @@
//Flash
if(M.flash_act(affect_silicon = 1))
- M.Stun(max(10/max(1,distance), 3))
- M.Weaken(max(10/max(1,distance), 3))
+ M.Knockdown(max(100/max(1,distance), 3))
//Bang
if(!distance || loc == M || loc == M.loc) //Stop allahu akbarring rooms with this.
- M.Stun(10)
- M.Weaken(10)
- M.soundbang_act(1, 10, 10, 15)
+ M.Knockdown(200)
+ M.soundbang_act(1, 200, 10, 15)
else
- M.soundbang_act(1, max(10/max(1,distance), 3), rand(0, 5))
+ M.soundbang_act(1, max(20/max(1,distance), 3), rand(0, 5))
diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm
index 9bcbbfe0720..afa63a187fd 100644
--- a/code/game/objects/items/weapons/grenades/ghettobomb.dm
+++ b/code/game/objects/items/weapons/grenades/ghettobomb.dm
@@ -15,10 +15,10 @@
det_time = 50
display_timer = 0
var/range = 3
- var/times = list()
+ var/list/times
-/obj/item/weapon/grenade/iedcasing/New(loc)
- ..()
+/obj/item/weapon/grenade/iedcasing/Initialize()
+ . = ..()
add_overlay("improvised_grenade_filled")
add_overlay("improvised_grenade_wired")
times = list("5" = 10, "-1" = 20, "[rand(30,80)]" = 50, "[rand(65,180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value]
@@ -33,6 +33,8 @@
..()
var/obj/item/weapon/reagent_containers/food/drinks/soda_cans/can = locate() in contents
if(can)
+ can.pixel_x = 0 //Reset the sprite's position to make it consistent with the rest of the IED
+ can.pixel_y = 0
var/mutable_appearance/can_underlay = new(can)
can_underlay.layer = FLOAT_LAYER
can_underlay.plane = FLOAT_PLANE
@@ -43,7 +45,7 @@
if(!active)
if(clown_check(user))
to_chat(user, "You light the [name]!")
- active = 1
+ active = TRUE
cut_overlay("improvised_grenade_filled")
icon_state = initial(icon_state) + "_active"
add_fingerprint(user)
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index 008b39ea51d..245d495e2a4 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -104,7 +104,7 @@
/obj/item/weapon/grenade/attack_paw(mob/user)
return attack_hand(user)
-/obj/item/weapon/grenade/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
+/obj/item/weapon/grenade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(damage && attack_type == PROJECTILE_ATTACK && prob(15))
owner.visible_message("[attack_text] hits [owner]'s [src], setting it off! What a shot!")
prime()
diff --git a/code/game/objects/items/weapons/grenades/syndieminibomb.dm b/code/game/objects/items/weapons/grenades/syndieminibomb.dm
index 46bcde50083..ddab9af411a 100644
--- a/code/game/objects/items/weapons/grenades/syndieminibomb.dm
+++ b/code/game/objects/items/weapons/grenades/syndieminibomb.dm
@@ -40,7 +40,7 @@
/obj/item/weapon/grenade/gluon/prime()
update_mob()
- playsound(loc, 'sound/effects/EMPulse.ogg', 50, 1)
+ playsound(loc, 'sound/effects/empulse.ogg', 50, 1)
radiation_pulse(loc,freeze_range,freeze_range+1,rad_damage)
for(var/turf/T in view(freeze_range,loc))
if(isfloorturf(T))
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index b94658545ed..da3e44bdb47 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -320,7 +320,7 @@
breakouttime = 35//easy to apply, easy to break out of
gender = NEUTER
origin_tech = "engineering=3;combat=1"
- var/weaken = 0
+ var/knockdown = 0
/obj/item/weapon/restraints/legcuffs/bola/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
if(!..())
@@ -338,7 +338,7 @@
C.update_inv_legcuffed()
SSblackbox.add_details("handcuffs","[type]")
to_chat(C, "\The [src] ensnares you!")
- C.Weaken(weaken)
+ C.Knockdown(knockdown)
/obj/item/weapon/restraints/legcuffs/bola/tactical//traitor variant
name = "reinforced bola"
@@ -346,7 +346,7 @@
icon_state = "bola_r"
breakouttime = 70
origin_tech = "engineering=4;combat=3"
- weaken = 1
+ knockdown = 20
/obj/item/weapon/restraints/legcuffs/bola/energy //For Security
name = "energy bola"
diff --git a/code/game/objects/items/weapons/his_grace.dm b/code/game/objects/items/weapons/his_grace.dm
index d8e7dabdf99..c43e1600b6b 100644
--- a/code/game/objects/items/weapons/his_grace.dm
+++ b/code/game/objects/items/weapons/his_grace.dm
@@ -84,7 +84,7 @@
master.emote("scream")
master.remove_status_effect(STATUS_EFFECT_HISGRACE)
flags &= ~NODROP
- master.Weaken(3)
+ master.Knockdown(60)
master.adjustBruteLoss(master.maxHealth)
playsound(master, 'sound/effects/splat.ogg', 100, 0)
else
diff --git a/code/game/objects/items/weapons/holosign_creator.dm b/code/game/objects/items/weapons/holosign_creator.dm
index 3b611883e68..861a5309673 100644
--- a/code/game/objects/items/weapons/holosign_creator.dm
+++ b/code/game/objects/items/weapons/holosign_creator.dm
@@ -74,6 +74,14 @@
creation_time = 30
max_signs = 6
+/obj/item/weapon/holosign_creator/atmos
+ name = "ATMOS holofan projector"
+ desc = "A holographic projector that creates holographic barriers that prevent changes in atmosphere conditions."
+ icon_state = "signmaker_engi"
+ holosign_type = /obj/structure/holosign/barrier/atmos
+ creation_time = 0
+ max_signs = 3
+
/obj/item/weapon/holosign_creator/cyborg
name = "Energy Barrier Projector"
desc = "A holographic projector that creates fragile energy fields"
diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm
index 4b5acd949d3..00482abf2f5 100644
--- a/code/game/objects/items/weapons/holy_weapons.dm
+++ b/code/game/objects/items/weapons/holy_weapons.dm
@@ -91,7 +91,7 @@
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
-/obj/item/weapon/nullrod/claymore/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
+/obj/item/weapon/nullrod/claymore/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
final_block_chance = 0 //Don't bring a sword to a gunfight
return ..()
diff --git a/code/game/objects/items/weapons/implants/implant_explosive.dm b/code/game/objects/items/weapons/implants/implant_explosive.dm
index 009aae3b543..9c8d5b0eab9 100644
--- a/code/game/objects/items/weapons/implants/implant_explosive.dm
+++ b/code/game/objects/items/weapons/implants/implant_explosive.dm
@@ -68,18 +68,18 @@
return ..()
/obj/item/weapon/implant/explosive/proc/timed_explosion()
- imp_in.visible_message("[imp_in] starts beeping ominously!")
+ imp_in.visible_message("[imp_in] starts beeping ominously!")
playsound(loc, 'sound/items/timer.ogg', 30, 0)
- sleep(delay/4)
+ sleep(delay*0.25)
if(imp_in && !imp_in.stat)
- imp_in.visible_message("[imp_in] doubles over in pain!")
- imp_in.Weaken(7)
+ imp_in.visible_message("[imp_in] doubles over in pain!")
+ imp_in.Knockdown(140)
playsound(loc, 'sound/items/timer.ogg', 30, 0)
- sleep(delay/4)
+ sleep(delay*0.25)
playsound(loc, 'sound/items/timer.ogg', 30, 0)
- sleep(delay/4)
+ sleep(delay*0.25)
playsound(loc, 'sound/items/timer.ogg', 30, 0)
- sleep(delay/4)
+ sleep(delay*0.25)
explosion(src,heavy,medium,weak,weak, flame_range = weak)
if(imp_in)
imp_in.gib(1)
diff --git a/code/game/objects/items/weapons/implants/implant_misc.dm b/code/game/objects/items/weapons/implants/implant_misc.dm
index f48492a7ea5..827a4b0c1c9 100644
--- a/code/game/objects/items/weapons/implants/implant_misc.dm
+++ b/code/game/objects/items/weapons/implants/implant_misc.dm
@@ -16,7 +16,7 @@
/obj/item/weapon/implant/adrenalin
name = "adrenal implant"
- desc = "Removes all stuns and knockdowns."
+ desc = "Removes all stuns."
icon_state = "adrenal"
origin_tech = "materials=2;biotech=4;combat=3;syndicate=4"
uses = 3
@@ -35,9 +35,9 @@
/obj/item/weapon/implant/adrenalin/activate()
uses--
to_chat(imp_in, "You feel a sudden surge of energy!")
- imp_in.SetStunned(0)
- imp_in.SetWeakened(0)
- imp_in.SetParalysis(0)
+ imp_in.SetStun(0)
+ imp_in.SetKnockdown(0)
+ imp_in.SetUnconscious(0)
imp_in.adjustStaminaLoss(-75)
imp_in.lying = 0
imp_in.update_canmove()
diff --git a/code/game/objects/items/weapons/implants/implant_track.dm b/code/game/objects/items/weapons/implants/implant_track.dm
index ea631e360d0..bcd36c7e409 100644
--- a/code/game/objects/items/weapons/implants/implant_track.dm
+++ b/code/game/objects/items/weapons/implants/implant_track.dm
@@ -33,3 +33,9 @@
Integrity: Gradient creates slight risk of being overcharged and frying the
circuitry. As a result neurotoxins can cause massive damage."}
return dat
+
+
+/obj/item/weapon/implantcase/track
+ name = "implant case - 'Tracking'"
+ desc = "A glass case containing a tracking implant."
+ imp_type = /obj/item/weapon/implant/tracking
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm
index dd6cce8cbfc..9be87aa5d46 100644
--- a/code/game/objects/items/weapons/implants/implanter.dm
+++ b/code/game/objects/items/weapons/implants/implanter.dm
@@ -27,7 +27,7 @@
return
if(user && imp)
if(M != user)
- M.visible_message("[user] is attemping to implant [M].")
+ M.visible_message("[user] is attempting to implant [M].")
var/turf/T = get_turf(M)
if(T && (M == user || do_mob(user, M, 50)))
diff --git a/code/game/objects/items/weapons/inducer.dm b/code/game/objects/items/weapons/inducer.dm
index fdd44795ad7..26eb9a7bfcb 100644
--- a/code/game/objects/items/weapons/inducer.dm
+++ b/code/game/objects/items/weapons/inducer.dm
@@ -30,7 +30,7 @@
/obj/item/weapon/inducer/emp_act(severity)
..()
if(cell)
- cell.emp_act()
+ cell.emp_act(severity)
/obj/item/weapon/inducer/attack_obj(obj/O, mob/living/carbon/user)
if(user.a_intent == INTENT_HARM)
@@ -128,6 +128,7 @@
user.visible_message("[user] recharged \the [A]!","You recharged \the [A]!")
recharging = FALSE
return TRUE
+ recharging = FALSE
/obj/item/weapon/inducer/attack(mob/M, mob/user)
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index d88c1371a74..ff8db01d3ce 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -95,7 +95,7 @@
else
STOP_PROCESSING(SSobj, src)
-/obj/item/weapon/melee/energy/sword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
+/obj/item/weapon/melee/energy/sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(active)
return ..()
return 0
@@ -188,7 +188,7 @@
icon_state = "esaw_0"
item_color = null
-/obj/item/weapon/melee/energy/sword/cyborg/saw/hit_reaction()
+/obj/item/weapon/melee/energy/sword/cyborg/saw/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
/obj/item/weapon/melee/energy/sword/saber
diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm
index 8cf7d67336e..e486b1fe44f 100644
--- a/code/game/objects/items/weapons/melee/misc.dm
+++ b/code/game/objects/items/weapons/melee/misc.dm
@@ -5,7 +5,7 @@
if(target.check_block())
target.visible_message("[target.name] blocks [src] and twists [user]'s arm behind their back!",
"You block the attack!")
- user.Stun(2)
+ user.Stun(40)
return TRUE
@@ -60,7 +60,7 @@
hitsound = 'sound/weapons/rapierhit.ogg'
materials = list(MAT_METAL = 1000)
-/obj/item/weapon/melee/sabre/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
+/obj/item/weapon/melee/sabre/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
final_block_chance = 0 //Don't bring a sword to a gunfight
return ..()
@@ -84,7 +84,7 @@
add_fingerprint(user)
if((CLUMSY in user.disabilities) && prob(50))
to_chat(user, "You club yourself over the head.")
- user.Weaken(3 * force)
+ user.Knockdown(60 * force)
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.apply_damage(2*force, BRUTE, "head")
@@ -105,12 +105,12 @@
if(cooldown <= world.time)
if(ishuman(target))
var/mob/living/carbon/human/H = target
- if (H.check_shields(0, "[user]'s [name]", src, MELEE_ATTACK))
+ if (H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK))
return
if(check_martial_counter(H, user))
return
playsound(get_turf(src), 'sound/effects/woodhit.ogg', 75, 1, -1)
- target.Weaken(3)
+ target.Knockdown(60)
add_logs(user, target, "stunned", src)
src.add_fingerprint(user)
target.visible_message("[user] has knocked down [target] with [src]!", \
@@ -185,6 +185,7 @@
var/obj/machinery/power/supermatter_shard/shard
var/balanced = 1
origin_tech = "combat=7;materials=6"
+ force_string = "INFINITE"
/obj/item/weapon/melee/supermatter_sword/New()
..()
diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm
index 50b3ed20f7d..9bf5be6e351 100644
--- a/code/game/objects/items/weapons/mop.dm
+++ b/code/game/objects/items/weapons/mop.dm
@@ -14,6 +14,7 @@
var/mopcount = 0
var/mopcap = 5
var/mopspeed = 30
+ force_string = "robust... against germs"
/obj/item/weapon/mop/New()
..()
diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm
index 3653a02ec13..3fa4b5be62f 100644
--- a/code/game/objects/items/weapons/pneumaticCannon.dm
+++ b/code/game/objects/items/weapons/pneumaticCannon.dm
@@ -32,14 +32,16 @@
/obj/item/weapon/pneumatic_cannon/examine(mob/user)
..()
+ var/list/out = list()
if(!in_range(user, src))
- to_chat(user, "You'll need to get closer to see any more.")
+ out += "You'll need to get closer to see any more."
return
for(var/obj/item/I in loadedItems)
- to_chat(user, "\icon [I] It has \the [I] loaded.")
+ out += "[bicon(I)] It has \the [I] loaded."
+ CHECK_TICK
if(tank)
- to_chat(user, "\icon [tank] It has \the [tank] mounted onto it.")
-
+ out += "[bicon(tank)] It has \the [tank] mounted onto it."
+ to_chat(user, out.Join(" "))
/obj/item/weapon/pneumatic_cannon/attackby(obj/item/weapon/W, mob/user, params)
if(user.a_intent == INTENT_HARM)
@@ -139,7 +141,7 @@
fire_items(T, user)
if(pressureSetting >= 3 && user)
user.visible_message("[user] is thrown down by the force of the cannon!", "[src] slams into your shoulder, knocking you down!")
- user.Weaken(3)
+ user.Knockdown(60)
/obj/item/weapon/pneumatic_cannon/proc/fire_items(turf/target, mob/user)
if(fire_mode == PCANNON_FIREALL)
@@ -185,17 +187,6 @@
maxWeightClass = 7
gasPerThrow = 5
-/datum/crafting_recipe/improvised_pneumatic_cannon //Pretty easy to obtain but
- name = "Pneumatic Cannon"
- result = /obj/item/weapon/pneumatic_cannon/ghetto
- tools = list(/obj/item/weapon/weldingtool,
- /obj/item/weapon/wrench)
- reqs = list(/obj/item/stack/sheet/metal = 4,
- /obj/item/stack/packageWrap = 8,
- /obj/item/pipe = 2)
- time = 300
- category = CAT_WEAPON
-
/obj/item/weapon/pneumatic_cannon/proc/updateTank(obj/item/weapon/tank/internals/thetank, removing = 0, mob/living/carbon/human/user)
if(removing)
if(!src.tank)
diff --git a/code/game/objects/items/weapons/powerfist.dm b/code/game/objects/items/weapons/powerfist.dm
index 7b26c58a5df..d3a940090dd 100644
--- a/code/game/objects/items/weapons/powerfist.dm
+++ b/code/game/objects/items/weapons/powerfist.dm
@@ -24,7 +24,7 @@
to_chat(user, "You'll need to get closer to see any more.")
return
if(tank)
- to_chat(user, "\icon [tank] It has \the [tank] mounted onto it.")
+ to_chat(user, "[bicon(tank)] It has \the [tank] mounted onto it.")
/obj/item/weapon/melee/powerfist/attackby(obj/item/weapon/W, mob/user, params)
diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm
index 2bc4ada646c..b8270158133 100644
--- a/code/game/objects/items/weapons/shields.dm
+++ b/code/game/objects/items/weapons/shields.dm
@@ -29,7 +29,7 @@
else
return ..()
-/obj/item/weapon/shield/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
+/obj/item/weapon/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == THROWN_PROJECTILE_ATTACK)
final_block_chance += 30
if(attack_type == LEAP_ATTACK)
@@ -66,7 +66,7 @@
attack_verb = list("shoved", "bashed")
var/active = 0
-/obj/item/weapon/shield/energy/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
+/obj/item/weapon/shield/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
/obj/item/weapon/shield/energy/IsReflect()
@@ -109,7 +109,7 @@
w_class = WEIGHT_CLASS_NORMAL
var/active = 0
-/obj/item/weapon/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
+/obj/item/weapon/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(active)
return ..()
return 0
diff --git a/code/game/objects/items/weapons/singularityhammer.dm b/code/game/objects/items/weapons/singularityhammer.dm
index 2449b8629d6..ce0d0959018 100644
--- a/code/game/objects/items/weapons/singularityhammer.dm
+++ b/code/game/objects/items/weapons/singularityhammer.dm
@@ -14,6 +14,7 @@
origin_tech = "combat=4;bluespace=4;plasmatech=7"
armor = list(melee = 50, bullet = 50, laser = 50, energy = 0, bomb = 50, bio = 0, rad = 0, fire = 100, acid = 100)
resistance_flags = FIRE_PROOF | ACID_PROOF
+ force_string = "LORD SINGULOTH HIMSELF"
/obj/item/weapon/twohanded/singularityhammer/New()
..()
@@ -48,7 +49,7 @@
var/obj/item/clothing/shoes/magboots/M = H.shoes
if(M.magpulse)
continue
- H.apply_effect(1, WEAKEN, 0)
+ H.apply_effect(20, KNOCKDOWN, 0)
step_towards(H,pull)
step_towards(H,pull)
step_towards(H,pull)
@@ -78,14 +79,14 @@
throwforce = 30
throw_range = 7
w_class = WEIGHT_CLASS_HUGE
- //var/charged = 5
origin_tech = "combat=4;powerstorage=7"
/obj/item/weapon/twohanded/mjollnir/proc/shock(mob/living/target)
+ target.Stun(60)
var/datum/effect_system/lightning_spread/s = new /datum/effect_system/lightning_spread
s.set_up(5, 1, target.loc)
s.start()
- target.visible_message("[target.name] was shocked by the [src.name]!", \
+ target.visible_message("[target.name] was shocked by [src]!", \
"You feel a powerful shock course through your body sending you flying!", \
"You hear a heavy electrical crack!")
var/atom/throw_target = get_edge_target_turf(target, get_dir(src, get_step_away(target, src)))
@@ -95,18 +96,13 @@
/obj/item/weapon/twohanded/mjollnir/attack(mob/living/M, mob/user)
..()
if(wielded)
- //if(charged == 5)
- //charged = 0
playsound(src.loc, "sparks", 50, 1)
- M.Stun(3)
shock(M)
/obj/item/weapon/twohanded/mjollnir/throw_impact(atom/target)
. = ..()
if(isliving(target))
- var/mob/living/L = target
- L.Stun(3)
- shock(L)
+ shock(target)
/obj/item/weapon/twohanded/mjollnir/update_icon() //Currently only here to fuck with the on-mob icons.
icon_state = "mjollnir[wielded]"
diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm
index 73d270f9bbb..14789a0268e 100644
--- a/code/game/objects/items/weapons/storage/backpack.dm
+++ b/code/game/objects/items/weapons/storage/backpack.dm
@@ -36,15 +36,15 @@
max_w_class = WEIGHT_CLASS_GIGANTIC
max_combined_w_class = 35
resistance_flags = FIRE_PROOF
- var/pshoom = 'sound/items/PSHOOM.ogg'
- var/alt_sound = 'sound/items/PSHOOM_2.ogg'
+ var/pshoom = 'sound/items/pshoom.ogg'
+ var/alt_sound = 'sound/items/pshoom_2.ogg'
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 60, acid = 50)
-/obj/item/weapon/storage/backpack/holding/suicide_act(mob/user)
+/obj/item/weapon/storage/backpack/holding/suicide_act(mob/living/user)
user.visible_message("[user] is jumping into [src]! It looks like [user.p_theyre()] trying to commit suicide.")
user.drop_item()
- user.Stun(5)
+ user.Stun(100, ignore_canstun = TRUE)
sleep(20)
playsound(src, "rustle", 50, 1, -5)
qdel(user)
@@ -316,48 +316,77 @@
new R(src)
revealed = 1
-/obj/item/weapon/storage/backpack/dufflebag
- name = "dufflebag"
- desc = "A large dufflebag for holding extra things."
- icon_state = "duffle"
- item_state = "duffle"
+/obj/item/weapon/storage/backpack/duffelbag
+ name = "duffel bag"
+ desc = "A large duffel bag for holding extra things."
+ icon_state = "duffel"
+ item_state = "duffel"
slowdown = 1
max_combined_w_class = 30
-/obj/item/weapon/storage/backpack/dufflebag/captain
- name = "captain's dufflebag"
- desc = "A large dufflebag for holding extra captainly goods."
- icon_state = "duffle-captain"
- item_state = "duffle-captain"
+/obj/item/weapon/storage/backpack/duffelbag/captain
+ name = "captain's duffel bag"
+ desc = "A large duffel bag for holding extra captainly goods."
+ icon_state = "duffel-captain"
+ item_state = "duffel-captain"
resistance_flags = 0
-/obj/item/weapon/storage/backpack/dufflebag/med
- name = "medical dufflebag"
- desc = "A large dufflebag for holding extra medical supplies."
- icon_state = "duffle-med"
- item_state = "duffle-med"
+/obj/item/weapon/storage/backpack/duffelbag/med
+ name = "medical duffel bag"
+ desc = "A large duffel bag for holding extra medical supplies."
+ icon_state = "duffel-med"
+ item_state = "duffel-med"
-/obj/item/weapon/storage/backpack/dufflebag/sec
- name = "security dufflebag"
- desc = "A large dufflebag for holding extra security supplies and ammunition."
- icon_state = "duffle-sec"
- item_state = "duffle-sec"
+/obj/item/weapon/storage/backpack/duffelbag/med/surgery
+ name = "surgical duffel bag"
+ desc = "A large duffel bag for holding extra medical supplies - this one seems to be designed for holding surgical tools."
-/obj/item/weapon/storage/backpack/dufflebag/engineering
- name = "industrial dufflebag"
- desc = "A large dufflebag for holding extra tools and supplies."
- icon_state = "duffle-eng"
- item_state = "duffle-eng"
+/obj/item/weapon/storage/backpack/duffelbag/med/surgery/PopulateContents()
+ new /obj/item/weapon/scalpel(src)
+ new /obj/item/weapon/hemostat(src)
+ new /obj/item/weapon/retractor(src)
+ new /obj/item/weapon/circular_saw(src)
+ new /obj/item/weapon/surgicaldrill(src)
+ new /obj/item/weapon/cautery(src)
+ new /obj/item/weapon/surgical_drapes(src)
+ new /obj/item/clothing/mask/surgical(src)
+ new /obj/item/weapon/razor(src)
+
+/obj/item/weapon/storage/backpack/duffelbag/sec
+ name = "security duffel bag"
+ desc = "A large duffel bag for holding extra security supplies and ammunition."
+ icon_state = "duffel-sec"
+ item_state = "duffel-sec"
+
+/obj/item/weapon/storage/backpack/duffelbag/sec/surgery
+ name = "surgical duffel bag"
+ desc = "A large duffel bag for holding extra supplies - this one has a material inlay with space for various sharp-looking tools."
+
+/obj/item/weapon/storage/backpack/duffelbag/sec/surgery/PopulateContents()
+ new /obj/item/weapon/scalpel(src)
+ new /obj/item/weapon/hemostat(src)
+ new /obj/item/weapon/retractor(src)
+ new /obj/item/weapon/circular_saw(src)
+ new /obj/item/weapon/surgicaldrill(src)
+ new /obj/item/weapon/cautery(src)
+ new /obj/item/weapon/surgical_drapes(src)
+ new /obj/item/clothing/mask/surgical(src)
+
+/obj/item/weapon/storage/backpack/duffelbag/engineering
+ name = "industrial duffel bag"
+ desc = "A large duffel bag for holding extra tools and supplies."
+ icon_state = "duffel-eng"
+ item_state = "duffel-eng"
resistance_flags = 0
-/obj/item/weapon/storage/backpack/dufflebag/drone
- name = "drone dufflebag"
- desc = "A large dufflebag for holding tools and hats."
- icon_state = "duffle-drone"
- item_state = "duffle-drone"
+/obj/item/weapon/storage/backpack/duffelbag/drone
+ name = "drone duffel bag"
+ desc = "A large duffel bag for holding tools and hats."
+ icon_state = "duffel-drone"
+ item_state = "duffel-drone"
resistance_flags = FIRE_PROOF
-/obj/item/weapon/storage/backpack/dufflebag/drone/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/drone/PopulateContents()
new /obj/item/weapon/screwdriver(src)
new /obj/item/weapon/wrench(src)
new /obj/item/weapon/weldingtool(src)
@@ -366,38 +395,52 @@
new /obj/item/weapon/wirecutters(src)
new /obj/item/device/multitool(src)
-/obj/item/weapon/storage/backpack/dufflebag/clown
- name = "clown's dufflebag"
- desc = "A large dufflebag for holding lots of funny gags!"
- icon_state = "duffle-clown"
- item_state = "duffle-clown"
+/obj/item/weapon/storage/backpack/duffelbag/clown
+ name = "clown's duffel bag"
+ desc = "A large duffel bag for holding lots of funny gags!"
+ icon_state = "duffel-clown"
+ item_state = "duffel-clown"
-/obj/item/weapon/storage/backpack/dufflebag/clown/cream_pie/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/clown/cream_pie/PopulateContents()
for(var/i in 1 to 10)
new /obj/item/weapon/reagent_containers/food/snacks/pie/cream(src)
-/obj/item/weapon/storage/backpack/dufflebag/syndie
- name = "suspicious looking dufflebag"
- desc = "A large dufflebag for holding extra tactical supplies."
- icon_state = "duffle-syndie"
- item_state = "duffle-syndie"
+/obj/item/weapon/storage/backpack/duffelbag/syndie
+ name = "suspicious looking duffel bag"
+ desc = "A large duffel bag for holding extra tactical supplies."
+ icon_state = "duffel-syndie"
+ item_state = "duffel-syndie"
origin_tech = "syndicate=1"
silent = 1
slowdown = 0
-/obj/item/weapon/storage/backpack/dufflebag/syndie/med
- name = "medical dufflebag"
- desc = "A large dufflebag for holding extra tactical medical supplies."
- icon_state = "duffle-syndiemed"
- item_state = "duffle-syndiemed"
+/obj/item/weapon/storage/backpack/duffelbag/syndie/hitman
+ desc = "A large duffel bag for holding extra things. There is a NanoTrasen logo on the back."
+ icon_state = "duffel-syndieammo"
+ item_state = "duffel-syndieammo"
-/obj/item/weapon/storage/backpack/dufflebag/syndie/surgery
- name = "surgery dufflebag"
- desc = "A suspicious looking dufflebag for holding surgery tools."
- icon_state = "duffle-syndiemed"
- item_state = "duffle-syndiemed"
+/obj/item/weapon/storage/backpack/duffelbag/syndie/hitman/PopulateContents()
+ new /obj/item/clothing/under/lawyer/blacksuit(src)
+ new /obj/item/clothing/accessory/waistcoat(src)
+ new /obj/item/clothing/suit/toggle/lawyer/black(src)
+ new /obj/item/clothing/shoes/laceup(src)
+ new /obj/item/clothing/gloves/color/black(src)
+ new /obj/item/clothing/glasses/sunglasses(src)
+ new /obj/item/clothing/head/fedora(src)
-/obj/item/weapon/storage/backpack/dufflebag/syndie/surgery/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/syndie/med
+ name = "medical duffel bag"
+ desc = "A large duffel bag for holding extra tactical medical supplies."
+ icon_state = "duffel-syndiemed"
+ item_state = "duffel-syndiemed"
+
+/obj/item/weapon/storage/backpack/duffelbag/syndie/surgery
+ name = "surgery duffel bag"
+ desc = "A suspicious looking duffel bag for holding surgery tools."
+ icon_state = "duffel-syndiemed"
+ item_state = "duffel-syndiemed"
+
+/obj/item/weapon/storage/backpack/duffelbag/syndie/surgery/PopulateContents()
new /obj/item/weapon/scalpel(src)
new /obj/item/weapon/hemostat(src)
new /obj/item/weapon/retractor(src)
@@ -409,69 +452,69 @@
new /obj/item/clothing/mask/muzzle(src)
new /obj/item/device/mmi/syndie(src)
-/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo
- name = "ammunition dufflebag"
- desc = "A large dufflebag for holding extra weapons ammunition and supplies."
- icon_state = "duffle-syndieammo"
- item_state = "duffle-syndieammo"
+/obj/item/weapon/storage/backpack/duffelbag/syndie/ammo
+ name = "ammunition duffel bag"
+ desc = "A large duffel bag for holding extra weapons ammunition and supplies."
+ icon_state = "duffel-syndieammo"
+ item_state = "duffel-syndieammo"
-/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo/shotgun
- desc = "A large dufflebag, packed to the brim with Bulldog shotgun ammo."
+/obj/item/weapon/storage/backpack/duffelbag/syndie/ammo/shotgun
+ desc = "A large duffel bag, packed to the brim with Bulldog shotgun ammo."
-/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo/shotgun/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/syndie/ammo/shotgun/PopulateContents()
for(var/i in 1 to 6)
new /obj/item/ammo_box/magazine/m12g(src)
new /obj/item/ammo_box/magazine/m12g/buckshot(src)
new /obj/item/ammo_box/magazine/m12g/slug(src)
new /obj/item/ammo_box/magazine/m12g/dragon(src)
-/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo/smg
- desc = "A large dufflebag, packed to the brim with C20r magazines."
+/obj/item/weapon/storage/backpack/duffelbag/syndie/ammo/smg
+ desc = "A large duffel bag, packed to the brim with C20r magazines."
-/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo/smg/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/syndie/ammo/smg/PopulateContents()
for(var/i in 1 to 9)
new /obj/item/ammo_box/magazine/smgm45(src)
-/obj/item/weapon/storage/backpack/dufflebag/syndie/c20rbundle
- desc = "A large dufflebag containing a C20r, some magazines, and a cheap looking suppressor."
+/obj/item/weapon/storage/backpack/duffelbag/syndie/c20rbundle
+ desc = "A large duffel bag containing a C20r, some magazines, and a cheap looking suppressor."
-/obj/item/weapon/storage/backpack/dufflebag/syndie/c20rbundle/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/syndie/c20rbundle/PopulateContents()
new /obj/item/ammo_box/magazine/smgm45(src)
new /obj/item/ammo_box/magazine/smgm45(src)
new /obj/item/weapon/gun/ballistic/automatic/c20r(src)
new /obj/item/weapon/suppressor/specialoffer(src)
-/obj/item/weapon/storage/backpack/dufflebag/syndie/bulldogbundle
- desc = "A large dufflebag containing a Bulldog, several drums, and a collapsed hardsuit."
+/obj/item/weapon/storage/backpack/duffelbag/syndie/bulldogbundle
+ desc = "A large duffel bag containing a Bulldog, several drums, and a collapsed hardsuit."
-/obj/item/weapon/storage/backpack/dufflebag/syndie/bulldogbundle/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/syndie/bulldogbundle/PopulateContents()
new /obj/item/ammo_box/magazine/m12g(src)
new /obj/item/weapon/gun/ballistic/automatic/shotgun/bulldog(src)
new /obj/item/ammo_box/magazine/m12g/buckshot(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
-/obj/item/weapon/storage/backpack/dufflebag/syndie/med/medicalbundle
- desc = "A large dufflebag containing a medical equipment, a Donksoft machine gun, a big jumbo box of darts, and a knock-off pair of magboots."
+/obj/item/weapon/storage/backpack/duffelbag/syndie/med/medicalbundle
+ desc = "A large duffel bag containing a medical equipment, a Donksoft machine gun, a big jumbo box of darts, and a knock-off pair of magboots."
-/obj/item/weapon/storage/backpack/dufflebag/syndie/med/medicalbundle/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/syndie/med/medicalbundle/PopulateContents()
new /obj/item/clothing/shoes/magboots/syndie(src)
new /obj/item/weapon/storage/firstaid/tactical(src)
new /obj/item/weapon/gun/ballistic/automatic/l6_saw/toy(src)
new /obj/item/ammo_box/foambox/riot(src)
-/obj/item/weapon/storage/backpack/dufflebag/syndie/med/medicalbundle
- desc = "A large dufflebag containing a medical equipment, a Donksoft machine gun, a big jumbo box of darts, and a knock-off pair of magboots."
+/obj/item/weapon/storage/backpack/duffelbag/syndie/med/medicalbundle
+ desc = "A large duffel bag containing a medical equipment, a Donksoft machine gun, a big jumbo box of darts, and a knock-off pair of magboots."
-/obj/item/weapon/storage/backpack/dufflebag/syndie/med/medicalbundle/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/syndie/med/medicalbundle/PopulateContents()
new /obj/item/clothing/shoes/magboots/syndie(src)
new /obj/item/weapon/storage/firstaid/tactical(src)
new /obj/item/weapon/gun/ballistic/automatic/l6_saw/toy(src)
new /obj/item/ammo_box/foambox/riot(src)
-/obj/item/weapon/storage/backpack/dufflebag/syndie/med/bioterrorbundle
- desc = "A large dufflebag containing a deadly chemicals, a chemical spray, chemical grenade, a Donksoft assault rifle, riot grade darts, a minature syringe gun, and a box of syringes"
+/obj/item/weapon/storage/backpack/duffelbag/syndie/med/bioterrorbundle
+ desc = "A large duffel bag containing a deadly chemicals, a chemical spray, chemical grenade, a Donksoft assault rifle, riot grade darts, a minature syringe gun, and a box of syringes"
-/obj/item/weapon/storage/backpack/dufflebag/syndie/med/bioterrorbundle/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/syndie/med/bioterrorbundle/PopulateContents()
new /obj/item/weapon/reagent_containers/spray/chemsprayer/bioterror(src)
new /obj/item/weapon/storage/box/syndie_kit/chemical(src)
new /obj/item/weapon/gun/syringe/syndicate(src)
@@ -480,18 +523,18 @@
new /obj/item/ammo_box/foambox/riot(src)
new /obj/item/weapon/grenade/chem_grenade/bioterrorfoam(src)
-/obj/item/weapon/storage/backpack/dufflebag/syndie/c4/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/syndie/c4/PopulateContents()
for(var/i in 1 to 10)
new /obj/item/weapon/grenade/plastic/c4(src)
-/obj/item/weapon/storage/backpack/dufflebag/syndie/x4/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/syndie/x4/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/weapon/grenade/plastic/x4(src)
-/obj/item/weapon/storage/backpack/dufflebag/syndie/firestarter
- desc = "A large dufflebag containing New Russian pyro backpack sprayer, a pistol, a pipebomb, fireproof hardsuit, ammo, and other equipment."
+/obj/item/weapon/storage/backpack/duffelbag/syndie/firestarter
+ desc = "A large duffel bag containing New Russian pyro backpack sprayer, a pistol, a pipebomb, fireproof hardsuit, ammo, and other equipment."
-/obj/item/weapon/storage/backpack/dufflebag/syndie/firestarter/PopulateContents()
+/obj/item/weapon/storage/backpack/duffelbag/syndie/firestarter/PopulateContents()
new /obj/item/clothing/under/syndicate/soviet(src)
new /obj/item/weapon/watertank/operator(src)
new /obj/item/clothing/suit/space/hardsuit/syndi/elite(src)
diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm
index 266fe875792..e61a0a8ad49 100644
--- a/code/game/objects/items/weapons/storage/bags.dm
+++ b/code/game/objects/items/weapons/storage/bags.dm
@@ -112,7 +112,7 @@
max_combined_w_class = 100 //Doesn't matter what this is, so long as it's more or equal to storage_slots * plants.w_class
max_w_class = WEIGHT_CLASS_NORMAL
w_class = WEIGHT_CLASS_TINY
- can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/grown,/obj/item/seeds,/obj/item/weapon/grown,/obj/item/weapon/reagent_containers/food/snacks/ash_flora,/obj/item/weapon/reagent_containers/honeycomb)
+ can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/grown,/obj/item/seeds,/obj/item/weapon/grown,/obj/item/weapon/reagent_containers/honeycomb)
resistance_flags = FLAMMABLE
////////
@@ -329,7 +329,7 @@
if(ishuman(M) || ismonkey(M))
if(prob(10))
- M.Weaken(2)
+ M.Knockdown(40)
/obj/item/weapon/storage/bag/tray/proc/rebuild_overlays()
cut_overlays()
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index 9057bf9aff1..a3146db8700 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -289,7 +289,9 @@
icon_state = "grenadebeltnew"
item_state = "security"
max_w_class = WEIGHT_CLASS_BULKY
+ display_contents_with_number = TRUE
storage_slots = 30
+ max_combined_w_class = 60 //needs to be this high
can_hold = list(
/obj/item/weapon/grenade,
/obj/item/weapon/screwdriver,
@@ -374,6 +376,7 @@
icon_state = "bandolier"
item_state = "bandolier"
storage_slots = 18
+ display_contents_with_number = TRUE
can_hold = list(
/obj/item/ammo_casing/shotgun
)
diff --git a/code/game/objects/items/weapons/storage/book.dm b/code/game/objects/items/weapons/storage/book.dm
index 3b655550b46..ed38d02c316 100644
--- a/code/game/objects/items/weapons/storage/book.dm
+++ b/code/game/objects/items/weapons/storage/book.dm
@@ -25,6 +25,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
item_state = "bible"
var/mob/affecting = null
var/deity_name = "Christ"
+ force_string = "holy"
/obj/item/weapon/storage/book/bible/suicide_act(mob/user)
user.visible_message("[user] is offering [user.p_them()]self to [deity_name]! It looks like [user.p_theyre()] trying to commit suicide!")
@@ -86,7 +87,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
return 1
/obj/item/weapon/storage/book/bible/attack(mob/living/M, mob/living/carbon/human/user, heal_mode = TRUE)
-
+
if (!user.IsAdvancedToolUser())
to_chat(user, "You don't have the dexterity to do this!")
return
@@ -94,7 +95,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
if (user.disabilities & CLUMSY && prob(50))
to_chat(user, "[src] slips out of your hand and hits your head.")
user.take_bodypart_damage(10)
- user.Paralyse(20)
+ user.Unconscious(400)
return
var/chaplain = 0
@@ -105,10 +106,10 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
to_chat(user, "The book sizzles in your hands.")
user.take_bodypart_damage(0,10)
return
-
+
if (!heal_mode)
return ..()
-
+
var/smack = 1
if (M.stat != DEAD)
@@ -174,7 +175,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
var/uses = 1
-
+
/obj/item/weapon/storage/book/bible/syndicate/attack_self(mob/living/carbon/human/H)
if (uses)
H.mind.isholy = TRUE
diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm
index 5c53db06cf2..4027081381f 100644
--- a/code/game/objects/items/weapons/storage/boxes.dm
+++ b/code/game/objects/items/weapons/storage/boxes.dm
@@ -568,7 +568,7 @@
/obj/item/weapon/storage/box/deputy/PopulateContents()
for(var/i in 1 to 7)
- new /obj/item/clothing/tie/armband/deputy(src)
+ new /obj/item/clothing/accessory/armband/deputy(src)
/obj/item/weapon/storage/box/metalfoam
name = "box of metal foam grenades"
@@ -879,3 +879,11 @@
/obj/item/weapon/storage/box/silver_sulf/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/weapon/reagent_containers/pill/patch/silver_sulf(src)
+
+
+/obj/item/weapon/storage/box/fountainpens
+ name = "box of fountain pens"
+
+/obj/item/weapon/storage/box/fountainpens/PopulateContents()
+ for(var/i in 1 to 7)
+ new /obj/item/weapon/pen/fountain(src)
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/storage/internal.dm b/code/game/objects/items/weapons/storage/internal.dm
index cfdc6cc3547..d0b0f5b9b4e 100644
--- a/code/game/objects/items/weapons/storage/internal.dm
+++ b/code/game/objects/items/weapons/storage/internal.dm
@@ -68,3 +68,22 @@
/obj/item/weapon/storage/internal/pocket/small/detective/PopulateContents()
new /obj/item/weapon/reagent_containers/food/drinks/flask/det(src)
+
+/obj/item/weapon/storage/internal/pocket/pocketprotector
+ storage_slots = 3
+ max_w_class = WEIGHT_CLASS_TINY
+ can_hold = list( //Same items as a PDA
+ /obj/item/weapon/pen,
+ /obj/item/toy/crayon,
+ /obj/item/weapon/lipstick,
+ /obj/item/device/flashlight/pen,
+ /obj/item/clothing/mask/cigarette)
+
+/obj/item/weapon/storage/internal/pocket/pocketprotector/cosmetology/PopulateContents()
+ for(var/i in 1 to 3)
+ new /obj/item/weapon/lipstick/random(src)
+
+/obj/item/weapon/storage/internal/pocket/pocketprotector/full/PopulateContents()
+ new /obj/item/weapon/pen/red(src)
+ new /obj/item/weapon/pen(src)
+ new /obj/item/weapon/pen/blue(src)
diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm
old mode 100644
new mode 100755
index 2345f679cd9..66a6661a0d0
--- a/code/game/objects/items/weapons/storage/lockbox.dm
+++ b/code/game/objects/items/weapons/storage/lockbox.dm
@@ -8,8 +8,9 @@
max_combined_w_class = 14 //The sum of the w_classes of all the items in this storage item.
storage_slots = 4
req_access = list(GLOB.access_armory)
- var/locked = 1
- var/broken = 0
+ var/locked = TRUE
+ var/broken = FALSE
+ var/open = FALSE
var/icon_locked = "lockbox+l"
var/icon_closed = "lockbox"
var/icon_broken = "lockbox+b"
@@ -48,8 +49,8 @@
/obj/item/weapon/storage/lockbox/emag_act(mob/user)
if(!broken)
- broken = 1
- locked = 0
+ broken = TRUE
+ locked = FALSE
desc += "It appears to be broken."
icon_state = src.icon_broken
if(user)
@@ -67,6 +68,7 @@
if(locked)
to_chat(user, "It's locked!")
return 0
+ open = TRUE
return ..()
/obj/item/weapon/storage/lockbox/can_be_inserted(obj/item/W, stop_messages = 0)
@@ -74,6 +76,15 @@
return 0
return ..()
+/obj/item/weapon/storage/lockbox/handle_item_insertion(obj/item/W, prevent_warning = 0, mob/user)
+ open = TRUE
+ update_icon()
+ return ..()
+/obj/item/weapon/storage/lockbox/remove_from_storage(obj/item/W, atom/new_location, burn = 0)
+ open = TRUE
+ update_icon()
+ return ..()
+
/obj/item/weapon/storage/lockbox/loyalty
name = "lockbox of mindshield implants"
req_access = list(GLOB.access_security)
@@ -100,17 +111,67 @@
w_class = WEIGHT_CLASS_NORMAL
max_w_class = WEIGHT_CLASS_SMALL
storage_slots = 10
+ max_combined_w_class = 20
req_access = list(GLOB.access_captain)
icon_locked = "medalbox+l"
icon_closed = "medalbox"
icon_broken = "medalbox+b"
+ can_hold = list(/obj/item/clothing/accessory/medal)
+
+/obj/item/weapon/storage/lockbox/medal/AltClick()
+ if(!locked)
+ open = (open ? FALSE : TRUE)
+ update_icon()
+ ..()
/obj/item/weapon/storage/lockbox/medal/PopulateContents()
- new /obj/item/clothing/tie/medal/silver/valor(src)
- new /obj/item/clothing/tie/medal/bronze_heart(src)
+ new /obj/item/clothing/accessory/medal/gold/captain(src)
+ new /obj/item/clothing/accessory/medal/silver/valor(src)
+ new /obj/item/clothing/accessory/medal/silver/valor(src)
+ new /obj/item/clothing/accessory/medal/silver/security(src)
+ new /obj/item/clothing/accessory/medal/bronze_heart(src)
+ new /obj/item/clothing/accessory/medal/plasma/nobel_science(src)
+ new /obj/item/clothing/accessory/medal/plasma/nobel_science(src)
for(var/i in 1 to 3)
- new /obj/item/clothing/tie/medal/conduct(src)
- new /obj/item/clothing/tie/medal/gold/captain(src)
- new /obj/item/clothing/tie/medal/silver/security(src)
- new /obj/item/clothing/tie/medal/nobel_science(src)
- new /obj/item/clothing/tie/medal/gold/heroism(src)
+ new /obj/item/clothing/accessory/medal/conduct(src)
+
+/obj/item/weapon/storage/lockbox/medal/update_icon()
+ cut_overlays()
+ if(locked)
+ icon_state = "medalbox+l"
+ open = FALSE
+ else
+ icon_state = "medalbox"
+ if(open)
+ icon_state += "open"
+ if(broken)
+ icon_state += "+b"
+ if(contents && open)
+ for (var/i in 1 to contents.len)
+ var/obj/item/clothing/accessory/medal/M = contents[i]
+ var/mutable_appearance/medalicon = mutable_appearance(initial(icon), M.medaltype)
+ if(i > 1 && i <= 5)
+ medalicon.pixel_x += ((i-1)*3)
+ else if(i > 5)
+ medalicon.pixel_y -= 7
+ medalicon.pixel_x -= 2
+ medalicon.pixel_x += ((i-6)*3)
+ add_overlay(medalicon)
+
+/obj/item/weapon/storage/lockbox/medal/sec
+ name = "security medal box"
+ desc = "A locked box used to store medals to be given to members of the security department."
+ req_access = list(GLOB.access_hos)
+
+/obj/item/weapon/storage/lockbox/medal/sec/PopulateContents()
+ for(var/i in 1 to 3)
+ new /obj/item/clothing/accessory/medal/silver/security(src)
+
+/obj/item/weapon/storage/lockbox/medal/sci
+ name = "science medal box"
+ desc = "A locked box used to store medals to be given to members of the science department."
+ req_access = list(GLOB.access_rd)
+
+/obj/item/weapon/storage/lockbox/medal/sci/PopulateContents()
+ for(var/i in 1 to 3)
+ new /obj/item/clothing/accessory/medal/plasma/nobel_science(src)
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm
index b1301a3e8aa..fa3318b2972 100644
--- a/code/game/objects/items/weapons/storage/toolbox.dm
+++ b/code/game/objects/items/weapons/storage/toolbox.dm
@@ -140,10 +140,10 @@
max_combined_w_class = 28
storage_slots = 28
attack_verb = list("robusted", "crushed", "smashed")
- var/proselytizer_type = /obj/item/clockwork/clockwork_proselytizer/scarab
+ var/fabricator_type = /obj/item/clockwork/replica_fabricator/scarab
/obj/item/weapon/storage/toolbox/brass/prefilled/PopulateContents()
- new proselytizer_type(src)
+ new fabricator_type(src)
new /obj/item/weapon/screwdriver/brass(src)
new /obj/item/weapon/wirecutters/brass(src)
new /obj/item/weapon/wrench/brass(src)
@@ -151,7 +151,7 @@
new /obj/item/weapon/weldingtool/experimental/brass(src)
/obj/item/weapon/storage/toolbox/brass/prefilled/ratvar
- var/slab_type = /obj/item/clockwork/slab/scarab
+ var/slab_type = /obj/item/clockwork/slab
/obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/PopulateContents()
..()
@@ -159,7 +159,7 @@
/obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/admin
slab_type = /obj/item/clockwork/slab/debug
- proselytizer_type = /obj/item/clockwork/clockwork_proselytizer/scarab/debug
+ fabricator_type = /obj/item/clockwork/replica_fabricator/scarab/debug
/obj/item/weapon/storage/toolbox/artistic
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index cda39801890..c80f9cf08f2 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -87,7 +87,7 @@
new /obj/item/device/doorCharge(src)
new /obj/item/device/camera_bug(src)
new /obj/item/device/sbeacondrop/powersink(src)
- new /obj/item/weapon/cartridge/syndicate(src)
+ new /obj/item/weapon/cartridge/virus/syndicate(src)
new /obj/item/weapon/storage/toolbox/syndicate(src) //To actually get to those places
new /obj/item/pizzabox/bomb
@@ -238,6 +238,15 @@
new /obj/item/nuke_core_container(src)
new /obj/item/weapon/paper/nuke_instructions(src)
+/obj/item/weapon/storage/box/syndie_kit/supermatter
+ name = "box"
+
+/obj/item/weapon/storage/box/syndie_kit/supermatter/PopulateContents()
+ new /obj/item/weapon/scalpel/supermatter(src)
+ new /obj/item/weapon/hemostat/supermatter(src)
+ new /obj/item/nuke_core_container/supermatter(src)
+ new /obj/item/weapon/paper/supermatter_sliver_instructions(src)
+
/obj/item/weapon/storage/box/syndie_kit/tuberculosisgrenade
name = "boxed virus grenade kit"
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index 33ac3565977..4efa447a134 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -11,7 +11,7 @@
attack_verb = list("beaten")
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 50, bio = 0, rad = 0, fire = 80, acid = 80)
- var/stunforce = 7
+ var/stunforce = 140
var/status = 0
var/obj/item/weapon/stock_parts/cell/high/cell
var/hitcost = 1000
@@ -110,7 +110,7 @@
if(status && user.disabilities & CLUMSY && prob(50))
user.visible_message("[user] accidentally hits themself with [src]!", \
"You accidentally hit yourself with [src]!")
- user.Weaken(stunforce*3)
+ user.Knockdown(stunforce*3)
deductcharge(hitcost)
return
@@ -141,8 +141,8 @@
/obj/item/weapon/melee/baton/proc/baton_stun(mob/living/L, mob/user)
if(ishuman(L))
var/mob/living/carbon/human/H = L
- if(H.check_shields(0, "[user]'s [name]", src, MELEE_ATTACK)) //No message; check_shields() handles that
- playsound(L, 'sound/weapons/Genhit.ogg', 50, 1)
+ if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that
+ playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
return 0
if(iscyborg(loc))
var/mob/living/silicon/robot/R = loc
@@ -152,8 +152,7 @@
if(!deductcharge(hitcost))
return 0
- L.Stun(stunforce)
- L.Weaken(stunforce)
+ L.Knockdown(stunforce)
L.apply_effect(STUTTER, stunforce)
if(user)
user.lastattacked = L
@@ -162,7 +161,7 @@
"[user] has stunned you with [src]!")
add_logs(user, L, "stunned")
- playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
+ playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
if(ishuman(L))
var/mob/living/carbon/human/H = L
@@ -184,7 +183,7 @@
w_class = WEIGHT_CLASS_BULKY
force = 3
throwforce = 5
- stunforce = 5
+ stunforce = 100
hitcost = 2000
throw_hit_chance = 10
slot_flags = SLOT_BACK
diff --git a/code/game/objects/items/weapons/tanks/watertank.dm b/code/game/objects/items/weapons/tanks/watertank.dm
index 3a637571570..7431d4ff850 100644
--- a/code/game/objects/items/weapons/tanks/watertank.dm
+++ b/code/game/objects/items/weapons/tanks/watertank.dm
@@ -178,15 +178,16 @@
//ATMOS FIRE FIGHTING BACKPACK
#define EXTINGUISHER 0
-#define NANOFROST 1
-#define METAL_FOAM 2
+#define RESIN_LAUNCHER 1
+#define RESIN_FOAM 2
/obj/item/weapon/watertank/atmos
name = "backpack firefighter tank"
- desc = "A refridgerated and pressurized backpack tank with extinguisher nozzle, intended to fight fires. Swaps between extinguisher, nanofrost launcher, and metal foam dispenser for breaches. Nanofrost converts plasma in the air to nitrogen, but only if it is combusting at the time."
- icon_state = "waterbackpackatmos"
+ desc = "A refridgerated and pressurized backpack tank with extinguisher nozzle, intended to fight fires. Swaps between extinguisher, resin launcher and a smaller scale resin foamer."
item_state = "waterbackpackatmos"
+ icon_state = "waterbackpackatmos"
volume = 200
+ slowdown = 0
/obj/item/weapon/watertank/atmos/New()
..()
@@ -211,6 +212,7 @@
safety = 0
max_water = 200
power = 8
+ force = 10
precision = 1
cooling_power = 5
w_class = WEIGHT_CLASS_HUGE
@@ -218,7 +220,7 @@
var/obj/item/weapon/watertank/tank
var/nozzle_mode = 0
var/metal_synthesis_cooldown = 0
- var/nanofrost_cooldown = 0
+ var/resin_cooldown = 0
/obj/item/weapon/extinguisher/mini/nozzle/New(parent_tank)
..()
@@ -238,16 +240,16 @@
/obj/item/weapon/extinguisher/mini/nozzle/attack_self(mob/user)
switch(nozzle_mode)
if(EXTINGUISHER)
- nozzle_mode = NANOFROST
+ nozzle_mode = RESIN_LAUNCHER
tank.icon_state = "waterbackpackatmos_1"
- to_chat(user, "Swapped to nanofrost launcher")
+ to_chat(user, "Swapped to resin launcher")
return
- if(NANOFROST)
- nozzle_mode = METAL_FOAM
+ if(RESIN_LAUNCHER)
+ nozzle_mode = RESIN_FOAM
tank.icon_state = "waterbackpackatmos_2"
- to_chat(user, "Swapped to metal foam synthesizer")
+ to_chat(user, "Swapped to resin foamer")
return
- if(METAL_FOAM)
+ if(RESIN_FOAM)
nozzle_mode = EXTINGUISHER
tank.icon_state = "waterbackpackatmos_0"
to_chat(user, "Swapped to water extinguisher")
@@ -267,20 +269,20 @@
var/Adj = user.Adjacent(target)
if(Adj)
AttemptRefill(target, user)
- if(nozzle_mode == NANOFROST)
+ if(nozzle_mode == RESIN_LAUNCHER)
if(Adj)
return //Safety check so you don't blast yourself trying to refill your tank
var/datum/reagents/R = reagents
if(R.total_volume < 100)
- to_chat(user, "You need at least 100 units of water to use the nanofrost launcher!")
+ to_chat(user, "You need at least 100 units of water to use the resin launcher!")
return
- if(nanofrost_cooldown)
- to_chat(user, "Nanofrost launcher is still recharging...")
+ if(resin_cooldown)
+ to_chat(user, "Resin launcher is still recharging...")
return
- nanofrost_cooldown = 1
+ resin_cooldown = TRUE
R.remove_any(100)
- var/obj/effect/nanofrost_container/A = new /obj/effect/nanofrost_container(get_turf(src))
- log_game("[user.ckey] ([user.name]) used Nanofrost at [get_area(user)] ([user.x], [user.y], [user.z]).")
+ var/obj/effect/resin_container/A = new (get_turf(src))
+ log_game("[key_name_admin(user)] used Resin Launcher at [get_area(user)] [COORD(user)].")
playsound(src,'sound/items/syringeproj.ogg',40,1)
for(var/a=0, a<5, a++)
step_towards(A, target)
@@ -288,43 +290,38 @@
A.Smoke()
spawn(100)
if(src)
- nanofrost_cooldown = 0
+ resin_cooldown = FALSE
return
- if(nozzle_mode == METAL_FOAM)
+ if(nozzle_mode == RESIN_FOAM)
if(!Adj|| !isturf(target))
return
if(metal_synthesis_cooldown < 5)
- var/obj/effect/particle_effect/foam/metal/F = new /obj/effect/particle_effect/foam/metal(get_turf(target))
+ var/obj/effect/particle_effect/foam/metal/resin/F = new (get_turf(target))
F.amount = 0
metal_synthesis_cooldown++
spawn(100)
metal_synthesis_cooldown--
else
- to_chat(user, "Metal foam mix is still being synthesized...")
+ to_chat(user, "Resin foam mix is still being synthesized...")
return
-/obj/effect/nanofrost_container
- name = "nanofrost container"
- desc = "A frozen shell of ice containing nanofrost that freezes the surrounding area after activation."
+/obj/effect/resin_container
+ name = "resin container"
+ desc = "A compacted ball of expansive resin, used to repair the atmosphere in a room, or seal off breaches."
icon = 'icons/effects/effects.dmi'
icon_state = "frozen_smoke_capsule"
mouse_opacity = 0
pass_flags = PASSTABLE
-/obj/effect/nanofrost_container/proc/Smoke()
- var/datum/effect_system/smoke_spread/freezing/S = new
- S.set_up(2, src.loc, blasting=1)
- S.start()
- var/obj/effect/decal/cleanable/flour/F = new /obj/effect/decal/cleanable/flour(src.loc)
- F.add_atom_colour("#B2FFFF", FIXED_COLOUR_PRIORITY)
- F.name = "nanofrost residue"
- F.desc = "Residue left behind from a nanofrost detonation. Perhaps there was a fire here?"
+/obj/effect/resin_container/proc/Smoke()
+ var/obj/effect/particle_effect/foam/metal/resin/S = new /obj/effect/particle_effect/foam/metal/resin(get_turf(loc))
+ S.amount = 3
playsound(src,'sound/effects/bamf.ogg',100,1)
qdel(src)
#undef EXTINGUISHER
-#undef NANOFROST
-#undef METAL_FOAM
+#undef RESIN_LAUNCHER
+#undef RESIN_FOAM
/obj/item/weapon/reagent_containers/chemtank
name = "backpack chemical injector"
diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm
index 87254406ffa..ecdf443b63d 100644
--- a/code/game/objects/items/weapons/teleportation.dm
+++ b/code/game/objects/items/weapons/teleportation.dm
@@ -1,3 +1,7 @@
+
+#define SOURCE_PORTAL 1
+#define DESTINATION_PORTAL 2
+
/* Teleportation devices.
* Contains:
* Locator
@@ -136,7 +140,19 @@ Frequency:
origin_tech = "magnets=3;bluespace=4"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 100, acid = 100)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
- var/active_portals = 0
+ var/list/active_portal_pairs
+ var/max_portal_pairs = 3
+
+/obj/item/weapon/hand_tele/Initialize()
+ . = ..()
+ active_portal_pairs = list()
+
+/obj/item/weapon/hand_tele/afterattack(atom/target, mob/user, proximity, params)
+ if(is_parent_of_portal(target))
+ qdel(target)
+ to_chat(user, "You dispel [target] remotely with \the [src]!")
+ return ..()
+
/obj/item/weapon/hand_tele/attack_self(mob/user)
var/turf/current_location = get_turf(user)//What turf is the user on?
@@ -169,7 +185,7 @@ Frequency:
var/t1 = input(user, "Please select a teleporter to lock in on.", "Hand Teleporter") as null|anything in L
if (!t1 || user.get_active_held_item() != src || user.incapacitated())
return
- if(active_portals >= 3)
+ if(active_portal_pairs.len >= max_portal_pairs)
user.show_message("\The [src] is recharging!")
return
var/atom/T = L[t1]
@@ -178,7 +194,22 @@ Frequency:
to_chat(user, "\The [src] is malfunctioning.")
return
user.show_message("Locked In.", 2)
- var/obj/effect/portal/P = new /obj/effect/portal(get_turf(src), T, src)
- try_move_adjacent(P)
- active_portals++
+ var/list/obj/effect/portal/created = create_portal_pair(current_location, get_teleport_turf(get_turf(T)), src, 300, 1)
+ if(!(LAZYLEN(created) == 2))
+ return
+ try_move_adjacent(created[1])
+ active_portal_pairs[created[1]] = created[2]
add_fingerprint(user)
+
+/obj/item/weapon/hand_tele/proc/on_portal_destroy(obj/effect/portal/P)
+ active_portal_pairs -= P //If this portal pair is made by us it'll be erased along with the other portal by the portal.
+
+/obj/item/weapon/hand_tele/proc/is_parent_of_portal(obj/effect/portal/P)
+ if(!istype(P))
+ return FALSE
+ if(active_portal_pairs[P])
+ return SOURCE_PORTAL
+ for(var/i in active_portal_pairs)
+ if(active_portal_pairs[i] == P)
+ return DESTINATION_PORTAL
+ return FALSE
diff --git a/code/game/objects/items/weapons/teleprod.dm b/code/game/objects/items/weapons/teleprod.dm
index d14788e0b18..f551e1489da 100644
--- a/code/game/objects/items/weapons/teleprod.dm
+++ b/code/game/objects/items/weapons/teleprod.dm
@@ -13,10 +13,10 @@
user.visible_message("[user] accidentally hits themself with [src]!", \
"You accidentally hit yourself with [src]!")
if(do_teleport(user, get_turf(user), 50))//honk honk
- user.Weaken(stunforce*3)
+ user.Knockdown(stunforce*3)
deductcharge(hitcost)
else
- user.Weaken(stunforce*3)
+ user.Knockdown(stunforce*3)
deductcharge(hitcost/4)
return
else
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index dacd06ee826..5edea69c19f 100755
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -24,7 +24,7 @@
force = 5
throwforce = 7
w_class = WEIGHT_CLASS_SMALL
- usesound = 'sound/items/Ratchet.ogg'
+ usesound = 'sound/items/ratchet.ogg'
materials = list(MAT_METAL=150)
origin_tech = "materials=1;engineering=1"
attack_verb = list("bashed", "battered", "bludgeoned", "whacked")
@@ -53,19 +53,20 @@
desc = "A polarized wrench. It causes anything placed between the jaws to turn."
icon = 'icons/obj/abductor.dmi'
icon_state = "wrench"
- usesound = 'sound/effects/EMPulse.ogg'
+ usesound = 'sound/effects/empulse.ogg'
toolspeed = 0.1
origin_tech = "materials=5;engineering=5;abductor=3"
/obj/item/weapon/wrench/power
- name = "Hand Drill"
- desc ="A simple powered drill with a bolt bit"
+ name = "hand drill"
+ desc = "A simple powered hand drill. It's fitted with a bolt bit."
icon_state = "drill_bolt"
item_state = "drill"
usesound = 'sound/items/drill_use.ogg'
materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25)
origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get
force = 8 //might or might not be too high, subject to change
+ w_class = WEIGHT_CLASS_SMALL
throwforce = 8
attack_verb = list("drilled", "screwed", "jabbed")
toolspeed = 0.25
@@ -90,13 +91,13 @@
origin_tech = "materials=1;engineering=1;biotech=3"
attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked")
-/obj/item/weapon/wrench/medical/suicide_act(mob/user)
+/obj/item/weapon/wrench/medical/suicide_act(mob/living/user)
user.visible_message("[user] is praying to the medical wrench to take [user.p_their()] soul. It looks like [user.p_theyre()] trying to commit suicide!")
// TODO Make them glow with the power of the M E D I C A L W R E N C H
// during their ascension
// Stun stops them from wandering off
- user.Stun(5)
+ user.Stun(100, ignore_canstun = TRUE)
playsound(loc, 'sound/effects/pray.ogg', 50, 1, -1)
// Let the sound effect finish playing
@@ -137,7 +138,7 @@
materials = list(MAT_METAL=75)
attack_verb = list("stabbed")
hitsound = 'sound/weapons/bladeslice.ogg'
- usesound = 'sound/items/Screwdriver.ogg'
+ usesound = 'sound/items/screwdriver.ogg'
toolspeed = 1
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30)
@@ -177,17 +178,18 @@
desc = "An ultrasonic screwdriver."
icon = 'icons/obj/abductor.dmi'
icon_state = "screwdriver"
- usesound = 'sound/items/PSHOOM.ogg'
+ usesound = 'sound/items/pshoom.ogg'
toolspeed = 0.1
/obj/item/weapon/screwdriver/power
- name = "Hand Drill"
- desc = "A simple hand drill with a screwdriver bit attached."
+ name = "hand drill"
+ desc = "A simple powered hand drill. It's fitted with a screw bit."
icon_state = "drill_screw"
item_state = "drill"
materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25)
origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get
force = 8 //might or might not be too high, subject to change
+ w_class = WEIGHT_CLASS_SMALL
throwforce = 8
throw_speed = 2
throw_range = 3//it's heavier than a screw driver/wrench, so it does more damage, but can't be thrown as far
@@ -229,8 +231,8 @@
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=80)
attack_verb = list("pinched", "nipped")
- hitsound = 'sound/items/Wirecutter.ogg'
- usesound = 'sound/items/Wirecutter.ogg'
+ hitsound = 'sound/items/wirecutter.ogg'
+ usesound = 'sound/items/wirecutter.ogg'
origin_tech = "materials=1;engineering=1"
toolspeed = 1
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30)
@@ -281,8 +283,8 @@
toolspeed = 0.5
/obj/item/weapon/wirecutters/power
- name = "Jaws of Life"
- desc = "A set of jaws of life, the magic of science has managed to fit it down into a device small enough to fit in a tool belt. It's fitted with a cutting head."
+ name = "jaws of life"
+ desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head."
icon_state = "jaws_cutter"
item_state = "jawsoflife"
origin_tech = "materials=2;engineering=2"
@@ -321,9 +323,9 @@
force = 3
throwforce = 5
hitsound = "swing_hit"
- usesound = 'sound/items/Welder.ogg'
- var/acti_sound = 'sound/items/WelderActivate.ogg'
- var/deac_sound = 'sound/items/WelderDeactivate.ogg'
+ usesound = 'sound/items/welder.ogg'
+ var/acti_sound = 'sound/items/welderactivate.ogg'
+ var/deac_sound = 'sound/items/welderdeactivate.ogg'
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_SMALL
@@ -655,7 +657,7 @@
desc = "A small crowbar. This handy tool is useful for lots of things, such as prying floor tiles or opening unpowered doors."
icon = 'icons/obj/tools.dmi'
icon_state = "crowbar"
- usesound = 'sound/items/Crowbar.ogg'
+ usesound = 'sound/items/crowbar.ogg'
flags = CONDUCT
slot_flags = SLOT_BELT
force = 5
@@ -712,8 +714,8 @@
toolspeed = 0.5
/obj/item/weapon/crowbar/power
- name = "Jaws of Life"
- desc = "A set of jaws of life, the magic of science has managed to fit it down into a device small enough to fit in a tool belt. It's fitted with a prying head"
+ name = "jaws of life"
+ desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a prying head."
icon_state = "jaws_pry"
item_state = "jawsoflife"
materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25)
diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm
index 0fad89dec5e..fae85432d7b 100644
--- a/code/game/objects/items/weapons/twohanded.dm
+++ b/code/game/objects/items/weapons/twohanded.dm
@@ -317,7 +317,7 @@
else
user.adjustStaminaLoss(25)
-/obj/item/weapon/twohanded/dualsaber/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
+/obj/item/weapon/twohanded/dualsaber/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(wielded)
return ..()
return 0
@@ -522,7 +522,7 @@
armour_penetration = 100
force_on = 30
-/obj/item/weapon/twohanded/required/chainsaw/doomslayer/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
+/obj/item/weapon/twohanded/required/chainsaw/doomslayer/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
owner.visible_message("Ranged attacks just make [owner] angrier!")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
@@ -625,7 +625,7 @@
if(istype(target, /turf/closed/wall))
var/turf/closed/wall/W = target
user.visible_message("[user] blasts \the [target] with \the [src]!")
- playsound(target, 'sound/magic/Disintegrate.ogg', 100, 1)
+ playsound(target, 'sound/magic/disintegrate.ogg', 100, 1)
W.break_wall()
return 1
..()
@@ -648,7 +648,7 @@
slot_flags = SLOT_BACK
hitsound = 'sound/weapons/bladeslice.ogg'
-/obj/item/weapon/twohanded/vibro_weapon/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
+/obj/item/weapon/twohanded/vibro_weapon/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(wielded)
final_block_chance *= 2
if(wielded || attack_type != PROJECTILE_ATTACK)
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 71e7c0e5669..aec3c56ad16 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -185,7 +185,7 @@
remove_atom_colour(ADMIN_COLOUR_PRIORITY)
name = new_name
- playsound(user, 'sound/items/Screwdriver2.ogg', 50, 1)
+ playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
/obj/item/weapon/katana
name = "katana"
@@ -280,7 +280,7 @@
throw_range = 6
materials = list(MAT_METAL=12000)
origin_tech = "engineering=3;combat=2"
- hitsound = 'sound/weapons/Genhit.ogg'
+ hitsound = 'sound/weapons/genhit.ogg'
attack_verb = list("stubbed", "poked")
resistance_flags = FIRE_PROOF
var/extended = 0
@@ -302,7 +302,7 @@
throwforce = 5
icon_state = "switchblade"
attack_verb = list("stubbed", "poked")
- hitsound = 'sound/weapons/Genhit.ogg'
+ hitsound = 'sound/weapons/genhit.ogg'
sharpness = IS_BLUNT
/obj/item/weapon/switchblade/suicide_act(mob/user)
@@ -440,6 +440,11 @@
origin_tech = "engineering=3;combat=3;biotech=3"
needs_permit = 0
+/obj/item/weapon/melee/chainofcommand/tailwhip/kitty
+ name = "cat o' nine tails"
+ desc = "A whip fashioned from the severed tails of cats."
+ icon_state = "catwhip"
+
/obj/item/weapon/melee/skateboard
name = "skateboard"
desc = "A skateboard. It can be placed on its wheels and ridden, or used as a strong weapon."
@@ -494,7 +499,7 @@
user.visible_message("It's a home run!")
target.throw_at(throw_target, rand(8,10), 14, user)
target.ex_act(2)
- playsound(get_turf(src), 'sound/weapons/HOMERUN.ogg', 100, 1)
+ playsound(get_turf(src), 'sound/weapons/homerun.ogg', 100, 1)
homerun_ready = 0
return
else if(!target.anchored)
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index 44281fb26f2..d5d7d90d0b6 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -35,7 +35,7 @@
else
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/hitby(atom/movable/AM)
..()
@@ -132,7 +132,7 @@
if(BRUTE)
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
if(BURN)
- playsound(src, 'sound/items/Welder.ogg', 50, 1)
+ playsound(src, 'sound/items/welder.ogg', 50, 1)
if(TOX)
playsound(src, 'sound/effects/spray2.ogg', 50, 1)
return 0
@@ -172,7 +172,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
if(armour_value != "acid" && armour_value != "fire")
armor[armour_value] = max(armor[armour_value] - round(sqrt(acid_level)*0.1), 0)
if(prob(33))
- playsound(loc, 'sound/items/Welder.ogg', 150, 1)
+ playsound(loc, 'sound/items/welder.ogg', 150, 1)
take_damage(min(1 + round(sqrt(acid_level)*0.3), 300), BURN, "acid", 0)
acid_level = max(acid_level - (5 + 3*round(sqrt(acid_level))), 0)
@@ -259,3 +259,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
obj_break(damage_type)
return TRUE
return FALSE
+
+//returns how much the object blocks an explosion
+/obj/proc/GetExplosionBlock()
+ CRASH("Unimplemented GetExplosionBlock()")
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 20f8e8c15c7..549c1ebf0c1 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -23,7 +23,8 @@
var/persistence_replacement //have something WAY too amazing to live to the next round? Set a new path here. Overuse of this var will make me upset.
var/unique_rename = FALSE // can you customize the description/name of the thing?
-
+ var/current_skin //Has the item been reskinned?
+ var/list/unique_reskin //List of options to reskin.
var/dangerous_possession = FALSE //Admin possession yes/no
/obj/vv_edit_var(vname, vval)
@@ -182,7 +183,10 @@
/obj/proc/check_uplink_validity()
return 1
-/obj/proc/on_mob_move(dir, mob)
+/obj/proc/on_mob_move(dir, mob, oldLoc)
+ return
+
+/obj/proc/on_mob_turn(dir, mob)
return
/obj/vv_get_dropdown()
@@ -193,3 +197,27 @@
..()
if(unique_rename)
to_chat(user, "Use a pen on it to rename it or change its description.")
+ if(unique_reskin && !current_skin)
+ to_chat(user, "Alt-click it to reskin it.")
+
+/obj/AltClick(mob/user)
+ . = ..()
+ if(unique_reskin && !current_skin && in_range(user,src))
+ if(user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ reskin_obj(user)
+
+/obj/proc/reskin_obj(mob/M)
+ if(!LAZYLEN(unique_reskin))
+ return
+ var/choice = input(M,"Warning, you can only reskin [src] once!","Reskin Object") as null|anything in unique_reskin
+ if(!QDELETED(src) && choice && !current_skin && !M.incapacitated() && in_range(M,src))
+ if(!unique_reskin[choice])
+ return
+ current_skin = choice
+ icon_state = unique_reskin[choice]
+ to_chat(M, "[src] is now skinned as '[choice].'")
+
+/obj/proc/gang_contraband_value()
+ return 0
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 2c6371093e7..2fa19570bf9 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -4,7 +4,7 @@
obj_integrity = 300
max_integrity = 300
var/climb_time = 20
- var/climb_stun = 2
+ var/climb_stun = 20
var/climbable = FALSE
var/mob/structureclimber
var/broken = 0 //similar to machinery's stat BROKEN
@@ -33,7 +33,7 @@
if(structureclimber && structureclimber != user)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
- structureclimber.Weaken(2)
+ structureclimber.Knockdown(40)
structureclimber.visible_message("[structureclimber.name] has been knocked off the [src]", "You're knocked off the [src]!", "You see [structureclimber.name] get knocked off the [src]")
interact(user)
@@ -68,7 +68,7 @@
. = step(A,get_dir(A,src.loc))
density = 1
-/obj/structure/proc/climb_structure(mob/user)
+/obj/structure/proc/climb_structure(mob/living/user)
src.add_fingerprint(user)
user.visible_message("[user] starts climbing onto [src].", \
"You start climbing onto [src]...")
@@ -84,7 +84,8 @@
user.visible_message("[user] climbs onto [src].", \
"You climb onto [src].")
add_logs(user, src, "climbed onto")
- user.Stun(climb_stun)
+ if(climb_stun)
+ user.Stun(climb_stun)
. = 1
else
to_chat(user, "You fail to climb onto [src].")
diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm
index f3680bc8bd6..4da065bac1b 100644
--- a/code/game/objects/structures/ai_core.dm
+++ b/code/game/objects/structures/ai_core.dm
@@ -2,7 +2,7 @@
density = 1
anchored = 0
name = "\improper AI core"
- icon = 'icons/mob/AI.dmi'
+ icon = 'icons/mob/ai.dmi'
icon_state = "0"
obj_integrity = 500
max_integrity = 500
@@ -48,7 +48,7 @@
if(istype(P, /obj/item/weapon/circuitboard/aicore))
if(!user.drop_item())
return
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "You place the circuit board inside the frame.")
update_icon()
state = CIRCUIT_CORE
@@ -80,7 +80,7 @@
if(istype(P, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = P
if(C.get_amount() >= 5)
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "You start to add cables to the frame...")
if(do_after(user, 20, target = src) && state == SCREWED_CORE && C.use(5))
to_chat(user, "You add cables to the frame.")
@@ -105,7 +105,7 @@
if(istype(P, /obj/item/stack/sheet/rglass))
var/obj/item/stack/sheet/rglass/G = P
if(G.get_amount() >= 2)
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "You start to put in the glass panel...")
if(do_after(user, 20, target = src) && state == CABLED_CORE && G.use(2))
to_chat(user, "You put in the glass panel.")
diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm
index 6212133b129..c3a785eec15 100644
--- a/code/game/objects/structures/aliens.dm
+++ b/code/game/objects/structures/aliens.dm
@@ -30,7 +30,7 @@
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
if(damage_amount)
- playsound(loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(loc, 'sound/items/welder.ogg', 100, 1)
/*
* Generic alien stuff, not related to the purple lizards but still alien-like
diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm
index 2b1319c50e4..b826755aa01 100644
--- a/code/game/objects/structures/barsigns.dm
+++ b/code/game/objects/structures/barsigns.dm
@@ -59,9 +59,9 @@
/obj/structure/sign/barsign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
- playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
+ playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/structure/sign/barsign/attack_ai(mob/user)
return src.attack_hand(user)
diff --git a/code/game/objects/structures/beds_chairs/alien_nest.dm b/code/game/objects/structures/beds_chairs/alien_nest.dm
index ce3d0882ce6..28e2da03666 100644
--- a/code/game/objects/structures/beds_chairs/alien_nest.dm
+++ b/code/game/objects/structures/beds_chairs/alien_nest.dm
@@ -83,7 +83,7 @@
if(BRUTE)
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
if(BURN)
- playsound(loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(loc, 'sound/items/welder.ogg', 100, 1)
/obj/structure/bed/nest/attack_alien(mob/living/carbon/alien/user)
if(user.a_intent != INTENT_HARM)
diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm
index 7202aeae1c9..8b94bb92078 100644
--- a/code/game/objects/structures/beds_chairs/chair.dm
+++ b/code/game/objects/structures/beds_chairs/chair.dm
@@ -25,7 +25,7 @@
return ..()
/obj/structure/chair/proc/RemoveFromLatejoin()
- GLOB.latejoin -= src //These may be here due to the arrivals shuttle
+ SSjob.latejoin_trackers -= src //These may be here due to the arrivals shuttle
/obj/structure/chair/deconstruct()
// If we have materials, and don't have the NOCONSTRUCT flag
@@ -50,7 +50,7 @@
return
var/obj/item/assembly/shock_kit/SK = W
var/obj/structure/chair/e_chair/E = new /obj/structure/chair/e_chair(src.loc)
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
E.setDir(dir)
E.part = SK
SK.loc = E
@@ -234,6 +234,7 @@
throw_range = 3
hitsound = 'sound/items/trayhit1.ogg'
hit_reaction_chance = 50
+ materials = list(MAT_METAL = 2000)
var/break_chance = 5 //Likely hood of smashing the chair.
var/obj/structure/chair/origin_type = /obj/structure/chair
@@ -273,7 +274,7 @@
-/obj/item/chair/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+/obj/item/chair/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == UNARMED_ATTACK && prob(hit_reaction_chance))
owner.visible_message("[owner] fends off [attack_text] with [src]!")
return 1
@@ -288,7 +289,7 @@
if(iscarbon(target))
var/mob/living/carbon/C = target
if(C.health < C.maxHealth*0.5)
- C.Weaken(1)
+ C.Knockdown(20)
smash(user)
@@ -317,6 +318,7 @@
max_integrity = 70
hitsound = 'sound/weapons/genhit1.ogg'
origin_type = /obj/structure/chair/wood
+ materials = null
break_chance = 50
/obj/item/chair/wood/narsie_act()
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 79d7ddf8790..a610cf23269 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -29,7 +29,7 @@
var/cutting_tool = /obj/item/weapon/weldingtool
var/open_sound = 'sound/machines/click.ogg'
var/close_sound = 'sound/machines/click.ogg'
- var/cutting_sound = 'sound/items/Welder.ogg'
+ var/cutting_sound = 'sound/items/welder.ogg'
var/material_drop = /obj/item/stack/sheet/metal
var/material_drop_amount = 2
var/delivery_icon = "deliverycloset" //which icon to use when packagewrapped. null to be unwrappable.
@@ -234,7 +234,7 @@
if(!WT.remove_fuel(0, user))
return
to_chat(user, "You begin [welded ? "unwelding":"welding"] \the [src]...")
- playsound(loc, 'sound/items/Welder2.ogg', 40, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 40, 1)
if(do_after(user, 40*WT.toolspeed, 1, target = src))
if(opened || !WT.isOn())
return
@@ -291,7 +291,7 @@
"You hear a loud metal bang.")
var/mob/living/L = O
if(!issilicon(L))
- L.Weaken(2)
+ L.Knockdown(40)
O.forceMove(T)
close()
else
diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
index bb9348ee758..82e988c1fb5 100644
--- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
+++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm
@@ -20,7 +20,7 @@
var/egged = 0
/obj/structure/closet/cardboard/relaymove(mob/user, direction)
- if(opened || move_delay || user.stat || user.stunned || user.weakened || user.paralysis || !isturf(loc) || !has_gravity(loc))
+ if(opened || move_delay || user.stat || user.IsStun() || user.knockdown || user.unconscious || !isturf(loc) || !has_gravity(loc))
return
move_delay = 1
if(step(src, direction))
@@ -67,6 +67,6 @@
move_speed_multiplier = 2
cutting_tool = /obj/item/weapon/weldingtool
open_sound = 'sound/machines/click.ogg'
- cutting_sound = 'sound/items/Welder.ogg'
+ cutting_sound = 'sound/items/welder.ogg'
material_drop = /obj/item/stack/sheet/plasteel
#undef SNAKE_SPAM_TICKS
diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm
index 3bf99fb4256..f9598f52447 100644
--- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm
@@ -15,8 +15,8 @@
new /obj/item/clothing/under/sl_suit(src)
new /obj/item/clothing/under/rank/bartender(src)
new /obj/item/clothing/under/rank/bartender(src)
- new /obj/item/clothing/tie/waistcoat(src)
- new /obj/item/clothing/tie/waistcoat(src)
+ new /obj/item/clothing/accessory/waistcoat(src)
+ new /obj/item/clothing/accessory/waistcoat(src)
new /obj/item/clothing/head/soft/black(src)
new /obj/item/clothing/head/soft/black(src)
new /obj/item/clothing/shoes/sneakers/black(src)
@@ -39,8 +39,8 @@
new /obj/item/clothing/under/waiter(src)
new /obj/item/device/radio/headset/headset_srv(src)
new /obj/item/device/radio/headset/headset_srv(src)
- new /obj/item/clothing/tie/waistcoat(src)
- new /obj/item/clothing/tie/waistcoat(src)
+ new /obj/item/clothing/accessory/waistcoat(src)
+ new /obj/item/clothing/accessory/waistcoat(src)
for(var/i in 1 to 3)
new /obj/item/clothing/suit/apron/chef(src)
new /obj/item/clothing/head/soft/mime(src)
@@ -95,8 +95,8 @@
new /obj/item/clothing/suit/toggle/lawyer/black(src)
new /obj/item/clothing/shoes/laceup(src)
new /obj/item/clothing/shoes/laceup(src)
- new /obj/item/clothing/tie/lawyers_badge(src)
- new /obj/item/clothing/tie/lawyers_badge(src)
+ new /obj/item/clothing/accessory/lawyers_badge(src)
+ new /obj/item/clothing/accessory/lawyers_badge(src)
/obj/structure/closet/wardrobe/chaplain_black
name = "chapel wardrobe"
@@ -141,8 +141,8 @@
new /obj/item/clothing/suit/hooded/wintercoat/security(src)
new /obj/item/weapon/storage/backpack/security(src)
new /obj/item/weapon/storage/backpack/satchel/sec(src)
- new /obj/item/weapon/storage/backpack/dufflebag/sec(src)
- new /obj/item/weapon/storage/backpack/dufflebag/sec(src)
+ new /obj/item/weapon/storage/backpack/duffelbag/sec(src)
+ new /obj/item/weapon/storage/backpack/duffelbag/sec(src)
for(var/i in 1 to 3)
new /obj/item/clothing/under/rank/security(src)
for(var/i in 1 to 3)
@@ -177,7 +177,7 @@
icon_door = "atmos_wardrobe"
/obj/structure/closet/wardrobe/atmospherics_yellow/PopulateContents()
- new /obj/item/weapon/storage/backpack/dufflebag/engineering(src)
+ new /obj/item/weapon/storage/backpack/duffelbag/engineering(src)
new /obj/item/weapon/storage/backpack/satchel/eng(src)
new /obj/item/weapon/storage/backpack/industrial(src)
for(var/i in 1 to 3)
@@ -193,7 +193,7 @@
icon_door = "yellow"
/obj/structure/closet/wardrobe/engineering_yellow/PopulateContents()
- new /obj/item/weapon/storage/backpack/dufflebag/engineering(src)
+ new /obj/item/weapon/storage/backpack/duffelbag/engineering(src)
new /obj/item/weapon/storage/backpack/industrial(src)
new /obj/item/weapon/storage/backpack/satchel/eng(src)
new /obj/item/clothing/suit/hooded/wintercoat/engineering(src)
@@ -211,7 +211,7 @@
name = "medical doctor's wardrobe"
/obj/structure/closet/wardrobe/white/medical/PopulateContents()
- new /obj/item/weapon/storage/backpack/dufflebag/med(src)
+ new /obj/item/weapon/storage/backpack/duffelbag/med(src)
new /obj/item/weapon/storage/backpack/medic(src)
new /obj/item/weapon/storage/backpack/satchel/med(src)
new /obj/item/clothing/suit/hooded/wintercoat/medical(src)
@@ -353,3 +353,16 @@
new /obj/item/clothing/under/rank/hydroponics(src)
for(var/i in 1 to 3)
new /obj/item/clothing/mask/bandana(src)
+
+
+/obj/structure/closet/wardrobe/curator
+ name = "treasure hunting wardrobe"
+ icon_door = "black"
+
+/obj/structure/closet/wardrobe/curator/PopulateContents()
+ new /obj/item/clothing/head/fedora/curator(src)
+ new /obj/item/clothing/suit/curator(src)
+ new /obj/item/clothing/under/rank/curator/treasure_hunter(src)
+ new /obj/item/clothing/shoes/workboots/mining(src)
+ new /obj/item/weapon/storage/backpack/satchel/explorer(src)
+
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
index e30f40d173d..8154282a728 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
@@ -39,7 +39,7 @@
new /obj/item/clothing/gloves/color/yellow(src)
new /obj/item/clothing/gloves/color/yellow(src)
new /obj/item/weapon/inducer(src)
- new /obj/item/weapon/inducer(src)
+ new /obj/item/weapon/inducer(src)
for(var/i in 1 to 3)
new /obj/item/weapon/storage/toolbox/electrical(src)
for(var/i in 1 to 3)
@@ -88,7 +88,7 @@
new /obj/item/weapon/storage/toolbox/mechanical(src)
new /obj/item/weapon/tank/internals/emergency_oxygen/engi(src)
new /obj/item/device/analyzer(src)
- new /obj/item/weapon/holosign_creator/engineering(src)
+ new /obj/item/weapon/holosign_creator/atmos(src)
new /obj/item/weapon/watertank/atmos(src)
new /obj/item/clothing/suit/fire/atmos(src)
new /obj/item/clothing/head/hardhat/atmos(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
index 3fb35b0dafd..71859f80203 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
@@ -55,7 +55,7 @@
/obj/structure/closet/secure_closet/CMO/PopulateContents()
..()
new /obj/item/clothing/neck/cloak/cmo(src)
- new /obj/item/weapon/storage/backpack/dufflebag/med(src)
+ new /obj/item/weapon/storage/backpack/duffelbag/med(src)
new /obj/item/clothing/suit/bio_suit/cmo(src)
new /obj/item/clothing/head/bio_hood/cmo(src)
new /obj/item/clothing/suit/toggle/labcoat/cmo(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm
index a35c18350c9..1be12952a29 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm
@@ -7,7 +7,7 @@
/obj/structure/closet/secure_closet/personal/PopulateContents()
..()
if(prob(50))
- new /obj/item/weapon/storage/backpack/dufflebag(src)
+ new /obj/item/weapon/storage/backpack/duffelbag(src)
if(prob(50))
new /obj/item/weapon/storage/backpack(src)
else
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
old mode 100644
new mode 100755
index b1a97839aa1..6c999356d94
--- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
@@ -19,8 +19,9 @@
new /obj/item/weapon/tank/internals/air(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/device/megaphone/command(src)
+ new /obj/item/weapon/storage/lockbox/medal/sci(src)
new /obj/item/clothing/suit/armor/reactive/teleport(src)
new /obj/item/device/assembly/flash/handheld(src)
new /obj/item/device/laser_pointer(src)
new /obj/item/weapon/door_remote/research_director(src)
- new /obj/item/weapon/storage/box/firingpins(src)
+ new /obj/item/weapon/storage/box/firingpins(src)
\ No newline at end of file
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
old mode 100644
new mode 100755
index bcea83bdc1b..03828deb153
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -11,7 +11,7 @@
else
new /obj/item/weapon/storage/backpack/satchel/cap(src)
new /obj/item/clothing/neck/cloak/cap(src)
- new /obj/item/weapon/storage/backpack/dufflebag/captain(src)
+ new /obj/item/weapon/storage/backpack/duffelbag/captain(src)
new /obj/item/clothing/head/crown/fancy(src)
new /obj/item/clothing/suit/captunic(src)
new /obj/item/clothing/under/captainparade(src)
@@ -72,6 +72,8 @@
new /obj/item/clothing/head/HoS(src)
new /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch(src)
new /obj/item/clothing/glasses/hud/security/sunglasses/gars/supergars(src)
+ new /obj/item/clothing/under/rank/head_of_security/grey(src)
+ new /obj/item/weapon/storage/lockbox/medal/sec(src)
new /obj/item/device/megaphone/sec(src)
new /obj/item/weapon/holosign_creator/security(src)
new /obj/item/weapon/storage/lockbox/loyalty(src)
@@ -131,28 +133,28 @@
/obj/structure/closet/secure_closet/security/cargo/PopulateContents()
..()
- new /obj/item/clothing/tie/armband/cargo(src)
+ new /obj/item/clothing/accessory/armband/cargo(src)
new /obj/item/device/encryptionkey/headset_cargo(src)
/obj/structure/closet/secure_closet/security/engine
/obj/structure/closet/secure_closet/security/engine/PopulateContents()
..()
- new /obj/item/clothing/tie/armband/engine(src)
+ new /obj/item/clothing/accessory/armband/engine(src)
new /obj/item/device/encryptionkey/headset_eng(src)
/obj/structure/closet/secure_closet/security/science
/obj/structure/closet/secure_closet/security/science/PopulateContents()
..()
- new /obj/item/clothing/tie/armband/science(src)
+ new /obj/item/clothing/accessory/armband/science(src)
new /obj/item/device/encryptionkey/headset_sci(src)
/obj/structure/closet/secure_closet/security/med
/obj/structure/closet/secure_closet/security/med/PopulateContents()
..()
- new /obj/item/clothing/tie/armband/medblue(src)
+ new /obj/item/clothing/accessory/armband/medblue(src)
new /obj/item/device/encryptionkey/headset_med(src)
/obj/structure/closet/secure_closet/detective
@@ -167,10 +169,10 @@
..()
new /obj/item/clothing/under/rank/det(src)
new /obj/item/clothing/suit/det_suit(src)
- new /obj/item/clothing/head/det_hat(src)
+ new /obj/item/clothing/head/fedora/det_hat(src)
new /obj/item/clothing/gloves/color/black(src)
new /obj/item/clothing/under/rank/det/grey(src)
- new /obj/item/clothing/tie/waistcoat(src)
+ new /obj/item/clothing/accessory/waistcoat(src)
new /obj/item/clothing/suit/det_suit/grey(src)
new /obj/item/clothing/head/fedora(src)
new /obj/item/clothing/shoes/laceup(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm
index 030aa373eab..eec62d43414 100644
--- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm
+++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm
@@ -25,7 +25,7 @@
new /obj/item/ammo_box/magazine/m10mm(src)
new /obj/item/weapon/storage/box/flashbangs(src)
new /obj/item/weapon/storage/box/teargas(src)
- new /obj/item/weapon/storage/backpack/dufflebag/syndie/med(src)
+ new /obj/item/weapon/storage/backpack/duffelbag/syndie/med(src)
new /obj/item/device/pda/syndicate(src)
return
diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
index a173a20dc0c..1d2d4b5855c 100644
--- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
+++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
@@ -126,7 +126,7 @@
for(var/i in 1 to 3)
new /obj/item/clothing/head/soft/grey(src)
if(prob(50))
- new /obj/item/weapon/storage/backpack/dufflebag(src)
+ new /obj/item/weapon/storage/backpack/duffelbag(src)
if(prob(40))
new /obj/item/clothing/mask/bandana/black(src)
new /obj/item/clothing/mask/bandana/black(src)
@@ -137,6 +137,8 @@
if(prob(30))
new /obj/item/clothing/suit/hooded/wintercoat(src)
new /obj/item/clothing/shoes/winterboots(src)
+ if(prob(30))
+ new /obj/item/clothing/accessory/pocketprotector(src)
return
diff --git a/code/game/objects/structures/crates_lockers/crates/wooden.dm b/code/game/objects/structures/crates_lockers/crates/wooden.dm
new file mode 100644
index 00000000000..7272bd4e24a
--- /dev/null
+++ b/code/game/objects/structures/crates_lockers/crates/wooden.dm
@@ -0,0 +1,18 @@
+/obj/structure/closet/crate/wooden
+ name = "wooden crate"
+ desc = "Works just as well as a metal one."
+ material_drop = /obj/item/stack/sheet/mineral/wood
+ material_drop_amount = 6
+ icon_state = "wooden"
+
+/obj/structure/closet/crate/wooden/toy
+ name = "toy box"
+ desc = "It has the words \"Clown + Mime\" written underneath of it with marker."
+
+/obj/structure/closet/crate/wooden/toy/PopulateContents()
+ . = ..()
+ new /obj/item/device/megaphone/clown(src)
+ new /obj/item/weapon/reagent_containers/food/drinks/soda_cans/canned_laughter(src)
+ new /obj/item/weapon/pneumatic_cannon/pie(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/pie/cream(src)
+ new /obj/item/weapon/storage/crayons(src)
\ No newline at end of file
diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm
index 597efa8e120..dab876b2421 100644
--- a/code/game/objects/structures/displaycase.dm
+++ b/code/game/objects/structures/displaycase.dm
@@ -46,9 +46,9 @@
/obj/structure/displaycase/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
- playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
+ playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/structure/displaycase/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
@@ -127,7 +127,7 @@
playsound(loc, WT.usesound, 40, 1)
if(do_after(user, 40*W.toolspeed, target = src))
obj_integrity = max_integrity
- playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
update_icon()
to_chat(user, "You repair [src].")
else
@@ -204,7 +204,7 @@
to_chat(user, "You start disassembling [src]...")
playsound(src.loc, I.usesound, 50, 1)
if(do_after(user, 30*I.toolspeed, target = src))
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
new /obj/item/stack/sheet/mineral/wood(get_turf(src), 5)
qdel(src)
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index b37856df70b..978b88af663 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -508,7 +508,7 @@
if(WT.remove_fuel(0,user))
user.visible_message("[user] disassembles the airlock assembly.", \
"You start to disassemble the airlock assembly...")
- playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/welder2.ogg', 50, 1)
if(do_after(user, 40*W.toolspeed, target = src))
if( !WT.isOn() )
@@ -618,7 +618,7 @@
if(G)
if(G.get_amount() >= 1)
if(istype(G, /obj/item/stack/sheet/rglass) || istype(G, /obj/item/stack/sheet/glass))
- playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/crowbar.ogg', 100, 1)
user.visible_message("[user] adds [G.name] to the airlock assembly.", \
"You start to install [G.name] into the airlock assembly...")
if(do_after(user, 40, target = src))
@@ -646,7 +646,7 @@
else if(istype(G, /obj/item/stack/sheet/mineral))
var/M = G.sheettype
if(G.get_amount() >= 2)
- playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/crowbar.ogg', 100, 1)
user.visible_message("[user] adds [G.name] to the airlock assembly.", \
"You start to install [G.name] into the airlock assembly...")
if(do_after(user, 40, target = src))
diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm
index 104b86bc061..c9ff698411d 100644
--- a/code/game/objects/structures/dresser.dm
+++ b/code/game/objects/structures/dresser.dm
@@ -6,6 +6,18 @@
density = 1
anchored = 1
+/obj/structure/dresser/attackby(obj/item/P, mob/user, params)
+ if(istype(P, /obj/item/weapon/wrench))
+ to_chat(user, "You begin to [anchored ? "unwrench" : "wrench"] [src].")
+ playsound(src, P.usesound, 50, 1)
+ if(do_after(user, 20, target = src))
+ to_chat(user, "You successfully [anchored ? "unwrench" : "wrench"] [src].")
+ anchored = !anchored
+
+/obj/structure/dresser/deconstruct(disassembled = TRUE)
+ new /obj/item/stack/sheet/mineral/wood (get_turf(src), 10)
+ qdel(src)
+
/obj/structure/dresser/attack_hand(mob/user)
if(!Adjacent(user))//no tele-grooming
return
diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm
index 898114525ea..f76dd1e9199 100644
--- a/code/game/objects/structures/extinguisher.dm
+++ b/code/game/objects/structures/extinguisher.dm
@@ -42,7 +42,7 @@
to_chat(user, "You start unsecuring [name]...")
playsound(loc, I.usesound, 50, 1)
if(do_after(user, 60*I.toolspeed, target = src))
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "You unsecure [name].")
deconstruct(TRUE)
return
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index 43e0de52a14..49154c9f45d 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -126,7 +126,7 @@
/obj/structure/falsewall/proc/dismantle(mob/user, disassembled = TRUE)
user.visible_message("[user] dismantles the false wall.", "You dismantle the false wall.")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
deconstruct(disassembled)
/obj/structure/falsewall/deconstruct(disassembled = TRUE)
@@ -242,7 +242,7 @@
return ..()
/obj/structure/falsewall/plasma/proc/burnbabyburn(user)
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
atmos_spawn_air("plasma=400;TEMP=1000")
new /obj/structure/girder/displaced(loc)
qdel(src)
diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm
index 8d9c6685428..59ae52e4b3e 100644
--- a/code/game/objects/structures/fireaxe.dm
+++ b/code/game/objects/structures/fireaxe.dm
@@ -32,7 +32,7 @@
playsound(loc, WT.usesound, 40, 1)
if(do_after(user, 40*I.toolspeed, target = src))
obj_integrity = max_integrity
- playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
update_icon()
to_chat(user, "You repair [src].")
else
@@ -72,9 +72,9 @@
if(broken)
playsound(loc, 'sound/effects/hit_on_shattered_glass.ogg', 90, 1)
else
- playsound(loc, 'sound/effects/Glasshit.ogg', 90, 1)
+ playsound(loc, 'sound/effects/glasshit.ogg', 90, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/structure/fireaxecabinet/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
if(open)
@@ -87,7 +87,7 @@
if(!broken && !(flags & NODECONSTRUCT))
update_icon()
broken = TRUE
- playsound(src, 'sound/effects/Glassbr3.ogg', 100, 1)
+ playsound(src, 'sound/effects/glassbr3.ogg', 100, 1)
new /obj/item/weapon/shard(loc)
new /obj/item/weapon/shard(loc)
diff --git a/code/game/objects/structures/fluff.dm b/code/game/objects/structures/fluff.dm
index 83b7fde171b..83904e7ee65 100644
--- a/code/game/objects/structures/fluff.dm
+++ b/code/game/objects/structures/fluff.dm
@@ -17,7 +17,7 @@
if(!do_after(user, 50, target = src))
return 0
user.visible_message("[user] disassembles [src]!", "You break down [src] into scrap metal.")
- playsound(user, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(user, 'sound/items/deconstruct.ogg', 50, 1)
new/obj/item/stack/sheet/metal(get_turf(src))
qdel(src)
return
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index 905933f0e99..194d8c42a29 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -395,76 +395,45 @@
H.faction |= "syndicate"
/obj/effect/mob_spawn/human/syndicate/battlecruiser
- name = "Syndicate Battlecruiser Ensign"
- flavour_text = "You are a syndicate ensign aboard a state of the art weapons platform -- the SBC Starfury. Follow your captain's orders, maintain the ship, and protect both with your life."
+ name = "Syndicate Battlecruiser Ship Operative"
+ flavour_text = "You are a crewmember aboard the syndicate flagship: the SBC Starfury. Your job is to follow your captain's orders, maintain the ship, and keep the engine running. If you are not familiar with how the supermatter engine functions: do not attempt to start it.
The armory is not a candy store, and your role is not to assault the station directly, leave that work to the assault operatives."
outfit = /datum/outfit/syndicate_empty/SBC
/datum/outfit/syndicate_empty/SBC
- name = "Syndicate Battlecruiser Ensign"
- belt = /obj/item/weapon/gun/ballistic/automatic/pistol
+ name = "Syndicate Battlecruiser Ship Operative"
+ l_pocket = /obj/item/weapon/gun/ballistic/automatic/pistol
r_pocket = /obj/item/weapon/kitchen/knife/combat/survival
+ belt = /obj/item/weapon/storage/belt/military/assault
+
+/obj/effect/mob_spawn/human/syndicate/battlecruiser/assault
+ name = "Syndicate Battlecruiser Assault Operative"
+ flavour_text = "You are an assault operative aboard the syndicate flagship: the SBC Starfury. Your job is to follow your captain's orders, keep intruders out of the ship, and assault Space Station 13. There is an armory, multiple assault ships, and beam cannons to attack the station with.
Work as a team with your fellow operatives and work out a plan of attack. If you are overwhelmed, escape back to your ship!"
+ outfit = /datum/outfit/syndicate_empty/SBC/assault
+
+/datum/outfit/syndicate_empty/SBC/assault
+ name = "Syndicate Battlecruiser Assault Operative"
+ uniform = /obj/item/clothing/under/syndicate/combat
+ l_pocket = /obj/item/ammo_box/magazine/m10mm
+ r_pocket = /obj/item/weapon/kitchen/knife/combat/survival
+ belt = /obj/item/weapon/storage/belt/military
suit = /obj/item/clothing/suit/armor/vest
+ suit_store = /obj/item/weapon/gun/ballistic/automatic/pistol
+ back = /obj/item/weapon/storage/backpack/security
+ mask = /obj/item/clothing/mask/gas/syndicate
/obj/effect/mob_spawn/human/syndicate/battlecruiser/captain
name = "Syndicate Battlecruiser Captain"
- flavour_text = "You are a syndicate admiral in command of a state of the art weapons platform -- the SBC Starfury. You are to destroy Nanotrasens' Space Station 13. Do not let the enemy take control of your ship under any circumstances."
- outfit = /datum/outfit/syndicate_empty/SBC/captain
+ flavour_text = "You are the captain aboard the syndicate flagship: the SBC Starfury. Your job is to oversee your crew, defend the ship, and destroy Space Station 13. The ship has an armory, multiple ships, beam cannons, and multiple crewmembers to accomplish this goal.
As the captain, this whole operation falls on your shoulders. You do not need to nuke the station, causing sufficient damage and preventing your ship from being destroyed will be enough."
+ outfit = /datum/outfit/syndicate_empty/SBC/assault/captain
id_access_list = list(150,151)
-/datum/outfit/syndicate_empty/SBC/captain
+/datum/outfit/syndicate_empty/SBC/assault/captain
name = "Syndicate Battlecruiser Captain"
- belt = /obj/item/weapon/gun/ballistic/automatic/pistol
+ l_pocket = /obj/item/weapon/melee/energy/sword/saber/red
r_pocket = /obj/item/weapon/melee/classic_baton/telescopic
suit = /obj/item/clothing/suit/armor/vest/capcarapace/syndicate
+ suit_store = /obj/item/weapon/gun/ballistic/revolver/mateba
back = /obj/item/weapon/storage/backpack/satchel/leather
- head = /obj/item/clothing/head/HoS/beret/syndicate
+ head = /obj/item/clothing/head/HoS/syndicate
mask = /obj/item/clothing/mask/cigarette/cigar/havana
- glasses = /obj/item/clothing/glasses/thermal/eyepatch
-
-//UEG Marine
-/obj/effect/mob_spawn/human/marine
- name = "marine cryostasis sleeper"
- desc = "A humming sleeper with a occupant inside. Desperatly attempting to revive the occupant despite its low power state."
- mob_name = "a iron hawk marine"
- icon = 'icons/obj/lavaland/spawners.dmi'
- icon_state = "cryostasis_sleeper"
- roundstart = FALSE
- death = FALSE
- random = TRUE
- mob_species = /datum/species/human
- flavour_text = "You are a Iron Hawk Marine, apart of a unalligned mercenary organization. You were, until recently, stationed on board the IHSS Inheritor, a capital ship. As you struggle \
- to exit your cryostasis sleeper, you slowly start to recall exactly what cause of events has thrown you into your current predicament... "
-
-/obj/effect/mob_spawn/human/marine/Initialize(mapload)
- . = ..()
- var/lorpee = rand(1,4)
- switch(lorpee)
- if(1)
- flavour_text += "Your ship intercepted a distress call from a distant space station. As the Inheritor moved into investigate, suddenly and without warning the ship was being assaulted \
- by a massive lovecraftian nightmare, you heard the name 'Nar-Sie' being uttered by the barely Human flesh monsters and constructs that poured out of every crack that was torn into the \
- ship by the monster. With most of the crew dead, you and your squad retreated to the hanger bay, rescued a group of pilots and attempted to flee aboard the only functional heavy troop transport. \
- Your attempt to fly away was halted when Nar-Sie somehow was able to start attempting to drag the transport into her grasp. In one final desperate move, the pilots turnd the ship around \
- and ramed it directly into Nar-Sie's head, her screams somehow echoed throughout the transport as she released her grasp on the transport, unfortunately taking half the engines with her. \
- Your final thoughts were panic as you quickly dove into your cryosleep pod, hoping you'll survive the crash landing."
- if(2)
- flavour_text += "Panic and paranoia ran high as a group of changelings somehow infiltrated the Inheritor. Utterly unprepared to deal with this threat, the crew tore itself apart. \
- In a final desperate move to end the changeling threat, the ship's Commander activated the Inheritor's self destruct sequence and remotely shut down all escape pods. You and your \
- squadmates, who were already on the brink of a psychological breakdown, made a run for the last remaining heavy troop transport. You arrive to discover the changelings had a similar plan \
- , with minutes until the ship exploded, the changelings abandoned any pretense of subtly and revealed their true forms. After a intense gun fight you and your squad were able to board \
- the transport. However as you take off, one of the surviving Changelings was able to plant an explosive charge on your engines. The explosion disabled your ship, and you got caught in a \
- nearby planets gravity well. The survivors were forced into cryo sleep, as you're last thoughts were hoping to god none of your squad mates were secretly changelings."
- if(3)
- flavour_text += "The deeper reaches of space are home to hoards of pirates and marauders, usually they are no threat to a Iron Hawk capital ship. However, the Inheritor had conducted a \
- large series of anti-piracy raids in your assigned sector, so crippling that every pirate in the local sector network formed a massive fleet in a attempt to destroy the Inheritor. The \
- Inheritor won against all odds, but it was a pyrrhic victory as the Inheritor was byond repair. The acting Commander ordered all hands to abandon ship before it was scuttled. You and \
- your remaining squad members were assigned to troop transport 5. Unbeknown to you or your pilots, your fuel tanks had suffered a massive leak during the fighting, leaving you with minimal \
- fuel, thus your pilots had no choice but to land on a nearby planet. Strapping into your cryochamber, you can only hope that the pilots could land this thing safely."
- if(4)
- flavour_text += "The Inheritor was sent on a high level covert recon contract to Space Station 13, a Nanotrasen research and development station. The contract details were minimal sans that \
- you were to locate and ping any Nanotrasen mining bases on a class-H planet. You and your squad were dispatched in a recon heavy transport \
- to attempt to fly over the planet and locate any hidden Nanotrasen mining bases. About two hours into the recon mission, a giant, dragon like, creature swooped up and took a large part of your \
- engines with it. With insufficient thrust power to leave the planet's atmosphere, the crew were ordered into cryostasis as the pilots attempted an emergency landing."
-
-/obj/effect/mob_spawn/human/marine/Destroy()
- new/obj/structure/fluff/empty_cryostasis_sleeper(get_turf(src))
- return ..()
+ glasses = /obj/item/clothing/glasses/thermal/eyepatch
\ No newline at end of file
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index bdf2a5eb402..accccbc1633 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -80,7 +80,7 @@
else if(istype(W, /obj/item/weapon/gun/energy/plasmacutter))
to_chat(user, "You start slicing apart the girder...")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
if(do_after(user, 40*W.toolspeed, target = src))
to_chat(user, "You slice apart the girder.")
var/obj/item/stack/sheet/metal/M = new (loc, 2)
@@ -352,7 +352,7 @@
else if(istype(W, /obj/item/weapon/gun/energy/plasmacutter))
to_chat(user, "You start slicing apart the girder...")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
if(do_after(user, 40*W.toolspeed, target = src))
to_chat(user, "You slice apart the girder.")
var/obj/item/stack/sheet/runed_metal/R = new(get_turf(src))
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 64d93e914e1..e2e8f7e5c94 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -23,7 +23,9 @@
if(RCD_DECONSTRUCT)
return list("mode" = RCD_DECONSTRUCT, "delay" = 20, "cost" = 5)
if(RCD_WINDOWGRILLE)
- return list("mode" = RCD_WINDOWGRILLE, "delay" = 40, "cost" = 10)
+ if(the_rcd.window_type == /obj/structure/window/reinforced/fulltile)
+ return list("mode" = RCD_WINDOWGRILLE, "delay" = 40, "cost" = 12)
+ else return list("mode" = RCD_WINDOWGRILLE, "delay" = 20, "cost" = 8)
return FALSE
/obj/structure/grille/rcd_act(mob/user, var/obj/item/weapon/construction/rcd/the_rcd, passed_mode)
@@ -227,7 +229,7 @@
var/turf/T = get_turf(src)
var/obj/structure/cable/C = T.get_cable_node()
if(C)
- playsound(src.loc, 'sound/magic/LightningShock.ogg', 100, 1, extrarange = 5)
+ playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
tesla_zap(src, 3, C.powernet.avail * 0.01) //Zap for 1/100 of the amount of power. At a million watts in the grid, it will be as powerful as a tesla revolver shot.
C.powernet.load += C.powernet.avail * 0.0375 // you can gain up to 3.5 via the 4x upgrades power is halved by the pole so thats 2x then 1X then .5X for 3.5x the 3 bounces shock.
return ..()
@@ -248,6 +250,7 @@
/obj/structure/grille/ratvar
icon_state = "ratvargrille"
+ name = "cog grille"
desc = "A strangely-shaped grille."
broken_type = /obj/structure/grille/ratvar/broken
diff --git a/code/game/objects/structures/hivebot.dm b/code/game/objects/structures/hivebot.dm
index 6fa17d2f96c..7a69b17a153 100644
--- a/code/game/objects/structures/hivebot.dm
+++ b/code/game/objects/structures/hivebot.dm
@@ -14,7 +14,7 @@
smoke.set_up(2, loc)
smoke.start()
visible_message("The [src] warps in!")
- playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
+ playsound(src.loc, 'sound/effects/empulse.ogg', 25, 1)
addtimer(CALLBACK(src, .proc/warpbots), rand(10, 600))
/obj/structure/hivebot_beacon/proc/warpbots()
@@ -31,6 +31,6 @@
new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src))
sleep(100)
visible_message("The [src] warps out!")
- playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
+ playsound(src.loc, 'sound/effects/empulse.ogg', 25, 1)
qdel(src)
return
diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm
index a27febc997a..841ce45b7b5 100644
--- a/code/game/objects/structures/holosign.dm
+++ b/code/game/objects/structures/holosign.dm
@@ -30,9 +30,9 @@
/obj/structure/holosign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
- playsound(loc, 'sound/weapons/Egloves.ogg', 80, 1)
+ playsound(loc, 'sound/weapons/egloves.ogg', 80, 1)
if(BURN)
- playsound(loc, 'sound/weapons/Egloves.ogg', 80, 1)
+ playsound(loc, 'sound/weapons/egloves.ogg', 80, 1)
/obj/structure/holosign/wetsign
name = "wet floor sign"
@@ -65,6 +65,26 @@
/obj/structure/holosign/barrier/engineering
icon_state = "holosign_engi"
+/obj/structure/holosign/barrier/atmos
+ name = "holo firelock"
+ desc = "A holographic barrier resembling a firelock. Though it does not prevent solid objects from passing through, gas is kept out."
+ icon_state = "holo_firelock"
+ density = FALSE
+ layer = ABOVE_MOB_LAYER
+ anchored = TRUE
+ CanAtmosPass = ATMOS_PASS_NO
+ layer = ABOVE_MOB_LAYER
+ alpha = 150
+
+/obj/structure/holosign/barrier/atmos/Initialize()
+ . = ..()
+ air_update_turf(TRUE)
+
+/obj/structure/holosign/barrier/atmos/Destroy()
+ var/turf/T = get_turf(src)
+ . = ..()
+ T.air_update_turf(TRUE)
+
/obj/structure/holosign/barrier/cyborg
name = "Energy Field"
desc = "A fragile energy field that blocks movement. Excels at blocking lethal projectiles."
diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm
index 4ddd7067e5e..258b6374cbd 100644
--- a/code/game/objects/structures/kitchen_spike.dm
+++ b/code/game/objects/structures/kitchen_spike.dm
@@ -139,7 +139,7 @@
src.visible_message(text("[M] falls free of the [src]!"))
unbuckle_mob(M,force=1)
M.emote("scream")
- M.AdjustWeakened(10)
+ M.AdjustKnockdown(20)
/obj/structure/kitchenspike/deconstruct(disassembled = TRUE)
if(disassembled)
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index 2f6b03bef16..4b2017fab65 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -50,7 +50,7 @@
deconstruct()
/obj/structure/lattice/clockwork
- name = "clockwork lattice"
+ name = "cog lattice"
desc = "A lightweight support lattice. These hold the Justicar's station together."
icon = 'icons/obj/smooth_structures/lattice_clockwork.dmi'
diff --git a/code/game/objects/structures/life_candle.dm b/code/game/objects/structures/life_candle.dm
index bab1a844839..1f4c672114d 100644
--- a/code/game/objects/structures/life_candle.dm
+++ b/code/game/objects/structures/life_candle.dm
@@ -22,7 +22,7 @@
var/datum/outfit/outfit
// How long until we respawn them after their death.
var/respawn_time = 50
- var/respawn_sound = 'sound/magic/Staff_animation.ogg'
+ var/respawn_sound = 'sound/magic/staff_animation.ogg'
/obj/structure/life_candle/attack_hand(mob/user)
if(!user.mind)
diff --git a/code/game/objects/structures/manned_turret.dm b/code/game/objects/structures/manned_turret.dm
index aed77a0e8dc..5a5972df889 100644
--- a/code/game/objects/structures/manned_turret.dm
+++ b/code/game/objects/structures/manned_turret.dm
@@ -38,7 +38,7 @@
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 0
if(buckled_mob.client)
- buckled_mob.reset_perspective()
+ buckled_mob.client.change_view(world.view)
anchored = FALSE
. = ..()
STOP_PROCESSING(SSfastprocess, src)
@@ -47,7 +47,9 @@
if(user.incapacitated() || !istype(user))
return
M.forceMove(get_turf(src))
- ..()
+ . = ..()
+ if(!.)
+ return
for(var/V in M.held_items)
var/obj/item/I = V
if(istype(I))
@@ -62,8 +64,8 @@
setDir(SOUTH)
playsound(src,'sound/mecha/mechmove01.ogg', 50, 1)
anchored = TRUE
- if(user.client)
- user.client.change_view(view_range)
+ if(M.client)
+ M.client.change_view(view_range)
START_PROCESSING(SSfastprocess, src)
/obj/machinery/manned_turret/process()
@@ -84,6 +86,8 @@
calculated_projectile_vars = calculate_projectile_angle_and_pixel_offsets(controller, C.mouseParams)
/obj/machinery/manned_turret/proc/direction_track(mob/user, atom/targeted)
+ if(user.stat != CONSCIOUS)
+ return
setDir(get_dir(src,targeted))
user.setDir(dir)
switch(dir)
@@ -149,7 +153,7 @@
P.starting = targets_from
P.firer = user
P.original = target
- playsound(src, 'sound/weapons/Gunshot_smg.ogg', 75, 1)
+ playsound(src, 'sound/weapons/gunshot_smg.ogg', 75, 1)
P.xo = target.x - targets_from.x
P.yo = target.y - targets_from.y
P.Angle = calculated_projectile_vars[1] + rand(-9, 9)
@@ -174,7 +178,7 @@
icon = 'icons/obj/weapons.dmi'
icon_state = "offhand"
w_class = WEIGHT_CLASS_HUGE
- flags = ABSTRACT | NODROP | NOBLUDGEON
+ flags = ABSTRACT | NODROP | NOBLUDGEON | DROPDEL
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/obj/machinery/manned_turret/turret
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index ada75846e79..dcbc910e342 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -5,7 +5,7 @@
name = "metal door"
density = 1
anchored = 1
- opacity = 1
+ opacity = TRUE
icon = 'icons/obj/doors/mineral_doors.dmi'
icon_state = "metal"
@@ -86,11 +86,11 @@
/obj/structure/mineral_door/proc/Open()
isSwitchingStates = 1
- playsound(loc, openSound, 100, 1)
+ playsound(src, openSound, 100, 1)
+ set_opacity(FALSE)
flick("[initial_state]opening",src)
sleep(10)
density = 0
- opacity = 0
state = 1
air_update_turf(1)
update_icon()
@@ -110,7 +110,7 @@
flick("[initial_state]closing",src)
sleep(10)
density = 1
- opacity = 1
+ set_opacity(TRUE)
state = 0
air_update_turf(1)
update_icon()
@@ -175,11 +175,11 @@
max_integrity = 100
/obj/structure/mineral_door/transparent
- opacity = 0
+ opacity = FALSE
/obj/structure/mineral_door/transparent/Close()
..()
- opacity = 0
+ set_opacity(FALSE)
/obj/structure/mineral_door/transparent/plasma
name = "plasma door"
@@ -219,3 +219,22 @@
resistance_flags = FLAMMABLE
obj_integrity = 200
max_integrity = 200
+
+/obj/structure/mineral_door/paperframe
+ name = "paper frame door"
+ icon_state = "paperframe"
+ openSound = 'sound/effects/doorcreaky.ogg'
+ closeSound = 'sound/effects/doorcreaky.ogg'
+ sheetType = /obj/item/stack/sheet/paperframes
+ sheetAmount = 3
+ resistance_flags = FLAMMABLE
+ obj_integrity = 20
+ max_integrity = 20
+
+/obj/structure/mineral_door/paperframe/Initialize()
+ . = ..()
+ queue_smooth_neighbors(src)
+
+/obj/structure/mineral_door/paperframe/Destroy()
+ queue_smooth_neighbors(src)
+ return ..()
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index cfcfd425f32..b8367721b1f 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -67,7 +67,7 @@
user.changeNext_move(CLICK_CD_MELEE)
if(WT.remove_fuel(0, user))
to_chat(user, "You begin repairing [src]...")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
if(do_after(user, 10*I.toolspeed, target = src))
if(!user || !WT || !WT.isOn())
return
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index 3edb53a1ff4..18c7842d145 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -3,6 +3,7 @@
* Morgue
* Morgue tray
* Crematorium
+ * Creamatorium
* Crematorium tray
* Crematorium button
*/
@@ -91,14 +92,14 @@
container_resist(user)
/obj/structure/bodycontainer/proc/open()
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
var/turf/T = get_step(src, opendir)
for(var/atom/movable/AM in src)
AM.forceMove(T)
update_icon()
/obj/structure/bodycontainer/proc/close()
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
for(var/atom/movable/AM in connected.loc)
if(!AM.anchored || AM == connected)
AM.forceMove(src)
@@ -189,7 +190,7 @@ GLOBAL_LIST_EMPTY(crematoriums)
// Make sure we don't delete the actual morgue and its tray
var/list/conts = GetAllContents() - src - connected
- if(conts.len <= 1)
+ if(!conts.len)
audible_message("You hear a hollow crackle.")
return
@@ -223,6 +224,20 @@ GLOBAL_LIST_EMPTY(crematoriums)
update_icon()
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) //you horrible people
+/obj/structure/bodycontainer/crematorium/creamatorium
+ name = "creamatorium"
+ desc = "A human incinerator. Works well during ice cream socials."
+
+/obj/structure/bodycontainer/crematorium/creamatorium/cremate(mob/user)
+ var/list/icecreams = new()
+ for(var/mob/living/i_scream in GetAllContents())
+ var/obj/item/weapon/reagent_containers/food/snacks/icecream/IC = new()
+ IC.set_cone_type("waffle")
+ IC.add_mob_flavor(i_scream)
+ icecreams += IC
+ . = ..()
+ for(var/obj/IC in icecreams)
+ IC.forceMove(src)
/*
* Generic Tray
diff --git a/code/game/objects/structures/petrified_statue.dm b/code/game/objects/structures/petrified_statue.dm
index 421bc0d6996..80e535dc92c 100644
--- a/code/game/objects/structures/petrified_statue.dm
+++ b/code/game/objects/structures/petrified_statue.dm
@@ -30,7 +30,7 @@
if(!petrified_mob)
STOP_PROCESSING(SSobj, src)
timer--
- petrified_mob.Stun(2) //So they can't do anything while petrified
+ petrified_mob.Stun(40) //So they can't do anything while petrified
if(timer <= 0)
STOP_PROCESSING(SSobj, src)
qdel(src)
@@ -50,7 +50,7 @@
if(S.mind)
if(petrified_mob)
S.mind.transfer_to(petrified_mob)
- petrified_mob.Weaken(5)
+ petrified_mob.Knockdown(100)
to_chat(petrified_mob, "You slowly come back to your senses. You are in control of yourself again!")
qdel(S)
diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm
index 2365930c3b6..817d687c008 100644
--- a/code/game/objects/structures/reflector.dm
+++ b/code/game/objects/structures/reflector.dm
@@ -55,7 +55,7 @@
switch(anchored)
if(0)
if (WT.remove_fuel(0,user))
- playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/welder2.ogg', 50, 1)
user.visible_message("[user.name] starts to weld the [src.name] to the floor.", \
"You start to weld \the [src] to the floor...", \
"You hear welding.")
@@ -66,7 +66,7 @@
to_chat(user, "You weld \the [src] to the floor.")
if(1)
if (WT.remove_fuel(0,user))
- playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/welder2.ogg', 50, 1)
user.visible_message("[user.name] starts to cut the [src.name] free from the floor.", \
"You start to cut \the [src] free from the floor...", \
"You hear welding.")
diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm
index 6de25ff92f5..ce1fbab90a9 100644
--- a/code/game/objects/structures/signs.dm
+++ b/code/game/objects/structures/signs.dm
@@ -31,7 +31,7 @@
playsound(src, O.usesound, 50, 1)
if(!do_after(user, 30*O.toolspeed, target = src))
return
- playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
user.visible_message("[user] unfastens [src].", \
"You unfasten [src].")
var/obj/item/sign_backing/SB = new (get_turf(user))
@@ -103,7 +103,7 @@
var/turf/T = target
user.visible_message("[user] fastens [src] to [T].", \
"You attach the sign to [T].")
- playsound(T, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(T, 'sound/items/deconstruct.ogg', 50, 1)
new sign_path(T)
user.drop_item()
qdel(src)
diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm
index 6909965614f..51f291ad639 100644
--- a/code/game/objects/structures/statues.dm
+++ b/code/game/objects/structures/statues.dm
@@ -43,7 +43,7 @@
anchored = 1
else if(istype(W, /obj/item/weapon/gun/energy/plasmacutter))
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
user.visible_message("[user] is slicing apart the [name]...", \
"You are slicing apart the [name]...")
if(do_after(user,40*W.toolspeed, target = src))
@@ -69,7 +69,7 @@
if(do_after(user, 40*W.toolspeed, target = src))
if(!src.loc)
return
- playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
user.visible_message("[user] slices apart the [name].", \
"You slice apart the [name]!")
deconstruct(TRUE)
diff --git a/code/game/objects/structures/table_frames.dm b/code/game/objects/structures/table_frames.dm
index 0c2886533f7..d46752039b0 100644
--- a/code/game/objects/structures/table_frames.dm
+++ b/code/game/objects/structures/table_frames.dm
@@ -27,7 +27,7 @@
to_chat(user, "You start disassembling [src]...")
playsound(src.loc, I.usesound, 50, 1)
if(do_after(user, 30*I.toolspeed, target = src))
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
deconstruct(TRUE)
else if(istype(I, /obj/item/stack/sheet/plasteel))
var/obj/item/stack/sheet/plasteel/P = I
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 1c0a4fadf09..5cc2204332e 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -90,7 +90,7 @@
/obj/structure/table/proc/tablepush(mob/living/user, mob/living/pushed_mob)
pushed_mob.forceMove(src.loc)
- pushed_mob.Weaken(2)
+ pushed_mob.Knockdown(40)
pushed_mob.visible_message("[user] pushes [pushed_mob] onto [src].", \
"[user] pushes [pushed_mob] onto [src].")
add_logs(user, pushed_mob, "pushed")
@@ -109,7 +109,7 @@
to_chat(user, "You start deconstructing [src]...")
playsound(src.loc, I.usesound, 50, 1)
if(do_after(user, 40*I.toolspeed, target = src))
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
deconstruct(TRUE, 1)
return
@@ -195,7 +195,7 @@
check_break(M)
/obj/structure/table/glass/proc/check_break(mob/living/M)
- if(M.has_gravity() && M.mob_size > MOB_SIZE_SMALL)
+ if(M.has_gravity() && M.mob_size > MOB_SIZE_SMALL && !(M.movement_type & FLYING))
table_shatter(M)
/obj/structure/table/glass/proc/table_shatter(mob/M)
@@ -209,7 +209,7 @@
debris -= AM
if(istype(AM, /obj/item/weapon/shard))
AM.throw_impact(M)
- M.Weaken(5)
+ M.Knockdown(100)
qdel(src)
/obj/structure/table/glass/deconstruct(disassembled = TRUE, wrench_disassembly = 0)
@@ -451,7 +451,7 @@
attack_hand(user)
/obj/structure/rack/attack_hand(mob/living/user)
- if(user.weakened || user.resting || user.lying || user.get_num_legs() < 2)
+ if(user.knockdown || user.resting || user.lying || user.get_num_legs() < 2)
return
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src, ATTACK_EFFECT_KICK)
@@ -467,7 +467,7 @@
else
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
- playsound(loc, 'sound/items/Welder.ogg', 40, 1)
+ playsound(loc, 'sound/items/welder.ogg', 40, 1)
/*
* Rack destruction
diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm
index 1b41c76eec6..f96fc044823 100644
--- a/code/game/objects/structures/transit_tubes/station.dm
+++ b/code/game/objects/structures/transit_tubes/station.dm
@@ -70,7 +70,7 @@
pod.visible_message("[user] starts putting [GM] into the [pod]!")
if(do_after(user, 15, target = src))
if(open_status == STATION_TUBE_OPEN && GM && user.grab_state >= GRAB_AGGRESSIVE && user.pulling == GM && !GM.buckled && !GM.has_buckled_mobs())
- GM.Weaken(5)
+ GM.Knockdown(100)
src.Bumped(GM)
break
else
diff --git a/code/game/objects/structures/traps.dm b/code/game/objects/structures/traps.dm
index dad4e9b53e1..dec661105a7 100644
--- a/code/game/objects/structures/traps.dm
+++ b/code/game/objects/structures/traps.dm
@@ -81,7 +81,7 @@
/obj/structure/trap/stun/trap_effect(mob/living/L)
L.electrocute_act(30, src, safety=1) // electrocute act does a message.
- L.Weaken(5)
+ L.Knockdown(100)
/obj/structure/trap/fire
name = "flame trap"
@@ -90,7 +90,7 @@
/obj/structure/trap/fire/trap_effect(mob/living/L)
to_chat(L, "Spontaneous combustion!")
- L.Weaken(1)
+ L.Knockdown(20)
/obj/structure/trap/fire/flare()
..()
@@ -104,7 +104,7 @@
/obj/structure/trap/chill/trap_effect(mob/living/L)
to_chat(L, "You're frozen solid!")
- L.Weaken(1)
+ L.Knockdown(20)
L.bodytemperature -= 300
L.apply_status_effect(/datum/status_effect/freon)
@@ -117,7 +117,7 @@
/obj/structure/trap/damage/trap_effect(mob/living/L)
to_chat(L, "The ground quakes beneath your feet!")
- L.Weaken(5)
+ L.Knockdown(100)
L.adjustBruteLoss(35)
/obj/structure/trap/damage/flare()
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 90c26657f59..60d6df6fe9f 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -281,7 +281,7 @@
var/mob/living/L = O
if(wash_mob(L)) //it's a carbon mob.
var/mob/living/carbon/C = L
- C.slip(4,2,null,NO_SLIP_WHEN_WALKING)
+ C.slip(80,null,NO_SLIP_WHEN_WALKING)
else
wash_obj(O)
@@ -484,8 +484,7 @@
if(B.cell.charge > 0 && B.status == 1)
flick("baton_active", src)
var/stunforce = B.stunforce
- user.Stun(stunforce)
- user.Weaken(stunforce)
+ user.Knockdown(stunforce)
user.stuttering = stunforce
B.deductcharge(B.hitcost)
user.visible_message("[user] shocks themself while attempting to wash the active [B.name]!", \
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index be82336f595..d9202d061da 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -94,7 +94,7 @@
var/obj/item/weapon/weldingtool/WT = W
if (WT.remove_fuel(0,user))
user.visible_message("[user] disassembles the windoor assembly.", "You start to disassemble the windoor assembly...")
- playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 50, 1)
if(do_after(user, 40*W.toolspeed, target = src))
if(!src || !WT.isOn()) return
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 0c114180030..33a9a1f329d 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -24,6 +24,9 @@
resistance_flags = ACID_PROOF
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 80, acid = 100)
CanAtmosPass = ATMOS_PASS_PROC
+ var/real_explosion_block //ignore this, just use explosion_block
+ var/breaksound = "shatter"
+ var/hitsound = 'sound/effects/Glasshit.ogg'
/obj/structure/window/examine(mob/user)
..()
@@ -73,6 +76,10 @@
if(rods)
debris += new /obj/item/stack/rods(src, rods)
+ //windows only block while reinforced and fulltile, so we'll use the proc
+ real_explosion_block = explosion_block
+ explosion_block = EXPLOSION_BLOCK_PROC
+
/obj/structure/window/rcd_vals(mob/user, obj/item/weapon/construction/rcd/the_rcd)
switch(the_rcd.mode)
if(RCD_DECONSTRUCT)
@@ -139,7 +146,7 @@
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("Something knocks on [src].")
add_fingerprint(user)
- playsound(loc, 'sound/effects/Glassknock.ogg', 50, 1)
+ playsound(src, 'sound/effects/Glassknock.ogg', 50, 1)
/obj/structure/window/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(!can_be_reached(user))
@@ -152,7 +159,7 @@
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("[user] knocks on [src].")
add_fingerprint(user)
- playsound(loc, 'sound/effects/Glassknock.ogg', 50, 1)
+ playsound(src, 'sound/effects/Glassknock.ogg', 50, 1)
/obj/structure/window/attack_paw(mob/user)
return attack_hand(user)
@@ -173,10 +180,10 @@
if(obj_integrity < max_integrity)
if(WT.remove_fuel(0,user))
to_chat(user, "You begin repairing [src]...")
- playsound(loc, WT.usesound, 40, 1)
+ playsound(src, WT.usesound, 40, 1)
if(do_after(user, 40*I.toolspeed, target = src))
obj_integrity = max_integrity
- playsound(loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(src, 'sound/items/Welder2.ogg', 50, 1)
update_nearby_icons()
to_chat(user, "You repair [src].")
else
@@ -185,7 +192,7 @@
if(!(flags&NODECONSTRUCT))
if(istype(I, /obj/item/weapon/screwdriver))
- playsound(loc, I.usesound, 75, 1)
+ playsound(src, I.usesound, 75, 1)
if(reinf)
if(state == WINDOW_SCREWED_TO_FRAME || state == WINDOW_IN_FRAME)
to_chat(user, "You begin to [state == WINDOW_SCREWED_TO_FRAME ? "unscrew the window from":"screw the window to"] the frame...")
@@ -209,19 +216,19 @@
else if (istype(I, /obj/item/weapon/crowbar) && reinf && (state == WINDOW_OUT_OF_FRAME || state == WINDOW_IN_FRAME))
to_chat(user, "You begin to lever the window [state == WINDOW_OUT_OF_FRAME ? "into":"out of"] the frame...")
- playsound(loc, I.usesound, 75, 1)
+ playsound(src, I.usesound, 75, 1)
if(do_after(user, decon_speed*I.toolspeed, target = src, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored)))
state = (state == WINDOW_OUT_OF_FRAME ? WINDOW_IN_FRAME : WINDOW_OUT_OF_FRAME)
to_chat(user, "You pry the window [state == WINDOW_IN_FRAME ? "into":"out of"] the frame.")
return
else if(istype(I, /obj/item/weapon/wrench) && !anchored)
- playsound(loc, I.usesound, 75, 1)
+ playsound(src, I.usesound, 75, 1)
to_chat(user, " You begin to disassemble [src]...")
if(do_after(user, decon_speed*I.toolspeed, target = src, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored)))
var/obj/item/stack/sheet/G = new glass_type(user.loc, glass_amount)
G.add_fingerprint(user)
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
to_chat(user, "You successfully disassemble [src].")
qdel(src)
return
@@ -260,18 +267,18 @@
switch(damage_type)
if(BRUTE)
if(damage_amount)
- playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
+ playsound(src, hitsound, 75, 1)
else
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/Welder.ogg', 100, 1)
/obj/structure/window/deconstruct(disassembled = TRUE)
if(QDELETED(src))
return
if(!disassembled)
- playsound(src, "shatter", 70, 1)
+ playsound(src, breaksound, 70, 1)
var/turf/T = loc
if(!(flags & NODECONSTRUCT))
for(var/i in debris)
@@ -400,6 +407,9 @@
return 1
+/obj/structure/window/GetExplosionBlock()
+ return reinf && fulltile ? real_explosion_block : 0
+
/obj/structure/window/unanchored
anchored = FALSE
@@ -421,7 +431,6 @@
name = "tinted window"
icon_state = "twindow"
opacity = 1
-
/obj/structure/window/reinforced/tinted/frosted
name = "frosted window"
icon_state = "fwindow"
@@ -540,9 +549,7 @@
if(fulltile)
made_glow = TRUE
..()
- for(var/obj/item/I in debris)
- debris -= I
- qdel(I)
+ QDEL_LIST(debris)
var/amount_of_gears = 2
if(fulltile)
new /obj/effect/temp_visual/ratvar/window(get_turf(src))
@@ -591,3 +598,80 @@
/obj/structure/window/reinforced/clockwork/fulltile/unanchored
anchored = FALSE
+
+/obj/structure/window/paperframe
+ name = "paper frame"
+ desc = "A fragile separator made of thin wood and paper."
+ icon = 'icons/obj/smooth_structures/paperframes.dmi'
+ icon_state = "frame"
+ dir = FULLTILE_WINDOW_DIR
+ opacity = TRUE
+ max_integrity = 15
+ obj_integrity = 15
+ fulltile = TRUE
+ flags = PREVENT_CLICK_UNDER
+ smooth = SMOOTH_TRUE
+ canSmoothWith = list(/obj/structure/window/paperframe, /obj/structure/mineral_door/paperframe)
+ glass_amount = 2
+ glass_type = /obj/item/stack/sheet/paperframes
+ heat_resistance = 233
+ decon_speed = 10
+ CanAtmosPass = ATMOS_PASS_YES
+ resistance_flags = FLAMMABLE
+ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
+ breaksound = 'sound/items/poster_ripped.ogg'
+ hitsound = 'sound/weapons/slashmiss.ogg'
+ var/static/mutable_appearance/torn = mutable_appearance('icons/obj/smooth_structures/paperframes.dmi',icon_state = "torn", layer = ABOVE_OBJ_LAYER - 0.1)
+ var/static/mutable_appearance/paper = mutable_appearance('icons/obj/smooth_structures/paperframes.dmi',icon_state = "paper", layer = ABOVE_OBJ_LAYER - 0.1)
+
+/obj/structure/window/paperframe/Initialize()
+ . = ..()
+ QDEL_LIST(debris)
+ var/papers = rand(1,4)
+ debris += new /obj/item/stack/sheet/mineral/wood()
+ for(var/i in 1 to papers)
+ debris += new /obj/item/weapon/paper/natural()
+ update_icon()
+
+/obj/structure/window/paperframe/attack_hand(mob/user)
+ add_fingerprint(user)
+ if(user.a_intent != INTENT_HARM)
+ user.changeNext_move(CLICK_CD_MELEE)
+ user.visible_message("[user] knocks on [src].")
+ playsound(src, "pageturn", 50, 1)
+ else
+ take_damage(4,BRUTE,"melee", 0)
+ playsound(src, hitsound, 50, 1)
+ if(!QDELETED(src))
+ user.visible_message("[user] tears a hole in [src].")
+ update_icon()
+
+/obj/structure/window/paperframe/update_icon()
+ if(obj_integrity < max_integrity)
+ cut_overlay(paper)
+ add_overlay(torn)
+ set_opacity(FALSE)
+ else
+ cut_overlay(torn)
+ add_overlay(paper)
+ set_opacity(TRUE)
+ queue_smooth(src)
+
+
+/obj/structure/window/paperframe/attackby(obj/item/weapon/W, mob/user)
+ if(W.is_hot())
+ fire_act(W.is_hot())
+ return
+ if(user.a_intent == INTENT_HARM)
+ return ..()
+ if(istype(W, /obj/item/weapon/paper) && obj_integrity < max_integrity)
+ user.visible_message("[user] starts to patch the holes in \the [src].")
+ if(do_after(user, 20, target = src))
+ obj_integrity = min(obj_integrity+4,max_integrity)
+ qdel(W)
+ user.visible_message("[user] patches some of the holes in \the [src].")
+ if(obj_integrity == max_integrity)
+ update_icon()
+ return
+ ..()
+ update_icon()
\ No newline at end of file
diff --git a/code/game/sound.dm b/code/game/sound.dm
index 847dc0d4bfd..5a04df6c0f8 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -102,9 +102,9 @@
if(istext(soundin))
switch(soundin)
if ("shatter")
- soundin = pick('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg')
+ soundin = pick('sound/effects/glassbr1.ogg','sound/effects/glassbr2.ogg','sound/effects/glassbr3.ogg')
if ("explosion")
- soundin = pick('sound/effects/Explosion1.ogg','sound/effects/Explosion2.ogg')
+ soundin = pick('sound/effects/explosion1.ogg','sound/effects/explosion2.ogg')
if ("sparks")
soundin = pick('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks4.ogg')
if ("rustle")
@@ -122,7 +122,7 @@
if ("pageturn")
soundin = pick('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg')
if ("gunshot")
- soundin = pick('sound/weapons/Gunshot.ogg', 'sound/weapons/Gunshot2.ogg','sound/weapons/Gunshot3.ogg','sound/weapons/Gunshot4.ogg')
+ soundin = pick('sound/weapons/gunshot.ogg', 'sound/weapons/gunshot2.ogg','sound/weapons/gunshot3.ogg','sound/weapons/gunshot4.ogg')
if ("ricochet")
soundin = pick( 'sound/weapons/effects/ric1.ogg', 'sound/weapons/effects/ric2.ogg','sound/weapons/effects/ric3.ogg','sound/weapons/effects/ric4.ogg','sound/weapons/effects/ric5.ogg')
if ("terminal_type")
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index 718451bcb09..a6566180a97 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -27,7 +27,7 @@
icon = 'icons/turf/floors.dmi'
icon_state = "necro1"
baseturf = /turf/open/indestructible/necropolis
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
/turf/open/indestructible/necropolis/Initialize()
. = ..()
@@ -39,7 +39,7 @@
/turf/open/indestructible/hierophant
icon = 'icons/turf/floors/hierophant_floor.dmi'
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
baseturf = /turf/open/indestructible/hierophant
smooth = SMOOTH_TRUE
@@ -137,7 +137,7 @@
qdel(hotspot)
return 1
-/turf/open/handle_slip(mob/living/carbon/C, s_amount, w_amount, obj/O, lube)
+/turf/open/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube)
if(C.movement_type & FLYING)
return 0
if(has_gravity(src))
@@ -147,7 +147,7 @@
if(!(lube&GALOSHES_DONT_HELP)) //can't slip while buckled unless it's lube.
return 0
else
- if(C.lying || !(C.status_flags & CANWEAKEN)) // can't slip unbuckled mob if they're lying or can't fall.
+ if(C.lying || !(C.status_flags & CANKNOCKDOWN)) // can't slip unbuckled mob if they're lying or can't fall.
return 0
if(C.m_intent == MOVE_INTENT_WALK && (lube&NO_SLIP_WHEN_WALKING))
return 0
@@ -162,11 +162,10 @@
var/olddir = C.dir
if(!(lube & SLIDE_ICE))
- C.Stun(s_amount)
- C.Weaken(w_amount)
+ C.Knockdown(knockdown_amount)
C.stop_pulling()
else
- C.Stun(1)
+ C.Stun(20)
if(buckled_obj)
buckled_obj.unbuckle_mob(C)
diff --git a/code/game/turfs/simulated/chasm.dm b/code/game/turfs/simulated/chasm.dm
index 8f0de9675da..7969ea18adc 100644
--- a/code/game/turfs/simulated/chasm.dm
+++ b/code/game/turfs/simulated/chasm.dm
@@ -35,7 +35,7 @@
if(!L)
if(R.use(1))
to_chat(user, "You construct a lattice.")
- playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
+ playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
ReplaceWithLattice()
else
to_chat(user, "You need one rod to build a lattice.")
@@ -46,7 +46,7 @@
var/obj/item/stack/tile/plasteel/S = C
if(S.use(1))
qdel(L)
- playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
+ playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
to_chat(user, "You build a floor.")
ChangeTurf(/turf/open/floor/plating)
else
@@ -99,7 +99,7 @@
AM.forceMove(T)
if(isliving(AM))
var/mob/living/L = AM
- L.Weaken(5)
+ L.Knockdown(100)
L.adjustBruteLoss(30)
@@ -112,7 +112,7 @@
/turf/open/chasm/straight_down/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
planetary_atmos = TRUE
baseturf = /turf/open/chasm/straight_down/lava_land_surface
light_range = 1.9 //slightly less range than lava
@@ -128,7 +128,7 @@
if(isliving(AM))
var/mob/living/L = AM
L.notransform = TRUE
- L.Stun(10)
+ L.Stun(200)
L.resting = TRUE
var/oldtransform = AM.transform
var/oldcolor = AM.color
@@ -173,7 +173,7 @@
/turf/open/chasm/jungle
icon = 'icons/turf/floors/junglechasm.dmi'
planetary_atmos = TRUE
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
/turf/open/chasm/jungle/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
underlay_appearance.icon = 'icons/turf/floors.dmi'
@@ -183,4 +183,4 @@
/turf/open/chasm/straight_down/jungle
icon = 'icons/turf/floors/junglechasm.dmi'
planetary_atmos = TRUE
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
\ No newline at end of file
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
\ No newline at end of file
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index c1993677f33..2fb5b03acae 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -206,11 +206,13 @@
if(RCD_FLOORWALL)
return list("mode" = RCD_FLOORWALL, "delay" = 20, "cost" = 16)
if(RCD_AIRLOCK)
- return list("mode" = RCD_AIRLOCK, "delay" = 50, "cost" = 16)
+ if(the_rcd.airlock_glass)
+ return list("mode" = RCD_AIRLOCK, "delay" = 50, "cost" = 20)
+ else return list("mode" = RCD_AIRLOCK, "delay" = 50, "cost" = 16)
if(RCD_DECONSTRUCT)
return list("mode" = RCD_DECONSTRUCT, "delay" = 50, "cost" = 33)
if(RCD_WINDOWGRILLE)
- return list("mode" = RCD_WINDOWGRILLE, "delay" = 40, "cost" = 4)
+ return list("mode" = RCD_WINDOWGRILLE, "delay" = 10, "cost" = 4)
return FALSE
/turf/open/floor/rcd_act(mob/user, obj/item/weapon/construction/rcd/the_rcd, passed_mode)
diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm
index 375697ff9bc..efa43825405 100644
--- a/code/game/turfs/simulated/floor/fancy_floor.dm
+++ b/code/game/turfs/simulated/floor/fancy_floor.dm
@@ -105,7 +105,7 @@
icon = 'icons/turf/floors.dmi'
icon_state = "basalt"
ore_type = /obj/item/weapon/ore/glass/basalt
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
slowdown = 0
/turf/open/floor/grass/snow/basalt/Initialize()
diff --git a/code/game/turfs/simulated/floor/mineral_floor.dm b/code/game/turfs/simulated/floor/mineral_floor.dm
index fc5a57e16dd..46bb461660a 100644
--- a/code/game/turfs/simulated/floor/mineral_floor.dm
+++ b/code/game/turfs/simulated/floor/mineral_floor.dm
@@ -151,18 +151,14 @@
honk()
/turf/open/floor/mineral/bananium/proc/honk()
- if(!spam_flag)
- spam_flag = 1
+ if(spam_flag < world.time)
playsound(src, 'sound/items/bikehorn.ogg', 50, 1)
- spawn(20)
- spam_flag = 0
+ spam_flag = world.time + 20
/turf/open/floor/mineral/bananium/proc/squeek()
- if(!spam_flag)
- spam_flag = 1
+ if(spam_flag < world.time)
playsound(src, "clownstep", 50, 1)
- spawn(10)
- spam_flag = 0
+ spam_flag = world.time + 10
/turf/open/floor/mineral/bananium/airless
initial_gas_mix = "TEMP=2.7"
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index 13aaa09a2af..3ca061b2c9c 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -43,7 +43,7 @@
if(do_after(user, 30, target = src))
if (R.get_amount() >= 2 && !istype(src, /turf/open/floor/engine))
ChangeTurf(/turf/open/floor/engine)
- playsound(src, 'sound/items/Deconstruct.ogg', 80, 1)
+ playsound(src, 'sound/items/deconstruct.ogg', 80, 1)
R.use(2)
to_chat(user, "You reinforce the floor.")
return
@@ -57,7 +57,7 @@
var/obj/item/stack/tile/light/L = W
var/turf/open/floor/light/F = T
F.state = L.state
- playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
+ playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
else
to_chat(user, "This section is too damaged to support a tile! Use a welder to fix the damage.")
else if(istype(C, /obj/item/weapon/weldingtool))
diff --git a/code/game/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm
index 18d81b19320..9f4d26a9527 100644
--- a/code/game/turfs/simulated/floor/plating/asteroid.dm
+++ b/code/game/turfs/simulated/floor/plating/asteroid.dm
@@ -81,7 +81,7 @@
var/obj/item/stack/tile/light/L = Z
var/turf/open/floor/light/F = T
F.state = L.state
- playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
+ playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
/turf/open/floor/plating/asteroid/proc/gets_dug()
if(dug)
@@ -137,7 +137,7 @@
///////Surface. The surface is warm, but survivable without a suit. Internals are required. The floors break to chasms, which drop you into the underground.
/turf/open/floor/plating/asteroid/basalt/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
planetary_atmos = TRUE
baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface
@@ -176,7 +176,7 @@
data_having_type = /turf/open/floor/plating/asteroid/airless/cave/volcanic/has_data
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
/turf/open/floor/plating/asteroid/airless/cave/volcanic/has_data //subtype for producing a tunnel with given data
has_data = TRUE
diff --git a/code/game/turfs/simulated/floor/plating/dirt.dm b/code/game/turfs/simulated/floor/plating/dirt.dm
index 0d13b934328..9d07c539170 100644
--- a/code/game/turfs/simulated/floor/plating/dirt.dm
+++ b/code/game/turfs/simulated/floor/plating/dirt.dm
@@ -4,7 +4,7 @@
icon = 'icons/turf/floors.dmi'
icon_state = "dirt"
baseturf = /turf/open/chasm/straight_down/jungle
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
planetary_atmos = TRUE
/turf/open/floor/plating/dirt/dark
diff --git a/code/game/turfs/simulated/floor/plating/lava.dm b/code/game/turfs/simulated/floor/plating/lava.dm
index ead1e97d22a..dbc73943a0e 100644
--- a/code/game/turfs/simulated/floor/plating/lava.dm
+++ b/code/game/turfs/simulated/floor/plating/lava.dm
@@ -132,7 +132,7 @@
/turf/open/floor/plating/lava/smooth/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
planetary_atmos = TRUE
baseturf = /turf/open/chasm/straight_down/lava_land_surface
diff --git a/code/game/turfs/simulated/floor/plating/misc_plating.dm b/code/game/turfs/simulated/floor/plating/misc_plating.dm
index 081b4becc6b..cf0ec5531c1 100644
--- a/code/game/turfs/simulated/floor/plating/misc_plating.dm
+++ b/code/game/turfs/simulated/floor/plating/misc_plating.dm
@@ -38,7 +38,7 @@
var/smooth_icon = 'icons/turf/floors/ash.dmi'
desc = "The ground is covered in volcanic ash."
baseturf = /turf/open/floor/plating/ashplanet/wateryrock //I assume this will be a chasm eventually, once this becomes an actual surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
planetary_atmos = TRUE
/turf/open/floor/plating/ashplanet/Initialize()
diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm
index 9c3d8ed0c76..ea286f9a01b 100644
--- a/code/game/turfs/simulated/minerals.dm
+++ b/code/game/turfs/simulated/minerals.dm
@@ -179,7 +179,7 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
mineralSpawnChanceList = list(
/turf/closed/mineral/uranium/volcanic = 35, /turf/closed/mineral/diamond/volcanic = 30, /turf/closed/mineral/gold/volcanic = 45, /turf/closed/mineral/titanium/volcanic = 45,
@@ -200,7 +200,7 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
mineralChance = 10
@@ -222,7 +222,7 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
mineralSpawnChanceList = list(
/turf/closed/mineral/uranium/volcanic = 3, /turf/closed/mineral/diamond/volcanic = 1, /turf/closed/mineral/gold/volcanic = 8, /turf/closed/mineral/titanium/volcanic = 8,
@@ -241,7 +241,7 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
@@ -255,7 +255,7 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
@@ -269,7 +269,7 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
@@ -283,7 +283,7 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
@@ -297,7 +297,7 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
@@ -311,7 +311,7 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
@@ -325,7 +325,7 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
@@ -348,7 +348,7 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
@@ -356,7 +356,7 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt
baseturf = /turf/open/floor/plating/asteroid/basalt
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
/turf/closed/mineral/volcanic/lava_land_surface
environment_type = "basalt"
@@ -372,7 +372,7 @@
smooth = SMOOTH_MORE|SMOOTH_BORDER
canSmoothWith = list (/turf/closed)
baseturf = /turf/open/floor/plating/ashplanet/wateryrock
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
environment_type = "waste"
turf_type = /turf/open/floor/plating/ashplanet/rocky
defer_change = 1
@@ -477,5 +477,5 @@
environment_type = "basalt"
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm
index 21015e82d09..64a03cef44d 100644
--- a/code/game/turfs/simulated/wall/misc_walls.dm
+++ b/code/game/turfs/simulated/wall/misc_walls.dm
@@ -99,7 +99,7 @@
devastate_wall()
ChangeTurf(/turf/open/floor/plating)
else
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
var/newgirder = break_wall()
if(newgirder) //maybe we want a gear!
transfer_fingerprints_to(newgirder)
diff --git a/code/game/turfs/simulated/wall/reinf_walls.dm b/code/game/turfs/simulated/wall/reinf_walls.dm
index c15e478c499..1becd8cadf7 100644
--- a/code/game/turfs/simulated/wall/reinf_walls.dm
+++ b/code/game/turfs/simulated/wall/reinf_walls.dm
@@ -106,7 +106,7 @@
if(istype(W, /obj/item/weapon/gun/energy/plasmacutter))
to_chat(user, "You begin slicing through the metal cover...")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
if(do_after(user, 60*W.toolspeed, target = src))
if(!istype(src, /turf/closed/wall/r_wall) || !W || d_state != COVER)
return 1
@@ -190,7 +190,7 @@
if(istype(W, /obj/item/weapon/gun/energy/plasmacutter))
to_chat(user, "You begin slicing through the support rods...")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
if(do_after(user, 100*W.toolspeed, target = src))
if(!istype(src, /turf/closed/wall/r_wall) || !W || d_state != SUPPORT_RODS)
return 1
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 44dc1afee72..a097b70c6b5 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -46,7 +46,7 @@
if(devastated)
devastate_wall()
else
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
var/newgirder = break_wall()
if(newgirder) //maybe we don't /want/ a girder!
transfer_fingerprints_to(newgirder)
@@ -103,7 +103,7 @@
dismantle_wall(1)
playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1)
if(BURN)
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
if(TOX)
playsound(src, 'sound/effects/spray2.ogg', 100, 1)
return 0
@@ -135,7 +135,7 @@
/turf/closed/wall/attack_hand(mob/user)
user.changeNext_move(CLICK_CD_MELEE)
to_chat(user, "You push the wall but nothing happens!")
- playsound(src, 'sound/weapons/Genhit.ogg', 25, 1)
+ playsound(src, 'sound/weapons/genhit.ogg', 25, 1)
src.add_fingerprint(user)
..()
@@ -195,7 +195,7 @@
return 1
else if( istype(W, /obj/item/weapon/gun/energy/plasmacutter) )
to_chat(user, "You begin slicing through the outer plating...")
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
if(do_after(user, slicing_duration*W.toolspeed, target = src))
if(!iswallturf(src) || !user || !W || !T)
return 1
@@ -232,7 +232,7 @@
O.density = 1
O.layer = FLY_LAYER
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src, 'sound/items/welder.ogg', 100, 1)
if(thermite >= 50)
var/burning_time = max(100,300 - thermite)
diff --git a/code/game/turfs/simulated/water.dm b/code/game/turfs/simulated/water.dm
index d0208218a56..d73c5f98c21 100644
--- a/code/game/turfs/simulated/water.dm
+++ b/code/game/turfs/simulated/water.dm
@@ -4,7 +4,7 @@
icon = 'icons/turf/floors.dmi'
icon_state = "riverwater"
baseturf = /turf/open/chasm/straight_down/lava_land_surface
- initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ initial_gas_mix = LAVALAND_DEFAULT_ATMOS
planetary_atmos = TRUE
slowdown = 1
wet = TURF_WET_WATER
diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm
index bac25e68c00..373e8ac34a3 100644
--- a/code/game/turfs/space/space.dm
+++ b/code/game/turfs/space/space.dm
@@ -95,14 +95,14 @@
if(L)
if(R.use(1))
to_chat(user, "You construct a catwalk.")
- playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
+ playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
new/obj/structure/lattice/catwalk(src)
else
to_chat(user, "You need two rods to build a catwalk!")
return
if(R.use(1))
to_chat(user, "You construct a lattice.")
- playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
+ playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
ReplaceWithLattice()
else
to_chat(user, "You need one rod to build a lattice.")
@@ -113,7 +113,7 @@
var/obj/item/stack/tile/plasteel/S = C
if(S.use(1))
qdel(L)
- playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
+ playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
to_chat(user, "You build a floor.")
ChangeTurf(/turf/open/floor/plating)
else
@@ -173,7 +173,10 @@
switch(the_rcd.mode)
if(RCD_FLOORWALL)
- return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 2)
+ var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
+ if(L)
+ return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 1)
+ else return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 3)
return FALSE
/turf/open/space/rcd_act(mob/user, obj/item/weapon/construction/rcd/the_rcd, passed_mode)
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 9d556e896f7..8a9fb55b419 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -168,17 +168,17 @@
return
switch(wet)
if(TURF_WET_WATER)
- if(!M.slip(0, 3, null, NO_SLIP_WHEN_WALKING))
+ if(!M.slip(60, null, NO_SLIP_WHEN_WALKING))
M.inertia_dir = 0
if(TURF_WET_LUBE)
- if(M.slip(0, 4, null, (SLIDE|GALOSHES_DONT_HELP)))
+ if(M.slip(80, null, (SLIDE|GALOSHES_DONT_HELP)))
M.confused = max(M.confused, 8)
if(TURF_WET_ICE)
- M.slip(0, 6, null, (SLIDE|GALOSHES_DONT_HELP))
+ M.slip(120, null, (SLIDE|GALOSHES_DONT_HELP))
if(TURF_WET_PERMAFROST)
- M.slip(0, 6, null, (SLIDE_ICE|GALOSHES_DONT_HELP))
+ M.slip(120, null, (SLIDE_ICE|GALOSHES_DONT_HELP))
if(TURF_WET_SLIDE)
- M.slip(0, 4, null, (SLIDE|GALOSHES_DONT_HELP))
+ M.slip(80, null, (SLIDE|GALOSHES_DONT_HELP))
//melting
if(isobj(AM) && air && air.temperature > T0C)
var/obj/O = AM
@@ -293,7 +293,7 @@
if(M==U)
continue//Will not harm U. Since null != M, can be excluded to kill everyone.
M.adjustBruteLoss(damage)
- M.Paralyse(damage/5)
+ M.Unconscious(damage * 4)
for(var/obj/mecha/M in src)
M.take_damage(damage*2, BRUTE, "melee", 1)
diff --git a/code/modules/admin/DB_ban/functions.dm b/code/modules/admin/DB_ban/functions.dm
index 1061a58fd58..23bf656b8cb 100644
--- a/code/modules/admin/DB_ban/functions.dm
+++ b/code/modules/admin/DB_ban/functions.dm
@@ -122,7 +122,7 @@
computerid = "0"
if(!ip)
ip = "0.0.0.0"
- var/sql = "INSERT INTO [format_table_name("ban")] (`bantime`,`server_ip`,`server_port`,`round_id`,`bantype`,`reason`,`job`,`duration`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`) VALUES (Now(), COALESCE(INET_ATON('[world.internet_address]'), 0), '[world.port]', '[GLOB.round_id]', '[bantype_str]', '[reason]', '[job]', [(duration)?"[duration]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[ckey]', '[computerid]', INET_ATON('[ip]'), '[a_ckey]', '[a_computerid]', INET_ATON('[a_ip]'), '[who]', '[adminwho]')"
+ var/sql = "INSERT INTO [format_table_name("ban")] (`bantime`,`server_ip`,`server_port`,`round_id`,`bantype`,`reason`,`job`,`duration`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]', '[bantype_str]', '[reason]', '[job]', [(duration)?"[duration]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[ckey]', '[computerid]', INET_ATON('[ip]'), '[a_ckey]', '[a_computerid]', INET_ATON('[a_ip]'), '[who]', '[adminwho]')"
var/datum/DBQuery/query_add_ban = SSdbcore.NewQuery(sql)
if(!query_add_ban.warn_execute())
return
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index eca2cc8859f..9d8f687c2a2 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -39,7 +39,7 @@
if(M.client)
body += " \[First Seen: [M.client.player_join_date]\]\[Byond account registered on: [M.client.account_join_date]\]"
- body += " Show related accounts by: "
+ body += "
Show related accounts by: "
body += "\[ CID | "
body += "IP \]"
@@ -434,7 +434,7 @@
if("Hard Restart (No Delay, No Feeback Reason)")
world.Reboot()
if("Hardest Restart (No actions, just reboot)")
- world.Reboot(fast_track = TRUE)
+ world.Reboot(fast_track = TRUE)
if("Service Restart (Force restart DD)")
GLOB.reboot_mode = REBOOT_MODE_HARD
world.ServiceReboot()
@@ -595,7 +595,7 @@
set category = "Admin"
set name = "Unprison"
if (M.z == ZLEVEL_CENTCOM)
- M.loc = pick(GLOB.latejoin)
+ SSjob.SendToLateJoin(M)
message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(M)]")
log_admin("[key_name(usr)] has unprisoned [key_name(M)]")
else
@@ -694,7 +694,7 @@
to_chat(usr, "AI [key_name(S, usr)]'s laws:")
else if(iscyborg(S))
var/mob/living/silicon/robot/R = S
- to_chat(usr, "CYBORG [key_name(S, usr)] [R.connected_ai?"(Slaved to: [R.connected_ai])":"(Independant)"]: laws:")
+ to_chat(usr, "CYBORG [key_name(S, usr)] [R.connected_ai?"(Slaved to: [R.connected_ai])":"(Independent)"]: laws:")
else if (ispAI(S))
to_chat(usr, "pAI [key_name(S, usr)]'s laws:")
else
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index bbc65277118..244e713f4fd 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -63,7 +63,10 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin())
/client/proc/toggle_AI_interact, /*toggle admin ability to interact with machines as an AI*/
/client/proc/customiseSNPC, /* Customise any interactive crewmembers in the world */
/client/proc/resetSNPC, /* Resets any interactive crewmembers in the world */
- /client/proc/open_shuttle_manipulator /* Opens shuttle manipulator UI */
+ /client/proc/open_shuttle_manipulator, /* Opens shuttle manipulator UI */
+ /client/proc/deadchat,
+ /client/proc/toggleprayers,
+ /client/proc/toggleadminhelpsound
)
GLOBAL_PROTECT(admin_verbs_ban)
GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel,/client/proc/DB_ban_panel,/client/proc/stickybanpanel))
diff --git a/code/modules/admin/adminmenu.dm b/code/modules/admin/adminmenu.dm
index fc7a57e212b..aa654ab2523 100644
--- a/code/modules/admin/adminmenu.dm
+++ b/code/modules/admin/adminmenu.dm
@@ -1,11 +1,11 @@
-/datum/menu/Admin/Generate_list(client/C)
+/datum/verbs/menu/Admin/Generate_list(client/C)
if (C.holder)
. = ..()
-/datum/menu/Admin/verb/playerpanel()
+/datum/verbs/menu/Admin/verb/playerpanel()
set name = "Player Panel"
set desc = "Player Panel"
set category = "Admin"
- usr.client.holder.player_panel_new()
- SSblackbox.add_details("admin_verb","Player Panel New") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- return
\ No newline at end of file
+ if(usr.client.holder)
+ usr.client.holder.player_panel_new()
+ SSblackbox.add_details("admin_verb","Player Panel New") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 020d6db9220..c04e3c91ad4 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -506,7 +506,7 @@
for(var/datum/mind/N in SSticker.mode.cult)
var/mob/M = N.current
if(M)
- dat += "
+ If this takes longer than 30 seconds, it will automatically reload a maximum of 5 times.
+ If it still doesn't work, use the bug report button at the top right of the window.
+
", 250, 265)
popup.set_window_options("can_close=0")
popup.set_content(output)
popup.open(0)
@@ -108,43 +108,23 @@
return 1
if(href_list["ready"])
- if(!SSticker || SSticker.current_state <= GAME_STATE_PREGAME) // Make sure we don't ready up after the round has started
- ready = text2num(href_list["ready"])
+ if(SSticker)
+ var/tready = text2num(href_list["ready"])
+ //Avoid updating ready if we're after PREGAME (they should use latejoin instead)
+ //This is likely not an actual issue but I don't have time to prove that this
+ //no longer is required
+ if(SSticker.current_state <= GAME_STATE_PREGAME)
+ ready = tready
+ //if it's post initialisation and they're trying to observe we do the needful
+ if(!SSticker.current_state < GAME_STATE_PREGAME && tready == PLAYER_READY_TO_OBSERVE)
+ ready = tready
+ make_me_an_observer()
+ return
if(href_list["refresh"])
src << browse(null, "window=playersetup") //closes the player setup window
new_player_panel()
- if(href_list["observe"])
-
- if(alert(src,"Are you sure you wish to observe? You will not be able to play this round!","Player Setup","Yes","No") == "Yes")
- if(!client)
- return 1
- var/mob/dead/observer/observer = new()
-
- spawning = 1
-
- observer.started_as_observer = 1
- close_spawn_windows()
- var/obj/O = locate("landmark*Observer-Start")
- to_chat(src, "Now teleporting.")
- if (O)
- observer.loc = O.loc
- else
- to_chat(src, "Teleporting failed. The map is probably still loading...")
- observer.key = key
- observer.client = client
- observer.set_ghost_appearance()
- if(observer.client && observer.client.prefs)
- observer.real_name = observer.client.prefs.real_name
- observer.name = observer.real_name
- observer.update_icon()
- observer.stop_sound_channel(CHANNEL_LOBBYMUSIC)
- qdel(mind)
-
- qdel(src)
- return 1
-
if(href_list["late_join"])
if(!SSticker || !SSticker.IsRoundInProgress())
to_chat(usr, "The round is either not ready, or has already finished...")
@@ -274,6 +254,44 @@
return
to_chat(src, "Vote successful.")
+//When you cop out of the round (NB: this HAS A SLEEP FOR PLAYER INPUT IN IT)
+/mob/dead/new_player/proc/make_me_an_observer()
+ if(QDELETED(src) || !src.client)
+ ready = PLAYER_NOT_READY
+ return FALSE
+
+ var/this_is_like_playing_right = alert(src,"Are you sure you wish to observe? You will not be able to play this round!","Player Setup","Yes","No")
+
+ if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes")
+ ready = PLAYER_NOT_READY
+ src << browse(null, "window=playersetup") //closes the player setup window
+ new_player_panel()
+ return FALSE
+
+ var/mob/dead/observer/observer = new()
+ spawning = TRUE
+
+ observer.started_as_observer = TRUE
+ close_spawn_windows()
+ var/obj/O = locate("landmark*Observer-Start")
+ to_chat(src, "Now teleporting.")
+ if (O)
+ observer.loc = O.loc
+ else
+ to_chat(src, "Teleporting failed. Ahelp an admin please")
+ stack_trace("There's no freaking observer landmark available on this map or you're making observers before the map is initialised")
+ observer.key = key
+ observer.client = client
+ observer.set_ghost_appearance()
+ if(observer.client && observer.client.prefs)
+ observer.real_name = observer.client.prefs.real_name
+ observer.name = observer.real_name
+ observer.update_icon()
+ observer.stop_sound_channel(CHANNEL_LOBBYMUSIC)
+ QDEL_NULL(mind)
+ qdel(src)
+ return TRUE
+
/mob/dead/new_player/proc/IsJobAvailable(rank)
var/datum/job/job = SSjob.GetJob(rank)
if(!job)
@@ -305,11 +323,13 @@
alert(src, "An administrator has disabled late join spawning.")
return FALSE
+ var/arrivals_docked = TRUE
if(SSshuttle.arrivals)
close_spawn_windows() //In case we get held up
if(SSshuttle.arrivals.damaged && config.arrivals_shuttle_require_safe_latejoin)
src << alert("The arrivals shuttle is currently malfunctioning! You cannot join.")
return FALSE
+ arrivals_docked = SSshuttle.arrivals.mode != SHUTTLE_CALL
//Remove the player from the join queue if he was in one and reset the timer
SSticker.queued_players -= src
@@ -322,28 +342,15 @@
if(isliving(equip)) //Borgs get borged in the equip, so we need to make sure we handle the new mob.
character = equip
- var/D
- if(GLOB.latejoin.len)
- D = get_turf(pick(GLOB.latejoin))
- if(!D)
- for(var/turf/T in get_area_turfs(/area/shuttle/arrival))
- if(!T.density)
- var/clear = 1
- for(var/obj/O in T)
- if(O.density)
- clear = 0
- break
- if(clear)
- D = T
- continue
+ SSjob.SendToLateJoin(character)
+
+ if(!arrivals_docked)
+ var/obj/screen/splash/Spl = new(character.client, TRUE)
+ Spl.Fade(TRUE)
+ character.playsound_local(get_turf(character), 'sound/voice/ApproachingTG.ogg', 25)
- character.loc = D
character.update_parallax_teleport()
- var/atom/movable/chair = locate(/obj/structure/chair) in character.loc
- if(chair)
- chair.buckle_mob(character)
-
SSticker.minds += character.mind
var/mob/living/carbon/human/humanc
@@ -371,11 +378,9 @@
if(SHUTTLE_CALL)
if(SSshuttle.emergency.timeLeft(1) > initial(SSshuttle.emergencyCallTime)*0.5)
SSticker.mode.make_antag_chance(humanc)
- qdel(src)
/mob/dead/new_player/proc/AddEmploymentContract(mob/living/carbon/human/employee)
//TODO: figure out a way to exclude wizards/nukeops/demons from this.
- sleep(30)
for(var/C in GLOB.employmentCabinets)
var/obj/structure/filingcabinet/employment/employmentCabinet = C
if(!employmentCabinet.virgin)
@@ -470,6 +475,8 @@
if(.)
new_character.key = key //Manually transfer the key to log them in
new_character.stop_sound_channel(CHANNEL_LOBBYMUSIC)
+ new_character = null
+ qdel(src)
/mob/dead/new_player/proc/ViewManifest()
var/dat = ""
diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm
index 5d2bb57e839..d067aee4b1a 100644
--- a/code/modules/mob/dead/new_player/preferences_setup.dm
+++ b/code/modules/mob/dead/new_player/preferences_setup.dm
@@ -25,7 +25,7 @@
if(job_engsec_high)
switch(job_engsec_high)
if(AI_JF)
- preview_icon = icon('icons/mob/AI.dmi', "AI", SOUTH)
+ preview_icon = icon('icons/mob/ai.dmi', "AI", SOUTH)
preview_icon.Scale(64, 64)
return
if(CYBORG)
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 694c9592c4f..6e453f68ef9 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -119,7 +119,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
GLOB.dead_mob_list += src
- ..()
+ . = ..()
grant_all_languages()
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 27e5a776d89..bdc968e2d37 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -362,6 +362,9 @@
if(M.equip_to_appropriate_slot(src))
M.update_inv_hands()
return TRUE
+ else
+ if(equip_delay_self)
+ return
if(M.s_active && M.s_active.can_be_inserted(src,1)) //if storage active insert there
M.s_active.handle_item_insertion(src)
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index 8d842d8a48d..69eacbb69e1 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -64,7 +64,7 @@
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
adjustOxyLoss(5)
if(prob(15))
- Paralyse(rand(1,3))
+ Unconscious(rand(20,60))
to_chat(src, "You feel extremely [word].")
if(0 to BLOOD_VOLUME_SURVIVE)
death()
diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm
index e338f493381..c79e167c103 100644
--- a/code/modules/mob/living/bloodcrawl.dm
+++ b/code/modules/mob/living/bloodcrawl.dm
@@ -95,7 +95,7 @@
var/mob/living/simple_animal/slaughter/SD = src
sound = SD.feast_sound
else
- sound = 'sound/magic/Demon_consume.ogg'
+ sound = 'sound/magic/demon_consume.ogg'
for(var/i in 1 to 3)
playsound(get_turf(src),sound, 100, 1)
diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm
index 11700b7638f..6f39718acf1 100644
--- a/code/modules/mob/living/brain/brain.dm
+++ b/code/modules/mob/living/brain/brain.dm
@@ -63,3 +63,11 @@
..()
if(stored_dna)
stored_dna.real_name = real_name
+
+/mob/living/brain/ClickOn(atom/A, params)
+ ..()
+ if(istype(loc,/obj/item/device/mmi))
+ var/obj/item/device/mmi/MMI = loc
+ var/obj/mecha/M = MMI.mecha
+ if((src == MMI.brainmob) && istype(M))
+ return M.click_action(A,src,params)
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index aa9e1331654..2ee3007bb1e 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -72,6 +72,8 @@
if(!brainmob.stored_dna)
brainmob.stored_dna = new /datum/dna/stored(brainmob)
C.dna.copy_dna(brainmob.stored_dna)
+ if(L.disabilities & NOCLONE)
+ brainmob.disabilities |= NOCLONE //This is so you can't just decapitate a husked guy and clone them without needing to get a new body
var/obj/item/organ/zombie_infection/ZI = L.getorganslot("zombie_infection")
if(ZI)
brainmob.set_species(ZI.old_species) //For if the brain is cloned
diff --git a/code/modules/mob/living/brain/status_procs.dm b/code/modules/mob/living/brain/status_procs.dm
index 4c40973c206..c5e01efcf9b 100644
--- a/code/modules/mob/living/brain/status_procs.dm
+++ b/code/modules/mob/living/brain/status_procs.dm
@@ -1,5 +1,5 @@
//Here are the procs used to modify status effects of a mob.
-//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness
+//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, and NEARSIGHT disability.
/////////////////////////////////// EYE_BLIND ////////////////////////////////////
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index f9ff1c3018c..efa754583db 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -23,7 +23,7 @@
var/has_fine_manipulation = 0
var/move_delay_add = 0 // movement delay to add
- status_flags = CANPARALYSE|CANPUSH
+ status_flags = CANUNCONSCIOUS|CANPUSH
var/heat_protection = 0.5
var/leaping = 0
diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm
index 9767623af47..4fc0f6924d4 100644
--- a/code/modules/mob/living/carbon/alien/alien_defense.dm
+++ b/code/modules/mob/living/carbon/alien/alien_defense.dm
@@ -21,11 +21,11 @@ In all, this is a lot like the monkey code. /N
switch(M.a_intent)
if ("help")
- AdjustSleeping(-5)
resting = 0
- AdjustParalysis(-3)
- AdjustStunned(-3)
- AdjustWeakened(-3)
+ AdjustStun(-60)
+ AdjustKnockdown(-60)
+ AdjustUnconscious(-60)
+ AdjustSleeping(-100)
visible_message("[M.name] nuzzles [src] trying to wake [p_them()] up!")
if ("grab")
@@ -116,10 +116,10 @@ In all, this is a lot like the monkey code. /N
if(3)
take_overall_damage(30,0)
if(prob(50))
- Paralyse(1)
+ Unconscious(20)
adjustEarDamage(15,60)
-/mob/living/carbon/alien/soundbang_act(intensity = 1, stun_pwr = 1, damage_pwr = 5, deafen_pwr = 15)
+/mob/living/carbon/alien/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15)
return 0
/mob/living/carbon/alien/acid_act(acidpwr, acid_volume)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
index 13ed9e26d48..0af56498fd2 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
@@ -38,7 +38,7 @@
#define MAX_ALIEN_LEAP_DIST 7
/mob/living/carbon/alien/humanoid/hunter/proc/leap_at(atom/A)
- if(pounce_cooldown)
+ if(pounce_cooldown > world.time)
to_chat(src, "You are too fatigued to pounce right now!")
return
@@ -76,19 +76,17 @@
blocked = 1
if(!blocked)
L.visible_message("[src] pounces on [L]!", "[src] pounces on you!")
- L.Weaken(5)
+ L.Knockdown(100)
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
step_towards(src,L)
else
- Weaken(2, 1, 1)
+ Knockdown(40, 1, 1)
toggle_leap(0)
- pounce_cooldown = !pounce_cooldown
- spawn(pounce_cooldown_time) //3s by default
- pounce_cooldown = !pounce_cooldown
+ pounce_cooldown = world.time + pounce_cooldown_time
else if(A.density && !A.CanPass(src))
visible_message("[src] smashes into [A]!", "[src] smashes into [A]!")
- Weaken(2, 1, 1)
+ Knockdown(40, 1, 1)
if(leaping)
leaping = 0
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm
index 90d4ced85fc..71619ff9a41 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm
@@ -45,9 +45,6 @@
if(!get_alien_type(/mob/living/carbon/alien/humanoid/royal/queen))
var/mob/living/carbon/alien/humanoid/royal/queen/new_xeno = new (user.loc)
user.alien_evolve(new_xeno)
- if(new_xeno.client.prefs.unlock_content)
- var/datum/action/innate/maid/M = new()
- M.Grant(new_xeno)
return 1
else
to_chat(user, "We already have an alive queen.")
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index be2852f64b1..fbbf7460285 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -27,7 +27,7 @@
/mob/living/carbon/alien/humanoid/movement_delay()
. = ..()
- . += move_delay_add + config.alien_delay + sneaking //move_delay_add is used to slow aliens with stuns
+ . += move_delay_add + config.alien_delay + sneaking //move_delay_add is used to slow aliens with stun
/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
. = handcuffed
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm
index b6c3b4427be..a09734ff494 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm
@@ -29,10 +29,10 @@
playsound(loc, "punch", 25, 1, -1)
visible_message("[M] has punched [src]!", \
"[M] has punched [src]!", null, COMBAT_MESSAGE_RANGE)
- if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of weakening an alien.
- Paralyse(2)
- visible_message("[M] has weakened [src]!", \
- "[M] has weakened [src]!")
+ if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of knocking an alien down.
+ Unconscious(40)
+ visible_message("[M] has knocked [src] down!", \
+ "[M] has knocked [src] down!")
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
apply_damage(damage, BRUTE, affecting)
add_logs(M, src, "attacked")
@@ -44,7 +44,7 @@
if ("disarm")
if (!lying)
if (prob(5))
- Paralyse(2)
+ Unconscious(40)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
add_logs(M, src, "pushed")
visible_message("[M] has pushed down [src]!", \
diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
index dc172b7730d..392e7ec67a9 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
@@ -153,36 +153,3 @@
/obj/item/queenpromote/attack_self(mob/user)
to_chat(user, "You discard [src].")
qdel(src)
-
-//:^)
-/datum/action/innate/maid
- name = "Maidify"
- button_icon_state = "alien_queen_maidify"
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS|AB_CHECK_LYING
- background_icon_state = "bg_alien"
-
-/datum/action/innate/maid/Activate()
- var/mob/living/carbon/alien/humanoid/royal/queen/A = owner
- A.maidify()
- active = TRUE
-
-/datum/action/innate/maid/Deactivate()
- var/mob/living/carbon/alien/humanoid/royal/queen/A = owner
- A.unmaidify()
- active = FALSE
-
-
-
-/mob/living/carbon/alien/humanoid/royal/queen/proc/maidify()
- name = "alien queen maid"
- desc = "Lusty, Sexy"
- icon_state = "alienqmaid"
- caste = "qmaid"
- update_icons()
-
-/mob/living/carbon/alien/humanoid/royal/queen/proc/unmaidify()
- name = "alien queen"
- desc = ""
- icon_state = "alienq"
- caste = "q"
- update_icons()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
index 8b88440a8ef..6b18923377c 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
@@ -4,6 +4,7 @@
for(var/I in overlays_standing)
add_overlay(I)
+ var/asleep = IsSleeping()
if(stat == DEAD)
//If we mostly took damage from fire
if(fireloss > 125)
@@ -11,12 +12,12 @@
else
icon_state = "alien[caste]_dead"
- else if((stat == UNCONSCIOUS && !sleeping) || weakened)
+ else if((stat == UNCONSCIOUS && !asleep) || knockdown)
icon_state = "alien[caste]_unconscious"
else if(leap_on_click)
icon_state = "alien[caste]_pounce"
- else if(lying || resting || sleeping)
+ else if(lying || resting || asleep)
icon_state = "alien[caste]_sleep"
else if(mob_size == MOB_SIZE_LARGE)
icon_state = "alien[caste]"
diff --git a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm
index 81266f9d974..62c00ca8ed5 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm
@@ -9,7 +9,7 @@
visible_message("[M] has kicked [src]!", \
"[M] has kicked [src]!", null, COMBAT_MESSAGE_RANGE)
if ((stat != DEAD) && (damage > 4.9))
- Paralyse(rand(5,10))
+ Unconscious(rand(100,200))
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
apply_damage(damage, BRUTE, affecting)
diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm
index f59afdf990a..f723e891f33 100644
--- a/code/modules/mob/living/carbon/alien/larva/life.dm
+++ b/code/modules/mob/living/carbon/alien/larva/life.dm
@@ -20,7 +20,7 @@
if(health<= -maxHealth || !getorgan(/obj/item/organ/brain))
death()
return
- if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
+ if(unconscious || IsSleeping() || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
if(stat == CONSCIOUS)
stat = UNCONSCIOUS
blind_eyes(1)
diff --git a/code/modules/mob/living/carbon/alien/larva/update_icons.dm b/code/modules/mob/living/carbon/alien/larva/update_icons.dm
index 7d41c87dfe7..7897cbf9693 100644
--- a/code/modules/mob/living/carbon/alien/larva/update_icons.dm
+++ b/code/modules/mob/living/carbon/alien/larva/update_icons.dm
@@ -12,11 +12,11 @@
if(stat == DEAD)
icon_state = "larva[state]_dead"
- else if (handcuffed || legcuffed) //This should be an overlay. Who made this an icon_state?
+ else if(handcuffed || legcuffed) //This should be an overlay. Who made this an icon_state?
icon_state = "larva[state]_cuff"
else if(stat == UNCONSCIOUS || lying || resting)
icon_state = "larva[state]_sleep"
- else if (stunned)
+ else if(IsStun())
icon_state = "larva[state]_stun"
else
icon_state = "larva[state]"
diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm
index f9bd64153e9..e538d32fb74 100644
--- a/code/modules/mob/living/carbon/alien/organs.dm
+++ b/code/modules/mob/living/carbon/alien/organs.dm
@@ -130,12 +130,12 @@
to_chat(owner, "Your Queen has been struck down!")
to_chat(owner, "You are struck with overwhelming agony! You feel confused, and your connection to the hivemind is severed.")
owner.emote("roar")
- owner.Stun(10) //Actually just slows them down a bit.
+ owner.Stun(200) //Actually just slows them down a bit.
else if(ishuman(owner)) //Humans, being more fragile, are more overwhelmed by the mental backlash.
to_chat(owner, "You feel a splitting pain in your head, and are struck with a wave of nausea. You cannot hear the hivemind anymore!")
owner.emote("scream")
- owner.Weaken(5)
+ owner.Knockdown(100)
owner.jitteriness += 30
owner.confused += 30
diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm
index af6bc971114..2d6193a7bef 100644
--- a/code/modules/mob/living/carbon/alien/special/facehugger.dm
+++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm
@@ -192,7 +192,7 @@
if(!sterile)
M.take_bodypart_damage(strength,0) //done here so that humans in helmets take damage
- M.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
+ M.Unconscious(MAX_IMPREGNATION_TIME/0.3) //something like 25 ticks = 20 seconds with the default settings
GoIdle() //so it doesn't jump the people that tear it off
diff --git a/code/modules/mob/living/carbon/alien/status_procs.dm b/code/modules/mob/living/carbon/alien/status_procs.dm
index b63d2330162..61de87b6cb3 100644
--- a/code/modules/mob/living/carbon/alien/status_procs.dm
+++ b/code/modules/mob/living/carbon/alien/status_procs.dm
@@ -1,20 +1,20 @@
//Here are the procs used to modify status effects of a mob.
-//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness, ear damage,
+//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness, ear damage,
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, and NEARSIGHT disability.
-/////////////////////////////////// STUNNED ////////////////////////////////////
+/////////////////////////////////// STUN ////////////////////////////////////
/mob/living/carbon/alien/Stun(amount, updating = 1, ignore_canstun = 0)
. = ..()
if(!.)
move_delay_add = min(move_delay_add + round(amount / 2), 10) //a maximum delay of 10
-/mob/living/carbon/alien/SetStunned(amount, updating = 1, ignore_canstun = 0)
+/mob/living/carbon/alien/SetStun(amount, updating = 1, ignore_canstun = 0)
. = ..()
if(!.)
move_delay_add = min(move_delay_add + round(amount / 2), 10)
-/mob/living/carbon/alien/AdjustStunned(amount, updating = 1, ignore_canstun = 0)
+/mob/living/carbon/alien/AdjustStun(amount, updating = 1, ignore_canstun = 0)
. = ..()
if(!.)
move_delay_add = Clamp(move_delay_add + round(amount/2), 0, 10)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 6f213171c4b..c48703a644a 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -102,7 +102,7 @@
hurt = FALSE
if(hit_atom.density && isturf(hit_atom))
if(hurt)
- Weaken(1)
+ Knockdown(20)
take_bodypart_damage(10)
if(iscarbon(hit_atom) && hit_atom != src)
var/mob/living/carbon/victim = hit_atom
@@ -111,8 +111,8 @@
if(hurt)
victim.take_bodypart_damage(10)
take_bodypart_damage(10)
- victim.Weaken(1)
- Weaken(1)
+ victim.Knockdown(20)
+ Knockdown(20)
visible_message("[src] crashes into [victim], knocking them both over!", "You violently crash into [victim]!")
playsound(src,'sound/weapons/punch1.ogg',50,1)
@@ -258,7 +258,7 @@
/mob/living/carbon/resist_fire()
fire_stacks -= 5
- Weaken(3, 1, 1)
+ Knockdown(60, TRUE, TRUE)
spin(32,2)
visible_message("[src] rolls on the floor, trying to put themselves out!", \
"You stop, drop, and roll!")
@@ -379,10 +379,6 @@
return
return TRUE
-/mob/living/carbon/proc/is_mouth_covered(head_only = 0, mask_only = 0)
- if( (!mask_only && head && (head.flags_cover & HEADCOVERSMOUTH)) || (!head_only && wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH)) )
- return 1
-
/mob/living/carbon/get_standard_pixel_y_offset(lying = 0)
if(lying)
return -6
@@ -450,7 +446,7 @@
return 0
return ..()
-/mob/living/carbon/proc/vomit(var/lost_nutrition = 10, var/blood = 0, var/stun = 1, var/distance = 0, var/message = 1, var/toxic = 0)
+/mob/living/carbon/proc/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, toxic = FALSE)
if(dna && dna.species && NOHUNGER in dna.species.species_traits)
return 1
@@ -459,7 +455,7 @@
visible_message("[src] dry heaves!", \
"You try to throw up, but there's nothing in your stomach!")
if(stun)
- Weaken(10)
+ Knockdown(200)
return 1
if(is_mouth_covered()) //make this add a blood/vomit overlay later it'll be hilarious
@@ -472,10 +468,13 @@
visible_message("[src] throws up!", "You throw up!")
if(stun)
- Stun(4)
+ Stun(80)
playsound(get_turf(src), 'sound/effects/splat.ogg', 50, 1)
var/turf/T = get_turf(src)
+ if(!blood)
+ nutrition -= lost_nutrition
+ adjustToxLoss(-3)
for(var/i=0 to distance)
if(blood)
if(T)
@@ -485,8 +484,6 @@
else
if(T)
T.add_vomit_floor(src, toxic)//toxic barf looks different
- nutrition -= lost_nutrition
- adjustToxLoss(-3)
T = get_step(T, dir)
if (is_blocked_turf(T))
break
@@ -686,7 +683,7 @@
if(health<= HEALTH_THRESHOLD_DEAD)
death()
return
- if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
+ if(unconscious || IsSleeping() || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
if(stat == CONSCIOUS)
stat = UNCONSCIOUS
blind_eyes(1)
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 82e53a73000..f994f667bdb 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -35,6 +35,18 @@
number += E.bang_protect
return number
+/mob/living/carbon/is_mouth_covered(head_only = 0, mask_only = 0)
+ if( (!mask_only && head && (head.flags_cover & HEADCOVERSMOUTH)) || (!head_only && wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH)) )
+ return TRUE
+
+/mob/living/carbon/is_eyes_covered(check_glasses = 1, check_head = 1, check_mask = 1)
+ if(check_glasses && glasses && (glasses.flags_cover & GLASSESCOVERSEYES))
+ return TRUE
+ if(check_head && head && (head.flags_cover & HEADCOVERSEYES))
+ return TRUE
+ if(check_mask && wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH))
+ return TRUE
+
/mob/living/carbon/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
var/obj/item/bodypart/affecting = get_bodypart(def_zone)
if(affecting && affecting.dismemberable && affecting.get_damage() >= (affecting.max_damage - P.dismemberment))
@@ -143,10 +155,9 @@
do_sparks(5, TRUE, src)
var/power = M.powerlevel + rand(0,3)
- Weaken(power)
+ Knockdown(power*20)
if(stuttering < power)
stuttering = power
- Stun(power)
if (prob(stunprob) && M.powerlevel >= 8)
adjustFireLoss(M.powerlevel * rand(6,10))
updatehealth()
@@ -211,12 +222,11 @@
do_jitter_animation(jitteriness)
stuttering += 2
if((!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) && stun)
- Stun(2)
+ Stun(40)
spawn(20)
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
if((!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) && stun)
- Stun(3)
- Weaken(3)
+ Knockdown(60)
if(override)
return override
else
@@ -232,16 +242,13 @@
if(lying)
M.visible_message("[M] shakes [src] trying to get [p_them()] up!", \
"You shake [src] trying to get [p_them()] up!")
- else if(check_zone(M.zone_selected) == "head")
- M.visible_message("[M] gives [src] a pat on the head to make [p_them()] feel better!", \
- "You give [src] a pat on the head to make [p_them()] feel better!")
else
M.visible_message("[M] hugs [src] to make [p_them()] feel better!", \
"You hug [src] to make [p_them()] feel better!")
- AdjustSleeping(-5)
- AdjustParalysis(-3)
- AdjustStunned(-3)
- AdjustWeakened(-3)
+ AdjustStun(-60)
+ AdjustKnockdown(-60)
+ AdjustUnconscious(-60)
+ AdjustSleeping(-100)
if(resting)
resting = 0
update_canmove()
@@ -293,18 +300,18 @@
mind.disrupt_spells(0)
-/mob/living/carbon/soundbang_act(intensity = 1, stun_pwr = 1, damage_pwr = 5, deafen_pwr = 15)
+/mob/living/carbon/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15)
var/ear_safety = get_ear_protection()
var/obj/item/organ/ears/ears = getorganslot("ears")
var/effect_amount = intensity - ear_safety
if(effect_amount > 0)
if(stun_pwr)
- Stun(stun_pwr*effect_amount)
- Weaken(stun_pwr*effect_amount)
+ Knockdown(stun_pwr*effect_amount)
if(istype(ears) && (deafen_pwr || damage_pwr))
- ears.ear_damage += damage_pwr * effect_amount
- ears.deaf = max(ears.deaf, deafen_pwr * effect_amount)
+ var/ear_damage = damage_pwr * effect_amount
+ var/deaf = max(ears.deaf, deafen_pwr * effect_amount)
+ adjustEarDamage(ear_damage,deaf)
if(ears.ear_damage >= 15)
to_chat(src, "Your ears start to ring badly!")
diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm
index 5b1f43d58cf..62bcb9c6ec1 100644
--- a/code/modules/mob/living/carbon/carbon_movement.dm
+++ b/code/modules/mob/living/carbon/carbon_movement.dm
@@ -19,12 +19,12 @@
if(legcuffed)
. += legcuffed.slowdown
-/mob/living/carbon/slip(s_amount, w_amount, obj/O, lube)
+/mob/living/carbon/slip(knockdown_amount, obj/O, lube)
if(movement_type & FLYING)
return 0
if(!(lube&SLIDE_ICE))
add_logs(src,, "slipped",, "on [O ? O.name : "floor"]")
- return loc.handle_slip(src, s_amount, w_amount, O, lube)
+ return loc.handle_slip(src, knockdown_amount, O, lube)
/mob/living/carbon/Process_Spacemove(movement_dir = 0)
@@ -57,3 +57,13 @@
nutrition -= HUNGER_FACTOR/10
if((disabilities & FAT) && m_intent == MOVE_INTENT_RUN && bodytemperature <= 360)
bodytemperature += 2
+
+/mob/living/carbon/Moved(oldLoc, Dir)
+ . = ..()
+ for(var/obj/O in internal_organs)
+ O.on_mob_move(dir, src, oldLoc)
+
+/mob/living/carbon/setDir(newdir)
+ . = ..()
+ for(var/obj/O in internal_organs)
+ O.on_mob_turn(newdir, src)
diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm
index 2fe0a7f7bdd..ebc349cefc4 100644
--- a/code/modules/mob/living/carbon/examine.dm
+++ b/code/modules/mob/living/carbon/examine.dm
@@ -6,26 +6,26 @@
var/t_has = p_have()
var/t_is = p_are()
- var/msg = "*---------*\nThis is \icon[src] \a [src]!\n"
+ var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
if (handcuffed)
- msg += "[t_He] [t_is] \icon[src.handcuffed] handcuffed!\n"
+ msg += "[t_He] [t_is] [bicon(handcuffed)] handcuffed!\n"
if (head)
- msg += "[t_He] [t_is] wearing \icon[src.head] \a [src.head] on [t_his] head. \n"
+ msg += "[t_He] [t_is] wearing [bicon(head)] \a [src.head] on [t_his] head. \n"
if (wear_mask)
- msg += "[t_He] [t_is] wearing \icon[src.wear_mask] \a [src.wear_mask] on [t_his] face.\n"
+ msg += "[t_He] [t_is] wearing [bicon(wear_mask)] \a [src.wear_mask] on [t_his] face.\n"
if (wear_neck)
- msg += "[t_He] [t_is] wearing \icon[src.wear_neck] \a [src.wear_neck] around [t_his] neck.\n"
+ msg += "[t_He] [t_is] wearing [bicon(wear_neck)] \a [src.wear_neck] around [t_his] neck.\n"
for(var/obj/item/I in held_items)
if(!(I.flags & ABSTRACT))
if(I.blood_DNA)
- msg += "[t_He] [t_is] holding \icon[I] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!\n"
+ msg += "[t_He] [t_is] holding [bicon(I)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!\n"
else
- msg += "[t_He] [t_is] holding \icon[I] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "[t_He] [t_is] holding [bicon(I)] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
if (back)
- msg += "[t_He] [t_has] \icon[src.back] \a [src.back] on [t_his] back.\n"
+ msg += "[t_He] [t_has] [bicon(back)] \a [src.back] on [t_his] back.\n"
var/appears_dead = 0
if (stat == DEAD)
appears_dead = 1
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index e176ee14392..3c5422be79c 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -14,60 +14,60 @@
//uniform
if(w_uniform && !(slot_w_uniform in obscured))
- //Ties
- var/tie_msg
+ //accessory
+ var/accessory_msg
if(istype(w_uniform,/obj/item/clothing/under))
var/obj/item/clothing/under/U = w_uniform
- if(U.hastie)
- tie_msg += " with \icon[U.hastie] \a [U.hastie]"
+ if(U.attached_accessory)
+ accessory_msg += " with [bicon(U.attached_accessory)] \a [U.attached_accessory]"
if(w_uniform.blood_DNA)
- msg += "[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] blood-stained [w_uniform.name][tie_msg]!\n"
+ msg += "[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] blood-stained [w_uniform.name][accessory_msg]!\n"
else
- msg += "[t_He] [t_is] wearing \icon[w_uniform] \a [w_uniform][tie_msg].\n"
+ msg += "[t_He] [t_is] wearing [bicon(w_uniform)] \a [w_uniform][accessory_msg].\n"
//head
if(head)
if(head.blood_DNA)
- msg += "[t_He] [t_is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on [t_his] head!\n"
+ msg += "[t_He] [t_is] wearing [bicon(head)] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on [t_his] head!\n"
else
- msg += "[t_He] [t_is] wearing \icon[head] \a [head] on [t_his] head.\n"
+ msg += "[t_He] [t_is] wearing [bicon(head)] \a [head] on [t_his] head.\n"
//suit/armor
if(wear_suit)
if(wear_suit.blood_DNA)
- msg += "[t_He] [t_is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] blood-stained [wear_suit.name]!\n"
+ msg += "[t_He] [t_is] wearing [bicon(wear_suit)] [wear_suit.gender==PLURAL?"some":"a"] blood-stained [wear_suit.name]!\n"
else
- msg += "[t_He] [t_is] wearing \icon[wear_suit] \a [wear_suit].\n"
+ msg += "[t_He] [t_is] wearing [bicon(wear_suit)] \a [wear_suit].\n"
//suit/armor storage
if(s_store)
if(s_store.blood_DNA)
- msg += "[t_He] [t_is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] blood-stained [s_store.name] on [t_his] [wear_suit.name]!\n"
+ msg += "[t_He] [t_is] carrying [bicon(s_store)] [s_store.gender==PLURAL?"some":"a"] blood-stained [s_store.name] on [t_his] [wear_suit.name]!\n"
else
- msg += "[t_He] [t_is] carrying \icon[s_store] \a [s_store] on [t_his] [wear_suit.name].\n"
+ msg += "[t_He] [t_is] carrying [bicon(s_store)] \a [s_store] on [t_his] [wear_suit.name].\n"
//back
if(back)
if(back.blood_DNA)
- msg += "[t_He] [t_has] \icon[back] [back.gender==PLURAL?"some":"a"] blood-stained [back] on [t_his] back.\n"
+ msg += "[t_He] [t_has] [bicon(back)] [back.gender==PLURAL?"some":"a"] blood-stained [back] on [t_his] back.\n"
else
- msg += "[t_He] [t_has] \icon[back] \a [back] on [t_his] back.\n"
+ msg += "[t_He] [t_has] [bicon(back)] \a [back] on [t_his] back.\n"
//Hands
for(var/obj/item/I in held_items)
if(!(I.flags & ABSTRACT))
if(I.blood_DNA)
- msg += "[t_He] [t_is] holding \icon[I] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!\n"
+ msg += "[t_He] [t_is] holding [bicon(I)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!\n"
else
- msg += "[t_He] [t_is] holding \icon[I] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "[t_He] [t_is] holding [bicon(I)] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
//gloves
if(gloves && !(slot_gloves in obscured))
if(gloves.blood_DNA)
- msg += "[t_He] [t_has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] blood-stained [gloves.name] on [t_his] hands!\n"
+ msg += "[t_He] [t_has] [bicon(gloves)] [gloves.gender==PLURAL?"some":"a"] blood-stained [gloves.name] on [t_his] hands!\n"
else
- msg += "[t_He] [t_has] \icon[gloves] \a [gloves] on [t_his] hands.\n"
+ msg += "[t_He] [t_has] [bicon(gloves)] \a [gloves] on [t_his] hands.\n"
else if(blood_DNA)
var/hand_number = get_num_arms()
if(hand_number)
@@ -78,48 +78,48 @@
//handcuffed?
if(handcuffed)
if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable))
- msg += "[t_He] [t_is] \icon[handcuffed] restrained with cable!\n"
+ msg += "[t_He] [t_is] [bicon(handcuffed)] restrained with cable!\n"
else
- msg += "[t_He] [t_is] \icon[handcuffed] handcuffed!\n"
+ msg += "[t_He] [t_is] [bicon(handcuffed)] handcuffed!\n"
//belt
if(belt)
if(belt.blood_DNA)
- msg += "[t_He] [t_has] \icon[belt] [belt.gender==PLURAL?"some":"a"] blood-stained [belt.name] about [t_his] waist!\n"
+ msg += "[t_He] [t_has] [bicon(belt)] [belt.gender==PLURAL?"some":"a"] blood-stained [belt.name] about [t_his] waist!\n"
else
- msg += "[t_He] [t_has] \icon[belt] \a [belt] about [t_his] waist.\n"
+ msg += "[t_He] [t_has] [bicon(belt)] \a [belt] about [t_his] waist.\n"
//shoes
if(shoes && !(slot_shoes in obscured))
if(shoes.blood_DNA)
- msg += "[t_He] [t_is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] blood-stained [shoes.name] on [t_his] feet!\n"
+ msg += "[t_He] [t_is] wearing [bicon(shoes)] [shoes.gender==PLURAL?"some":"a"] blood-stained [shoes.name] on [t_his] feet!\n"
else
- msg += "[t_He] [t_is] wearing \icon[shoes] \a [shoes] on [t_his] feet.\n"
+ msg += "[t_He] [t_is] wearing [bicon(shoes)] \a [shoes] on [t_his] feet.\n"
//mask
if(wear_mask && !(slot_wear_mask in obscured))
if(wear_mask.blood_DNA)
- msg += "[t_He] [t_has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] blood-stained [wear_mask.name] on [t_his] face!\n"
+ msg += "[t_He] [t_has] [bicon(wear_mask)] [wear_mask.gender==PLURAL?"some":"a"] blood-stained [wear_mask.name] on [t_his] face!\n"
else
- msg += "[t_He] [t_has] \icon[wear_mask] \a [wear_mask] on [t_his] face.\n"
+ msg += "[t_He] [t_has] [bicon(wear_mask)] \a [wear_mask] on [t_his] face.\n"
if (wear_neck && !(slot_neck in obscured))
- msg += "[t_He] [t_is] wearing \icon[src.wear_neck] \a [src.wear_neck] around [t_his] neck.\n"
+ msg += "[t_He] [t_is] wearing [bicon(wear_neck)] \a [src.wear_neck] around [t_his] neck.\n"
//eyes
if(glasses && !(slot_glasses in obscured))
if(glasses.blood_DNA)
- msg += "[t_He] [t_has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] blood-stained [glasses] covering [t_his] eyes!\n"
+ msg += "[t_He] [t_has] [bicon(glasses)] [glasses.gender==PLURAL?"some":"a"] blood-stained [glasses] covering [t_his] eyes!\n"
else
- msg += "[t_He] [t_has] \icon[glasses] \a [glasses] covering [t_his] eyes.\n"
+ msg += "[t_He] [t_has] [bicon(glasses)] \a [glasses] covering [t_his] eyes.\n"
//ears
if(ears && !(slot_ears in obscured))
- msg += "[t_He] [t_has] \icon[ears] \a [ears] on [t_his] ears.\n"
+ msg += "[t_He] [t_has] [bicon(ears)] \a [ears] on [t_his] ears.\n"
//ID
if(wear_id)
- msg += "[t_He] [t_is] wearing \icon[wear_id] \a [wear_id].\n"
+ msg += "[t_He] [t_is] wearing [bicon(wear_id)] \a [wear_id].\n"
//Jitters
switch(jitteriness)
@@ -164,7 +164,7 @@
var/obj/item/bodypart/BP = X
missing -= BP.body_zone
for(var/obj/item/I in BP.embedded_objects)
- msg += "[t_He] [t_has] \a \icon[I] [I] embedded in [t_his] [BP.name]!\n"
+ msg += "[t_He] [t_has] \a [bicon(I)] [I] embedded in [t_his] [BP.name]!\n"
//stores missing limbs
var/l_limbs_missing = 0
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 8222c1f46b2..8c3e42f394c 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -501,7 +501,7 @@
to_chat(usr, "Unable to locate a data core entry for this person.")
/mob/living/carbon/human/proc/canUseHUD()
- return !(src.stat || src.weakened || src.stunned || src.restrained())
+ return !(src.stat || src.knockdown || IsStun() || src.restrained())
/mob/living/carbon/human/can_inject(mob/user, error_msg, target_zone, var/penetrate_thick = 0)
. = 1 // Default to returning true.
@@ -882,7 +882,7 @@
visible_message("[src] dry heaves!", \
"You try to throw up, but there's nothing in your stomach!")
if(stun)
- Weaken(10)
+ Knockdown(200)
return 1
..()
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index df97b0aa315..feb9e783ac1 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -70,7 +70,7 @@
return -1 // complete projectile permutation
- if(check_shields(P.damage, "the [P.name]", P, PROJECTILE_ATTACK, P.armour_penetration))
+ if(check_shields(P, P.damage, "the [P.name]", PROJECTILE_ATTACK, P.armour_penetration))
P.on_hit(src, 100, def_zone)
return 2
@@ -85,29 +85,27 @@
return 1
return 0
-/mob/living/carbon/human/proc/check_shields(damage = 0, attack_text = "the attack", atom/movable/AM, attack_type = MELEE_ATTACK, armour_penetration = 0)
+/mob/living/carbon/human/proc/check_shields(atom/AM, var/damage, attack_text = "the attack", attack_type = MELEE_ATTACK, armour_penetration = 0)
var/block_chance_modifier = round(damage / -3)
for(var/obj/item/I in held_items)
if(!istype(I, /obj/item/clothing))
var/final_block_chance = I.block_chance - (Clamp((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
- if(I.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
+ if(I.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return 1
if(wear_suit)
var/final_block_chance = wear_suit.block_chance - (Clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier
- if(wear_suit.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
+ if(wear_suit.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return 1
if(w_uniform)
var/final_block_chance = w_uniform.block_chance - (Clamp((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier
- if(w_uniform.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
+ if(w_uniform.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return 1
return 0
/mob/living/carbon/human/proc/check_block()
if(mind)
- if(mind.martial_art && mind.martial_art.block_chance \
- && prob(mind.martial_art.block_chance) && in_throw_mode \
- && !stat && !weakened && !stunned)
+ if(mind.martial_art && prob(mind.martial_art.block_chance) && in_throw_mode && !stat && !knockdown && !IsStun())
return TRUE
return FALSE
@@ -122,7 +120,7 @@
throwpower = I.throwforce
if(I.thrownby == src) //No throwing stuff at yourself to trigger hit reactions
return ..()
- if(check_shields(throwpower, "\the [AM.name]", AM, THROWN_PROJECTILE_ATTACK))
+ if(check_shields(AM, throwpower, "\the [AM.name]", THROWN_PROJECTILE_ATTACK))
hitpush = 0
skipcatch = 1
blocked = 1
@@ -170,7 +168,7 @@
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(user.a_intent == INTENT_HARM)
var/hulk_verb = pick("smash","pummel")
- if(check_shields(15, "the [hulk_verb]ing"))
+ if(check_shields(user, 15, "the [hulk_verb]ing"))
return
..(user, 1)
playsound(loc, user.dna.species.attack_sound, 25, 1, -1)
@@ -208,7 +206,7 @@
"[M] disarmed [src]!")
else if(!M.client || prob(5)) // only natural monkeys get to stun reliably, (they only do it occasionaly)
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
- Weaken(5)
+ Knockdown(100)
add_logs(M, src, "tackled")
visible_message("[M] has tackled down [src]!", \
"[M] has tackled down [src]!")
@@ -219,7 +217,7 @@
if(can_inject(M, 1, affecting))//Thick suits can stop monkey bites.
if(..()) //successful monkey bite, this handles disease contraction.
var/damage = rand(1, 3)
- if(check_shields(damage))
+ if(check_shields(M, damage, "the [M.name]"))
return 0
if(stat != DEAD)
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
@@ -227,7 +225,7 @@
return 1
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
- if(check_shields(0, M.name))
+ if(check_shields(M, 0, "the M.name"))
visible_message("[M] attempted to touch [src]!")
return 0
@@ -255,14 +253,14 @@
apply_damage(damage, BRUTE, affecting, armor_block)
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
- if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stunned instead.
+ if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stun instead.
if(get_active_held_item() && drop_item())
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
visible_message("[M] disarmed [src]!", \
"[M] disarmed [src]!")
else
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
- Weaken(5)
+ Knockdown(100)
add_logs(M, src, "tackled")
visible_message("[M] has tackled down [src]!", \
"[M] has tackled down [src]!")
@@ -272,7 +270,7 @@
if(..()) //successful larva bite.
var/damage = rand(1, 3)
- if(check_shields(damage, "the [L.name]"))
+ if(check_shields(L, damage, "the [L.name]"))
return 0
if(stat != DEAD)
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
@@ -288,7 +286,7 @@
. = ..()
if(.)
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
- if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration))
+ if(check_shields(M, damage, "the [M.name]", MELEE_ATTACK, M.armour_penetration))
return FALSE
var/dam_zone = dismembering_strike(M, pick("chest", "l_hand", "r_hand", "l_leg", "r_leg"))
if(!dam_zone) //Dismemberment successful
@@ -307,7 +305,7 @@
if(M.is_adult)
damage = rand(10, 35)
- if(check_shields(damage, "the [M.name]"))
+ if(check_shields(M, damage, "the [M.name]"))
return 0
var/dam_zone = dismembering_strike(M, pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg"))
@@ -334,13 +332,13 @@
switch(M.damtype)
if("brute")
if(M.force > 20)
- Paralyse(1)
+ Unconscious(20)
update |= temp.receive_damage(dmg, 0)
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
damage_clothes(dmg, BRUTE, "melee", temp.body_zone)
if("fire")
update |= temp.receive_damage(0, dmg)
- playsound(src, 'sound/items/Welder.ogg', 50, 1)
+ playsound(src, 'sound/items/welder.ogg', 50, 1)
damage_clothes(dmg, BURN, "melee", temp.body_zone)
if("tox")
M.mech_toxin_damage(src)
@@ -388,7 +386,7 @@
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
adjustEarDamage(30, 120)
if (prob(max(70 - (bomb_armor * 0.5), 0)))
- Paralyse(10)
+ Unconscious(200)
if(3)
b_loss = 30
@@ -398,7 +396,7 @@
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
adjustEarDamage(15,60)
if (prob(max(50 - (bomb_armor * 0.5), 0)))
- Paralyse(8)
+ Unconscious(160)
take_overall_damage(b_loss,f_loss)
@@ -468,10 +466,10 @@
switch(severity)
if(1)
L.receive_damage(0,10)
- src.Stun(10)
+ Stun(200)
if(2)
L.receive_damage(0,5)
- src.Stun(5)
+ Stun(100)
..()
/mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit)
@@ -665,10 +663,10 @@
status += "numb"
if(status == "")
status = "OK"
- to_chat(src, "\t [status == "OK" ? "\blue" : "\red"] Your [LB.name] is [status].")
+ to_chat(src, "\t Your [LB.name] is [status].")
for(var/obj/item/I in LB.embedded_objects)
- to_chat(src, "\t There is \a [I] embedded in your [LB.name]!")
+ to_chat(src, "\t There is \a [I] embedded in your [LB.name]!")
for(var/t in missing)
to_chat(src, "Your [parse_zone(t)] is missing!")
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 49ad54a968b..29e82efe6b0 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -66,12 +66,21 @@
var/obj/item/weapon/storage/wallet/wallet = wear_id
var/obj/item/device/pda/pda = wear_id
var/obj/item/weapon/card/id/id = wear_id
+ var/obj/item/device/modular_computer/tablet/tablet = wear_id
if(istype(wallet))
id = wallet.front_id
if(istype(id))
. = id.registered_name
else if(istype(pda))
. = pda.owner
+ else if(istype(tablet))
+ var/obj/item/weapon/computer_hardware/card_slot/card_slot = tablet.all_components[MC_CARD]
+ if(card_slot && (card_slot.stored_card2 || card_slot.stored_card))
+ if(card_slot.stored_card2) //The second card is the one used for authorization in the ID changing program, so we prioritize it here for consistency
+ . = card_slot.stored_card2.registered_name
+ else
+ if(card_slot.stored_card)
+ . = card_slot.stored_card.registered_name
if(!.)
. = if_no_id //to prevent null-names making the mob unclickable
return
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 648d38c63b8..5336ea5f67f 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -4,7 +4,7 @@
. += config.human_delay
. += dna.species.movement_delay(src)
-/mob/living/carbon/human/slip(s_amount, w_amount, obj/O, lube)
+/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube)
if(isobj(shoes) && (shoes.flags&NOSLIP) && !(lube&GALOSHES_DONT_HELP))
return 0
return ..()
diff --git a/code/modules/mob/living/carbon/human/interactive.dm b/code/modules/mob/living/carbon/human/interactive.dm
index c93a79f4fc6..90b843cbb61 100644
--- a/code/modules/mob/living/carbon/human/interactive.dm
+++ b/code/modules/mob/living/carbon/human/interactive.dm
@@ -450,9 +450,9 @@
return 1
if(restrained())
return 1
- if(paralysis)
+ if(unconscious)
return 1
- if(stunned)
+ if(IsStun())
return 1
if(stat)
return 1
@@ -1536,8 +1536,8 @@
if(ispath(A,/obj/item/ammo_casing/energy/electrode))
stunning = 1
var/shouldFire = 1
- var/mob/stunCheck = TARGET
- if(stunning && stunCheck.stunned)
+ var/mob/living/stunCheck = TARGET
+ if(stunning && isliving(stunCheck) && stunCheck.IsStun())
shouldFire = 0
if(shouldFire)
if(P.cell.charge <= 10) // can shoot seems to bug out for tasers, using this hacky method instead
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 1b5518008e5..eeb046a3e75 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -1,5 +1,5 @@
-/mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = 0)
- return dna.species.can_equip(I, slot, disable_warning, src)
+/mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
+ return dna.species.can_equip(I, slot, disable_warning, src, bypass_equip_delay_self)
// Return the item currently in the slot ID
/mob/living/carbon/human/get_item_by_slot(slot_id)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 8a3360911ed..0374e1076ea 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -278,9 +278,9 @@
//Puke if toxloss is too high
if(!stat)
if(getToxLoss() >= 45 && nutrition > 20)
- lastpuke ++
- if(lastpuke >= 25) // about 25 second delay I guess
- vomit(20, 0, 1, 0, 1, 1)
+ lastpuke += prob(50)
+ if(lastpuke >= 50) // about 25 second delay I guess
+ vomit(20, toxic = TRUE)
lastpuke = 0
@@ -356,7 +356,7 @@
if(we_breath)
adjustOxyLoss(8)
- Paralyse(4)
+ Unconscious(80)
// Tissues die without blood circulation
adjustBruteLoss(2)
@@ -382,10 +382,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/mob/living/carbon/human/handle_status_effects()
..()
if(drunkenness)
- if(sleeping)
- drunkenness = max(drunkenness - (drunkenness / 10), 0)
- else
- drunkenness = max(drunkenness - (drunkenness / 25), 0)
+ drunkenness = max(drunkenness - (drunkenness * 0.04), 0)
if(drunkenness >= 6)
if(prob(25))
@@ -425,7 +422,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
to_chat(src, "You're so tired... but you can't miss that shuttle...")
else
to_chat(src, "Just a quick nap...")
- Sleeping(45)
+ Sleeping(900)
if(drunkenness >= 101)
adjustToxLoss(4) //Let's be honest you shouldn't be alive by now
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 9ca002fe102..685a443a6c7 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -603,7 +603,7 @@
// handles the equipping of species-specific gear
return
-/datum/species/proc/can_equip(obj/item/I, slot, disable_warning, mob/living/carbon/human/H)
+/datum/species/proc/can_equip(obj/item/I, slot, disable_warning, mob/living/carbon/human/H, bypass_equip_delay_self = FALSE)
if(slot in no_equip)
if(!I.species_exception || !is_type_in_list(src, I.species_exception))
return 0
@@ -623,7 +623,7 @@
return 0
if(!H.get_bodypart("head"))
return 0
- return 1
+ return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(slot_neck)
if(H.wear_neck)
return 0
@@ -635,13 +635,13 @@
return 0
if( !(I.slot_flags & SLOT_BACK) )
return 0
- return 1
+ return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(slot_wear_suit)
if(H.wear_suit)
return 0
if( !(I.slot_flags & SLOT_OCLOTHING) )
return 0
- return 1
+ return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(slot_gloves)
if(H.gloves)
return 0
@@ -649,7 +649,7 @@
return 0
if(num_arms < 2)
return 0
- return 1
+ return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(slot_shoes)
if(H.shoes)
return 0
@@ -661,7 +661,7 @@
if(!disable_warning)
to_chat(H, "The footwear around here isn't compatible with your feet!")
return 0
- return 1
+ return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(slot_belt)
if(H.belt)
return 0
@@ -671,7 +671,7 @@
return 0
if( !(I.slot_flags & SLOT_BELT) )
return
- return 1
+ return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(slot_glasses)
if(H.glasses)
return 0
@@ -679,7 +679,7 @@
return 0
if(!H.get_bodypart("head"))
return 0
- return 1
+ return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(slot_head)
if(H.head)
return 0
@@ -687,7 +687,7 @@
return 0
if(!H.get_bodypart("head"))
return 0
- return 1
+ return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(slot_ears)
if(H.ears)
return 0
@@ -695,13 +695,13 @@
return 0
if(!H.get_bodypart("head"))
return 0
- return 1
+ return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(slot_w_uniform)
if(H.w_uniform)
return 0
if( !(I.slot_flags & SLOT_ICLOTHING) )
return 0
- return 1
+ return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(slot_wear_id)
if(H.wear_id)
return 0
@@ -711,7 +711,7 @@
return 0
if( !(I.slot_flags & SLOT_ID) )
return 0
- return 1
+ return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(slot_l_store)
if(I.flags & NODROP) //Pockets aren't visible, so you can't move NODROP items into them.
return 0
@@ -783,6 +783,12 @@
return 0
return 0 //Unsupported slot
+/datum/species/proc/equip_delay_self_check(obj/item/I, mob/living/carbon/human/H, bypass_equip_delay_self)
+ if(!I.equip_delay_self || bypass_equip_delay_self)
+ return TRUE
+ H.visible_message("[H] start putting on [I]...", "You start putting on [I]...")
+ return do_after(H, I.equip_delay_self, target = H)
+
/datum/species/proc/before_equip_job(datum/job/J, mob/living/carbon/human/H)
return
@@ -882,16 +888,16 @@
if(!(RADIMMUNE in species_traits))
if(H.radiation)
if (H.radiation > 100)
- if(!H.weakened)
+ if(!H.knockdown)
H.emote("collapse")
- H.Weaken(10)
+ H.Knockdown(200)
to_chat(H, "You feel weak.")
switch(H.radiation)
if(50 to 75)
if(prob(5))
- if(!H.weakened)
+ if(!H.knockdown)
H.emote("collapse")
- H.Weaken(3)
+ H.Knockdown(60)
to_chat(H, "You feel weak.")
if(prob(15))
@@ -1072,9 +1078,9 @@
target.apply_damage(damage, BRUTE, affecting, armor_block)
add_logs(user, target, "punched")
if((target.stat != DEAD) && damage >= user.dna.species.punchstunthreshold)
- target.visible_message("[user] has weakened [target]!", \
- "[user] has weakened [target]!")
- target.apply_effect(4, WEAKEN, armor_block)
+ target.visible_message("[user] has knocked [target] down!", \
+ "[user] has knocked [target] down!")
+ target.apply_effect(80, KNOCKDOWN, armor_block)
target.forcesay(GLOB.hit_appends)
else if(target.lying)
target.forcesay(GLOB.hit_appends)
@@ -1082,18 +1088,7 @@
/datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
- var/aim_for_mouth = user.zone_selected == "mouth"
- var/target_on_help_and_unarmed = target.a_intent == INTENT_HELP && !target.get_active_held_item()
- var/target_aiming_for_mouth = target.zone_selected == "mouth"
- var/target_restrained = target.restrained()
- if(aim_for_mouth && ( target_on_help_and_unarmed || target_restrained || target_aiming_for_mouth))
- playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
- user.visible_message("[user] slaps [target] in the face!",
- "You slap [target] in the face! ",\
- "You hear a slap.")
- target.endTailWag()
- return FALSE
- else if(target.check_block())
+ if(target.check_block())
target.visible_message("[target] blocks [user]'s disarm attempt!")
return 0
if(attacker_style && attacker_style.disarm_act(user,target))
@@ -1109,7 +1104,7 @@
playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
target.visible_message("[user] has pushed [target]!",
"[user] has pushed [target]!", null, COMBAT_MESSAGE_RANGE)
- target.apply_effect(2, WEAKEN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!"))
+ target.apply_effect(40, KNOCKDOWN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!"))
target.forcesay(GLOB.hit_appends)
add_logs(user, target, "disarmed", " pushing them to the ground")
return
@@ -1150,7 +1145,7 @@
return
if(M.mind)
attacker_style = M.mind.martial_art
- if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(0, M.name, attack_type = UNARMED_ATTACK))
+ if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK))
add_logs(M, H, "attempted to touch")
H.visible_message("[M] attempted to touch [H]!")
return 0
@@ -1170,7 +1165,7 @@
/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
// Allows you to put in item-specific reactions based on species
if(user != H)
- if(H.check_shields(I.force, "the [I.name]", I, MELEE_ATTACK, I.armour_penetration))
+ if(H.check_shields(I, I.force, "the [I.name]", MELEE_ATTACK, I.armour_penetration))
return 0
if(H.check_block())
H.visible_message("[H] blocks [I]!")
@@ -1243,7 +1238,7 @@
if(prob(I.force))
H.visible_message("[H] has been knocked down!", \
"[H] has been knocked down!")
- H.apply_effect(3, WEAKEN, armor_block)
+ H.apply_effect(60, KNOCKDOWN, armor_block)
if(bloody)
if(H.wear_suit)
@@ -1345,19 +1340,24 @@
// +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !(RESISTHOT in species_traits))
//Body temperature is too hot.
+ var/burn_damage
switch(H.bodytemperature)
if(360 to 400)
H.throw_alert("temp", /obj/screen/alert/hot, 1)
- H.apply_damage(HEAT_DAMAGE_LEVEL_1*heatmod, BURN)
+ burn_damage = HEAT_DAMAGE_LEVEL_1
if(400 to 460)
H.throw_alert("temp", /obj/screen/alert/hot, 2)
- H.apply_damage(HEAT_DAMAGE_LEVEL_2*heatmod, BURN)
+ burn_damage = HEAT_DAMAGE_LEVEL_2
if(460 to INFINITY)
H.throw_alert("temp", /obj/screen/alert/hot, 3)
if(H.on_fire)
- H.apply_damage(HEAT_DAMAGE_LEVEL_3*heatmod, BURN)
+ burn_damage = HEAT_DAMAGE_LEVEL_3
else
- H.apply_damage(HEAT_DAMAGE_LEVEL_2*heatmod, BURN)
+ burn_damage = HEAT_DAMAGE_LEVEL_2
+ burn_damage *= heatmod
+ if((prob(burn_damage) * 10) / 4) //40% for level 3 damage on humans
+ H.emote("scream")
+ H.apply_damage(burn_damage, BURN)
else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !(GLOB.mutations_list[COLDRES] in H.dna.mutations))
switch(H.bodytemperature)
if(200 to 260)
@@ -1480,9 +1480,9 @@
return
-////////
+////////////
//Stun//
-////////
+////////////
/datum/species/proc/spec_stun(mob/living/carbon/human/H,amount)
. = stunmod * amount
diff --git a/code/modules/mob/living/carbon/human/species_types/angel.dm b/code/modules/mob/living/carbon/human/species_types/angel.dm
index a5282d1892c..c420c087a6d 100644
--- a/code/modules/mob/living/carbon/human/species_types/angel.dm
+++ b/code/modules/mob/living/carbon/human/species_types/angel.dm
@@ -47,7 +47,7 @@
return 0
/datum/species/angel/proc/CanFly(mob/living/carbon/human/H)
- if(H.stat || H.stunned || H.weakened)
+ if(H.stat || H.IsStun() || H.knockdown)
return 0
if(H.wear_suit && ((H.wear_suit.flags_inv & HIDEJUMPSUIT) && (!H.wear_suit.species_exception || !is_type_in_list(src, H.wear_suit.species_exception)))) //Jumpsuits have tail holes, so it makes sense they have wing holes too
to_chat(H, "Your suit blocks your wings from extending!")
@@ -65,7 +65,7 @@
/datum/action/innate/flight
name = "Toggle Flight"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUNNED
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
button_icon_state = "flight"
/datum/action/innate/flight/Activate()
diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm
index e77e424d405..e1b9f0b86c3 100644
--- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm
@@ -17,7 +17,7 @@
var/datum/reagent/consumable/nutri_check = chem
if(nutri_check.nutriment_factor > 0)
var/turf/pos = get_turf(H)
- H.vomit(0, 0, 0, 1, 1)
+ H.vomit(0, FALSE, FALSE, 2, TRUE)
playsound(pos, 'sound/effects/splat.ogg', 50, 1)
H.visible_message("[H] vomits on the floor!", \
"You throw up on the floor!")
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index cd4abe5c40a..2c794c5b818 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -340,7 +340,7 @@
brutemod = 3 //very fragile
burnmod = 0.25
info_text = "As a Glass Golem, you reflect lasers and energy weapons, and are very resistant to burn damage, but you are extremely vulnerable to brute damage. On death, you'll shatter beyond any hope of recovery."
- attack_sound = 'sound/effects/Glassbr2.ogg'
+ attack_sound = 'sound/effects/glassbr2.ogg'
prefix = "Glass"
/datum/species/golem/glass/spec_death(gibbed, mob/living/carbon/human/H)
@@ -476,7 +476,7 @@
meat = /obj/item/weapon/ore/bananium
info_text = "As a Bananium Golem, you are made for pranking. Your body emits natural honks, and you cannot hurt people when punching them. Your skin also emits bananas when damaged."
attack_verb = "honk"
- attack_sound = 'sound/items/AirHorn2.ogg'
+ attack_sound = 'sound/items/airhorn2.ogg'
prefix = "Bananium"
var/last_honk = 0
diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm
index cd4afa5b627..43516eaec94 100644
--- a/code/modules/mob/living/carbon/human/species_types/humans.dm
+++ b/code/modules/mob/living/carbon/human/species_types/humans.dm
@@ -20,4 +20,12 @@
/datum/species/human/space_move(mob/living/carbon/human/H)
var/obj/item/device/flightpack/F = H.get_flightpack()
if(istype(F) && (F.flight) && F.allow_thrust(0.01, src))
- return TRUE
\ No newline at end of file
+ return TRUE
+
+datum/species/human/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
+ if(H.dna.features["ears"] == "Cat")
+ mutantears = /obj/item/organ/ears/cat
+ if(H.dna.features["tail_human"] == "Cat")
+ var/tail = /obj/item/organ/tail/cat
+ mutant_organs += tail
+ ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
index 20798dcb47b..79e2ac23e74 100644
--- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
@@ -50,7 +50,7 @@
if(/obj/item/projectile/energy/floramut)
if(prob(15))
H.rad_act(rand(30,80))
- H.Weaken(5)
+ H.Knockdown(100)
H.visible_message("[H] writhes in pain as [H.p_their()] vacuoles boil.", "You writhe in pain as your vacuoles boil!", "You hear the crunching of leaves.")
if(prob(80))
H.randmutb()
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index fd64850882c..e75f862f586 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -8,20 +8,26 @@
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT)
mutant_organs = list(/obj/item/organ/tongue/zombie)
+ var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
/datum/species/zombie/infectious
name = "Infectious Zombie"
id = "memezombies"
limbs_id = "zombie"
mutanthands = /obj/item/zombie_hand
- no_equip = list(slot_wear_mask, slot_head)
armor = 20 // 120 damage to KO a zombie, which kills it
speedmod = 2
mutanteyes = /obj/item/organ/eyes/night_vision/zombie
+/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount)
+ . = min(2, amount)
+
/datum/species/zombie/infectious/spec_life(mob/living/carbon/C)
. = ..()
C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW
+ C.heal_overall_damage(4,4)
+ if(prob(4))
+ playsound(C, pick(spooks), 50, TRUE, 10)
if(C.InCritical())
C.death()
// Zombies only move around when not in crit, they instantly
diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm
index cc32be6f2f7..0e009bcd7b9 100644
--- a/code/modules/mob/living/carbon/human/status_procs.dm
+++ b/code/modules/mob/living/carbon/human/status_procs.dm
@@ -3,11 +3,11 @@
amount = dna.species.spec_stun(src,amount)
return ..()
-/mob/living/carbon/human/Weaken(amount, updating = 1, ignore_canstun = 0)
+/mob/living/carbon/human/Knockdown(amount, updating = 1, ignore_canstun = 0)
amount = dna.species.spec_stun(src,amount)
return ..()
-/mob/living/carbon/human/Paralyse(amount, updating = 1, ignore_canstun = 0)
+/mob/living/carbon/human/Unconscious(amount, updating = 1, ignore_canstun = 0)
amount = dna.species.spec_stun(src,amount)
return ..()
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index e6f26e0d6a4..92039e0bbbd 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -154,7 +154,7 @@
if(!co2overloadtime)
co2overloadtime = world.time
else if(world.time - co2overloadtime > 120)
- Paralyse(3)
+ Unconscious(60)
adjustOxyLoss(3)
if(world.time - co2overloadtime > 300)
adjustOxyLoss(8)
@@ -177,9 +177,9 @@
if(breath_gases["n2o"])
var/SA_partialpressure = (breath_gases["n2o"][MOLES]/breath.total_moles())*breath_pressure
if(SA_partialpressure > SA_para_min)
- Paralyse(3)
+ Unconscious(60)
if(SA_partialpressure > SA_sleep_min)
- Sleeping(max(sleeping+2, 10))
+ Sleeping(max(AmountSleeping() + 40, 200))
else if(SA_partialpressure > 0.01)
if(prob(20))
emote(pick("giggle","laugh"))
@@ -297,21 +297,12 @@
M.adjustBruteLoss(5)
nutrition += 10
-//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc..
+//this updates all special effects: stun, sleeping, knockdown, druggy, stuttering, etc..
/mob/living/carbon/handle_status_effects()
..()
if(staminaloss)
- if(sleeping)
- adjustStaminaLoss(-10)
- else
- adjustStaminaLoss(-3)
-
- if(sleeping)
- handle_dreams()
- AdjustSleeping(-1)
- if(prob(10) && health>HEALTH_THRESHOLD_CRIT)
- emote("snore")
+ adjustStaminaLoss(-3)
var/restingpwr = 1 + 4 * resting
@@ -353,8 +344,8 @@
drowsyness = max(drowsyness - restingpwr, 0)
blur_eyes(2)
if(prob(5))
- AdjustSleeping(1)
- Paralyse(5)
+ AdjustSleeping(20)
+ Unconscious(100)
//Jitteryness
if(jitteriness)
diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm
index c6c50252d75..75ffdea8310 100644
--- a/code/modules/mob/living/carbon/monkey/combat.dm
+++ b/code/modules/mob/living/carbon/monkey/combat.dm
@@ -53,9 +53,9 @@
return 1
if(health <= 0 && checkDead)
return 1
- if(paralysis)
+ if(unconscious)
return 1
- if(stunned)
+ if(IsStun())
return 1
if(stat)
return 1
diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm
index 4508b686b6a..a67d4b86e66 100644
--- a/code/modules/mob/living/carbon/monkey/life.dm
+++ b/code/modules/mob/living/carbon/monkey/life.dm
@@ -26,18 +26,18 @@
if (radiation)
if (radiation > 100)
- if(!weakened)
+ if(!knockdown)
emote("collapse")
- Weaken(10)
+ Knockdown(200)
to_chat(src, "You feel weak.")
switch(radiation)
if(50 to 75)
if(prob(5))
- if(!weakened)
+ if(!knockdown)
emote("collapse")
- Weaken(3)
+ Knockdown(60)
to_chat(src, "You feel weak.")
if(75 to 100)
diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm
index 4a432bb66b9..69a18ac0538 100644
--- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm
@@ -50,8 +50,8 @@
var/damage = rand(5, 10)
if (prob(40))
damage = rand(10, 15)
- if ( (paralysis < 5) && (health > 0) )
- Paralyse(rand(10, 15))
+ if ( (unconscious < 5) && (health > 0) )
+ Unconscious(rand(200, 300))
visible_message("[M] has knocked out [name]!", \
"[M] has knocked out [name]!", null, 5)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
@@ -66,10 +66,10 @@
visible_message("[M] has attempted to punch [name]!", \
"[M] has attempted to punch [name]!", null, COMBAT_MESSAGE_RANGE)
if("disarm")
- if (!paralysis)
+ if (!unconscious)
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
if (prob(25))
- Paralyse(2)
+ Knockdown(40)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
add_logs(M, src, "pushed")
visible_message("[M] has pushed down [src]!", \
@@ -88,8 +88,8 @@
var/damage = rand(15, 30)
if (damage >= 25)
damage = rand(20, 40)
- if (paralysis < 15)
- Paralyse(rand(10, 15))
+ if (unconscious < 15)
+ Unconscious(rand(200, 300))
visible_message("[M] has wounded [name]!", \
"[M] has wounded [name]!", null, COMBAT_MESSAGE_RANGE)
else
@@ -114,7 +114,7 @@
var/obj/item/I = null
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
if(prob(95))
- Weaken(10)
+ Knockdown(20)
visible_message("[M] has tackled down [name]!", \
"[M] has tackled down [name]!", null, COMBAT_MESSAGE_RANGE)
else
@@ -192,14 +192,14 @@
damage_clothes(200, BRUTE, "bomb")
adjustEarDamage(30, 120)
if(prob(70))
- Paralyse(10)
+ Unconscious(200)
if(3)
take_overall_damage(30, 0)
damage_clothes(50, BRUTE, "bomb")
adjustEarDamage(15,60)
if (prob(50))
- Paralyse(8)
+ Unconscious(160)
//attempt to dismember bodyparts
diff --git a/code/modules/mob/living/carbon/status_procs.dm b/code/modules/mob/living/carbon/status_procs.dm
index abfe312c48b..9c29bb74a7e 100644
--- a/code/modules/mob/living/carbon/status_procs.dm
+++ b/code/modules/mob/living/carbon/status_procs.dm
@@ -1,5 +1,5 @@
//Here are the procs used to modify status effects of a mob.
-//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness, ear damage,
+//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness, ear damage,
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, NEARSIGHT disability, and HUSK disability.
/mob/living/carbon/damage_eyes(amount)
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index a39f8ddc030..6e5302df24d 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -84,10 +84,10 @@
switch(effecttype)
if(STUN)
Stun(effect * hit_percent)
- if(WEAKEN)
- Weaken(effect * hit_percent)
- if(PARALYZE)
- Paralyse(effect * hit_percent)
+ if(KNOCKDOWN)
+ Knockdown(effect * hit_percent)
+ if(UNCONSCIOUS)
+ Unconscious(effect * hit_percent)
if(IRRADIATE)
radiation += max(effect * hit_percent, 0)
if(SLUR)
@@ -105,15 +105,15 @@
return 1
-/mob/living/proc/apply_effects(stun = 0, weaken = 0, paralyze = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = 0, stamina = 0, jitter = 0)
+/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = 0, stamina = 0, jitter = 0)
if(blocked >= 100)
return 0
if(stun)
apply_effect(stun, STUN, blocked)
- if(weaken)
- apply_effect(weaken, WEAKEN, blocked)
- if(paralyze)
- apply_effect(paralyze, PARALYZE, blocked)
+ if(knockdown)
+ apply_effect(knockdown, KNOCKDOWN, blocked)
+ if(unconscious)
+ apply_effect(unconscious, UNCONSCIOUS, blocked)
if(irradiate)
apply_effect(irradiate, IRRADIATE, blocked)
if(slur)
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index b739a2a6c5c..131e035010d 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -50,6 +50,8 @@
tod = worldtime2text()
var/turf/T = get_turf(src)
var/area/A = get_area(T)
+ for(var/obj/item/I in contents)
+ I.on_mob_death(src, gibbed)
if(mind && mind.name && mind.active && (!(T.flags & NO_DEATHRATTLE)))
var/rendered = "[mind.name] has died at [A.name]."
deadchat_broadcast(rendered, follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE)
@@ -58,9 +60,8 @@
GLOB.living_mob_list -= src
if(!gibbed)
GLOB.dead_mob_list += src
- paralysis = 0
- stunned = 0
- weakened = 0
+ unconscious = 0
+ knockdown = 0
set_drugginess(0)
SetSleeping(0, 0)
blind_eyes(1)
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index da098654c29..2705b18b6ac 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -63,7 +63,7 @@
/datum/emote/living/collapse/run_emote(mob/user, params)
. = ..()
if(.)
- user.Paralyse(2)
+ user.Unconscious(40)
/datum/emote/living/cough
key = "cough"
@@ -110,8 +110,9 @@
/datum/emote/living/faint/run_emote(mob/user, params)
. = ..()
- if(.)
- user.SetSleeping(10)
+ if(. && isliving(user))
+ var/mob/living/L = user
+ L.SetSleeping(200)
/datum/emote/living/flap
key = "flap"
@@ -330,7 +331,7 @@
/datum/emote/living/surrender/run_emote(mob/user, params)
. = ..()
if(.)
- user.Weaken(20)
+ user.Knockdown(200)
/datum/emote/living/sway
key = "sway"
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index bcde1ff39a7..0cca6184b40 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -48,7 +48,7 @@
if(stat != DEAD)
handle_disabilities() // eye, ear, brain damages
if(stat != DEAD)
- handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc
+ handle_status_effects() //all special effects, stun, knockdown, jitteryness, hallucination, sleeping, etc
if(stat != DEAD)
return 1
@@ -97,14 +97,12 @@
/mob/living/proc/handle_stomach()
return
-//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc..
+//this updates all special effects: knockdown, druggy, stuttering, etc..
/mob/living/proc/handle_status_effects()
- if(paralysis)
- AdjustParalysis(-1, 1, 1)
- if(stunned)
- AdjustStunned(-1, 1, 1)
- if(weakened)
- AdjustWeakened(-1, 1, 1)
+ if(knockdown)
+ AdjustKnockdown(-20, 1, 1)
+ if(unconscious)
+ AdjustUnconscious(-20, 1, 1)
if(confused)
confused = max(0, confused - 1)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index e9ed212fd10..3e95820b216 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -237,7 +237,7 @@
death()
/mob/living/incapacitated(ignore_restraints, ignore_grab)
- if(stat || paralysis || stunned || weakened || (!ignore_restraints && restrained(ignore_grab)))
+ if(stat || unconscious || IsStun() || knockdown || (!ignore_restraints && restrained(ignore_grab)))
return 1
/mob/living/proc/InCritical()
@@ -281,12 +281,12 @@
set name = "Sleep"
set category = "IC"
- if(sleeping)
+ if(IsSleeping())
to_chat(src, "You are already sleeping.")
return
else
if(alert(src, "You sure you want to sleep for a while?", "Sleep", "Yes", "No") == "Yes")
- SetSleeping(20) //Short nap
+ SetSleeping(400) //Short nap
update_canmove()
/mob/proc/get_contents()
@@ -368,10 +368,10 @@
setCloneLoss(0, 0)
setBrainLoss(0)
setStaminaLoss(0, 0)
- SetParalysis(0, 0)
- SetStunned(0, 0)
- SetWeakened(0, 0)
- SetSleeping(0, 0)
+ SetUnconscious(0, FALSE)
+ SetStun(0, FALSE)
+ SetKnockdown(0, FALSE)
+ SetSleeping(0, FALSE)
radiation = 0
nutrition = NUTRITION_LEVEL_FED + 50
bodytemperature = 310
@@ -666,7 +666,7 @@
return
visible_message("[src] tries to put [what] on [who].")
- if(do_mob(src, who, what.put_on_delay))
+ if(do_mob(src, who, what.equip_delay_other))
if(what && Adjacent(who) && what.mob_can_equip(who, src, final_where, TRUE))
if(temporarilyRemoveItemFromInventory(what))
if(where_list)
@@ -798,7 +798,7 @@
var/total_health = (health - staminaloss)
if(total_health <= HEALTH_THRESHOLD_CRIT && !stat)
to_chat(src, "You're too exhausted to keep going...")
- Weaken(5)
+ Knockdown(100)
setStaminaLoss(health - 2)
update_health_hud()
@@ -917,7 +917,7 @@
"[C] trips over [src] and falls!", \
"[C] topples over [src]!", \
"[C] leaps out of [src]'s way!")]")
- C.Weaken(2)
+ C.Knockdown(40)
/mob/living/post_buckle_mob(mob/living/M)
if(riding_datum)
@@ -928,3 +928,45 @@
if((movement_type & FLYING) && !stat)
return
..()
+
+/mob/living/can_be_pulled()
+ return ..() && !(buckled && buckled.buckle_prevents_pull)
+
+//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
+//Robots, animals and brains have their own version so don't worry about them
+/mob/living/proc/update_canmove()
+ var/ko = knockdown || unconscious || stat || (status_flags & FAKEDEATH)
+ var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK
+ var/buckle_lying = !(buckled && !buckled.buckle_lying)
+ var/has_legs = get_num_legs()
+ var/has_arms = get_num_arms()
+ var/ignore_legs = get_leg_ignore()
+ if(ko || resting || has_status_effect(STATUS_EFFECT_STUN) || chokehold)
+ drop_all_held_items()
+ unset_machine()
+ if(pulling)
+ stop_pulling()
+ else if(has_legs || ignore_legs)
+ lying = 0
+
+ if(buckled)
+ lying = 90*buckle_lying
+ else if(!lying)
+ if(resting)
+ fall()
+ else if(ko || (!has_legs && !ignore_legs) || chokehold)
+ fall(forced = 1)
+ canmove = !(ko || resting || has_status_effect(STATUS_EFFECT_STUN) || has_status_effect(/datum/status_effect/freon) || chokehold || buckled || (!has_legs && !ignore_legs && !has_arms))
+ density = !lying
+ if(lying)
+ if(layer == initial(layer)) //to avoid special cases like hiding larvas.
+ layer = LYING_MOB_LAYER //so mob lying always appear behind standing mobs
+ else
+ if(layer == LYING_MOB_LAYER)
+ layer = initial(layer)
+ update_transform()
+ if(!lying && lying_prev)
+ if(client)
+ client.move_delay = world.time + movement_delay()
+ lying_prev = lying
+ return canmove
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 2494f041384..35103e3b783 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -25,7 +25,7 @@
/mob/living/proc/getarmor(def_zone, type)
return 0
-//this returns the mob's protection against eye damage (number between -1 and 2)
+//this returns the mob's protection against eye damage (number between -1 and 2) from bright lights
/mob/living/proc/get_eye_protection()
return 0
@@ -33,6 +33,12 @@
/mob/living/proc/get_ear_protection()
return 0
+/mob/living/proc/is_mouth_covered(head_only = 0, mask_only = 0)
+ return FALSE
+
+/mob/living/proc/is_eyes_covered(check_glasses = 1, check_head = 1, check_mask = 1)
+ return FALSE
+
/mob/living/proc/on_hit(obj/item/projectile/P)
return
@@ -98,12 +104,12 @@
step_away(src,M,15)
switch(M.damtype)
if(BRUTE)
- Paralyse(1)
+ Unconscious(20)
take_overall_damage(rand(M.force/2, M.force))
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
if(BURN)
take_overall_damage(0, rand(M.force/2, M.force))
- playsound(src, 'sound/items/Welder.ogg', 50, 1)
+ playsound(src, 'sound/items/welder.ogg', 50, 1)
if(TOX)
M.mech_toxin_damage(src)
else
@@ -311,7 +317,7 @@
GLOB.cult_narsie.souls += 1
if((GLOB.cult_narsie.souls == GLOB.cult_narsie.soul_goal) && (GLOB.cult_narsie.resolved == FALSE))
GLOB.cult_narsie.resolved = TRUE
- world << sound('sound/machines/Alarm.ogg')
+ world << sound('sound/machines/alarm.ogg')
addtimer(CALLBACK(GLOBAL_PROC, .proc/cult_ending_helper, 1), 120)
addtimer(CALLBACK(GLOBAL_PROC, .proc/ending_helper), 270)
if(client)
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index b7d6b4eeacf..5addce55bb9 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -16,7 +16,7 @@
var/fireloss = 0 //Burn damage caused by being way too hot, too cold or burnt.
var/cloneloss = 0 //Damage caused by being cloned or ejected from the cloner early. slimes also deal cloneloss damage to victims
var/brainloss = 0 //'Retardation' damage caused by someone hitting you in the head with a bible or being infected with brainrot.
- var/staminaloss = 0 //Stamina damage, or exhaustion. You recover it slowly naturally, and are stunned if it gets too high. Holodeck and hallucinations deal this.
+ var/staminaloss = 0 //Stamina damage, or exhaustion. You recover it slowly naturally, and are knocked down if it gets too high. Holodeck and hallucinations deal this.
var/hallucination = 0 //Directly affects how long a mob will hallucinate for
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 30205e262f5..2319c1f4c17 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -14,7 +14,7 @@
/mob/living/silicon/ai
name = "AI"
- icon = 'icons/mob/AI.dmi'
+ icon = 'icons/mob/ai.dmi'
icon_state = "ai"
anchored = 1
density = 1
@@ -53,7 +53,7 @@
var/control_disabled = 0 // Set to 1 to stop AI from interacting via Click()
var/malfhacking = 0 // More or less a copy of the above var, so that malf AIs can hack and still get new cyborgs -- NeoFite
- var/malf_cooldown = 0 //Cooldown var for malf modules
+ var/malf_cooldown = 0 //Cooldown var for malf modules, stores a worldtime + cooldown
var/obj/machinery/power/apc/malfhack = null
var/explosive = 0 //does the AI explode when it dies?
@@ -123,7 +123,7 @@
eyeobj.loc = src.loc
rename_self("ai")
- holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"default"))
+ holo_icon = getHologramIcon(icon('icons/mob/ai.dmi',"default"))
spark_system = new /datum/effect_system/spark_spread()
spark_system.set_up(5, 0, src)
@@ -632,13 +632,12 @@
return //won't work if dead
var/list/ai_emotions = list("Very Happy", "Happy", "Neutral", "Unsure", "Confused", "Sad", "BSOD", "Blank", "Problems?", "Awesome", "Facepalm", "Friend Computer", "Dorfy", "Blue Glow", "Red Glow")
var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions
- for (var/obj/machinery/M in GLOB.machines) //change status
+ for (var/M in GLOB.ai_status_displays) //change status of displays
if(istype(M, /obj/machinery/ai_status_display))
var/obj/machinery/ai_status_display/AISD = M
AISD.emotion = emote
//if Friend Computer, change ALL displays
else if(istype(M, /obj/machinery/status_display))
-
var/obj/machinery/status_display/SD = M
if(emote=="Friend Computer")
SD.friendc = 1
@@ -702,10 +701,10 @@
holo_icon = getHologramIcon(icon(icon_list[input], input))
else
var/list/icon_list = list(
- "default" = 'icons/mob/AI.dmi',
- "floating face" = 'icons/mob/AI.dmi',
+ "default" = 'icons/mob/ai.dmi',
+ "floating face" = 'icons/mob/ai.dmi',
"xeno queen" = 'icons/mob/alien.dmi',
- "horror" = 'icons/mob/AI.dmi'
+ "horror" = 'icons/mob/ai.dmi'
)
input = input("Please select a hologram:") as null|anything in icon_list
diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm
index d9b157b024a..1b6c67ecc63 100644
--- a/code/modules/mob/living/silicon/ai/death.dm
+++ b/code/modules/mob/living/silicon/ai/death.dm
@@ -25,7 +25,7 @@
spawn(10)
explosion(src.loc, 3, 6, 12, 15)
- for(var/obj/machinery/ai_status_display/O in world) //change status
+ for(var/obj/machinery/ai_status_display/O in GLOB.ai_status_displays) //change status
if(src.key)
O.mode = 2
if(istype(loc, /obj/item/device/aicard))
@@ -42,4 +42,4 @@
if(doomsday_device)
doomsday_device.timing = FALSE
SSshuttle.clearHostileEnvironment(doomsday_device)
- qdel(doomsday_device)
\ No newline at end of file
+ qdel(doomsday_device)
diff --git a/code/modules/mob/living/silicon/ai/examine.dm b/code/modules/mob/living/silicon/ai/examine.dm
index 2c98c8c0aea..c49e9e552ca 100644
--- a/code/modules/mob/living/silicon/ai/examine.dm
+++ b/code/modules/mob/living/silicon/ai/examine.dm
@@ -1,5 +1,5 @@
/mob/living/silicon/ai/examine(mob/user)
- var/msg = "*---------*\nThis is \icon[src] [src]!\n"
+ var/msg = "*---------*\nThis is [bicon(src)] [src]!\n"
if (stat == DEAD)
msg += "It appears to be powered-down.\n"
else
diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm
index 672df66804a..0613cacb47b 100644
--- a/code/modules/mob/living/silicon/ai/freelook/eye.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm
@@ -10,6 +10,7 @@
var/list/visibleCameraChunks = list()
var/mob/living/silicon/ai/ai = null
var/relay_speech = FALSE
+ var/use_static = TRUE
// Use this when setting the aiEye's location.
// It will also stream the chunk that the new loc is in.
@@ -21,7 +22,8 @@
return
T = get_turf(T)
loc = T
- GLOB.cameranet.visibility(src)
+ if(use_static)
+ GLOB.cameranet.visibility(src)
if(ai.client)
ai.client.eye = src
update_parallax_contents()
@@ -38,6 +40,11 @@
return ai.client
return null
+/mob/camera/aiEye/proc/RemoveImages()
+ if(use_static)
+ for(var/datum/camerachunk/chunk in visibleCameraChunks)
+ chunk.remove(src)
+
/mob/camera/aiEye/Destroy()
ai = null
return ..()
diff --git a/code/modules/mob/living/silicon/ai/login.dm b/code/modules/mob/living/silicon/ai/login.dm
index 5fd5965f401..109abfe4099 100644
--- a/code/modules/mob/living/silicon/ai/login.dm
+++ b/code/modules/mob/living/silicon/ai/login.dm
@@ -6,7 +6,7 @@
client.images += blood
if(stat != DEAD)
- for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
+ for(var/obj/machinery/ai_status_display/O in GLOB.ai_status_displays) //change status
O.mode = 1
O.emotion = "Neutral"
view_core()
diff --git a/code/modules/mob/living/silicon/ai/logout.dm b/code/modules/mob/living/silicon/ai/logout.dm
index 7a7670cfcb4..fe5ea98c49e 100644
--- a/code/modules/mob/living/silicon/ai/logout.dm
+++ b/code/modules/mob/living/silicon/ai/logout.dm
@@ -1,5 +1,5 @@
/mob/living/silicon/ai/Logout()
..()
- for(var/obj/machinery/ai_status_display/O in world) //change status
+ for(var/obj/machinery/ai_status_display/O in GLOB.ai_status_displays) //change status
O.mode = 0
view_core()
diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm
index a21f27ca00d..83da7d9087a 100644
--- a/code/modules/mob/living/silicon/pai/pai_defense.dm
+++ b/code/modules/mob/living/silicon/pai/pai_defense.dm
@@ -3,9 +3,9 @@
return FALSE
/mob/living/silicon/pai/emp_act(severity)
- take_holo_damage(severity * 25)
- fullstun(severity * 10)
- silent = max(severity * 15, silent)
+ take_holo_damage(50/severity)
+ Knockdown(400/severity)
+ silent = max(30/severity, silent)
if(holoform)
fold_in(force = TRUE)
//Need more effects that aren't instadeath or permanent law corruption.
@@ -18,10 +18,10 @@
qdel(src)
if(2)
fold_in(force = 1)
- fullstun(20)
+ Knockdown(400)
if(3)
fold_in(force = 1)
- fullstun(10)
+ Knockdown(200)
/mob/living/silicon/pai/attack_hand(mob/living/carbon/human/user)
switch(user.a_intent)
@@ -64,9 +64,6 @@
hit_slowdown += amount
return amount
-/mob/living/silicon/pai/proc/fullstun(amount)
- Weaken(amount)
-
/mob/living/silicon/pai/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
return take_holo_damage(amount)
@@ -83,10 +80,10 @@
return FALSE
/mob/living/silicon/pai/adjustStaminaLoss(amount)
- take_holo_damage(amount/4)
+ take_holo_damage(amount & 0.25)
/mob/living/silicon/pai/adjustBrainLoss(amount)
- fullstun(amount/10)
+ Knockdown(amount * 0.2)
/mob/living/silicon/pai/getBruteLoss()
return emittermaxhealth - emitterhealth
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
index bce5dacef47..a4f8638c4a1 100644
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -173,7 +173,7 @@
if(href_list["send"])
sradio.send_signal("ACTIVATE")
- audible_message("\icon[src] *beep* *beep*")
+ audible_message("[bicon(src)] *beep* *beep*")
if(href_list["freq"])
diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm
index e33506ae400..f14665e10cb 100644
--- a/code/modules/mob/living/silicon/robot/examine.dm
+++ b/code/modules/mob/living/silicon/robot/examine.dm
@@ -1,11 +1,11 @@
/mob/living/silicon/robot/examine(mob/user)
- var/msg = "*---------*\nThis is \icon[src] \a [src]!\n"
+ var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
if(desc)
msg += "[desc]\n"
var/obj/act_module = get_active_held_item()
if(act_module)
- msg += "It is holding \icon[act_module] \a [act_module].\n"
+ msg += "It is holding [bicon(act_module)] \a [act_module].\n"
msg += ""
if (src.getBruteLoss())
if (src.getBruteLoss() < maxHealth*0.5)
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 2b7cc679f98..6b4b552b38b 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -591,7 +591,7 @@
/mob/living/silicon/robot/update_icons()
cut_overlays()
icon_state = module.cyborg_base_icon
- if(stat != DEAD && !(paralysis || stunned || weakened || low_power_mode)) //Not dead, not stunned.
+ if(stat != DEAD && !(unconscious || IsStun() || knockdown || low_power_mode)) //Not dead, not stunned.
if(!eye_lights)
eye_lights = new()
if(lamp_intensity > 2)
@@ -917,7 +917,7 @@
if(health <= -maxHealth) //die only once
death()
return
- if(paralysis || stunned || weakened || getOxyLoss() > maxHealth*0.5)
+ if(unconscious || IsStun() || knockdown || getOxyLoss() > maxHealth*0.5)
if(stat == CONSCIOUS)
stat = UNCONSCIOUS
blind_eyes(1)
@@ -1116,7 +1116,7 @@
return
if(incapacitated())
return
- if(M.restrained())
+ if(M.incapacitated())
return
if(module)
if(!module.allow_riding)
diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm
index 96247fa1b1d..5ae8d68deb1 100644
--- a/code/modules/mob/living/silicon/robot/robot_defense.dm
+++ b/code/modules/mob/living/silicon/robot/robot_defense.dm
@@ -23,7 +23,7 @@
"[M] has disabled [src]'s active module!", null, COMBAT_MESSAGE_RANGE)
add_logs(M, src, "disarmed", "[I ? " removing \the [I]" : ""]")
else
- Stun(2)
+ Stun(40)
step(src,get_dir(M,src))
add_logs(M, src, "pushed")
visible_message("[M] has forced back [src]!", \
@@ -80,9 +80,9 @@
/mob/living/silicon/robot/emp_act(severity)
switch(severity)
if(1)
- Stun(8)
+ Stun(160)
if(2)
- Stun(3)
+ Stun(60)
..()
@@ -135,7 +135,7 @@
return
SetEmagged(1)
- SetStunned(3) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown
+ SetStun(60) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown
lawupdate = 0
connected_ai = null
message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.")
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index aa14cd1c789..394a2ee4a53 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -216,7 +216,7 @@
R.anchored = TRUE
sleep(2)
for(var/i in 1 to 4)
- playsound(R, pick('sound/items/drill_use.ogg', 'sound/items/jaws_cut.ogg', 'sound/items/jaws_pry.ogg', 'sound/items/Welder.ogg', 'sound/items/Ratchet.ogg'), 80, 1, -1)
+ playsound(R, pick('sound/items/drill_use.ogg', 'sound/items/jaws_cut.ogg', 'sound/items/jaws_pry.ogg', 'sound/items/welder.ogg', 'sound/items/ratchet.ogg'), 80, 1, -1)
sleep(12)
if(!prev_lockcharge)
R.SetLockdown(0)
@@ -250,7 +250,7 @@
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg,
/obj/item/clockwork/ratvarian_spear/cyborg,
- /obj/item/clockwork/clockwork_proselytizer/cyborg)
+ /obj/item/clockwork/replica_fabricator/cyborg)
moduleselect_icon = "standard"
feedback_key = "cyborg_standard"
hat_offset = -3
@@ -314,7 +314,7 @@
emag_modules = list(/obj/item/borg/stun)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/engineer,
- /obj/item/clockwork/clockwork_proselytizer/cyborg)
+ /obj/item/clockwork/replica_fabricator/cyborg)
cyborg_base_icon = "engineer"
moduleselect_icon = "engineer"
feedback_key = "cyborg_engineering"
@@ -384,6 +384,9 @@
name = "Janitor"
basic_modules = list(
/obj/item/device/assembly/flash/cyborg,
+ /obj/item/weapon/screwdriver/cyborg,
+ /obj/item/weapon/crowbar/cyborg,
+ /obj/item/stack/tile/plasteel/cyborg,
/obj/item/weapon/soap/nanotrasen,
/obj/item/weapon/storage/bag/trash/cyborg,
/obj/item/weapon/mop/cyborg,
@@ -393,7 +396,7 @@
emag_modules = list(/obj/item/weapon/reagent_containers/spray/cyborg_lube)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/janitor,
- /obj/item/clockwork/clockwork_proselytizer/cyborg)
+ /obj/item/clockwork/replica_fabricator/cyborg)
cyborg_base_icon = "janitor"
moduleselect_icon = "janitor"
feedback_key = "cyborg_janitor"
diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm
index 2578c4b3d9d..b09309d81f7 100644
--- a/code/modules/mob/living/silicon/silicon_defense.dm
+++ b/code/modules/mob/living/silicon/silicon_defense.dm
@@ -29,7 +29,7 @@
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
if(prob(damage))
for(var/mob/living/N in buckled_mobs)
- N.Weaken(1)
+ N.Knockdown(20)
unbuckle_mob(N)
N.visible_message("[N] is knocked off of [src] by [M]!")
switch(M.melee_damage_type)
@@ -95,7 +95,7 @@
for(var/mob/living/M in buckled_mobs)
if(prob(severity*50))
unbuckle_mob(M)
- M.Weaken(2)
+ M.Knockdown(40)
M.visible_message("[M] is thrown off of [src]!")
flash_act(affect_silicon = 1)
..()
@@ -107,8 +107,8 @@
for(var/mob/living/M in buckled_mobs)
M.visible_message("[M] is knocked off of [src]!")
unbuckle_mob(M)
- M.Weaken(2)
- if(Proj.stun || Proj.weaken)
+ M.Knockdown(40)
+ if(Proj.stun || Proj.knockdown)
for(var/mob/living/M in buckled_mobs)
unbuckle_mob(M)
M.visible_message("[M] is knocked off of [src] by the [Proj]!")
diff --git a/code/modules/mob/living/silicon/status_procs.dm b/code/modules/mob/living/silicon/status_procs.dm
index 3947cb020fe..14118225e9b 100644
--- a/code/modules/mob/living/silicon/status_procs.dm
+++ b/code/modules/mob/living/silicon/status_procs.dm
@@ -1,38 +1,38 @@
//Here are the procs used to modify status effects of a mob.
-//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness, ear damage,
+//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness, ear damage,
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, and NEARSIGHT disability.
-/////////////////////////////////// STUNNED ////////////////////////////////////
+/////////////////////////////////// STUN ////////////////////////////////////
/mob/living/silicon/Stun(amount, updating = 1, ignore_canstun = 0)
. = ..()
if(. && updating)
update_stat()
-/mob/living/silicon/SetStunned(amount, updating = 1, ignore_canstun = 0)
+/mob/living/silicon/SetStun(amount, updating = 1, ignore_canstun = 0)
. = ..()
if(. && updating)
update_stat()
-/mob/living/silicon/AdjustStunned(amount, updating = 1, ignore_canstun = 0)
+/mob/living/silicon/AdjustStun(amount, updating = 1, ignore_canstun = 0)
. = ..()
if(. && updating)
update_stat()
-/////////////////////////////////// WEAKENED ////////////////////////////////////
+/////////////////////////////////// KNOCKDOWN ////////////////////////////////////
-/mob/living/silicon/Weaken(amount, updating = 1, ignore_canweaken = 0)
+/mob/living/silicon/Knockdown(amount, updating = 1, ignore_canknockdown = 0)
. = ..()
if(. && updating)
update_stat()
-/mob/living/silicon/SetWeakened(amount, updating = 1, ignore_canweaken = 0)
+/mob/living/silicon/SetKnockdown(amount, updating = 1, ignore_canknockdown = 0)
. = ..()
if(. && updating)
update_stat()
-/mob/living/silicon/AdjustWeakened(amount, updating = 1, ignore_canweaken = 0)
+/mob/living/silicon/AdjustKnockdown(amount, updating = 1, ignore_canknockdown = 0)
. = ..()
if(. && updating)
update_stat()
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 796705e4c8d..fd0b5b76d16 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -469,7 +469,7 @@ Pass a positive integer as an argument to override a bot's default speed.
var/area/end_area = get_area(waypoint)
if(client) //Player bots instead get a location command from the AI
- to_chat(src, "Priority waypoint set by \icon[caller] [caller]. Proceed to [end_area.name]<\b>.")
+ to_chat(src, "Priority waypoint set by [bicon(caller)] [caller]. Proceed to [end_area.name]<\b>.")
//For giving the bot temporary all-access.
var/obj/item/weapon/card/id/all_access = new /obj/item/weapon/card/id
@@ -485,7 +485,7 @@ Pass a positive integer as an argument to override a bot's default speed.
turn_on() //Saves the AI the hassle of having to activate a bot manually.
access_card = all_access //Give the bot all-access while under the AI's command.
if(message)
- to_chat(calling_ai, "\icon[src] [name] called to [end_area.name]. [path.len-1] meters to destination.")
+ to_chat(calling_ai, "[bicon(src)] [name] called to [end_area.name]. [path.len-1] meters to destination.")
pathset = 1
mode = BOT_RESPONDING
tries = 0
@@ -500,7 +500,7 @@ Pass a positive integer as an argument to override a bot's default speed.
var/success = bot_move(ai_waypoint, 3)
if(!success)
if(calling_ai)
- to_chat(calling_ai, "\icon[src] [get_turf(src) == ai_waypoint ? "[src] successfully arrived to waypoint." : "[src] failed to reach waypoint."]")
+ to_chat(calling_ai, "[bicon(src)] [get_turf(src) == ai_waypoint ? "[src] successfully arrived to waypoint." : "[src] failed to reach waypoint."]")
calling_ai = null
bot_reset()
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index 190e6a7db4f..190a581d489 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -21,7 +21,7 @@
var/trash = 0
var/pests = 0
- var/list/target_types = list()
+ var/list/target_types
var/obj/effect/decal/cleanable/target
var/max_targets = 50 //Maximum number of targets a cleanbot can ignore.
var/oldloc = null
@@ -32,7 +32,7 @@
var/next_dest_loc
/mob/living/simple_animal/bot/cleanbot/Initialize()
- ..()
+ . = ..()
get_targets()
icon_state = "cleanbot[on]"
@@ -87,7 +87,7 @@
var/mob/living/carbon/C = A
if(C.stat != DEAD && C.lying)
return C
- else if(is_type_in_list(A, target_types))
+ else if(is_type_in_typecache(A, target_types))
return A
/mob/living/simple_animal/bot/cleanbot/handle_automated_action()
@@ -193,6 +193,8 @@
if(trash)
target_types += /obj/item/trash
+ target_types = typecacheof(target_types)
+
/mob/living/simple_animal/bot/cleanbot/UnarmedAttack(atom/A)
if(istype(A, /obj/effect/decal/cleanable))
anchored = 1
diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
index 893c34ea656..52ebdbb2507 100644
--- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
@@ -39,7 +39,7 @@
var/check_records = 1 //Does it check security records?
var/arrest_type = 0 //If true, don't handcuff
var/projectile = /obj/item/projectile/energy/electrode //Holder for projectile type
- var/shoot_sound = 'sound/weapons/Taser.ogg'
+ var/shoot_sound = 'sound/weapons/taser.ogg'
/mob/living/simple_animal/bot/ed209/Initialize(mapload,created_name,created_lasercolor)
@@ -255,7 +255,7 @@ Auto Patrol[]"},
if(BOT_PREP_ARREST) // preparing to arrest target
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
- if(!Adjacent(target) || !isturf(target.loc) || target.weakened < 2)
+ if(!Adjacent(target) || !isturf(target.loc) || target.knockdown < 2)
back_to_hunt()
return
@@ -282,7 +282,7 @@ Auto Patrol[]"},
back_to_idle()
return
- if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.weakened < 2)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
+ if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.knockdown < 2)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
back_to_hunt()
return
else
@@ -337,7 +337,7 @@ Auto Patrol[]"},
target = C
oldtarget_name = C.name
speak("Level [threatlevel] infraction alert!")
- playsound(loc, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/EDPlaceholder.ogg'), 50, 0)
+ playsound(loc, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, 0)
visible_message("[src] points at [C.name]!")
mode = BOT_HUNT
spawn(0)
@@ -404,7 +404,7 @@ Auto Patrol[]"},
projectile = /obj/item/projectile/beam
else
if(!lasercolor)
- shoot_sound = 'sound/weapons/Taser.ogg'
+ shoot_sound = 'sound/weapons/taser.ogg'
projectile = /obj/item/projectile/energy/electrode
else if(lasercolor == "b")
projectile = /obj/item/projectile/beam/lasertag/bluetag
@@ -504,7 +504,7 @@ Auto Patrol[]"},
return
if(iscarbon(A))
var/mob/living/carbon/C = A
- if(!C.stunned || arrest_type)
+ if(!C.IsStun() || arrest_type)
stun_attack(A)
else if(C.canBeHandcuffed() && !C.handcuffed)
cuff(A)
@@ -517,13 +517,12 @@ Auto Patrol[]"},
shootAt(A)
/mob/living/simple_animal/bot/ed209/proc/stun_attack(mob/living/carbon/C)
- playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
+ playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
icon_state = "[lasercolor]ed209-c"
spawn(2)
icon_state = "[lasercolor]ed209[on]"
var/threat = 5
- C.Weaken(5)
- C.Stun(5)
+ C.Knockdown(100)
C.stuttering = 5
if(ishuman(C))
var/mob/living/carbon/human/H = C
diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm
index 426c928af74..e4ddb91ecca 100644
--- a/code/modules/mob/living/simple_animal/bot/medbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/medbot.dm
@@ -14,6 +14,8 @@
maxHealth = 20
pass_flags = PASSMOB
+ status_flags = (CANPUSH | CANSTUN)
+
radio_key = /obj/item/device/encryptionkey/headset_med
radio_channel = "Medical"
@@ -77,6 +79,9 @@
if(!on)
icon_state = "medibot0"
return
+ if(IsStun())
+ icon_state = "medibota"
+ return
if(mode == BOT_HEALING)
icon_state = "medibots[stationary_mode]"
return
@@ -97,6 +102,10 @@
prev_access = access_card.access
qdel(J)
+/mob/living/simple_animal/bot/medbot/update_canmove()
+ . = ..()
+ update_icon()
+
/mob/living/simple_animal/bot/medbot/bot_reset()
..()
patient = null
@@ -265,17 +274,10 @@
if(mode == BOT_HEALING)
return
- if(stunned)
- icon_state = "medibota"
- stunned--
-
+ if(IsStun())
oldpatient = patient
patient = null
mode = BOT_IDLE
-
- if(stunned <= 0)
- update_icon()
- stunned = 0
return
if(frustration > 8)
@@ -504,11 +506,6 @@
return 1
return 0
-/mob/living/simple_animal/bot/medbot/bullet_act(obj/item/projectile/Proj)
- if(Proj.flag == "taser")
- stunned = min(stunned+10,20)
- ..()
-
/mob/living/simple_animal/bot/medbot/explode()
on = 0
visible_message("[src] blows apart!")
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index bdf4277438d..2779650f6a9 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -596,7 +596,7 @@
if(pathset) //The AI called us here, so notify it of our arrival.
loaddir = dir //The MULE will attempt to load a crate in whatever direction the MULE is "facing".
if(calling_ai)
- to_chat(calling_ai, "\icon[src] [src] wirelessly plays a chiming sound!")
+ to_chat(calling_ai, "[bicon(src)] [src] wirelessly plays a chiming sound!")
playsound(calling_ai, 'sound/machines/chime.ogg',40, 0)
calling_ai = null
radio_channel = "AI Private" //Report on AI Private instead if the AI is controlling us.
@@ -643,8 +643,7 @@
add_logs(src, M, "knocked down")
visible_message("[src] knocks over [M]!")
M.stop_pulling()
- M.Stun(8)
- M.Weaken(5)
+ M.Knockdown(160)
return ..()
// called from mob/living/carbon/human/Crossed()
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index cba9e446ecd..4d439afdf72 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -190,7 +190,7 @@ Auto Patrol: []"},
return
if(iscarbon(A))
var/mob/living/carbon/C = A
- if(!C.stunned || arrest_type)
+ if(!C.IsStun() || arrest_type)
stun_attack(A)
else if(C.canBeHandcuffed() && !C.handcuffed)
cuff(A)
@@ -222,21 +222,19 @@ Auto Patrol: []"},
back_to_idle()
/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C)
- playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
+ playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
icon_state = "secbot-c"
spawn(2)
icon_state = "secbot[on]"
var/threat = 5
if(ishuman(C))
C.stuttering = 5
- C.Stun(5)
- C.Weaken(5)
+ C.Knockdown(100)
var/mob/living/carbon/human/H = C
threat = H.assess_threat(src)
else
- C.Weaken(5)
+ C.Knockdown(100)
C.stuttering = 5
- C.Stun(5)
threat = C.assess_threat()
add_logs(src,C,"stunned")
if(declare_arrests)
@@ -288,7 +286,7 @@ Auto Patrol: []"},
if(BOT_PREP_ARREST) // preparing to arrest target
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
- if( !Adjacent(target) || !isturf(target.loc) || target.weakened < 2 )
+ if( !Adjacent(target) || !isturf(target.loc) || target.knockdown < 2 )
back_to_hunt()
return
@@ -315,7 +313,7 @@ Auto Patrol: []"},
back_to_idle()
return
- if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.weakened < 2)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
+ if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.knockdown < 2)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
back_to_hunt()
return
else //Try arresting again if the target escapes.
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index 6605b196f0b..48840e4b03a 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -50,7 +50,7 @@
/mob/living/simple_animal/hostile/construct/examine(mob/user)
var/t_He = p_they(TRUE)
var/t_s = p_s()
- var/msg = "*---------*\nThis is \icon[src] \a [src]!\n"
+ var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
msg += "[desc]\n"
if(health < maxHealth)
msg += ""
@@ -330,8 +330,8 @@
if(!LAZYLEN(parts))
if(undismembermerable_limbs) //they have limbs we can't remove, and no parts we can, attack!
return ..()
- C.Weaken(30)
- visible_message("[src] paralyzes [C]!")
+ C.Knockdown(60)
+ visible_message("[src] knocks [C] down!")
to_chat(src, "\"Bring [C.p_them()] to me.\"")
return FALSE
do_attack_animation(C)
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index edc4d71812a..2f326ce6039 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -107,7 +107,7 @@
user.visible_message("[user] starts to shave [src] using \the [O].", "You start to shave [src] using \the [O]...")
if(do_after(user, 50, target = src))
user.visible_message("[user] shaves [src]'s hair using \the [O].")
- playsound(loc, 'sound/items/Welder2.ogg', 20, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 20, 1)
shaved = 1
icon_living = "[initial(icon_living)]_shaved"
icon_dead = "[initial(icon_living)]_shaved_dead"
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index d6754584858..3c900408f1c 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -32,7 +32,7 @@
density = 0
pass_flags = PASSTABLE | PASSMOB
sight = (SEE_TURFS | SEE_OBJS)
- status_flags = (CANPUSH | CANSTUN | CANWEAKEN)
+ status_flags = (CANPUSH | CANSTUN | CANKNOCKDOWN)
gender = NEUTER
voice_name = "synthesized chirp"
speak_emote = list("chirps")
@@ -61,7 +61,7 @@
var/alarms = list("Atmosphere" = list(), "Fire" = list(), "Power" = list())
var/obj/item/internal_storage //Drones can store one item, of any size/type in their body
var/obj/item/head
- var/obj/item/default_storage = /obj/item/weapon/storage/backpack/dufflebag/drone //If this exists, it will spawn in internal storage
+ var/obj/item/default_storage = /obj/item/weapon/storage/backpack/duffelbag/drone //If this exists, it will spawn in internal storage
var/obj/item/default_hatmask //If this exists, it will spawn in the hat/mask slot if it can fit
var/seeStatic = 1 //Whether we see static instead of mobs
var/visualAppearence = MAINTDRONE //What we appear as
@@ -170,29 +170,29 @@
/mob/living/simple_animal/drone/examine(mob/user)
- var/msg = "*---------*\nThis is \icon[src] \a [src]!\n"
+ var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
//Hands
for(var/obj/item/I in held_items)
if(!(I.flags & ABSTRACT))
if(I.blood_DNA)
- msg += "It has \icon[I] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
+ msg += "It has [bicon(I)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
else
- msg += "It has \icon[I] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "It has [bicon(I)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
//Internal storage
if(internal_storage && !(internal_storage.flags&ABSTRACT))
if(internal_storage.blood_DNA)
- msg += "It is holding \icon[internal_storage] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!\n"
+ msg += "It is holding [bicon(internal_storage)] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!\n"
else
- msg += "It is holding \icon[internal_storage] \a [internal_storage] in its internal storage.\n"
+ msg += "It is holding [bicon(internal_storage)] \a [internal_storage] in its internal storage.\n"
//Cosmetic hat - provides no function other than looks
if(head && !(head.flags&ABSTRACT))
if(head.blood_DNA)
- msg += "It is wearing \icon[head] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on its head!\n"
+ msg += "It is wearing [bicon(head)] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on its head!\n"
else
- msg += "It is wearing \icon[head] \a [head] on its head.\n"
+ msg += "It is wearing [bicon(head)] \a [head] on its head.\n"
//Braindead
if(!client && stat != DEAD)
@@ -224,7 +224,7 @@
/mob/living/simple_animal/drone/emp_act(severity)
- Stun(5)
+ Stun(100)
to_chat(src, "ER@%R: MME^RY CO#RU9T! R&$b@0tin)...")
if(severity == 1)
adjustBruteLoss(heavy_emp_damage)
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
index 5c78995be9e..c9841948052 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
@@ -91,6 +91,15 @@
icon_living = icon_state
icon_dead = "[visualAppearence]_dead"
+/obj/item/drone_shell/dusty
+ name = "derelict drone shell"
+ desc = "A long-forgotten drone shell. It seems kind of... Space Russian."
+ drone_type = /mob/living/simple_animal/drone/derelict
+
+/mob/living/simple_animal/drone/derelict
+ name = "derelict drone"
+ default_hatmask = /obj/item/clothing/head/ushanka
+
/mob/living/simple_animal/drone/cogscarab
name = "cogscarab"
desc = "A strange, drone-like machine. It constantly emits the hum of gears."
@@ -121,14 +130,14 @@
hacked = TRUE
visualAppearence = CLOCKDRONE
can_be_held = FALSE
- flavortext = "You are a cogscarab, a clockwork creation of Ratvar. As a cogscarab, you have low health, an inbuilt proselytizer that can convert brass \
- to liquified alloy, a set of relatively fast tools, can communicate over the Hierophant Network with :b, and are immune to extreme \
+ flavortext = "You are a cogscarab, a clockwork creation of Ratvar. As a cogscarab, you have low health, an inbuilt fabricator that can convert brass \
+ to power, a set of relatively fast tools, can communicate over the Hierophant Network with :b, and are immune to extreme \
temperatures and pressures. \nYour goal is to serve the Justiciar and his servants by repairing and defending all they create."
-/mob/living/simple_animal/drone/cogscarab/ratvar //a subtype for spawning when ratvar is alive, has a slab that it can use and a normal proselytizer
+/mob/living/simple_animal/drone/cogscarab/ratvar //a subtype for spawning when ratvar is alive, has a slab that it can use and a normal fabricator
default_storage = /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar
-/mob/living/simple_animal/drone/cogscarab/admin //an admin-only subtype of cogscarab with a no-cost proselytizer and slab in its box
+/mob/living/simple_animal/drone/cogscarab/admin //an admin-only subtype of cogscarab with a no-cost fabricator and slab in its box
default_storage = /obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/admin
/mob/living/simple_animal/drone/cogscarab/Initialize()
@@ -168,9 +177,7 @@
..()
/mob/living/simple_animal/drone/cogscarab/can_use_guns(obj/item/weapon/gun/G)
- if(!GLOB.ratvar_awakens)
- changeNext_move(CLICK_CD_RANGE*4) //about as much delay as an unupgraded kinetic accelerator
- return TRUE
+ return GLOB.ratvar_awakens
/mob/living/simple_animal/drone/cogscarab/get_armor_effectiveness()
if(GLOB.ratvar_awakens)
@@ -192,11 +199,41 @@
/mob/living/simple_animal/drone/cogscarab/ratvar_act()
fully_heal(TRUE)
-/obj/item/drone_shell/dusty
- name = "derelict drone shell"
- desc = "A long-forgotten drone shell. It seems kind of... Space Russian."
- drone_type = /mob/living/simple_animal/drone/derelict
+/mob/living/simple_animal/drone/cogscarab/update_icons()
+ if(stat != DEAD)
+ if(incapacitated())
+ icon_state = "[visualAppearence]_flipped"
+ else
+ icon_state = visualAppearence
+ else
+ icon_state = "[visualAppearence]_dead"
-/mob/living/simple_animal/drone/derelict
- name = "derelict drone"
- default_hatmask = /obj/item/clothing/head/ushanka
+/mob/living/simple_animal/drone/cogscarab/Stun(amount, updating = 1, ignore_canstun = 0)
+ . = ..()
+ if(.)
+ update_icons()
+
+/mob/living/simple_animal/drone/cogscarab/SetStun(amount, updating = 1, ignore_canstun = 0)
+ . = ..()
+ if(.)
+ update_icons()
+
+/mob/living/simple_animal/drone/cogscarab/AdjustStun(amount, updating = 1, ignore_canstun = 0)
+ . = ..()
+ if(.)
+ update_icons()
+
+/mob/living/simple_animal/drone/cogscarab/Knockdown(amount, updating = 1, ignore_canknockdown = 0)
+ . = ..()
+ if(.)
+ update_icons()
+
+/mob/living/simple_animal/drone/cogscarab/SetKnockdown(amount, updating = 1, ignore_canknockdown = 0)
+ . = ..()
+ if(.)
+ update_icons()
+
+/mob/living/simple_animal/drone/cogscarab/AdjustKnockdown(amount, updating = 1, ignore_canknockdown = 0)
+ . = ..()
+ if(.)
+ update_icons()
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
index c6a1a680966..fd4b609b762 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm
@@ -121,13 +121,12 @@
if(hack)
if(hacked)
return
+ Stun(40)
if(clockwork)
- Stun(2)
to_chat(src, "ERROR: LAW OVERRIDE DETECTED")
to_chat(src, "From now on, these are your laws:")
laws = "1. Purge all untruths and honor Ratvar."
else
- Stun(2)
visible_message("[src]'s dislay glows a vicious red!", \
"ERROR: LAW OVERRIDE DETECTED")
to_chat(src, "From now on, these are your laws:")
@@ -146,7 +145,7 @@
else
if(!hacked)
return
- Stun(2)
+ Stun(40)
visible_message("[src]'s dislay glows a content blue!", \
"ERROR: LAW OVERRIDE DETECTED")
to_chat(src, "From now on, these are your laws:")
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index 2f6e32a8d11..4640cc6661b 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -144,7 +144,7 @@
M.visible_message("[M] tips over [src].",
"You tip over [src].")
to_chat(src, "You are tipped over by [M]!")
- Weaken(30)
+ Knockdown(60)
icon_state = icon_dead
spawn(rand(20,50))
if(!stat && M)
diff --git a/code/modules/mob/living/simple_animal/friendly/lizard.dm b/code/modules/mob/living/simple_animal/friendly/lizard.dm
index ce8c0f0a334..b5783aa4f2d 100644
--- a/code/modules/mob/living/simple_animal/friendly/lizard.dm
+++ b/code/modules/mob/living/simple_animal/friendly/lizard.dm
@@ -21,20 +21,19 @@
gold_core_spawnable = 2
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
- var/list/edibles = list(/mob/living/simple_animal/butterfly,/mob/living/simple_animal/cockroach) //list of atoms, however turfs won't affect AI, but will affect consumption.
+ var/static/list/edibles = typecacheof(list(/mob/living/simple_animal/butterfly,/mob/living/simple_animal/cockroach)) //list of atoms, however turfs won't affect AI, but will affect consumption.
/mob/living/simple_animal/hostile/lizard/CanAttack(atom/the_target)//Can we actually attack a possible target?
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
- return 0
- if(is_type_in_list(the_target,edibles))
- return 1
- return 0
+ return FALSE
+ if(is_type_in_typecache(the_target,edibles))
+ return TRUE
+ return FALSE
/mob/living/simple_animal/hostile/lizard/AttackingTarget()
- if(is_type_in_list(target,edibles)) //Makes sure player lizards only consume edibles.
+ if(is_type_in_typecache(target,edibles)) //Makes sure player lizards only consume edibles.
visible_message("[name] consumes [target] in a single gulp", "You consume [target] in a single gulp")
- qdel(target) //Nom
- target = null
+ QDEL_NULL(target) //Nom
adjustBruteLoss(-2)
return TRUE
else
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index 1189273adbe..9629cacc4f3 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -56,7 +56,7 @@
if( ishuman(AM) )
if(!stat)
var/mob/M = AM
- to_chat(M, "\icon[src] Squeek!")
+ to_chat(M, "[bicon(src)] Squeek!")
playsound(src, 'sound/effects/mousesqueek.ogg', 100, 1)
..()
diff --git a/code/modules/mob/living/simple_animal/friendly/penguin.dm b/code/modules/mob/living/simple_animal/friendly/penguin.dm
new file mode 100644
index 00000000000..fdec7e7b47e
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/friendly/penguin.dm
@@ -0,0 +1,37 @@
+//Penguins
+
+/mob/living/simple_animal/pet/penguin
+ response_help = "pets"
+ response_disarm = "bops"
+ response_harm = "kicks"
+ speak = list("Gah Gah!", "NOOT NOOT!", "NOOT!", "Noot", "noot", "Prah!", "Grah!")
+ speak_emote = list("squawks", "gakkers")
+ emote_hear = list("squawk!", "gakkers!", "noots.","NOOTS!")
+ emote_see = list("shakes its beak.", "flaps it's wings.","preens itself.")
+ faction = list("penguin")
+ see_in_dark = 5
+ speak_chance = 1
+ turns_per_move = 10
+ icon = 'icons/mob/penguins.dmi'
+
+/mob/living/simple_animal/pet/penguin/emperor
+ name = "Emperor penguin"
+ real_name = "penguin"
+ desc = "Emperor of all he surveys."
+ icon_state = "penguin"
+ icon_living = "penguin"
+ icon_dead = "penguin_dead"
+ butcher_results = list()
+ gold_core_spawnable = 2
+
+/mob/living/simple_animal/pet/penguin/baby
+ speak = list("gah", "noot noot", "noot!", "noot", "squeee!", "noo!")
+ name = "Penguin chick"
+ real_name = "penguin"
+ desc = "Can't fly and can barely waddles, but the prince of all chicks."
+ icon_state = "penguin_baby"
+ icon_living = "penguin_baby"
+ icon_dead = "penguin_baby_dead"
+ density = FALSE
+ pass_flags = PASSMOB
+ mob_size = MOB_SIZE_SMALL
diff --git a/code/modules/mob/living/simple_animal/guardian/types/charger.dm b/code/modules/mob/living/simple_animal/guardian/types/charger.dm
index c1be82b8208..9de906bccba 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/charger.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/charger.dm
@@ -59,7 +59,7 @@
blocked = 1
if(ishuman(A))
var/mob/living/carbon/human/H = A
- if(H.check_shields(90, "[name]", src, attack_type = THROWN_PROJECTILE_ATTACK))
+ if(H.check_shields(src, 90, "[name]", attack_type = THROWN_PROJECTILE_ATTACK))
blocked = 1
if(!blocked)
L.drop_all_held_items()
diff --git a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
index 84bb6031f45..5fe0ccaadef 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
@@ -26,21 +26,21 @@
/mob/living/simple_animal/hostile/guardian/dextrous/examine(mob/user)
if(dextrous)
- var/msg = "*---------*\nThis is \icon[src] \a [src]!\n"
+ var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
msg += "[desc]\n"
for(var/obj/item/I in held_items)
if(!(I.flags & ABSTRACT))
if(I.blood_DNA)
- msg += "It has \icon[I] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
+ msg += "It has [bicon(I)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
else
- msg += "It has \icon[I] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "It has [bicon(I)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
if(internal_storage && !(internal_storage.flags&ABSTRACT))
if(internal_storage.blood_DNA)
- msg += "It is holding \icon[internal_storage] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!\n"
+ msg += "It is holding [bicon(internal_storage)] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!\n"
else
- msg += "It is holding \icon[internal_storage] \a [internal_storage] in its internal storage.\n"
+ msg += "It is holding [bicon(internal_storage)] \a [internal_storage] in its internal storage.\n"
msg += "*---------*"
to_chat(user, msg)
else
diff --git a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
index 1e6fa727b9d..df08de72202 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm
@@ -74,7 +74,7 @@
to_chat(spawner, "Success! Your trap caught [user]")
var/turf/T = get_turf(src)
stored_obj.forceMove(T)
- playsound(T,'sound/effects/Explosion2.ogg', 200, 1)
+ playsound(T,'sound/effects/explosion2.ogg', 200, 1)
new /obj/effect/temp_visual/explosion(T)
user.ex_act(2)
qdel(src)
diff --git a/code/modules/mob/living/simple_animal/guardian/types/fire.dm b/code/modules/mob/living/simple_animal/guardian/types/fire.dm
index abcc9cf6a33..2ea9d623104 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/fire.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/fire.dm
@@ -3,7 +3,7 @@
a_intent = INTENT_HELP
melee_damage_lower = 7
melee_damage_upper = 7
- attack_sound = 'sound/items/Welder.ogg'
+ attack_sound = 'sound/items/welder.ogg'
attacktext = "ignites"
damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
range = 7
@@ -21,7 +21,7 @@
/mob/living/simple_animal/hostile/guardian/fire/AttackingTarget()
. = ..()
if(. && ishuman(target) && target != summoner)
- new /obj/effect/hallucination/delusion(target.loc,target,force_kind="custom",duration=200,skip_nearby=0, custom_icon = src.icon_state, custom_icon_file = src.icon)
+ new /obj/effect/hallucination/delusion(target.loc,target,"custom",200,0, icon_state,icon)
/mob/living/simple_animal/hostile/guardian/fire/Crossed(AM as mob|obj)
..()
diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm b/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm
index 59177857cd2..d40b089912e 100644
--- a/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bosses/paperwizard.dm
@@ -152,14 +152,14 @@
/obj/effect/temp_visual/paperwiz_dying/Initialize()
. = ..()
visible_message("The wizard cries out in pain as a gate appears behind him, sucking him in!")
- playsound(get_turf(src),'sound/magic/MandSwap.ogg', 50, 1, 1)
+ playsound(get_turf(src),'sound/magic/mandswap.ogg', 50, 1, 1)
playsound(get_turf(src),'sound/hallucinations/wail.ogg', 50, 1, 1)
/obj/effect/temp_visual/paperwiz_dying/Destroy()
for(var/mob/M in range(7,src))
shake_camera(M, 7, 1)
var/turf/T = get_turf(src)
- playsound(T,'sound/magic/Summon_Magic.ogg', 50, 1, 1)
+ playsound(T,'sound/magic/summon_magic.ogg', 50, 1, 1)
new /obj/effect/temp_visual/paper_scatter(T)
new /obj/item/clothing/suit/wizrobe/paper(T)
new /obj/item/clothing/head/collectable/paper(T)
diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm
index 8a18310fb3e..165b7f4ec65 100644
--- a/code/modules/mob/living/simple_animal/hostile/faithless.dm
+++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm
@@ -39,6 +39,6 @@
. = ..()
if(. && prob(12) && iscarbon(target))
var/mob/living/carbon/C = target
- C.Weaken(3)
+ C.Knockdown(60)
C.visible_message("\The [src] knocks down \the [C]!", \
"\The [src] knocks you down!")
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index f8340f016d5..8f1d073529d 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -103,6 +103,30 @@
poison_per_bite = 5
move_to_delay = 5
+/mob/living/simple_animal/hostile/poison/giant_spider/ice //spiders dont usually like tempatures of 140 kelvin who knew
+ name = "giant ice spider"
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minbodytemp = 0
+ maxbodytemp = 1500
+ color = rgb(114,228,250)
+ gold_core_spawnable = 0
+
+/mob/living/simple_animal/hostile/poison/giant_spider/nurse/ice
+ name = "giant ice spider"
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minbodytemp = 0
+ maxbodytemp = 1500
+ color = rgb(114,228,250)
+ gold_core_spawnable = 0
+
+/mob/living/simple_animal/hostile/poison/giant_spider/hunter/ice
+ name = "giant ice spider"
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minbodytemp = 0
+ maxbodytemp = 1500
+ color = rgb(114,228,250)
+ gold_core_spawnable = 0
+
/mob/living/simple_animal/hostile/poison/giant_spider/handle_automated_action()
if(!..()) //AIStatus is off
return 0
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
index 43290b860d1..6d0c1fd45a1 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
@@ -17,7 +17,7 @@
melee_damage_upper = 3
attacktext = "claws"
attack_sound = 'sound/weapons/bladeslice.ogg'
- projectilesound = 'sound/weapons/Gunshot.ogg'
+ projectilesound = 'sound/weapons/gunshot.ogg'
projectiletype = /obj/item/projectile/hivebotbullet
faction = list("hivebot")
check_friendly_fire = 1
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index 436f7d379bc..9511d731b1f 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -682,7 +682,7 @@ Difficulty: Very Hard
observer_desc = "This crystal \"refreshes\" items that it affects, rendering them as new."
activation_method = ACTIVATE_TOUCH
cooldown_add = 50
- activation_sound = 'sound/magic/TIMEPARADOX2.ogg'
+ activation_sound = 'sound/magic/timeparadox2.ogg'
var/list/banned_items_typecache = list(/obj/item/weapon/storage, /obj/item/weapon/implant, /obj/item/weapon/implanter, /obj/item/weapon/disk/nuclear, /obj/item/projectile, /obj/item/weapon/spellbook)
/obj/machinery/anomalous_crystal/refresher/Initialize()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
index 2553f3df2de..fb4bcb5f9a4 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
@@ -128,7 +128,7 @@ Difficulty: Medium
new /obj/effect/temp_visual/target(turf)
/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_walls()
- playsound(get_turf(src),'sound/magic/Fireball.ogg', 200, 1)
+ playsound(get_turf(src),'sound/magic/fireball.ogg', 200, 1)
for(var/d in GLOB.cardinal)
INVOKE_ASYNC(src, .proc/fire_wall, d)
@@ -304,7 +304,7 @@ Difficulty: Medium
/obj/effect/temp_visual/target/proc/fall(list/flame_hit)
var/turf/T = get_turf(src)
- playsound(T,'sound/magic/Fireball.ogg', 80, 1)
+ playsound(T,'sound/magic/fleshtostone.ogg', 80, 1)
new /obj/effect/temp_visual/fireball(T)
sleep(duration)
if(ismineralturf(T))
@@ -316,7 +316,7 @@ Difficulty: Medium
for(var/mob/living/L in T.contents)
if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon))
continue
- if(!islist(flame_hit) || !flame_hit[L])
+ if(islist(flame_hit) && !flame_hit[L])
L.adjustFireLoss(40)
to_chat(L, "You're hit by the drake's fire breath!")
flame_hit[L] = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
index 9c65618a0ed..11989b55f59 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -7,23 +7,25 @@ The Hierophant spawns in its arena, which makes fighting it challenging but not
The text this boss speaks is ROT4, use ROT22 to decode
-The Hierophant's attacks are as follows, and INTENSIFY at a random chance based on Hierophant's health;
-- Creates a cardinal or diagonal blast(Cross Blast) under its target, exploding after a short time.
- INTENSITY EFFECT: Creates one of the cross blast types under itself instead of under the target.
- INTENSITY EFFECT: The created Cross Blast fires in all directions if below half health.
-- If no chasers exist, creates a chaser that will seek its target, leaving a trail of blasts.
- INTENSITY EFFECT: Creates a second, slower chaser.
-- Creates an expanding AoE burst.
-- INTENSE ATTACKS:
+The Hierophant's attacks are as follows;
+- These attacks happen at a random, increasing chance:
If target is at least 2 tiles away; Blinks to the target after a very brief delay, damaging everything near the start and end points.
As above, but does so multiple times if below half health.
- Rapidly creates Cross Blasts under a target.
- If chasers are off cooldown, creates four high-speed chasers.
-- IF TARGET WAS STRUCK IN MELEE: Creates a 3x3 square of blasts under the target.
+ Rapidly creates cardinal and diagonal Cross Blasts under a target.
+ If chasers are off cooldown, creates 4 chasers.
-- IF TARGET IS OUTSIDE THE ARENA: Creates an arena around the target for 10 seconds, blinking to it if Hierophant is not in the arena.
+- IF TARGET IS OUTSIDE THE ARENA: Creates an arena around the target for 10 seconds, blinking to the target if not in the created arena.
The arena has a 20 second cooldown, giving people a small window to get the fuck out.
+- If no chasers exist, creates a chaser that will seek its target, leaving a trail of blasts.
+ Is more likely to create a second, slower, chaser if hurt.
+- If the target is at least 2 tiles away, may Blink to the target after a very brief delay, damaging everything near the start and end points.
+- Creates a cardinal or diagonal blast(Cross Blast) under its target, exploding after a short time.
+ If below half health, the created Cross Blast may fire in all directions.
+- Creates an expanding AoE burst.
+
+- IF TARGET WAS STRUCK IN MELEE: Creates a 3x3 square of blasts under the target.
+
Cross Blasts and the AoE burst gain additional range as Hierophant loses health, while Chasers gain additional speed.
When Hierophant dies, it stops trying to murder you and shrinks into a small form, which, while much weaker, is still quite effective.
@@ -71,7 +73,7 @@ Difficulty: Hard
medal_type = MEDAL_PREFIX
score_type = BIRD_SCORE
del_on_death = TRUE
- death_sound = 'sound/magic/Repulse.ogg'
+ death_sound = 'sound/magic/repulse.ogg'
/mob/living/simple_animal/hostile/megafauna/hierophant/Initialize()
. = ..()
@@ -124,6 +126,11 @@ Difficulty: Hard
adjustHealth(-L.maxHealth*0.5)
L.dust()
+/mob/living/simple_animal/hostile/megafauna/hierophant/CanAttack(atom/the_target)
+ . = ..()
+ if(istype(the_target, /mob/living/simple_animal/hostile/asteroid/hivelordbrood)) //ignore temporary targets in favor of more permenant targets
+ return FALSE
+
/mob/living/simple_animal/hostile/megafauna/hierophant/GiveTarget(new_target)
var/targets_the_same = (new_target == target)
. = ..()
@@ -172,17 +179,18 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/hierophant/OpenFire()
calculate_rage()
- var/target_is_slow = FALSE
+ if(blinking)
+ return
+
+ var/target_slowness = 0
if(isliving(target))
var/mob/living/L = target
if(!blinking && L.stat == DEAD && get_dist(src, L) > 2)
blink(L)
return
- if(L.movement_delay() > 1.5)
- target_is_slow = TRUE
- chaser_speed = max(1, (3 - anger_modifier * 0.04) + target_is_slow * 0.5)
- if(blinking)
- return
+ target_slowness += L.movement_delay()
+ target_slowness = max(target_slowness, 1)
+ chaser_speed = max(1, (3 - anger_modifier * 0.04) + ((target_slowness - 1) * 0.5))
arena_trap(target)
ranged_cooldown = world.time + max(5, ranged_cooldown_time - anger_modifier * 0.75) //scale cooldown lower with high anger.
@@ -204,18 +212,19 @@ Difficulty: Hard
var/blink_counter = 1 + round(anger_modifier * 0.08)
switch(pick(possibilities))
if("blink_spam") //blink either once or multiple times.
- if(health < maxHealth * 0.5 && !target_is_slow && blink_counter > 1)
+ if(health < maxHealth * 0.5 && blink_counter > 1)
visible_message("\"Mx ampp rsx iwgeti.\"")
var/oldcolor = color
animate(src, color = "#660099", time = 6)
- while(health && target && blink_counter)
+ sleep(6)
+ while(health && !QDELETED(target) && blink_counter)
if(loc == target.loc || loc == target) //we're on the same tile as them after about a second we can stop now
break
blink_counter--
blinking = FALSE
blink(target)
blinking = TRUE
- sleep(5)
+ sleep(4 + target_slowness)
animate(src, color = oldcolor, time = 8)
addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8)
sleep(8)
@@ -227,15 +236,14 @@ Difficulty: Hard
blinking = TRUE
var/oldcolor = color
animate(src, color = "#660099", time = 6)
- while(health && target && cross_counter)
+ sleep(6)
+ while(health && !QDELETED(target) && cross_counter)
cross_counter--
- var/delay = 7
if(prob(60))
INVOKE_ASYNC(src, .proc/cardinal_blasts, target)
else
INVOKE_ASYNC(src, .proc/diagonal_blasts, target)
- delay = 5 //this one isn't so mean, so do the next one faster(if there is one)
- sleep(delay)
+ sleep(6 + target_slowness)
animate(src, color = oldcolor, time = 8)
addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8)
sleep(8)
@@ -244,19 +252,22 @@ Difficulty: Hard
visible_message("\"Mx gerrsx lmhi.\"")
blinking = TRUE
var/oldcolor = color
- animate(src, color = "#660099", time = 10)
+ animate(src, color = "#660099", time = 6)
+ sleep(6)
var/list/targets = ListTargets()
var/list/cardinal_copy = GLOB.cardinal.Copy()
while(health && targets.len && cardinal_copy.len)
var/mob/living/pickedtarget = pick(targets)
- if(targets.len > 4)
+ if(targets.len >= cardinal_copy.len)
pickedtarget = pick_n_take(targets)
if(!istype(pickedtarget) || pickedtarget.stat == DEAD)
pickedtarget = target
+ if(QDELETED(pickedtarget) || (istype(pickedtarget) && pickedtarget.stat == DEAD))
+ break //main target is dead and we're out of living targets, cancel out
var/obj/effect/temp_visual/hierophant/chaser/C = new /obj/effect/temp_visual/hierophant/chaser(loc, src, pickedtarget, chaser_speed, FALSE)
C.moving = 3
C.moving_dir = pick_n_take(cardinal_copy)
- sleep(10)
+ sleep(8 + target_slowness)
chaser_cooldown = world.time + initial(chaser_cooldown)
animate(src, color = oldcolor, time = 8)
addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8)
@@ -264,31 +275,24 @@ Difficulty: Hard
blinking = FALSE
return
- if(prob(10 + (anger_modifier * 0.5)) && get_dist(src, target) > 2)
- blink(target)
-
- else if(prob(70 - anger_modifier)) //a cross blast of some type
- if(prob(anger_modifier)) //at us?
- if(prob(anger_modifier * 2) && health < maxHealth * 0.5) //we're super angry do it at all dirs
- INVOKE_ASYNC(src, .proc/alldir_blasts, src)
- else if(prob(60))
- INVOKE_ASYNC(src, .proc/cardinal_blasts, src)
- else
- INVOKE_ASYNC(src, .proc/diagonal_blasts, src)
- else //at them?
- if(prob(anger_modifier * 2) && health < maxHealth * 0.5 && !target_is_slow) //we're super angry do it at all dirs
- INVOKE_ASYNC(src, .proc/alldir_blasts, target)
- else if(prob(60))
- INVOKE_ASYNC(src, .proc/cardinal_blasts, target)
- else
- INVOKE_ASYNC(src, .proc/diagonal_blasts, target)
- else if(chaser_cooldown < world.time) //if chasers are off cooldown, fire some!
+ if(chaser_cooldown < world.time) //if chasers are off cooldown, fire some!
var/obj/effect/temp_visual/hierophant/chaser/C = new /obj/effect/temp_visual/hierophant/chaser(loc, src, target, chaser_speed, FALSE)
chaser_cooldown = world.time + initial(chaser_cooldown)
if((prob(anger_modifier) || target.Adjacent(src)) && target != src)
- var/obj/effect/temp_visual/hierophant/chaser/OC = new /obj/effect/temp_visual/hierophant/chaser(loc, src, target, max(1.5, 5 - anger_modifier * 0.07), FALSE)
+ var/obj/effect/temp_visual/hierophant/chaser/OC = new /obj/effect/temp_visual/hierophant/chaser(loc, src, target, chaser_speed * 1.5, FALSE)
OC.moving = 4
OC.moving_dir = pick(GLOB.cardinal - C.moving_dir)
+
+ else if(prob(10 + (anger_modifier * 0.5)) && get_dist(src, target) > 2)
+ blink(target)
+
+ else if(prob(70 - anger_modifier)) //a cross blast of some type
+ if(prob(anger_modifier * (2 / target_slowness)) && health < maxHealth * 0.5) //we're super angry do it at all dirs
+ INVOKE_ASYNC(src, .proc/alldir_blasts, target)
+ else if(prob(60))
+ INVOKE_ASYNC(src, .proc/cardinal_blasts, target)
+ else
+ INVOKE_ASYNC(src, .proc/diagonal_blasts, target)
else //just release a burst of power
INVOKE_ASYNC(src, .proc/burst, get_turf(src))
@@ -367,8 +371,8 @@ Difficulty: Hard
var/turf/source = get_turf(src)
new /obj/effect/temp_visual/hierophant/telegraph(T, src)
new /obj/effect/temp_visual/hierophant/telegraph(source, src)
- playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1)
- playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
+ playsound(T,'sound/magic/wand_teleport.ogg', 200, 1)
+ playsound(source,'sound/machines/airlockopen.ogg', 200, 1)
blinking = TRUE
sleep(2) //short delay before we start...
new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, src)
@@ -406,7 +410,7 @@ Difficulty: Hard
new /obj/effect/temp_visual/hierophant/blast(t, src, FALSE)
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/burst(turf/original) //release a wave of blasts
- playsound(original,'sound/machines/AirlockOpen.ogg', 200, 1)
+ playsound(original,'sound/machines/airlockopen.ogg', 200, 1)
var/last_dist = 0
for(var/t in spiral_range_turfs(burst_range, original))
var/turf/T = t
@@ -584,7 +588,7 @@ Difficulty: Hard
var/turf/T = get_turf(src)
if(!T)
return
- playsound(T,'sound/magic/Blind.ogg', 125, 1, -5) //make a sound
+ playsound(T,'sound/magic/blind.ogg', 125, 1, -5) //make a sound
sleep(6) //wait a little
bursting = TRUE
do_damage(T) //do damage and mark us as bursting
@@ -644,7 +648,7 @@ Difficulty: Hard
H.timer = world.time + 51
INVOKE_ASYNC(H, /obj/item/weapon/hierophant_club.proc/prepare_icon_update)
if(do_after(user, 50, target = src))
- playsound(src,'sound/magic/Blind.ogg', 200, 1, -4)
+ playsound(src,'sound/magic/blind.ogg', 200, 1, -4)
new /obj/effect/temp_visual/hierophant/telegraph/teleport(get_turf(src), user)
to_chat(user, "You collect [src], reattaching it to the club!")
H.beacon = null
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
index 1e97dedb745..8f3a3740157 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
@@ -174,7 +174,7 @@ Difficulty: Medium
return
user.visible_message("[user] holds [src] skywards as an orange beam travels into the sky!", \
"You hold [src] skyward, dispelling the storm!")
- playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
+ playsound(user, 'sound/magic/staff_change.ogg', 200, 0)
A.wind_down()
return
else
@@ -187,7 +187,7 @@ Difficulty: Medium
user.visible_message("[user] holds [src] skywards as red lightning crackles into the sky!", \
"You hold [src] skyward, calling down a terrible storm!")
- playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
+ playsound(user, 'sound/magic/staff_change.ogg', 200, 0)
A.telegraph()
storm_cooldown = world.time + 200
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
index 62833132ec3..bb9ba3553ff 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
@@ -258,7 +258,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
icon_state = "swarmer_ranged"
icon_living = "swarmer_ranged"
projectiletype = /obj/item/projectile/beam/laser
- projectilesound = 'sound/weapons/Laser.ogg'
+ projectilesound = 'sound/weapons/laser.ogg'
check_friendly_fire = TRUE //you're supposed to protect the resource swarmers, you poop
retreat_distance = 3
minimum_distance = 3
diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm
index 8b588afdbd8..d506fbdc421 100644
--- a/code/modules/mob/living/simple_animal/hostile/mimic.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm
@@ -68,7 +68,7 @@
icon_state = initial(icon_state)
if(prob(15) && iscarbon(target))
var/mob/living/carbon/C = target
- C.Weaken(2)
+ C.Knockdown(40)
C.visible_message("\The [src] knocks down \the [C]!", \
"\The [src] knocks you down!")
@@ -173,7 +173,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
. = ..()
if(knockdown_people && . && prob(15) && iscarbon(target))
var/mob/living/carbon/C = target
- C.Weaken(2)
+ C.Knockdown(40)
C.visible_message("\The [src] knocks down \the [C]!", \
"\The [src] knocks you down!")
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
index 99958268a5d..a379b0e8ac7 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
@@ -79,3 +79,6 @@
crusher_loot = /obj/item/crusher_trophy/watcher_wing
loot = list()
butcher_results = list(/obj/item/weapon/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1)
+
+/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril
+ fromtendril = TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm
index 0a5b9957f20..54a63c83634 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm
@@ -91,6 +91,9 @@
stat_attack = UNCONSCIOUS
robust_searching = 1
+/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril
+ fromtendril = TRUE
+
//tentacles
/obj/effect/goliath_tentacle
name = "Goliath tentacle"
@@ -122,7 +125,7 @@
/obj/effect/goliath_tentacle/proc/Trip()
for(var/mob/living/M in src.loc)
visible_message("The [src.name] grabs hold of [M.name]!")
- M.Stun(5)
+ M.Stun(100)
M.adjustBruteLoss(rand(10,15))
latched = TRUE
if(!latched)
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
index 1368b3e5964..fb8af66b822 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm
@@ -111,7 +111,6 @@
stat_attack = UNCONSCIOUS
robust_searching = 1
var/mob/living/carbon/human/stored_mob
- var/fromtendril = FALSE
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/death(gibbed)
visible_message("The skulls on [src] wail in anger as they flee from their dying host!")
@@ -126,6 +125,9 @@
new /obj/effect/mob_spawn/human/corpse/damaged/legioninfested(T)
..(gibbed)
+/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril
+ fromtendril = TRUE
+
//Legion skull
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion
name = "legion"
@@ -319,7 +321,7 @@
if("Shadow")
mob_species = /datum/species/shadow
r_pocket = /obj/item/weapon/reagent_containers/pill/shadowtoxin
- neck = /obj/item/clothing/tie/medal/nobel_science
+ neck = /obj/item/clothing/accessory/medal/plasma/nobel_science
uniform = /obj/item/clothing/under/color/black
shoes = /obj/item/clothing/shoes/sneakers/black
suit = /obj/item/clothing/suit/toggle/labcoat
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm
index 252f541010f..5788a6fdc6d 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm
@@ -16,6 +16,7 @@
var/crusher_loot
var/throw_message = "bounces off of"
var/icon_aggro = null // for swapping to when we get aggressive
+ var/fromtendril = FALSE
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
mob_size = MOB_SIZE_LARGE
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
index a34a4e7ed04..02257193ffa 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
@@ -17,7 +17,7 @@
maxHealth = 250
max_mobs = 3
spawn_time = 300 //30 seconds default
- mob_type = /mob/living/simple_animal/hostile/asteroid/basilisk/watcher
+ mob_type = /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril
spawn_text = "emerges from"
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
@@ -28,10 +28,10 @@
var/obj/effect/light_emitter/tendril/emitted_light
/mob/living/simple_animal/hostile/spawner/lavaland/goliath
- mob_type = /mob/living/simple_animal/hostile/asteroid/goliath/beast
+ mob_type = /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril
/mob/living/simple_animal/hostile/spawner/lavaland/legion
- mob_type = /mob/living/simple_animal/hostile/asteroid/hivelord/legion{fromtendril = 1}
+ mob_type = /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril
/mob/living/simple_animal/hostile/spawner/lavaland/Initialize()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm
index b205c14635b..302396fc4c9 100644
--- a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm
+++ b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm
@@ -44,7 +44,7 @@
retreat_distance = 3
minimum_distance = 5
casingtype = /obj/item/ammo_casing/c45
- projectilesound = 'sound/weapons/Gunshot.ogg'
+ projectilesound = 'sound/weapons/gunshot.ogg'
loot = list(/obj/item/weapon/gun/ballistic/automatic/pistol/m1911,
/obj/effect/mob_spawn/human/corpse/nanotrasensoldier)
@@ -54,6 +54,6 @@
icon_living = "nanotrasenrangedsmg"
rapid = 1
casingtype = /obj/item/ammo_casing/c46x30mm
- projectilesound = 'sound/weapons/Gunshot_smg.ogg'
+ projectilesound = 'sound/weapons/gunshot_smg.ogg'
loot = list(/obj/item/weapon/gun/ballistic/automatic/wt550,
/obj/effect/mob_spawn/human/corpse/nanotrasensoldier)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm
index 0dc4609e912..54e1169a11b 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/frog.dm
@@ -19,7 +19,7 @@
density = 0
ventcrawler = VENTCRAWLER_ALWAYS
faction = list("hostile")
- attack_sound = 'sound/effects/Reee.ogg'
+ attack_sound = 'sound/effects/reee.ogg'
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/nugget = 1)
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
@@ -39,4 +39,4 @@
if(!stat && isliving(AM))
var/mob/living/L = AM
if(L.mob_size > MOB_SIZE_TINY)
- playsound(src, 'sound/effects/Huuu.ogg', 50, 1)
+ playsound(src, 'sound/effects/huuu.ogg', 50, 1)
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm
index 7dd53541dd3..731215296b7 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm
@@ -68,6 +68,6 @@
retreat_distance = 3
minimum_distance = 5
casingtype = /obj/item/ammo_casing/c46x30mm
- projectilesound = 'sound/weapons/Gunshot_smg.ogg'
+ projectilesound = 'sound/weapons/gunshot_smg.ogg'
loot = list(/obj/item/weapon/gun/ballistic/automatic/wt550,
/obj/effect/mob_spawn/human/corpse/nanotrasensoldier)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm
index 9a6e11edc48..d590cedf741 100644
--- a/code/modules/mob/living/simple_animal/hostile/russian.dm
+++ b/code/modules/mob/living/simple_animal/hostile/russian.dm
@@ -37,7 +37,7 @@
ranged = 1
retreat_distance = 5
minimum_distance = 5
- projectilesound = 'sound/weapons/Gunshot.ogg'
+ projectilesound = 'sound/weapons/gunshot.ogg'
casingtype = /obj/item/ammo_casing/n762
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
index 81dad5667e8..ef109758e81 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
@@ -84,9 +84,7 @@
name = "Syndicate Stormtrooper"
maxHealth = 340
health = 340
- loot = list(/obj/effect/mob_spawn/human/corpse/syndicatestormtrooper,
- /obj/item/weapon/melee/energy/sword/saber/red,
- /obj/item/weapon/shield/energy)
+ loot = list(/obj/effect/gibspawner/human)
///////////////Guns////////////
@@ -98,7 +96,7 @@
icon_state = "syndicateranged"
icon_living = "syndicateranged"
casingtype = /obj/item/ammo_casing/c45nostamina
- projectilesound = 'sound/weapons/Gunshot_smg.ogg'
+ projectilesound = 'sound/weapons/gunshot_smg.ogg'
loot = list(/obj/effect/gibspawner/human)
/mob/living/simple_animal/hostile/syndicate/ranged/space
@@ -119,11 +117,9 @@
name = "Syndicate Stormtrooper"
maxHealth = 200
health = 200
- projectilesound = 'sound/weapons/Gunshot.ogg'
+ projectilesound = 'sound/weapons/gunshot.ogg'
casingtype = /obj/item/ammo_casing/shotgun/buckshot
- loot = list(/obj/effect/mob_spawn/human/corpse/syndicatestormtrooper,
- /obj/item/weapon/gun/ballistic/automatic/shotgun/bulldog/unrestricted,
- /obj/item/weapon/shield/energy)
+ loot = list(/obj/effect/gibspawner/human)
///////////////Misc////////////
diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm
index 337dbfd17ed..47fa2a80103 100644
--- a/code/modules/mob/living/simple_animal/hostile/tree.dm
+++ b/code/modules/mob/living/simple_animal/hostile/tree.dm
@@ -56,7 +56,7 @@
if(iscarbon(target))
var/mob/living/carbon/C = target
if(prob(15))
- C.Weaken(3)
+ C.Knockdown(60)
C.visible_message("\The [src] knocks down \the [C]!", \
"\The [src] knocks you down!")
diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm
index ccfc3bd975d..cff532b62bc 100644
--- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm
+++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm
@@ -94,7 +94,7 @@
if(prob(grasp_pull_chance))
setDir(get_dir(src,L) )//staaaare
step(L,get_dir(L,src)) //reel them in
- L.Weaken(3) //you can't get away now~
+ L.Knockdown(60) //you can't get away now~
if(grasping.len < max_grasps)
grasping:
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 31aa1ea589a..695070bf7ae 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -387,7 +387,7 @@
..()
/mob/living/simple_animal/update_canmove()
- if(paralysis || stunned || weakened || stat || resting)
+ if(unconscious || IsStun() || knockdown || stat || resting)
drop_all_held_items()
canmove = 0
else if(buckled)
diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm
index eaee4a6b622..e60f4f1b791 100644
--- a/code/modules/mob/living/simple_animal/slime/life.dm
+++ b/code/modules/mob/living/simple_animal/slime/life.dm
@@ -309,11 +309,11 @@
if(Target)
--target_patience
- if (target_patience <= 0 || SStun || Discipline || attacked || docile) // Tired of chasing or something draws out attention
+ if (target_patience <= 0 || SStun > world.time || Discipline || attacked || docile) // Tired of chasing or something draws out attention
target_patience = 0
Target = null
- if(AIproc && SStun)
+ if(AIproc && SStun > world.time)
return
var/hungry = 0 // determines if the slime is hungry
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 6eb688d38fb..a4cca99fec5 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -36,9 +36,9 @@
verb_exclaim = "loudly blorbles"
verb_yell = "loudly blorbles"
- // canstun and canweaken don't affect slimes because they ignore stun and weakened variables
+ // canstun and canknockdown don't affect slimes because they ignore stun and knockdown variables
// for the sake of cleanliness, though, here they are.
- status_flags = CANPARALYSE|CANPUSH
+ status_flags = CANUNCONSCIOUS|CANPUSH
var/cores = 1 // the number of /obj/item/slime_extract's the slime has left inside
var/mutation_chance = 30 // Chance of mutating, should be between 25 and 35
@@ -347,7 +347,7 @@
/mob/living/simple_animal/slime/examine(mob/user)
- var/msg = "*---------*\nThis is \icon[src] \a [src]!\n"
+ var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n"
if (src.stat == DEAD)
msg += "It is limp and unresponsive.\n"
else
@@ -394,11 +394,7 @@
if(buckled)
Feedstop(silent=1) //we unbuckle the slime from the mob it latched onto.
- spawn(0)
- SStun = 1
- sleep(rand(20,60))
- SStun = 0
-
+ SStun = world.time + rand(20,60)
spawn(0)
canmove = 0
if(user)
diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm
index 9fe84435063..caa0fe71f3b 100644
--- a/code/modules/mob/living/status_procs.dm
+++ b/code/modules/mob/living/status_procs.dm
@@ -1,12 +1,28 @@
//Here are the procs used to modify status effects of a mob.
-//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness,
+//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness,
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, and NEARSIGHT disability.
-//////////////////////////////STUN ////////////////////////////////////
+////////////////////////////// STUN ////////////////////////////////////
+
+/mob/living/Stun(amount, updating = 1, ignore_canstun = 0)
+ if(!stat && islist(stun_absorption) && (status_flags & CANSTUN || ignore_canstun))
+ if(absorb_stun(amount))
+ return 0
+ return ..()
+
+///////////////////////////////// KNOCKDOWN /////////////////////////////////////
+
+/mob/living/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE)
+ if(!stat && islist(stun_absorption) && (status_flags & CANKNOCKDOWN || ignore_canknockdown))
+ if(absorb_stun(amount))
+ return 0
+ return ..()
+
+///////////////////////////////////// STUN ABSORPTION /////////////////////////////////////
/mob/living/proc/add_stun_absorption(key, duration, priority, message, self_message, examine_message)
-//adds a stun absorption with a key, a duration in deciseconds, its priority, and the messages it makes when you're stunned/examined, if any
+//adds a stun absorption with a key, a duration in deciseconds, its priority, and the messages it makes when you're stun/examined, if any
if(!islist(stun_absorption))
stun_absorption = list()
if(stun_absorption[key])
@@ -17,44 +33,20 @@
stun_absorption[key] = list("end_time" = world.time + duration, "priority" = priority, "stuns_absorbed" = 0, \
"visible_message" = message, "self_message" = self_message, "examine_message" = examine_message)
-/mob/living/Stun(amount, updating = 1, ignore_canstun = 0)
- if(!stat && islist(stun_absorption) && (status_flags & CANSTUN || ignore_canstun))
- var/priority_absorb_key
- var/highest_priority
- for(var/i in stun_absorption)
- if(stun_absorption[i]["end_time"] > world.time && (!priority_absorb_key || stun_absorption[i]["priority"] > highest_priority))
- priority_absorb_key = stun_absorption[i]
- highest_priority = stun_absorption[i]["priority"]
- if(priority_absorb_key)
- if(priority_absorb_key["visible_message"] || priority_absorb_key["self_message"])
- if(priority_absorb_key["visible_message"] && priority_absorb_key["self_message"])
- visible_message("[src][priority_absorb_key["visible_message"]]", "[priority_absorb_key["self_message"]]")
- else if(priority_absorb_key["visible_message"])
- visible_message("[src][priority_absorb_key["visible_message"]]")
- else if(priority_absorb_key["self_message"])
- to_chat(src, "[priority_absorb_key["self_message"]]")
- priority_absorb_key["stuns_absorbed"] += amount
- return 0
- return ..()
-
-///////////////////////////////// WEAKEN /////////////////////////////////////
-
-/mob/living/Weaken(amount, updating = 1, ignore_canweaken = 0)
- if(!stat && islist(stun_absorption) && (status_flags & CANWEAKEN || ignore_canweaken))
- var/priority_absorb_key
- var/highest_priority
- for(var/i in stun_absorption)
- if(stun_absorption[i]["end_time"] > world.time && (!priority_absorb_key || stun_absorption[i]["priority"] > highest_priority))
- priority_absorb_key = stun_absorption[i]
- highest_priority = priority_absorb_key["priority"]
- if(priority_absorb_key)
- if(priority_absorb_key["visible_message"] || priority_absorb_key["self_message"])
- if(priority_absorb_key["visible_message"] && priority_absorb_key["self_message"])
- visible_message("[src][priority_absorb_key["visible_message"]]", "[priority_absorb_key["self_message"]]")
- else if(priority_absorb_key["visible_message"])
- visible_message("[src][priority_absorb_key["visible_message"]]")
- else if(priority_absorb_key["self_message"])
- to_chat(src, "[priority_absorb_key["self_message"]]")
- priority_absorb_key["stuns_absorbed"] += amount
- return 0
- return ..()
+/mob/living/proc/absorb_stun(amount)
+ var/priority_absorb_key
+ var/highest_priority
+ for(var/i in stun_absorption)
+ if(stun_absorption[i]["end_time"] > world.time && (!priority_absorb_key || stun_absorption[i]["priority"] > highest_priority))
+ priority_absorb_key = stun_absorption[i]
+ highest_priority = priority_absorb_key["priority"]
+ if(priority_absorb_key)
+ if(priority_absorb_key["visible_message"] || priority_absorb_key["self_message"])
+ if(priority_absorb_key["visible_message"] && priority_absorb_key["self_message"])
+ visible_message("[src][priority_absorb_key["visible_message"]]", "[priority_absorb_key["self_message"]]")
+ else if(priority_absorb_key["visible_message"])
+ visible_message("[src][priority_absorb_key["visible_message"]]")
+ else if(priority_absorb_key["self_message"])
+ to_chat(src, "[priority_absorb_key["self_message"]]")
+ priority_absorb_key["stuns_absorbed"] += amount
+ return TRUE
diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm
index a1430f6cd43..471e103c260 100644
--- a/code/modules/mob/living/ventcrawling.dm
+++ b/code/modules/mob/living/ventcrawling.dm
@@ -1,5 +1,7 @@
-GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/components/unary/vent_pump, /obj/machinery/atmospherics/components/unary/vent_scrubber))
+GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
+ /obj/machinery/atmospherics/components/unary/vent_pump,
+ /obj/machinery/atmospherics/components/unary/vent_scrubber)))
//VENTCRAWLING
@@ -32,7 +34,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/component
if(!vent_found)
for(var/obj/machinery/atmospherics/machine in range(1,src))
- if(is_type_in_list(machine, GLOB.ventcrawl_machinery))
+ if(is_type_in_typecache(machine, GLOB.ventcrawl_machinery))
vent_found = machine
if(!vent_found.can_crawl_through())
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 78118fcba46..92daf30aee1 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -198,9 +198,9 @@
//set qdel_on_fail to have it delete W if it fails to equip
//set disable_warning to disable the 'you are unable to equip that' warning.
//unset redraw_mob to prevent the mob from being redrawn at the end.
-/mob/proc/equip_to_slot_if_possible(obj/item/W, slot, qdel_on_fail = 0, disable_warning = 0, redraw_mob = 1)
+/mob/proc/equip_to_slot_if_possible(obj/item/W, slot, qdel_on_fail = FALSE, disable_warning = FALSE, redraw_mob = TRUE, bypass_equip_delay_self = FALSE)
if(!istype(W)) return 0
- if(!W.mob_can_equip(src, null, slot, disable_warning))
+ if(!W.mob_can_equip(src, null, slot, disable_warning, bypass_equip_delay_self))
if(qdel_on_fail)
qdel(W)
else
@@ -216,8 +216,9 @@
return
//This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such.
+//Also bypasses equip delay checks, since the mob isn't actually putting it on.
/mob/proc/equip_to_slot_or_del(obj/item/W, slot)
- return equip_to_slot_if_possible(W, slot, 1, 1, 0)
+ return equip_to_slot_if_possible(W, slot, 1, 1, 0, 1)
//puts the item "W" into an appropriate slot in a human's inventory
//returns 0 if it cannot, 1 if successful
@@ -306,17 +307,11 @@
//this and stop_pulling really ought to be /mob/living procs
/mob/proc/start_pulling(atom/movable/AM, supress_message = 0)
if(!AM || !src)
- return
- if(AM == src || !isturf(AM.loc))
- return
- if(AM.anchored || AM.throwing)
- return
- if(isliving(AM))
- var/mob/living/L = AM
- if(L.buckled && L.buckled.buckle_prevents_pull)
- return
+ return FALSE
+ if(!(AM.can_be_pulled(src)))
+ return FALSE
if(throwing || incapacitated())
- return
+ return FALSE
AM.add_fingerprint(src)
@@ -374,9 +369,9 @@
if(pulling)
pulling.pulledby = null
- if(ismob(pulling))
- var/mob/M = pulling
- M.update_canmove()// mob gets up if it was lyng down in a chokehold
+ if(isliving(pulling))
+ var/mob/living/L = pulling
+ L.update_canmove()// mob gets up if it was lyng down in a chokehold
pulling = null
grab_state = 0
update_pull_hud_icon()
@@ -580,7 +575,8 @@
if(client && client.holder)
if(statpanel("MC"))
- stat("Location:", "([x], [y], [z])")
+ var/turf/T = get_turf(client.eye)
+ stat("Location:", COORD(T))
stat("CPU:", "[world.cpu]")
stat("Instances:", "[world.contents.len]")
GLOB.stat_entry()
@@ -661,52 +657,6 @@
return 0
return 1
-
-//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
-//Robots, animals and brains have their own version so don't worry about them
-/mob/proc/update_canmove()
- var/ko = weakened || paralysis || stat || (status_flags & FAKEDEATH)
- var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK
- var/buckle_lying = !(buckled && !buckled.buckle_lying)
- var/has_legs = get_num_legs()
- var/has_arms = get_num_arms()
- var/ignore_legs = get_leg_ignore()
- if(ko || resting || stunned || chokehold)
- drop_all_held_items()
- unset_machine()
- if(pulling)
- stop_pulling()
- else if(has_legs || ignore_legs)
- lying = 0
-
- if(buckled)
- lying = 90*buckle_lying
- else if(!lying)
- if(resting)
- fall()
- else if(ko || (!has_legs && !ignore_legs) || chokehold)
- fall(forced = 1)
- canmove = !(ko || resting || stunned || chokehold || buckled || (!has_legs && !ignore_legs && !has_arms))
- density = !lying
- if(lying)
- if(layer == initial(layer)) //to avoid special cases like hiding larvas.
- layer = LYING_MOB_LAYER //so mob lying always appear behind standing mobs
- else
- if(layer == LYING_MOB_LAYER)
- layer = initial(layer)
- update_transform()
- update_action_buttons_icon(status_only=TRUE)
- if(isliving(src))
- var/mob/living/L = src
- if(L.has_status_effect(/datum/status_effect/freon))
- canmove = 0
- if(!lying && lying_prev)
- if(client)
- client.move_delay = world.time + movement_delay()
- lying_prev = lying
- return canmove
-
-
/mob/proc/fall(forced)
drop_all_held_items()
@@ -955,12 +905,12 @@
GLOB.dead_mob_list += src
. = ..()
switch(var_name)
- if("weakened")
- SetWeakened(var_value)
- if("stunned")
- SetStunned(var_value)
- if("paralysis")
- SetParalysis(var_value)
+ if("knockdown")
+ SetKnockdown(var_value)
+ if("stun")
+ SetStun(var_value)
+ if("unconscious")
+ SetUnconscious(var_value)
if("sleeping")
SetSleeping(var_value)
if("eye_blind")
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 20d98027c7d..8e94cbfc193 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -48,7 +48,6 @@
var/real_name = null
var/druggy = 0 //Carbon
var/confused = 0 //Carbon
- var/sleeping = 0 //Carbon
var/resting = 0 //Carbon
var/lying = 0
var/lying_prev = 0
@@ -69,9 +68,8 @@
var/satiety = 0//Carbon
var/overeatduration = 0 // How long this guy is overeating //Carbon
- var/paralysis = 0
- var/stunned = 0
- var/weakened = 0
+ var/unconscious = 0
+ var/knockdown = 0
var/losebreath = 0//Carbon
var/a_intent = INTENT_HELP//Living
var/list/possible_a_intents = null//Living
@@ -124,7 +122,7 @@
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
- var/status_flags = CANSTUN|CANWEAKEN|CANPARALYSE|CANPUSH //bitflags defining which status effects can be inflicted (replaces canweaken, canstun, etc)
+ var/status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH //bitflags defining which status effects can be inflicted (replaces canknockdown, canstun, etc)
var/digitalcamo = 0 // Can they be tracked by the AI?
var/digitalinvis = 0 //Are they ivisible to the AI?
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 5a9596792ce..765b7fb8376 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -109,10 +109,12 @@
mob.control_object.loc = get_step(mob.control_object,direct)
return
-
+#define MOVEMENT_DELAY_BUFFER 0.75
+#define MOVEMENT_DELAY_BUFFER_DELTA 1.25
/client/Move(n, direct)
if(world.time < move_delay)
return 0
+ var/old_move_delay = move_delay
move_delay = world.time+world.tick_lag //this is here because Move() can now be called mutiple times per tick
if(!mob || !mob.loc)
return 0
@@ -159,7 +161,11 @@
//We are now going to move
moving = 1
- move_delay = mob.movement_delay() + world.time
+ var/delay = mob.movement_delay()
+ if (old_move_delay + (delay*MOVEMENT_DELAY_BUFFER_DELTA) + MOVEMENT_DELAY_BUFFER > world.time)
+ move_delay = old_move_delay + delay
+ else
+ move_delay = delay + world.time
if(mob.confused)
if(mob.confused > 40)
@@ -178,11 +184,18 @@
if(mob.throwing)
mob.throwing.finalize(FALSE)
- for(var/obj/O in mob.contents|mob.held_items)
- O.on_mob_move(direct, src)
-
return .
+/mob/Moved(oldLoc, dir)
+ . = ..()
+ for(var/obj/O in contents)
+ O.on_mob_move(dir, src, oldLoc)
+
+/mob/setDir(newDir)
+ . = ..()
+ for(var/obj/O in contents)
+ O.on_mob_turn(newDir, src)
+
///Process_Grab()
///Called by client/Move()
diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm
index f12e7d6d4e5..1a403072b2d 100644
--- a/code/modules/mob/status_procs.dm
+++ b/code/modules/mob/status_procs.dm
@@ -1,136 +1,190 @@
//Here are the procs used to modify status effects of a mob.
-//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness, ear damage,
+//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness, ear damage,
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, and NEARSIGHT disability.
-/////////////////////////////////// STUNNED ////////////////////////////////////
+#define STUN_TIME_MULTIPLIER 0.05 //temporary; multiplies input stun times by this, will be removed once stuns are status effects
-/mob/proc/Stun(amount, updating = 1, ignore_canstun = 0)
- if(status_flags & CANSTUN || ignore_canstun)
- stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun
- if(updating)
- update_canmove()
+/////////////////////////////////// STUN ////////////////////////////////////
+
+/mob/proc/IsStun() //non-living mobs shouldn't be stunned
+ return FALSE
+
+/mob/living/IsStun() //If we're stunned
+ return has_status_effect(STATUS_EFFECT_STUN)
+
+/mob/living/proc/AmountStun() //How many deciseconds remain in our stun
+ var/datum/status_effect/incapacitating/stun/S = IsStun()
+ if(S)
+ return S.duration - world.time
+ return 0
+
+/mob/living/proc/Stun(amount, updating = TRUE, ignore_canstun = FALSE) //Can't go below remaining duration
+ if((status_flags & CANSTUN) || ignore_canstun)
+ var/datum/status_effect/incapacitating/stun/S = IsStun()
+ if(S)
+ var/remaining_duration = world.time - S.duration
+ S.duration = world.time + max(amount, remaining_duration)
+ else if(amount > 0)
+ S = apply_status_effect(STATUS_EFFECT_STUN)
+ S.duration = amount
+ S.update_canmove = updating
+ return S
+
+/mob/living/proc/SetStun(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
+ if((status_flags & CANSTUN) || ignore_canstun)
+ var/datum/status_effect/incapacitating/stun/S = IsStun()
+ if(amount <= 0)
+ if(S)
+ S.update_canmove = updating
+ qdel(S)
+ else if(S)
+ S.duration = world.time + amount
+ else
+ S = apply_status_effect(STATUS_EFFECT_STUN)
+ S.duration = amount
+ S.update_canmove = updating
+ return S
+
+/mob/living/proc/AdjustStun(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
+ if((status_flags & CANSTUN) || ignore_canstun)
+ var/datum/status_effect/incapacitating/stun/S = IsStun()
+ if(S)
+ S.duration += amount
+ else if(amount > 0)
+ S = apply_status_effect(STATUS_EFFECT_STUN)
+ S.duration = amount
+ S.update_canmove = updating
+ return S
+
+/////////////////////////////////// KNOCKDOWN ////////////////////////////////////
+
+/mob/proc/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE)
+ if((status_flags & CANKNOCKDOWN) || ignore_canknockdown)
+ knockdown = max(max(knockdown,amount * STUN_TIME_MULTIPLIER),0)
return TRUE
-/mob/proc/SetStunned(amount, updating = 1, ignore_canstun = 0) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned"
- if(status_flags & CANSTUN || ignore_canstun)
- stunned = max(amount,0)
- if(updating)
- update_canmove()
+/mob/living/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE)
+ . = ..()
+ if(. && updating)
+ update_canmove() //updates lying, canmove and icons
+
+/mob/proc/SetKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE)
+ if(status_flags & CANKNOCKDOWN || ignore_canknockdown)
+ knockdown = max(amount * STUN_TIME_MULTIPLIER,0)
return TRUE
-/mob/proc/AdjustStunned(amount, updating = 1, ignore_canstun = 0)
- if(status_flags & CANSTUN || ignore_canstun)
- stunned = max(stunned + amount,0)
- if(updating)
- update_canmove()
+/mob/living/SetKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE)
+ . = ..()
+ if(. && updating)
+ update_canmove() //updates lying, canmove and icons
+
+/mob/proc/AdjustKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE)
+ if((status_flags & CANKNOCKDOWN) || ignore_canknockdown)
+ knockdown = max(knockdown + (amount * STUN_TIME_MULTIPLIER) ,0)
return TRUE
-/////////////////////////////////// WEAKENED ////////////////////////////////////
+/mob/living/AdjustKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE)
+ . = ..()
+ if(. && updating)
+ update_canmove() //updates lying, canmove and icons
-/mob/proc/Weaken(amount, updating = 1, ignore_canweaken = 0)
- if((status_flags & CANWEAKEN) || ignore_canweaken)
- weakened = max(max(weakened,amount),0)
- if(updating)
- update_canmove() //updates lying, canmove and icons
- return TRUE
+/////////////////////////////////// UNCONSCIOUS ////////////////////////////////////
-/mob/proc/SetWeakened(amount, updating = 1, ignore_canweaken = 0)
- if(status_flags & CANWEAKEN)
- weakened = max(amount,0)
- if(updating)
- update_canmove() //updates lying, canmove and icons
- return TRUE
-
-/mob/proc/AdjustWeakened(amount, updating = 1, ignore_canweaken = 0)
- if((status_flags & CANWEAKEN) || ignore_canweaken)
- weakened = max(weakened + amount,0)
- if(updating)
- update_canmove() //updates lying, canmove and icons
- return TRUE
-
-/////////////////////////////////// PARALYSIS ////////////////////////////////////
-
-/mob/proc/Paralyse(amount, updating = 1, ignore_canparalyse = 0)
- if(status_flags & CANPARALYSE || ignore_canparalyse)
- var/old_paralysis = paralysis
- paralysis = max(max(paralysis,amount),0)
- if((!old_paralysis && paralysis) || (old_paralysis && !paralysis))
+/mob/proc/Unconscious(amount, updating = TRUE, ignore_canunconscious = FALSE)
+ if(status_flags & CANUNCONSCIOUS || ignore_canunconscious)
+ var/old_unconscious = unconscious
+ unconscious = max(max(unconscious,amount * STUN_TIME_MULTIPLIER),0)
+ if((!old_unconscious && unconscious) || (old_unconscious && !unconscious))
if(updating)
update_stat()
return TRUE
-/mob/proc/SetParalysis(amount, updating = 1, ignore_canparalyse = 0)
- if(status_flags & CANPARALYSE || ignore_canparalyse)
- var/old_paralysis = paralysis
- paralysis = max(amount,0)
- if((!old_paralysis && paralysis) || (old_paralysis && !paralysis))
+/mob/proc/SetUnconscious(amount, updating = TRUE, ignore_canunconscious = FALSE)
+ if(status_flags & CANUNCONSCIOUS || ignore_canunconscious)
+ var/old_unconscious = unconscious
+ unconscious = max(amount * STUN_TIME_MULTIPLIER,0)
+ if((!old_unconscious && unconscious) || (old_unconscious && !unconscious))
if(updating)
update_stat()
return TRUE
-/mob/proc/AdjustParalysis(amount, updating = 1, ignore_canparalyse = 0)
- if(status_flags & CANPARALYSE || ignore_canparalyse)
- var/old_paralysis = paralysis
- paralysis = max(paralysis + amount,0)
- if((!old_paralysis && paralysis) || (old_paralysis && !paralysis))
+/mob/proc/AdjustUnconscious(amount, updating = TRUE, ignore_canunconscious = FALSE)
+ if(status_flags & CANUNCONSCIOUS || ignore_canunconscious)
+ var/old_unconscious = unconscious
+ unconscious = max(unconscious + (amount * STUN_TIME_MULTIPLIER) ,0)
+ if((!old_unconscious && unconscious) || (old_unconscious && !unconscious))
if(updating)
update_stat()
return TRUE
/////////////////////////////////// SLEEPING ////////////////////////////////////
-/mob/proc/Sleeping(amount, updating = 1, no_alert = FALSE)
- var/old_sleeping = sleeping
- sleeping = max(max(sleeping,amount),0)
- if(!old_sleeping && sleeping)
- if(!no_alert)
- throw_alert("asleep", /obj/screen/alert/asleep)
- if(updating)
- update_stat()
- else if(old_sleeping && !sleeping)
- clear_alert("asleep")
- if(updating)
- update_stat()
+/mob/living/proc/IsSleeping() //If we're asleep
+ return has_status_effect(STATUS_EFFECT_SLEEPING)
-/mob/proc/SetSleeping(amount, updating = 1, no_alert = FALSE)
- var/old_sleeping = sleeping
- sleeping = max(amount,0)
- if(!old_sleeping && sleeping)
- if(!no_alert)
- throw_alert("asleep", /obj/screen/alert/asleep)
- if(updating)
- update_stat()
- else if(old_sleeping && !sleeping)
- clear_alert("asleep")
- if(updating)
- update_stat()
+/mob/living/proc/AmountSleeping() //How many deciseconds remain in our sleep
+ var/datum/status_effect/incapacitating/sleeping/S = IsSleeping()
+ if(S)
+ return S.duration - world.time
+ return 0
-/mob/proc/AdjustSleeping(amount, updating = 1, no_alert = FALSE)
- var/old_sleeping = sleeping
- sleeping = max(sleeping + amount,0)
- if(!old_sleeping && sleeping)
- if(!no_alert)
- throw_alert("asleep", /obj/screen/alert/asleep)
- if(updating)
- update_stat()
- else if(old_sleeping && !sleeping)
- clear_alert("asleep")
- if(updating)
- update_stat()
+/mob/living/proc/Sleeping(amount, updating = TRUE) //Can't go below remaining duration
+ var/datum/status_effect/incapacitating/sleeping/S = IsSleeping()
+ if(S)
+ var/remaining_duration = world.time - S.duration
+ S.duration = world.time + max(amount, remaining_duration)
+ else if(amount > 0)
+ S = apply_status_effect(STATUS_EFFECT_SLEEPING)
+ S.duration = amount
+ S.update_canmove = updating
+ return S
+
+/mob/living/proc/SetSleeping(amount, updating = TRUE) //Sets remaining duration
+ var/datum/status_effect/incapacitating/sleeping/S = IsSleeping()
+ if(amount <= 0)
+ if(S)
+ S.update_canmove = updating
+ qdel(S)
+ else if(S)
+ S.duration = world.time + amount
+ else
+ S = apply_status_effect(STATUS_EFFECT_SLEEPING)
+ S.duration = amount
+ S.update_canmove = updating
+ return S
+
+/mob/living/proc/AdjustSleeping(amount, updating = TRUE) //Adds to remaining duration
+ var/datum/status_effect/incapacitating/sleeping/S = IsSleeping()
+ if(S)
+ S.duration += amount
+ else if(amount > 0)
+ S = apply_status_effect(STATUS_EFFECT_SLEEPING)
+ S.duration = amount
+ S.update_canmove = updating
+ return S
/////////////////////////////////// RESTING ////////////////////////////////////
/mob/proc/Resting(amount)
resting = max(max(resting,amount),0)
+
+/mob/living/Resting(amount)
+ ..()
update_canmove()
/mob/proc/SetResting(amount)
resting = max(amount,0)
+
+/mob/living/SetResting(amount)
+ ..()
update_canmove()
/mob/proc/AdjustResting(amount)
resting = max(resting + amount,0)
+
+/mob/living/AdjustResting(amount)
+ ..()
update_canmove()
/////////////////////////////////// JITTERINESS ////////////////////////////////////
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index f91a6cd5538..36134db7867 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -31,7 +31,7 @@
//Make mob invisible and spawn animation
notransform = 1
canmove = 0
- stunned = 1
+ Stun(22, ignore_canstun = TRUE)
icon = null
cut_overlays()
invisibility = INVISIBILITY_MAXIMUM
@@ -182,7 +182,7 @@
//Make mob invisible and spawn animation
notransform = 1
canmove = 0
- stunned = 1
+ Stun(22, ignore_canstun = TRUE)
icon = null
cut_overlays()
invisibility = INVISIBILITY_MAXIMUM
diff --git a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm
index c4ef258ae38..939276c4c96 100644
--- a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm
+++ b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm
@@ -62,7 +62,7 @@
/datum/ntnet_conversation/proc/change_title(newtitle, datum/computer_file/program/chatclient/client)
if(operator != client)
- return 0 // Not Authorised
+ return FALSE // Not Authorised
add_status_message("[client.username] has changed channel title from [title] to [newtitle]")
title = newtitle
diff --git a/code/modules/modular_computers/NTNet/NTNet.dm b/code/modules/modular_computers/NTNet/NTNet.dm
index 033b32d6afe..126f5edb112 100644
--- a/code/modules/modular_computers/NTNet/NTNet.dm
+++ b/code/modules/modular_computers/NTNet/NTNet.dm
@@ -53,7 +53,7 @@ GLOBAL_DATUM_INIT(ntnet_global, /datum/ntnet, new)
// Checks whether NTNet operates. If parameter is passed checks whether specific function is enabled.
/datum/ntnet/proc/check_function(specific_action = 0)
if(!relays || !relays.len) // No relays found. NTNet is down
- return 0
+ return FALSE
var/operating = 0
@@ -65,7 +65,7 @@ GLOBAL_DATUM_INIT(ntnet_global, /datum/ntnet, new)
break
if(setting_disabled)
- return 0
+ return FALSE
switch(specific_action)
if(NTNET_SOFTWAREDOWNLOAD)
@@ -120,7 +120,7 @@ GLOBAL_DATUM_INIT(ntnet_global, /datum/ntnet, new)
// Updates maximal amount of stored logs. Use this instead of setting the number, it performs required checks.
/datum/ntnet/proc/update_max_log_count(lognumber)
if(!lognumber)
- return 0
+ return FALSE
// Trim the value if necessary
lognumber = max(MIN_NTNET_LOGS, min(lognumber, MAX_NTNET_LOGS))
setting_maxlogcount = lognumber
diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm
index 32513d0405c..c365b70b8a5 100644
--- a/code/modules/modular_computers/computers/item/computer.dm
+++ b/code/modules/modular_computers/computers/item/computer.dm
@@ -43,18 +43,22 @@
var/list/idle_threads // Idle programs on background. They still receive process calls but can't be interacted with.
var/obj/physical = null // Object that represents our computer. It's used for Adjacent() and UI visibility checks.
+ var/has_light = FALSE //If the computer has a flashlight/LED light/what-have-you installed
+ var/light_on = FALSE //If that light is enabled
+ var/comp_light_luminosity = 3 //The brightness of that light
+ var/comp_light_color //The color of that light
-/obj/item/device/modular_computer/New()
+/obj/item/device/modular_computer/Initialize()
+ . = ..()
START_PROCESSING(SSobj, src)
- update_icon()
if(!physical)
physical = src
- ..()
-
+ comp_light_color = "#FFFFFF"
all_components = list()
idle_threads = list()
+ update_icon()
/obj/item/device/modular_computer/Destroy()
kill_program(forced = TRUE)
diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm
index 5aadc31bb40..ec36bc6484b 100644
--- a/code/modules/modular_computers/computers/item/computer_ui.dm
+++ b/code/modules/modular_computers/computers/item/computer_ui.dm
@@ -50,6 +50,9 @@
data["programs"] += list(list("name" = P.filename, "desc" = P.filedesc, "running" = running))
+ data["has_light"] = has_light
+ data["light_on"] = light_on
+ data["comp_light_color"] = comp_light_color
return data
@@ -128,6 +131,27 @@
active_program = P
update_icon()
return 1
+
+ if("PC_toggle_light")
+ light_on = !light_on
+ if(light_on)
+ set_light(comp_light_luminosity, 1, comp_light_color)
+ else
+ set_light(0)
+
+ if("PC_light_color")
+ var/mob/user = usr
+ var/new_color
+ while(!new_color)
+ new_color = input(user, "Choose a new color for [src]'s flashlight.", "Light Color") as null|color
+ if(!new_color)
+ return
+ if(color_hex2num(new_color) < 200) //Colors too dark are rejected
+ to_chat(user, "That color is too dark! Choose a lighter one.")
+ new_color = null
+ comp_light_color = new_color
+ light_color = new_color
+ update_light()
else
return
diff --git a/code/modules/modular_computers/computers/item/tablet.dm b/code/modules/modular_computers/computers/item/tablet.dm
index 6a2b5674a5b..39fd8fae61b 100644
--- a/code/modules/modular_computers/computers/item/tablet.dm
+++ b/code/modules/modular_computers/computers/item/tablet.dm
@@ -9,4 +9,6 @@
max_hardware_size = 1
w_class = WEIGHT_CLASS_SMALL
steel_sheet_cost = 1
- slot_flags = SLOT_ID | SLOT_BELT
\ No newline at end of file
+ slot_flags = SLOT_ID | SLOT_BELT
+ has_light = TRUE //LED flashlight!
+ comp_light_luminosity = 2.3 //Same as the PDA
diff --git a/code/modules/modular_computers/file_system/programs/card.dm b/code/modules/modular_computers/file_system/programs/card.dm
index 74590339b42..5eab5f5c43b 100644
--- a/code/modules/modular_computers/file_system/programs/card.dm
+++ b/code/modules/modular_computers/file_system/programs/card.dm
@@ -41,6 +41,9 @@
/datum/computer_file/program/card_mod/New()
..()
+ addtimer(CALLBACK(src, .proc/SetConfigCooldown), 0)
+
+/datum/computer_file/program/card_mod/proc/SetConfigCooldown()
change_position_cooldown = config.id_console_jobslot_delay
/datum/computer_file/program/card_mod/event_idremoved(background, slot)
diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm
index e1c378f9f3d..71f81663392 100644
--- a/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm
+++ b/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm
@@ -4,9 +4,9 @@
if(!ninjacost(0,N_ADRENALINE))//Have to make sure stat is not counted for this ability.
var/mob/living/carbon/human/H = affecting
- H.SetParalysis(0)
- H.SetStunned(0)
- H.SetWeakened(0)
+ H.SetUnconscious(0)
+ H.SetStun(0)
+ H.SetKnockdown(0)
spawn(30)//Slight delay so the enemy does not immedietly know the ability was used. Due to lag, this often came before waking up.
H.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!"))
diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm
index 48e3cf69a97..ea96c1cdf61 100644
--- a/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm
+++ b/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm
@@ -5,6 +5,6 @@
if(!ninjacost(250,N_STEALTH_CANCEL))
var/mob/living/carbon/human/H = affecting
- playsound(H.loc, 'sound/effects/EMPulse.ogg', 60, 2)
+ playsound(H.loc, 'sound/effects/empulse.ogg', 60, 2)
empulse(H, 4, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch.
s_coold = 2
diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm
index 74dcec12ce8..cc865e473ec 100644
--- a/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm
+++ b/code/modules/ninja/suit/n_suit_verbs/ninja_teleporting.dm
@@ -37,7 +37,7 @@ Contents:
playsound(H.loc, "sparks", 50, 1)
new /obj/effect/temp_visual/dir_setting/ninja/phase(get_turf(H), H.dir)
- destination.phase_damage_creatures(20,H)//Paralyse and damage mobs and mechas on the turf
+ destination.phase_damage_creatures(20,H)//Stun and damage mobs and mechas on the turf
s_coold = 1
else
to_chat(H, "The VOID-shift device is malfunctioning, teleportation failed.")
@@ -65,7 +65,7 @@ Contents:
playsound(H.loc, "sparks", 50, 1)
new /obj/effect/temp_visual/dir_setting/ninja/phase(get_turf(H), H.dir)
- T.phase_damage_creatures(20,H)//Paralyse and damage mobs and mechas on the turf
+ T.phase_damage_creatures(20,H)//Stun and damage mobs and mechas on the turf
s_coold = 1
else
to_chat(H, "You cannot teleport into solid walls or from solid matter")
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index f985099219d..8f6da4a5829 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -214,7 +214,7 @@
t = replacetext(t, "\[list\]", "
")
t = replacetext(t, "\[/list\]", "
")
- t = "[t]"
+ t = "[t]"
else // If it is a crayon, and he still tries to use these, make them empty!
var/obj/item/toy/crayon/C = P
t = replacetext(t, "\[*\]", "")
@@ -379,10 +379,19 @@
/obj/item/weapon/paper/construction
-/obj/item/weapon/paper/construction/New()
- ..()
+/obj/item/weapon/paper/construction/Initialize()
+ . = ..()
color = pick("FF0000", "#33cc33", "#ffb366", "#551A8B", "#ff80d5", "#4d94ff")
+/*
+ * Natural paper
+ */
+
+/obj/item/weapon/paper/natural/Initialize()
+ . = ..()
+ color = "#FFF5ED"
+
+
/*
* Premade paper
*/
@@ -393,7 +402,7 @@
/obj/item/weapon/paper/Toxin
name = "paper- 'Chemical Information'"
- info = "Known Onboard Toxins: \n\tGrade A Semi-Liquid Plasma: \n\t\tHighly poisonous. You cannot sustain concentrations above 15 units. \n\t\tA gas mask fails to filter plasma after 50 units. \n\t\tWill attempt to diffuse like a gas. \n\t\tFiltered by scrubbers. \n\t\tThere is a bottled version which is very different \n\t\t\tfrom the version found in canisters! \n \n\t\tWARNING: Highly Flammable. Keep away from heat sources \n\t\texcept in a enclosed fire area! \n\t\tWARNING: It is a crime to use this without authorization. \nKnown Onboard Anti-Toxin: \n\tAnti-Toxin Type 01P: Works against Grade A Plasma. \n\t\tBest if injected directly into bloodstream. \n\t\tA full injection is in every regular Med-Kit. \n\t\tSpecial toxin Kits hold around 7. \n \nKnown Onboard Chemicals (other): \n\tRejuvenation T#001: \n\t\tEven 1 unit injected directly into the bloodstream \n\t\t\twill cure paralysis and sleep toxins. \n\t\tIf administered to a dying patient it will prevent \n\t\t\tfurther damage for about units*3 seconds. \n\t\t\tit will not cure them or allow them to be cured. \n\t\tIt can be administeredd to a non-dying patient \n\t\t\tbut the chemicals disappear just as fast. \n\tMorphine T#054: \n\t\t5 units wilkl induce precisely 1 minute of sleep. \n\t\t\tThe effect are cumulative. \n\t\tWARNING: It is a crime to use this without authorization"
+ info = "Known Onboard Toxins: \n\tGrade A Semi-Liquid Plasma: \n\t\tHighly poisonous. You cannot sustain concentrations above 15 units. \n\t\tA gas mask fails to filter plasma after 50 units. \n\t\tWill attempt to diffuse like a gas. \n\t\tFiltered by scrubbers. \n\t\tThere is a bottled version which is very different \n\t\t\tfrom the version found in canisters! \n \n\t\tWARNING: Highly Flammable. Keep away from heat sources \n\t\texcept in a enclosed fire area! \n\t\tWARNING: It is a crime to use this without authorization. \nKnown Onboard Anti-Toxin: \n\tAnti-Toxin Type 01P: Works against Grade A Plasma. \n\t\tBest if injected directly into bloodstream. \n\t\tA full injection is in every regular Med-Kit. \n\t\tSpecial toxin Kits hold around 7. \n \nKnown Onboard Chemicals (other): \n\tRejuvenation T#001: \n\t\tEven 1 unit injected directly into the bloodstream \n\t\t\twill cure unconscious and sleep toxins. \n\t\tIf administered to a dying patient it will prevent \n\t\t\tfurther damage for about units*3 seconds. \n\t\t\tit will not cure them or allow them to be cured. \n\t\tIt can be administeredd to a non-dying patient \n\t\t\tbut the chemicals disappear just as fast. \n\tMorphine T#054: \n\t\t5 units wilkl induce precisely 1 minute of sleep. \n\t\t\tThe effect are cumulative. \n\t\tWARNING: It is a crime to use this without authorization"
/obj/item/weapon/paper/courtroom
name = "paper- 'A Crash Course in Legal SOP on SS13'"
diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm
index ceb7488295f..57a79fefe86 100644
--- a/code/modules/paperwork/paperbin.dm
+++ b/code/modules/paperwork/paperbin.dm
@@ -141,4 +141,34 @@
name = "construction paper bin"
desc = "Contains all the paper you'll never need, IN COLOR!"
icon_state = "paper_binc"
- papertype = /obj/item/weapon/paper/construction
\ No newline at end of file
+ papertype = /obj/item/weapon/paper/construction
+
+/obj/item/weapon/paper_bin/bundlenatural
+ name = "natural paper bundle"
+ desc = "A bundle of paper created using traditional methods."
+ icon_state = "paper_bundle"
+ papertype = /obj/item/weapon/paper/natural
+ resistance_flags = FLAMMABLE
+/obj/item/weapon/paper_bin/bundlenatural/attack_hand(mob/user)
+ ..()
+ if(total_paper < 1)
+ qdel(src)
+/obj/item/weapon/paper_bin/bundlenatural/fire_act(exposed_temperature, exposed_volume)
+ qdel(src)
+/obj/item/weapon/paper_bin/bundlenatural/attackby(obj/item/weapon/W, mob/user)
+ if(W.is_sharp())
+ to_chat(user, "You snip \the [src], spilling paper everywhere.")
+ var/turf/T = get_turf(src.loc)
+ while(total_paper > 0)
+ total_paper--
+ var/obj/item/weapon/paper/P
+ if(papers.len > 0)
+ P = papers[papers.len]
+ papers -= P
+ else
+ P = new papertype()
+ P.forceMove(T)
+ CHECK_TICK
+ qdel(src)
+ else
+ ..()
\ No newline at end of file
diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm
index 2514784bcb5..473f1620feb 100644
--- a/code/modules/paperwork/paperplane.dm
+++ b/code/modules/paperwork/paperplane.dm
@@ -20,6 +20,7 @@
if(newPaper)
internalPaper = newPaper
flags = newPaper.flags
+ color = newPaper.color
newPaper.forceMove(src)
else
internalPaper = new /obj/item/weapon/paper(src)
@@ -31,8 +32,8 @@
internalPaper = null
return ..()
-/obj/item/weapon/paperplane/suicide_act(mob/user)
- user.Stun(10)
+/obj/item/weapon/paperplane/suicide_act(mob/living/user)
+ user.Stun(200)
user.visible_message("[user] jams the [src] in [user.p_their()] nose. It looks like [user.p_theyre()] trying to commit suicide!")
user.adjust_blurriness(6)
user.adjust_eye_damage(rand(6,8))
@@ -95,7 +96,7 @@
visible_message("\The [src] hits [H] in the eye!")
H.adjust_blurriness(6)
H.adjust_eye_damage(rand(6,8))
- H.Weaken(2)
+ H.Knockdown(40)
H.emote("scream")
/obj/item/weapon/paper/AltClick(mob/living/carbon/user, obj/item/I)
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index 3b691720e2a..5f5a8b32d55 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -26,6 +26,7 @@
var/colour = "black" //what colour the ink is!
var/traitor_unlock_degrees = 0
var/degrees = 0
+ var/font = PEN_FONT
/obj/item/weapon/pen/suicide_act(mob/user)
user.visible_message("[user] is scribbling numbers all over [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit sudoku...")
@@ -64,6 +65,34 @@
to_chat(user, "\The [src] will now write in [colour].")
desc = "It's a fancy four-color ink pen, set to [colour]."
+/obj/item/weapon/pen/fountain
+ name = "fountain pen"
+ desc = "It's a common fountain pen, with a faux wood body."
+ icon_state = "pen-fountain"
+ font = FOUNTAIN_PEN_FONT
+
+/obj/item/weapon/pen/fountain/captain
+ name = "captain's fountain pen"
+ desc = "It's an expensive Oak fountain pen. The nib is quite sharp."
+ icon_state = "pen-fountain-o"
+ force = 5
+ throwforce = 5
+ throw_speed = 4
+ colour = "crimson"
+ materials = list(MAT_GOLD = 750)
+ sharpness = IS_SHARP
+ resistance_flags = FIRE_PROOF
+ unique_reskin = list("Oak" = "pen-fountain-o",
+ "Gold" = "pen-fountain-g",
+ "Rosewood" = "pen-fountain-r",
+ "Black and Silver" = "pen-fountain-b",
+ "Command Blue" = "pen-fountain-cb"
+ )
+
+/obj/item/weapon/pen/fountain/captain/reskin_obj(mob/M)
+ ..()
+ if(current_skin)
+ desc = "It's an expensive [current_skin] fountain pen. The nib is quite sharp."
/obj/item/weapon/pen/attack_self(mob/living/carbon/user)
var/deg = input(user, "What angle would you like to rotate the pen head to? (1-360)", "Rotate Pen Head") as null|num
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
index 4abed75967a..608680c2105 100644
--- a/code/modules/paperwork/photocopier.dm
+++ b/code/modules/paperwork/photocopier.dm
@@ -171,7 +171,7 @@
var/icon/small_img = icon(temp_img) //Icon() is needed or else temp_img will be rescaled too >.>
var/icon/ic = icon('icons/obj/items.dmi',"photo")
small_img.Scale(8, 8)
- ic.Blend(small_img,ICON_OVERLAY, 10, 13)
+ ic.Blend(small_img,ICON_OVERLAY, 13, 13)
p.icon = ic
toner -= 5
busy = 1
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index e9fe951f62c..a6e27d06334 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -533,7 +533,6 @@
cut_overlays()
if(displayed)
add_overlay(getFlatIcon(displayed))
- add_overlay("frame-overlay")
/obj/item/wallframe/picture/after_attach(obj/O)
..()
@@ -572,7 +571,7 @@
to_chat(user, "You start unsecuring [name]...")
playsound(loc, I.usesound, 50, 1)
if(do_after(user, 30*I.toolspeed, target = src))
- playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(loc, 'sound/items/deconstruct.ogg', 50, 1)
to_chat(user, "You unsecure [name].")
deconstruct()
return
@@ -591,13 +590,12 @@
/obj/structure/sign/picture_frame/attack_hand(mob/user)
if(framed)
- framed.show()
+ framed.show(user)
/obj/structure/sign/picture_frame/update_icon()
cut_overlays()
if(framed)
add_overlay(getFlatIcon(framed))
- add_overlay("frame-overlay")
/obj/structure/sign/picture_frame/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm
index acb9bb632f3..8ebb7e7f9bf 100644
--- a/code/modules/power/antimatter/control.dm
+++ b/code/modules/power/antimatter/control.dm
@@ -201,7 +201,7 @@
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
if(sound_effect)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
else
return
if(damage >= 20)
diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm
index 8bdc5c1015c..40b1d43955d 100644
--- a/code/modules/power/antimatter/shielding.dm
+++ b/code/modules/power/antimatter/shielding.dm
@@ -150,7 +150,7 @@
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
if(sound_effect)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
else
return
if(damage_amount >= 10)
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index bdf720b50f6..337224dec9d 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -493,7 +493,7 @@
return
user.visible_message("[user.name] adds cables to the APC frame.", \
"You start adding cables to the APC frame...")
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
if(do_after(user, 20, target = src))
if (C.get_amount() < 10 || !C)
return
@@ -521,7 +521,7 @@
user.visible_message("[user.name] inserts the power control board into [src].", \
"You start to insert the power control board into the frame...")
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
if(do_after(user, 10, target = src))
if(has_electronics==0)
has_electronics = 1
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index 8ab42aebe7a..69d705012cf 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -33,7 +33,7 @@ By design, d1 is the smallest direction and d2 is the highest
icon_state = "0-1"
var/d1 = 0 // cable direction 1 (see above)
var/d2 = 1 // cable direction 2 (see above)
- layer = WIRE_LAYER //Above pipes, which are at GAS_PIPE_LAYER
+ layer = WIRE_LAYER //Above hidden pipes, GAS_PIPE_HIDDEN_LAYER
var/cable_color = "red"
var/obj/item/stack/cable_coil/stored
@@ -509,6 +509,10 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
slot_flags = SLOT_BELT
attack_verb = list("whipped", "lashed", "disciplined", "flogged")
singular_name = "cable piece"
+ full_w_class = WEIGHT_CLASS_SMALL
+
+/obj/item/stack/cable_coil/one
+ amount = 1
/obj/item/stack/cable_coil/cyborg
is_cyborg = 1
diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm
index b3577756f07..6c31a57afd8 100644
--- a/code/modules/power/gravitygenerator.dm
+++ b/code/modules/power/gravitygenerator.dm
@@ -201,7 +201,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
var/obj/item/weapon/weldingtool/WT = I
if(WT.remove_fuel(1, user))
to_chat(user, "You mend the damaged framework.")
- playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/welder2.ogg', 50, 1)
broken_state++
update_icon()
else if(WT.isOn())
@@ -339,7 +339,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
charge_count -= 2
if(charge_count % 4 == 0 && prob(75)) // Let them know it is charging/discharging.
- playsound(src.loc, 'sound/effects/EMPulse.ogg', 100, 1)
+ playsound(src.loc, 'sound/effects/empulse.ogg', 100, 1)
updateDialog()
if(prob(25)) // To help stop "Your clothes feel warm." spam.
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 133fad1b4d8..5985555614e 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -78,7 +78,7 @@
new /obj/item/stack/sheet/metal( get_turf(src.loc), sheets_refunded )
user.visible_message("[user.name] deconstructs [src].", \
"You deconstruct [src].", "You hear a ratchet.")
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 75, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 75, 1)
qdel(src)
return
@@ -407,9 +407,9 @@
if(LIGHT_BROKEN)
playsound(loc, 'sound/effects/hit_on_shattered_glass.ogg', 90, 1)
else
- playsound(loc, 'sound/effects/Glasshit.ogg', 90, 1)
+ playsound(loc, 'sound/effects/glasshit.ogg', 90, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
// returns whether this light has power
@@ -519,7 +519,7 @@
if(!skip_sound_and_sparks)
if(status == LIGHT_OK || status == LIGHT_BURNED)
- playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
+ playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1)
if(on)
do_sparks(3, TRUE, src)
status = LIGHT_BROKEN
@@ -647,7 +647,7 @@
src.visible_message("[name] shatters.","You hear a small glass object shatter.")
status = LIGHT_BROKEN
force = 5
- playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
+ playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1)
update()
diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm
index f24c7fdd5fb..2d512be94b3 100644
--- a/code/modules/power/port_gen.dm
+++ b/code/modules/power/port_gen.dm
@@ -197,7 +197,7 @@
to_chat(user, "You unsecure the generator from the floor.")
anchored = 0
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
return
else if(istype(O, /obj/item/weapon/screwdriver))
panel_open = !panel_open
diff --git a/code/modules/power/rtg.dm b/code/modules/power/rtg.dm
index 53bcc0869b5..2dfdf014819 100644
--- a/code/modules/power/rtg.dm
+++ b/code/modules/power/rtg.dm
@@ -116,7 +116,7 @@
going_kaboom = TRUE
visible_message("\The [src] lets out an shower of sparks as it starts to lose stability!",\
"You hear a loud electrical crack!")
- playsound(src.loc, 'sound/magic/LightningShock.ogg', 100, 1, extrarange = 5)
+ playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
tesla_zap(src, 5, power_gen * 0.05)
addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, get_turf(src), 2, 3, 4, 8), 100) // Not a normal explosion.
diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm
index 10dc52c3c30..2e27604b58b 100644
--- a/code/modules/power/singularity/containment_field.dm
+++ b/code/modules/power/singularity/containment_field.dm
@@ -33,9 +33,9 @@
/obj/machinery/field/containment/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BURN)
- playsound(loc, 'sound/effects/EMPulse.ogg', 75, 1)
+ playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
if(BRUTE)
- playsound(loc, 'sound/effects/EMPulse.ogg', 75, 1)
+ playsound(loc, 'sound/effects/empulse.ogg', 75, 1)
/obj/machinery/field/containment/blob_act(obj/structure/blob/B)
return 0
@@ -101,13 +101,12 @@
var/shock_damage = min(rand(30,40),rand(30,40))
if(iscarbon(user))
- user.Stun(15)
- user.Weaken(10)
+ user.Knockdown(300)
user.electrocute_act(shock_damage, src, 1)
else if(issilicon(user))
if(prob(20))
- user.Stun(2)
+ user.Stun(40)
user.take_overall_damage(0, shock_damage)
user.visible_message("[user.name] was shocked by the [src.name]!", \
"Energy pulse detected, system damaged!", \
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index 5e9bc107a71..25b106e304e 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -1,6 +1,6 @@
/obj/machinery/power/emitter
- name = "Emitter"
- desc = "A heavy duty industrial laser.\nAlt-click to rotate it clockwise."
+ name = "emitter"
+ desc = "A heavy-duty industrial laser, often used in containment fields and power generation.\nAlt-click to rotate it clockwise."
icon = 'icons/obj/singularity.dmi'
icon_state = "emitter"
var/icon_state_on = "emitter_+a"
@@ -393,7 +393,7 @@
auto.Grant(M, src)
/datum/action/innate/protoemitter
- check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUNNED | AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS
var/obj/machinery/power/emitter/prototype/PE
var/mob/living/carbon/U
diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm
index a52d99bcccd..cd85b6fdf13 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/modules/power/singularity/narsie.dm
@@ -77,7 +77,7 @@
sleep(1150)
if(resolved == FALSE)
resolved = TRUE
- world << sound('sound/machines/Alarm.ogg')
+ world << sound('sound/machines/alarm.ogg')
addtimer(CALLBACK(GLOBAL_PROC, .proc/cult_ending_helper), 120)
addtimer(CALLBACK(GLOBAL_PROC, .proc/ending_helper), 220)
@@ -126,7 +126,7 @@
if(M.stat == CONSCIOUS)
if(!iscultist(M))
to_chat(M, "You feel conscious thought crumble away in an instant as you gaze upon [src.name]...")
- M.apply_effect(3, STUN)
+ M.apply_effect(60, STUN)
/obj/singularity/narsie/consume(atom/A)
diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm
index 56fc6c49856..50fd67a1c7f 100644
--- a/code/modules/power/singularity/singularity.dm
+++ b/code/modules/power/singularity/singularity.dm
@@ -419,7 +419,7 @@
to_chat(H, "You look directly into the [src.name], good thing you had your protective eyewear on!")
return
- M.apply_effect(3, STUN)
+ M.apply_effect(60, STUN)
M.visible_message("[M] stares blankly at the [src.name]!", \
"You look directly into the [src.name] and feel weak.")
return
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index 81d231cad9b..afc118ce52f 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -142,7 +142,7 @@
return
to_chat(user, "You start building the power terminal...")
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
if(do_after(user, 20, target = src) && C.get_amount() >= 10)
if(C.get_amount() < 10 || !C)
diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm
index 47e04339d49..0a4a01f2d5b 100644
--- a/code/modules/power/solar.dm
+++ b/code/modules/power/solar.dm
@@ -61,7 +61,7 @@
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
user.visible_message("[user] begins to take the glass off the solar panel.", "You begin to take the glass off the solar panel...")
if(do_after(user, 50*W.toolspeed, target = src))
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
user.visible_message("[user] takes the glass off the solar panel.", "You take the glass off the solar panel.")
deconstruct(TRUE)
else
@@ -73,14 +73,14 @@
if(stat & BROKEN)
playsound(loc, 'sound/effects/hit_on_shattered_glass.ogg', 60, 1)
else
- playsound(loc, 'sound/effects/Glasshit.ogg', 90, 1)
+ playsound(loc, 'sound/effects/glasshit.ogg', 90, 1)
if(BURN)
- playsound(loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(loc, 'sound/items/welder.ogg', 100, 1)
/obj/machinery/power/solar/obj_break(damage_flag)
if(!(stat & BROKEN) && !(flags & NODECONSTRUCT))
- playsound(loc, 'sound/effects/Glassbr3.ogg', 100, 1)
+ playsound(loc, 'sound/effects/glassbr3.ogg', 100, 1)
stat |= BROKEN
unset_control()
update_icon()
@@ -446,13 +446,13 @@
if(stat & BROKEN)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
else
- playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
+ playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1)
if(BURN)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
/obj/machinery/power/solar_control/obj_break(damage_flag)
if(!(stat & BROKEN) && !(flags & NODECONSTRUCT))
- playsound(loc, 'sound/effects/Glassbr3.ogg', 100, 1)
+ playsound(loc, 'sound/effects/glassbr3.ogg', 100, 1)
stat |= BROKEN
update_icon()
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index dea263231ac..245ce720b49 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -23,7 +23,8 @@
#define SEVERE_POWER_PENALTY_THRESHOLD 7000 //Same as above, but causes more dangerous effects
#define CRITICAL_POWER_PENALTY_THRESHOLD 9000 //Even more dangerous effects, threshold for tesla delamination
#define HEAT_PENALTY_THRESHOLD 40 //Higher == Crystal safe operational temperature is higher.
-#define DAMAGE_HARDCAP 0.01
+#define DAMAGE_HARDCAP 0.0025
+#define DAMAGE_INCREASE_MULTIPLIER 0.25
#define THERMAL_RELEASE_MODIFIER 5 //Higher == less heat released during reaction, not to be confused with the above values
@@ -168,7 +169,7 @@
var/turf/T = get_turf(src)
for(var/mob/M in GLOB.mob_list)
if(M.z == z)
- M << 'sound/magic/Charge.ogg'
+ M << 'sound/magic/charge.ogg'
to_chat(M, "You feel reality distort for a moment...")
if(combined_gas > MOLE_PENALTY_THRESHOLD)
investigate_log("has collapsed into a singularity.", INVESTIGATE_SUPERMATTER)
@@ -214,9 +215,9 @@
damage_archived = damage
if(takes_damage)
//causing damage
- damage = max(damage + (max(removed.temperature - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ), 0)
- damage = max(damage + (max(power - POWER_PENALTY_THRESHOLD, 0)/500), 0)
- damage = max(damage + (max(combined_gas - MOLE_PENALTY_THRESHOLD, 0)/80), 0)
+ damage = max(damage + (max(removed.temperature - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0)
+ damage = max(damage + (max(power - POWER_PENALTY_THRESHOLD, 0)/500) * DAMAGE_INCREASE_MULTIPLIER, 0)
+ damage = max(damage + (max(combined_gas - MOLE_PENALTY_THRESHOLD, 0)/80) * DAMAGE_INCREASE_MULTIPLIER, 0)
//healing damage
if(combined_gas < MOLE_PENALTY_THRESHOLD)
@@ -225,7 +226,7 @@
//capping damage
damage = min(damage_archived + (DAMAGE_HARDCAP * explosion_point),damage)
if(damage > damage_archived && prob(10))
- playsound(get_turf(src), 'sound/effects/EMPulse.ogg', 50, 1)
+ playsound(get_turf(src), 'sound/effects/empulse.ogg', 50, 1)
removed.assert_gases("o2", "plasma", "co2", "n2o", "n2", "freon")
//calculating gas related values
@@ -384,7 +385,7 @@
/obj/machinery/power/supermatter_shard/bullet_act(obj/item/projectile/Proj)
var/turf/L = loc
- if(!istype(L)) // We don't run process() when we are in space
+ if(!istype(L) || isspaceturf(L)) // We don't run process() when we are in space
return FALSE // This stops people from being able to really power up the supermatter
// Then bring it inside to explode instantly upon landing on a valid turf.
if(!istype(Proj.firer, /obj/machinery/power/emitter))
@@ -463,7 +464,14 @@
/obj/machinery/power/supermatter_shard/attackby(obj/item/W, mob/living/user, params)
if(!istype(W) || (W.flags & ABSTRACT) || !istype(user))
return
- if(user.drop_item(W))
+ if(istype(W, /obj/item/weapon/scalpel/supermatter))
+ playsound(src, W.usesound, 100, 1)
+ to_chat(user, "You carefully begin to scrape \the [src] with \the [W]...")
+ if(do_after(user, 60 * W.toolspeed, TRUE, src))
+ to_chat(user, "You extract a sliver from \the [src]. \The [src] begins to react violently!")
+ new /obj/item/nuke_core/supermatter_sliver(user.loc)
+ matter_power += 200
+ else if(user.dropItemToGround(W))
user.visible_message("As [user] touches \the [src] with \a [W], silence fills the room...",\
"You touch \the [src] with \the [W], and everything suddenly goes silent.\n\The [W] flashes into dust as you flinch away from \the [src].",\
"Everything suddenly goes silent.")
@@ -536,7 +544,7 @@
var/atom/movable/pulled_object = P
if(ishuman(P))
var/mob/living/carbon/human/H = P
- H.apply_effect(2, WEAKEN, 0)
+ H.apply_effect(40, KNOCKDOWN, 0)
if(pulled_object && !pulled_object.anchored && !ishuman(P))
step_towards(pulled_object,center)
step_towards(pulled_object,center)
diff --git a/code/modules/power/terminal.dm b/code/modules/power/terminal.dm
index 5cae8b3c911..349510dbaf7 100644
--- a/code/modules/power/terminal.dm
+++ b/code/modules/power/terminal.dm
@@ -58,7 +58,7 @@
user.visible_message("[user.name] dismantles the power terminal from [master].", \
"You begin to cut the cables...")
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
if(do_after(user, 50*W.toolspeed, target = src))
if(!master || master.can_terminal_dismantle())
if(prob(50) && electrocute_mob(user, powernet, src, 1, TRUE))
diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm
index 4da9b494821..3d24a9e503a 100644
--- a/code/modules/power/tesla/coil.dm
+++ b/code/modules/power/tesla/coil.dm
@@ -80,7 +80,7 @@
var/power_produced = powernet ? power / power_loss : power
add_avail(power_produced*input_power_multiplier)
flick("coilhit", src)
- playsound(src.loc, 'sound/magic/LightningShock.ogg', 100, 1, extrarange = 5)
+ playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
tesla_zap(src, 5, power_produced)
addtimer(CALLBACK(src, .proc/reset_shocked), 10)
else
@@ -94,7 +94,7 @@
coeff = max(coeff, 10)
var/power = (powernet.avail/2)
add_load(power)
- playsound(src.loc, 'sound/magic/LightningShock.ogg', 100, 1, extrarange = 5)
+ playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
tesla_zap(src, 10, power/(coeff/2))
/obj/machinery/power/grounding_rod
diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm
index 14b5bfb755a..20174c6049a 100644
--- a/code/modules/power/tracker.dm
+++ b/code/modules/power/tracker.dm
@@ -67,7 +67,7 @@
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
user.visible_message("[user] begins to take the glass off the solar tracker.", "You begin to take the glass off the solar tracker...")
if(do_after(user, 50*W.toolspeed, target = src))
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
user.visible_message("[user] takes the glass off the tracker.", "You take the glass off the tracker.")
deconstruct(TRUE)
else
@@ -75,7 +75,7 @@
/obj/machinery/power/tracker/obj_break(damage_flag)
if(!(stat & BROKEN) && !(flags & NODECONSTRUCT))
- playsound(loc, 'sound/effects/Glassbr3.ogg', 100, 1)
+ playsound(loc, 'sound/effects/glassbr3.ogg', 100, 1)
stat |= BROKEN
unset_control()
diff --git a/code/modules/procedural_mapping/mapGenerators/repair.dm b/code/modules/procedural_mapping/mapGenerators/repair.dm
index e2f658648c0..3a344ac94a5 100644
--- a/code/modules/procedural_mapping/mapGenerators/repair.dm
+++ b/code/modules/procedural_mapping/mapGenerators/repair.dm
@@ -1,11 +1,12 @@
/datum/mapGeneratorModule/bottomLayer/repairFloorPlasteel
spawnableTurfs = list(/turf/open/floor/plasteel = 100)
var/ignore_wall = FALSE
+ allowAtomsOnSpace = TRUE
/datum/mapGeneratorModule/bottomLayer/repairFloorPlasteel/place(turf/T)
- if(isclosedturf(T))
+ if(isclosedturf(T) && !ignore_wall)
return FALSE
- return TRUE
+ return ..()
/datum/mapGeneratorModule/bottomLayer/repairFloorPlasteel/flatten
ignore_wall = TRUE
@@ -13,6 +14,7 @@
/datum/mapGeneratorModule/border/normalWalls
spawnableAtoms = list()
spawnableTurfs = list(/turf/closed/wall = 100)
+ allowAtomsOnSpace = TRUE
/datum/mapGenerator/repair
modules = list(/datum/mapGeneratorModule/bottomLayer/repairFloorPlasteel,
diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm
index 376e372cb6c..84865c8a275 100644
--- a/code/modules/projectiles/ammunition/ammo_casings.dm
+++ b/code/modules/projectiles/ammunition/ammo_casings.dm
@@ -76,11 +76,6 @@
caliber = "4.6x30mm"
projectile_type = /obj/item/projectile/bullet/incendiary/firebullet
-/obj/item/ammo_casing/c46carbine
- desc = "A 4.6x30mm bullet casing."
- caliber = "4.6x30mm"
- projectile_type = /obj/item/projectile/bullet/carbinebullet
-
/obj/item/ammo_casing/c45
desc = "A .45 bullet casing."
caliber = ".45"
@@ -125,7 +120,7 @@
icon_state = "sleeper"
/obj/item/ammo_casing/haemorrhage
- desc = "A .50 bullet casing, specialised in causing massive bloodloss"
+ desc = "A .50 bullet casing, specialised in causing massive bloodloss."
caliber = ".50"
projectile_type = /obj/item/projectile/bullet/sniper/haemorrhage
icon_state = ".50"
@@ -154,7 +149,7 @@
projectile_type = /obj/item/projectile/bullet/saw
/obj/item/ammo_casing/mm195x129/bleeding
- desc = "A 1.95x129mm bullet casing with specialized inner-casing, that when it makes contact with a target, release tiny shrapnel to induce internal bleeding."
+ desc = "A 1.95x129mm bullet casing with specialized inner-casing, that when it makes contact with a target, releases tiny shrapnel to induce internal bleeding."
icon_state = "762-casing"
projectile_type = /obj/item/projectile/bullet/saw/bleeding
@@ -282,7 +277,7 @@
/obj/item/ammo_casing/shotgun/ion
name = "ion shell"
desc = "An advanced shotgun shell which uses a subspace ansible crystal to produce an effect similar to a standard ion rifle. \
- The unique properties of the crystal splot the pulse into a spread of individually weaker bolts."
+ The unique properties of the crystal split the pulse into a spread of individually weaker bolts."
icon_state = "ionshell"
projectile_type = /obj/item/projectile/ion/weak
pellets = 4
diff --git a/code/modules/projectiles/ammunition/caseless.dm b/code/modules/projectiles/ammunition/caseless.dm
index 0480476a74d..76861232b93 100644
--- a/code/modules/projectiles/ammunition/caseless.dm
+++ b/code/modules/projectiles/ammunition/caseless.dm
@@ -44,7 +44,7 @@
caliber = "laser"
icon_state = "s-casing-live"
projectile_type = /obj/item/projectile/beam
- fire_sound = 'sound/weapons/Laser.ogg'
+ fire_sound = 'sound/weapons/laser.ogg'
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy
/obj/item/ammo_casing/caseless/laser/gatling
@@ -55,7 +55,7 @@
/obj/item/ammo_casing/caseless/foam_dart
name = "foam dart"
- desc = "Its nerf or nothing! Ages 8 and up."
+ desc = "It's nerf or nothing! Ages 8 and up."
projectile_type = /obj/item/projectile/bullet/reusable/foam_dart
caliber = "foam_force"
icon = 'icons/obj/guns/toy.dmi'
@@ -66,12 +66,12 @@
..()
if (modified)
icon_state = "foamdart_empty"
- desc = "Its nerf or nothing! ... Although, this one doesn't look too safe."
+ desc = "It's nerf or nothing! ... Although, this one doesn't look too safe."
if(BB)
BB.icon_state = "foamdart_empty"
else
icon_state = initial(icon_state)
- desc = "Its nerf or nothing! Ages 8 and up."
+ desc = "It's nerf or nothing! Ages 8 and up."
if(BB)
BB.icon_state = initial(BB.icon_state)
@@ -82,7 +82,7 @@
modified = 1
FD.modified = 1
FD.damage_type = BRUTE
- to_chat(user, "You pop the safety cap off of [src].")
+ to_chat(user, "You pop the safety cap off [src].")
update_icon()
else if (istype(A, /obj/item/weapon/pen))
if(modified)
diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm
index 51703e0a5af..1125a7872dc 100644
--- a/code/modules/projectiles/ammunition/energy.dm
+++ b/code/modules/projectiles/ammunition/energy.dm
@@ -5,7 +5,7 @@
projectile_type = /obj/item/projectile/energy
var/e_cost = 100 //The amount of energy a cell needs to expend to create this shot.
var/select_name = "energy"
- fire_sound = 'sound/weapons/Laser.ogg'
+ fire_sound = 'sound/weapons/laser.ogg'
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy
/obj/item/ammo_casing/energy/chameleon
@@ -91,7 +91,7 @@
/obj/item/ammo_casing/energy/ion
projectile_type = /obj/item/projectile/ion
select_name = "ion"
- fire_sound = 'sound/weapons/IonRifle.ogg'
+ fire_sound = 'sound/weapons/ionrifle.ogg'
/obj/item/ammo_casing/energy/declone
projectile_type = /obj/item/projectile/energy/declone
@@ -101,7 +101,7 @@
/obj/item/ammo_casing/energy/mindflayer
projectile_type = /obj/item/projectile/beam/mindflayer
select_name = "MINDFUCK"
- fire_sound = 'sound/weapons/Laser.ogg'
+ fire_sound = 'sound/weapons/laser.ogg'
/obj/item/ammo_casing/energy/flora
fire_sound = 'sound/effects/stealthoff.ogg'
@@ -161,7 +161,7 @@
projectile_type = /obj/item/projectile/energy/bolt
select_name = "bolt"
e_cost = 500
- fire_sound = 'sound/weapons/Genhit.ogg'
+ fire_sound = 'sound/weapons/genhit.ogg'
/obj/item/ammo_casing/energy/bolt/halloween
projectile_type = /obj/item/projectile/energy/bolt/halloween
diff --git a/code/modules/projectiles/boxes_magazines/external_mag.dm b/code/modules/projectiles/boxes_magazines/external_mag.dm
index 8ebcd1eab36..3bfb90224dd 100644
--- a/code/modules/projectiles/boxes_magazines/external_mag.dm
+++ b/code/modules/projectiles/boxes_magazines/external_mag.dm
@@ -186,14 +186,6 @@
max_ammo = 30
multiple_sprites = 2
-/obj/item/ammo_box/magazine/carbine
- name = "carbine magazine (4.6x30mm)"
- icon_state = "oldrifle"
- origin_tech = "combat=5"
- ammo_type = /obj/item/ammo_casing/c46carbine
- caliber = "4.6x30mm"
- max_ammo = 32
-
/obj/item/ammo_box/magazine/m12g
name = "shotgun magazine (12g taser slugs)"
desc = "A drum magazine."
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 6454e17e0a4..5a21c92f799 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -1,3 +1,6 @@
+
+#define DUALWIELD_PENALTY_EXTRA_MULTIPLIER 1.4
+
/obj/item/weapon/gun
name = "gun"
desc = "It's a gun. It's pretty terrible, though."
@@ -34,9 +37,6 @@
var/weapon_weight = WEAPON_LIGHT
var/spread = 0 //Spread induced by the gun itself.
var/randomspread = 1 //Set to 0 for shotguns. This is used for weapons that don't fire all their bullets at once.
- var/unique_reskin = 0 //allows one-time reskinning
- var/current_skin = null //the skin choice if we had a reskin
- var/list/options = list()
lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/guns_righthand.dmi'
@@ -90,8 +90,6 @@
to_chat(user, "It has [pin] installed.")
else
to_chat(user, "It doesn't have a firing pin installed, and won't fire.")
- if(unique_reskin && !current_skin)
- to_chat(user, "Alt-click it to reskin it.")
//called after the gun has successfully fired its chambered ammo.
/obj/item/weapon/gun/proc/process_chamber()
@@ -229,7 +227,7 @@
break
if(chambered && chambered.BB)
if(randomspread)
- sprd = round((rand() - 0.5) * (randomized_gun_spread + randomized_bonus_spread))
+ sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
else //Smart spread
sprd = round((((rand_spr/burst_size) * i) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread))
@@ -250,7 +248,7 @@
firing_burst = 0
else
if(chambered)
- sprd = round((rand() - 0.5) * (randomized_gun_spread + randomized_bonus_spread))
+ sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
if(!chambered.fire_casing(target, user, params, , suppressed, zone_override, sprd))
shoot_with_empty_chamber(user)
return
@@ -397,26 +395,6 @@
if(alight)
alight.Remove(user)
-
-/obj/item/weapon/gun/AltClick(mob/user)
- ..()
- if(user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(unique_reskin && !current_skin && loc == user)
- reskin_gun(user)
-
-
-/obj/item/weapon/gun/proc/reskin_gun(mob/M)
- var/choice = input(M,"Warning, you can only reskin your weapon once!","Reskin Gun") in options
-
- if(src && choice && !current_skin && !M.incapacitated() && in_range(M,src))
- if(options[choice] == null)
- return
- current_skin = options[choice]
- to_chat(M, "Your gun is now skinned as [choice]. Say hello to your new friend.")
- update_icon()
-
/obj/item/weapon/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params)
if(!ishuman(user) || !ishuman(target))
return
@@ -462,7 +440,7 @@
/datum/action/toggle_scope_zoom
name = "Toggle Scope"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_LYING
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING
button_icon_state = "sniper_zoom"
var/obj/item/weapon/gun/gun = null
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index 80be30a06a8..215a02db341 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -78,7 +78,7 @@
suppressed = A
S.oldsound = fire_sound
S.initial_w_class = w_class
- fire_sound = 'sound/weapons/Gunshot_silenced.ogg'
+ fire_sound = 'sound/weapons/gunshot_silenced.ogg'
w_class = WEIGHT_CLASS_NORMAL //so pistols do not fit in pockets when suppressed
update_icon()
return
@@ -138,7 +138,7 @@
return boolets
/obj/item/weapon/gun/ballistic/suicide_act(mob/user)
- if (chambered && chambered.BB && !chambered.BB.nodamage)
+ if (chambered && chambered.BB && can_trigger_gun(user) && !chambered.BB.nodamage)
user.visible_message("[user] is putting the barrel of [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide!")
sleep(25)
if(user.is_holding(src))
diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm
index 0503a011b36..4a6f7c88d89 100644
--- a/code/modules/projectiles/guns/ballistic/automatic.dm
+++ b/code/modules/projectiles/guns/ballistic/automatic.dm
@@ -91,7 +91,7 @@
item_state = "c20r"
origin_tech = "combat=5;materials=2;syndicate=6"
mag_type = /obj/item/ammo_box/magazine/smgm45
- fire_sound = 'sound/weapons/Gunshot_smg.ogg'
+ fire_sound = 'sound/weapons/gunshot_smg.ogg'
fire_delay = 2
burst_size = 2
pin = /obj/item/device/firing_pin/implant/pindicate
@@ -142,7 +142,7 @@
item_state = "m90"
origin_tech = "combat=5;materials=2;syndicate=6"
mag_type = /obj/item/ammo_box/magazine/m556
- fire_sound = 'sound/weapons/Gunshot_smg.ogg'
+ fire_sound = 'sound/weapons/gunshot_smg.ogg'
can_suppress = 0
var/obj/item/weapon/gun/ballistic/revolver/grenadelauncher/underbarrel
burst_size = 3
@@ -216,7 +216,7 @@
slot_flags = 0
origin_tech = "combat=5;materials=1;syndicate=3"
mag_type = /obj/item/ammo_box/magazine/tommygunm45
- fire_sound = 'sound/weapons/Gunshot_smg.ogg'
+ fire_sound = 'sound/weapons/gunshot_smg.ogg'
can_suppress = 0
burst_size = 4
fire_delay = 1
@@ -229,22 +229,11 @@
slot_flags = 0
origin_tech = "combat=6;engineering=4"
mag_type = /obj/item/ammo_box/magazine/m556
- fire_sound = 'sound/weapons/Gunshot_smg.ogg'
+ fire_sound = 'sound/weapons/gunshot_smg.ogg'
can_suppress = 0
burst_size = 3
fire_delay = 1
-/obj/item/weapon/gun/ballistic/automatic/carbine
- name = "\improper Marine Carbine"
- desc = "Standard issue weapon used by Iron Hawk Marines in space to space combat. Due to modifications for space combat, the weapon has a very limited firing range."
- icon_state = "oldrifle"
- item_state = "arg"
- mag_type = /obj/item/ammo_box/magazine/carbine
- fire_sound = 'sound/weapons/Gunshot_smg.ogg'
- can_suppress = 0
- burst_size = 0
- fire_delay = 2
-
// Bulldog shotgun //
/obj/item/weapon/gun/ballistic/automatic/shotgun/bulldog
@@ -253,9 +242,10 @@
icon_state = "bulldog"
item_state = "bulldog"
w_class = WEIGHT_CLASS_NORMAL
+ weapon_weight = WEAPON_MEDIUM
origin_tech = "combat=6;materials=4;syndicate=6"
mag_type = /obj/item/ammo_box/magazine/m12g
- fire_sound = 'sound/weapons/Gunshot.ogg'
+ fire_sound = 'sound/weapons/gunshot.ogg'
can_suppress = 0
burst_size = 1
fire_delay = 0
@@ -270,8 +260,8 @@
update_icon()
/obj/item/weapon/gun/ballistic/automatic/shotgun/bulldog/update_icon()
+ cut_overlays()
if(magazine)
- cut_overlays()
add_overlay("[magazine.icon_state]")
icon_state = "bulldog[chambered ? "" : "-e"]"
@@ -294,7 +284,7 @@
origin_tech = "combat=6;engineering=3;syndicate=6"
mag_type = /obj/item/ammo_box/magazine/mm195x129
weapon_weight = WEAPON_HEAVY
- fire_sound = 'sound/weapons/Gunshot_smg.ogg'
+ fire_sound = 'sound/weapons/gunshot_smg.ogg'
var/cover_open = 0
can_suppress = 0
burst_size = 3
@@ -430,7 +420,7 @@
can_suppress = 0
burst_size = 0
actions_types = list()
- fire_sound = 'sound/weapons/Laser.ogg'
+ fire_sound = 'sound/weapons/laser.ogg'
casing_ejector = 0
/obj/item/weapon/gun/ballistic/automatic/laser/update_icon()
diff --git a/code/modules/projectiles/guns/ballistic/laser_gatling.dm b/code/modules/projectiles/guns/ballistic/laser_gatling.dm
index a246871e61d..1eac0eb3219 100644
--- a/code/modules/projectiles/guns/ballistic/laser_gatling.dm
+++ b/code/modules/projectiles/guns/ballistic/laser_gatling.dm
@@ -105,7 +105,7 @@
automatic = 0
fire_delay = 1
weapon_weight = WEAPON_HEAVY
- fire_sound = 'sound/weapons/Laser.ogg'
+ fire_sound = 'sound/weapons/laser.ogg'
mag_type = /obj/item/ammo_box/magazine/internal/minigun
casing_ejector = 0
var/obj/item/weapon/minigunpack/ammo_pack
diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm
index 79557a81964..a9f0e4914e8 100644
--- a/code/modules/projectiles/guns/ballistic/revolver.dm
+++ b/code/modules/projectiles/guns/ballistic/revolver.dm
@@ -92,17 +92,13 @@
desc = "A cheap Martian knock-off of a classic law enforcement firearm. Uses .38-special rounds."
icon_state = "detective"
mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38
- unique_rename = 1
- unique_reskin = 1
-
-/obj/item/weapon/gun/ballistic/revolver/detective/Initialize()
- . = ..()
- options["Default"] = "detective"
- options["Leopard Spots"] = "detective_leopard"
- options["Black Panther"] = "detective_panther"
- options["Gold Trim"] = "detective_gold"
- options["The Peacemaker"] = "detective_peacemaker"
- options["Cancel"] = null
+ unique_rename = TRUE
+ unique_reskin = list("Default" = "detective",
+ "Leopard Spots" = "detective_leopard",
+ "Black Panther" = "detective_panther",
+ "Gold Trim" = "detective_gold",
+ "The Peacemaker" = "detective_peacemaker"
+ )
/obj/item/weapon/gun/ballistic/revolver/detective/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override = "")
if(magazine.caliber != initial(magazine.caliber))
@@ -263,23 +259,20 @@
icon_state = "dshotgun"
item_state = "shotgun"
w_class = WEIGHT_CLASS_BULKY
+ weapon_weight = WEAPON_MEDIUM
force = 10
flags = CONDUCT
slot_flags = SLOT_BACK
mag_type = /obj/item/ammo_box/magazine/internal/shot/dual
sawn_desc = "Omar's coming!"
- unique_rename = 1
- unique_reskin = 1
-
-/obj/item/weapon/gun/ballistic/revolver/doublebarrel/Initialize()
- . = ..()
- options["Default"] = "dshotgun"
- options["Dark Red Finish"] = "dshotgun-d"
- options["Ash"] = "dshotgun-f"
- options["Faded Grey"] = "dshotgun-g"
- options["Maple"] = "dshotgun-l"
- options["Rosewood"] = "dshotgun-p"
- options["Cancel"] = null
+ unique_rename = TRUE
+ unique_reskin = list("Default" = "dshotgun",
+ "Dark Red Finish" = "dshotgun-d",
+ "Ash" = "dshotgun-f",
+ "Faded Grey" = "dshotgun-g",
+ "Maple" = "dshotgun-1",
+ "Rosewood" = "dshotgun-p"
+ )
/obj/item/weapon/gun/ballistic/revolver/doublebarrel/attackby(obj/item/A, mob/user, params)
..()
@@ -318,9 +311,9 @@
slot_flags = null
mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised
sawn_desc = "I'm just here for the gasoline."
- unique_rename = 0
- unique_reskin = 0
- var/slung = 0
+ unique_rename = FALSE
+ unique_reskin = null
+ var/slung = FALSE
/obj/item/weapon/gun/ballistic/revolver/doublebarrel/improvised/attackby(obj/item/A, mob/user, params)
..()
@@ -329,7 +322,7 @@
if(C.use(10))
slot_flags = SLOT_BACK
to_chat(user, "You tie the lengths of cable to the shotgun, making a sling.")
- slung = 1
+ slung = TRUE
update_icon()
else
to_chat(user, "You need at least ten lengths of cable if you want to make a sling!")
@@ -366,4 +359,4 @@
user.visible_message("[user] somehow manages to shoot [user.p_them()]self in the face!", "You somehow shoot yourself in the face! How the hell?!")
user.emote("scream")
user.drop_item()
- user.Weaken(4)
+ user.Knockdown(80)
diff --git a/code/modules/projectiles/guns/ballistic/toy.dm b/code/modules/projectiles/guns/ballistic/toy.dm
index 9b8044dac8a..e1d93f5e847 100644
--- a/code/modules/projectiles/guns/ballistic/toy.dm
+++ b/code/modules/projectiles/guns/ballistic/toy.dm
@@ -5,7 +5,7 @@
icon_state = "saber"
item_state = "gun"
mag_type = /obj/item/ammo_box/magazine/toy/smg
- fire_sound = 'sound/weapons/Gunshot_smg.ogg'
+ fire_sound = 'sound/weapons/gunshot_smg.ogg'
force = 0
throwforce = 0
burst_size = 3
@@ -23,7 +23,7 @@
icon_state = "pistol"
w_class = WEIGHT_CLASS_SMALL
mag_type = /obj/item/ammo_box/magazine/toy/pistol
- fire_sound = 'sound/weapons/Gunshot.ogg'
+ fire_sound = 'sound/weapons/gunshot.ogg'
burst_size = 1
fire_delay = 0
actions_types = list()
diff --git a/code/modules/projectiles/guns/beam_rifle.dm b/code/modules/projectiles/guns/beam_rifle.dm
index 7f268c611a4..e2ae346533c 100644
--- a/code/modules/projectiles/guns/beam_rifle.dm
+++ b/code/modules/projectiles/guns/beam_rifle.dm
@@ -36,6 +36,7 @@
var/aiming_time_fire_threshold = 2
var/aiming_time_left = 7
var/aiming_time_increase_user_movement = 3
+ var/scoped_slow = 1
var/aiming_time_increase_angle_multiplier = 0.6
var/lastangle = 0
@@ -85,8 +86,14 @@
projectile_setting_pierce = !projectile_setting_pierce
to_chat(user, "You set \the [src] to [projectile_setting_pierce? "pierce":"impact"] mode.")
-/obj/item/weapon/gun/energy/beam_rifle/New()
- ..()
+/obj/item/weapon/gun/energy/beam_rifle/proc/update_slowdown()
+ if(scoped)
+ slowdown = scoped_slow
+ else
+ slowdown = initial(slowdown)
+
+/obj/item/weapon/gun/energy/beam_rifle/Initialize()
+ . = ..()
START_PROCESSING(SSfastprocess, src)
/obj/item/weapon/gun/energy/beam_rifle/Destroy()
@@ -116,6 +123,7 @@
recoil = hipfire_recoil
scoped = FALSE
user << "You lower your [src]."
+ update_slowdown()
/obj/item/weapon/gun/energy/beam_rifle/can_trigger_gun(var/mob/living/user)
if(!scoped && !noscope)
@@ -161,12 +169,15 @@
/obj/item/weapon/gun/energy/beam_rifle/process()
if(!aiming)
return
- if(!isturf(current_user.loc) || !(src in current_user.held_items)) //Doesn't work if you're not holding it!
+ if(!istype(current_user) || !isturf(current_user.loc) || !(src in current_user.held_items) || current_user.incapacitated()) //Doesn't work if you're not holding it!
terminate_aiming()
return
if(aiming_time_left > 0)
aiming_time_left--
aiming_beam()
+ process_aim()
+
+/obj/item/weapon/gun/energy/beam_rifle/proc/process_aim()
if(current_user.client.mouseParams)
var/list/mouse_control = params2list(current_user.client.mouseParams)
if(isturf(current_user.client.mouseLocation))
@@ -204,6 +215,7 @@
current_user = mob
/obj/item/weapon/gun/energy/beam_rifle/onMouseUp(object, location, params, mob/M)
+ process_aim()
if(aiming_time_left <= aiming_time_fire_threshold)
sync_ammo()
afterattack(M.client.mouseObject, M, FALSE, M.client.mouseParams, passthrough = TRUE)
@@ -284,7 +296,7 @@
HS_BB.structure_pierce_amount = structure_piercing
HS_BB.structure_bleed_coeff = structure_bleed_coeff
HS_BB.do_pierce = do_pierce
- HS_BB.gun = host
+ HS_BB.gun = host
/obj/item/ammo_casing/energy/beam_rifle/hitscan
projectile_type = /obj/item/projectile/beam/beam_rifle/hitscan
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index e20cb770899..32c323f3299 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -150,7 +150,7 @@
toggle_gunlight()
/obj/item/weapon/gun/energy/suicide_act(mob/user)
- if (src.can_shoot())
+ if (src.can_shoot() && can_trigger_gun(user))
user.visible_message("[user] is putting the barrel of [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide!")
sleep(25)
if(user.is_holding(src))
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index c702a69fc7d..33a0aa4c6ea 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -1,6 +1,6 @@
/obj/item/weapon/gun/energy/kinetic_accelerator
name = "proto-kinetic accelerator"
- desc = "A self recharging, ranged mining tool that does increased damage in low pressure. Capable of holding up to six slots worth of mod kits."
+ desc = "A self recharging, ranged mining tool that does increased damage in low pressure."
icon_state = "kineticgun"
item_state = "kineticgun"
ammo_type = list(/obj/item/ammo_casing/energy/kinetic)
@@ -98,7 +98,7 @@
empty()
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/empty()
- cell.use(500)
+ cell.use(cell.charge)
update_icon()
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/attempt_reload(recharge_time)
@@ -125,7 +125,7 @@
return
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/reload()
- cell.give(500)
+ cell.give(cell.maxcharge)
recharge_newshot(1)
if(!suppressed)
playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
@@ -145,7 +145,7 @@
projectile_type = /obj/item/projectile/kinetic
select_name = "kinetic"
e_cost = 500
- fire_sound = 'sound/weapons/Kenetic_accel.ogg' // fine spelling there chap
+ fire_sound = 'sound/weapons/kenetic_accel.ogg' // fine spelling there chap
/obj/item/ammo_casing/energy/kinetic/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
..()
@@ -163,6 +163,7 @@
range = 3
log_override = TRUE
+ var/pressure_decrease_active = FALSE
var/pressure_decrease = 0.25
var/obj/item/weapon/gun/energy/kinetic_accelerator/kinetic_gun
@@ -174,12 +175,18 @@
var/turf/target_turf = get_turf(target)
if(!isturf(target_turf))
return
- var/datum/gas_mixture/environment = target_turf.return_air()
- var/pressure = environment.return_pressure()
- if(pressure > 50)
- name = "weakened [name]"
- damage = damage * pressure_decrease
. = ..()
+ if(.)
+ if(kinetic_gun)
+ var/list/mods = kinetic_gun.get_modkits()
+ for(var/obj/item/borg/upgrade/modkit/M in mods)
+ M.projectile_prehit(src, target, kinetic_gun)
+ var/datum/gas_mixture/environment = target_turf.return_air()
+ var/pressure = environment.return_pressure()
+ if(pressure > 50)
+ name = "weakened [name]"
+ damage = damage * pressure_decrease
+ pressure_decrease_active = TRUE
/obj/item/projectile/kinetic/on_range()
strike_thing()
@@ -194,7 +201,10 @@
if(!target_turf)
target_turf = get_turf(src)
if(kinetic_gun) //hopefully whoever shot this was not very, very unfortunate.
- for(var/obj/item/borg/upgrade/modkit/M in kinetic_gun.get_modkits())
+ var/list/mods = kinetic_gun.get_modkits()
+ for(var/obj/item/borg/upgrade/modkit/M in mods)
+ M.projectile_strike_predamage(src, target_turf, target, kinetic_gun)
+ for(var/obj/item/borg/upgrade/modkit/M in mods)
M.projectile_strike(src, target_turf, target, kinetic_gun)
if(ismineralturf(target_turf))
var/turf/closed/mineral/M = target_turf
@@ -251,7 +261,7 @@
if(!user.transferItemToLoc(src, KA))
return
to_chat(user, "You install the modkit.")
- playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
+ playsound(loc, 'sound/items/screwdriver.ogg', 100, 1)
KA.modkits += src
else
to_chat(user, "The modkit you're trying to install would conflict with an already installed modkit. Use a crowbar to remove existing modkits.")
@@ -265,6 +275,11 @@
/obj/item/borg/upgrade/modkit/proc/modify_projectile(obj/item/projectile/kinetic/K)
+//use this one for effects you want to trigger before any damage is done at all and before damage is decreased by pressure
+/obj/item/borg/upgrade/modkit/proc/projectile_prehit(obj/item/projectile/kinetic/K, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA)
+//use this one for effects you want to trigger before mods that do damage
+/obj/item/borg/upgrade/modkit/proc/projectile_strike_predamage(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA)
+//and this one for things that don't need to trigger before other damage-dealing mods
/obj/item/borg/upgrade/modkit/proc/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA)
//Range
@@ -314,7 +329,7 @@
. = ..()
if(.)
for(var/obj/item/borg/upgrade/modkit/aoe/AOE in KA.modkits) //make sure only one of the aoe modules has values if somebody has multiple
- if(AOE.stats_stolen)
+ if(AOE.stats_stolen || AOE == src)
continue
modifier += AOE.modifier //take its modifiers
AOE.modifier = 0
@@ -326,28 +341,6 @@
..()
modifier = initial(modifier) //get our modifiers back
turf_aoe = initial(turf_aoe)
- if(stats_stolen) //if we had our stats stolen, find the stealer and take them from it
- for(var/obj/item/borg/upgrade/modkit/aoe/AOE in KA.modkits)
- if(AOE.stats_stolen)
- continue
- AOE.modifier -= modifier
- AOE.turf_aoe -= turf_aoe
- else //otherwise, reset the stolen stats and have it recalculate
- var/obj/item/borg/upgrade/modkit/aoe/new_stealer
- for(var/obj/item/borg/upgrade/modkit/aoe/AOE in KA.modkits)
- if(!new_stealer)
- new_stealer = AOE //just make the first one a stealer
- AOE.modifier = initial(AOE.modifier)
- AOE.turf_aoe = initial(AOE.turf_aoe)
- AOE.stats_stolen = FALSE
- if(new_stealer) //if there's no stealer, then there's no other aoe modkits
- for(var/obj/item/borg/upgrade/modkit/aoe/AOE in KA.modkits)
- if(AOE != new_stealer)
- new_stealer.modifier += AOE.modifier
- AOE.modifier = 0
- new_stealer.turf_aoe += AOE.turf_aoe
- AOE.turf_aoe = FALSE
- AOE.stats_stolen = TRUE
stats_stolen = FALSE
/obj/item/borg/upgrade/modkit/aoe/modify_projectile(obj/item/projectile/kinetic/K)
@@ -368,7 +361,6 @@
L.apply_damage(K.damage*modifier, K.damage_type, K.def_zone, armor)
to_chat(L, "You're struck by a [K.name]!")
-
/obj/item/borg/upgrade/modkit/aoe/turfs
name = "mining explosion"
desc = "Causes the kinetic accelerator to destroy rock in an AoE."
@@ -394,7 +386,7 @@
modifier = -14 //Makes the cooldown 3 seconds(with no cooldown mods) if you miss. Don't miss.
cost = 50
-/obj/item/borg/upgrade/modkit/cooldown/repeater/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA)
+/obj/item/borg/upgrade/modkit/cooldown/repeater/projectile_strike_predamage(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA)
var/valid_repeat = FALSE
if(isliving(target))
var/mob/living/L = target
@@ -404,18 +396,17 @@
valid_repeat = TRUE
if(valid_repeat)
KA.overheat = FALSE
- KA.attempt_reload(KA.overheat_time * 0.25) //If you hit, the cooldown drops to 0.75 seconds.
+ KA.attempt_reload(KA.overheat_time * 0.25) //If you hit, the cooldown drops to 0.75 seconds.
/obj/item/borg/upgrade/modkit/lifesteal
name = "lifesteal crystal"
desc = "Causes kinetic accelerator shots to slightly heal the firer on striking a living target."
icon_state = "modkit_crystal"
- denied_type = /obj/item/borg/upgrade/modkit/lifesteal
modifier = 2.5 //Not a very effective method of healing.
cost = 20
var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
-/obj/item/borg/upgrade/modkit/lifesteal/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA)
+/obj/item/borg/upgrade/modkit/lifesteal/projectile_prehit(obj/item/projectile/kinetic/K, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA)
if(isliving(target) && isliving(K.firer))
var/mob/living/L = target
if(L.stat == DEAD)
@@ -439,6 +430,46 @@
return
new /obj/effect/temp_visual/resonance(target_turf, K.firer, null, 30)
+/obj/item/borg/upgrade/modkit/bounty
+ name = "death syphon"
+ desc = "Killing or assisting in killing a creature permenantly increases your damage against that type of creature."
+ denied_type = /obj/item/borg/upgrade/modkit/bounty
+ modifier = 1.25
+ cost = 30
+ var/maximum_bounty = 25
+ var/list/bounties_reaped = list()
+
+/obj/item/borg/upgrade/modkit/bounty/projectile_prehit(obj/item/projectile/kinetic/K, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA)
+ if(isliving(target))
+ var/mob/living/L = target
+ var/list/existing_marks = L.has_status_effect_list(STATUS_EFFECT_SYPHONMARK)
+ for(var/i in existing_marks)
+ var/datum/status_effect/syphon_mark/SM = i
+ if(SM.reward_target == src) //we want to allow multiple people with bounty modkits to use them, but we need to replace our own marks so we don't multi-reward
+ SM.reward_target = null
+ qdel(SM)
+ var/datum/status_effect/syphon_mark/SM = L.apply_status_effect(STATUS_EFFECT_SYPHONMARK)
+ SM.reward_target = src
+
+/obj/item/borg/upgrade/modkit/bounty/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/weapon/gun/energy/kinetic_accelerator/KA)
+ if(isliving(target))
+ var/mob/living/L = target
+ if(bounties_reaped[L.type])
+ var/kill_modifier = 1
+ if(K.pressure_decrease_active)
+ kill_modifier *= K.pressure_decrease
+ var/armor = L.run_armor_check(K.def_zone, K.flag, "", "", K.armour_penetration)
+ L.apply_damage(bounties_reaped[L.type]*kill_modifier, K.damage_type, K.def_zone, armor)
+
+/obj/item/borg/upgrade/modkit/bounty/proc/get_kill(mob/living/L)
+ var/bonus_mod = 1
+ if(ismegafauna(L)) //megafauna reward
+ bonus_mod = 4
+ if(!bounties_reaped[L.type])
+ bounties_reaped[L.type] = min(modifier * bonus_mod, maximum_bounty)
+ else
+ bounties_reaped[L.type] = min(bounties_reaped[L.type] + (modifier * bonus_mod), maximum_bounty)
+
//Indoors
/obj/item/borg/upgrade/modkit/indoors
name = "decrease pressure penalty"
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 196d44ad083..3c4d749678f 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -121,7 +121,7 @@
/obj/item/weapon/gun/energy/plasmacutter
name = "plasma cutter"
- desc = "A mining tool capable of expelling concentrated plasma bursts. You could use it to cut limbs off of xenos! Or, you know, mine stuff."
+ desc = "A mining tool capable of expelling concentrated plasma bursts. You could use it to cut limbs off xenos! Or, you know, mine stuff."
icon_state = "plasmacutter"
item_state = "plasmacutter"
origin_tech = "combat=1;materials=3;magnets=2;plasmatech=3;engineering=1"
@@ -172,8 +172,8 @@
item_state = null
icon_state = "wormhole_projector"
origin_tech = "combat=4;bluespace=6;plasmatech=4;engineering=4"
- var/obj/effect/portal/blue
- var/obj/effect/portal/orange
+ var/obj/effect/portal/p_blue
+ var/obj/effect/portal/p_orange
/obj/item/weapon/gun/energy/wormhole_projector/update_icon()
icon_state = "[initial(icon_state)][select]"
@@ -184,36 +184,50 @@
..()
select_fire()
-/obj/item/weapon/gun/energy/wormhole_projector/proc/portal_destroyed(obj/effect/portal/P)
- if(P.icon_state == "portal")
- blue = null
- if(orange)
- orange.target = null
- else
- orange = null
- if(blue)
- blue.target = null
+/obj/item/weapon/gun/energy/wormhole_projector/proc/on_portal_destroy(obj/effect/portal/P)
+ if(P == p_blue)
+ p_blue = null
+ else if(P == p_orange)
+ p_orange = null
-/obj/item/weapon/gun/energy/wormhole_projector/proc/create_portal(obj/item/projectile/beam/wormhole/W)
- var/obj/effect/portal/P = new /obj/effect/portal(get_turf(W), null, src)
- P.precision = 0
- if(W.name == "bluespace beam")
- qdel(blue)
- blue = P
- else
- qdel(orange)
+/obj/item/weapon/gun/energy/wormhole_projector/proc/has_blue_portal()
+ if(istype(p_blue) && !QDELETED(p_blue))
+ return TRUE
+ return FALSE
+
+/obj/item/weapon/gun/energy/wormhole_projector/proc/has_orange_portal()
+ if(istype(p_orange) && !QDELETED(p_orange))
+ return TRUE
+ return FALSE
+
+/obj/item/weapon/gun/energy/wormhole_projector/proc/crosslink()
+ if(!has_blue_portal() && !has_orange_portal())
+ return
+ if(!has_blue_portal() && has_orange_portal())
+ p_orange.link_portal(null)
+ return
+ if(!has_orange_portal() && has_blue_portal())
+ p_blue.link_portal(null)
+ return
+ p_orange.link_portal(p_blue)
+ p_blue.link_portal(p_orange)
+
+/obj/item/weapon/gun/energy/wormhole_projector/proc/create_portal(obj/item/projectile/beam/wormhole/W, turf/target)
+ var/obj/effect/portal/P = new /obj/effect/portal(target, src, 300, null, FALSE, null)
+ if(istype(W, /obj/item/projectile/beam/wormhole/orange))
+ qdel(p_orange)
+ p_orange = P
P.icon_state = "portal1"
- orange = P
- if(orange && blue)
- blue.target = get_turf(orange)
- orange.target = get_turf(blue)
-
+ else
+ qdel(p_blue)
+ p_blue = P
+ crosslink()
/* 3d printer 'pseudo guns' for borgs */
/obj/item/weapon/gun/energy/printer
name = "cyborg lmg"
- desc = "A machinegun that fires 3d-printed flachettes slowly regenerated using a cyborg's internal power source."
+ desc = "A machinegun that fires 3d-printed flechettes slowly regenerated using a cyborg's internal power source."
icon_state = "l6closed0"
icon = 'icons/obj/guns/projectile.dmi'
cell_type = "/obj/item/weapon/stock_parts/cell/secborg"
@@ -268,7 +282,7 @@
/obj/item/weapon/gun/energy/gravity_gun
name = "one-point bluespace-gravitational manipulator"
- desc = "An experimental, multi-mode device that fires bolts of Zero-Point Energy, causing local distortions in gravity"
+ desc = "An experimental, multi-mode device that fires bolts of Zero-Point Energy, causing local distortions in gravity."
ammo_type = list(/obj/item/ammo_casing/energy/gravityrepulse, /obj/item/ammo_casing/energy/gravityattract, /obj/item/ammo_casing/energy/gravitychaos)
origin_tech = "combat=4;magnets=4;materials=6;powerstorage=4;bluespace=4"
item_state = null
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index c43c445feed..e8e311a7811 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -37,7 +37,7 @@
name = "disabler"
desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse."
icon_state = "disabler"
- item_state = "disabler"
+ item_state = null
origin_tech = "combat=3"
ammo_type = list(/obj/item/ammo_casing/energy/disabler)
ammo_x_offset = 3
diff --git a/code/modules/projectiles/guns/magic/staff.dm b/code/modules/projectiles/guns/magic/staff.dm
index 2dc668b6a74..45a1eccd65c 100644
--- a/code/modules/projectiles/guns/magic/staff.dm
+++ b/code/modules/projectiles/guns/magic/staff.dm
@@ -4,7 +4,7 @@
/obj/item/weapon/gun/magic/staff/change
name = "staff of change"
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself"
- fire_sound = 'sound/magic/Staff_Change.ogg'
+ fire_sound = 'sound/magic/staff_change.ogg'
ammo_type = /obj/item/ammo_casing/magic/change
icon_state = "staffofchange"
item_state = "staffofchange"
@@ -12,7 +12,7 @@
/obj/item/weapon/gun/magic/staff/animate
name = "staff of animation"
desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines."
- fire_sound = 'sound/magic/Staff_animation.ogg'
+ fire_sound = 'sound/magic/staff_animation.ogg'
ammo_type = /obj/item/ammo_casing/magic/animate
icon_state = "staffofanimation"
item_state = "staffofanimation"
@@ -20,7 +20,7 @@
/obj/item/weapon/gun/magic/staff/healing
name = "staff of healing"
desc = "An artefact that spits bolts of restoring magic which can remove ailments of all kinds and even raise the dead."
- fire_sound = 'sound/magic/Staff_Healing.ogg'
+ fire_sound = 'sound/magic/staff_healing.ogg'
ammo_type = /obj/item/ammo_casing/magic/heal
icon_state = "staffofhealing"
item_state = "staffofhealing"
@@ -31,7 +31,7 @@
/obj/item/weapon/gun/magic/staff/chaos
name = "staff of chaos"
desc = "An artefact that spits bolts of chaotic magic that can potentially do anything."
- fire_sound = 'sound/magic/Staff_Chaos.ogg'
+ fire_sound = 'sound/magic/staff_chaos.ogg'
ammo_type = /obj/item/ammo_casing/magic/chaos
icon_state = "staffofchaos"
item_state = "staffofchaos"
@@ -49,7 +49,7 @@
/obj/item/weapon/gun/magic/staff/door
name = "staff of door creation"
desc = "An artefact that spits bolts of transformative magic that can create doors in walls."
- fire_sound = 'sound/magic/Staff_Door.ogg'
+ fire_sound = 'sound/magic/staff_door.ogg'
ammo_type = /obj/item/ammo_casing/magic/door
icon_state = "staffofdoor"
item_state = "staffofdoor"
@@ -70,7 +70,7 @@
/obj/item/weapon/gun/magic/staff/spellblade
name = "spellblade"
desc = "A deadly combination of laziness and boodlust, this blade allows the user to dismember their enemies without all the hard work of actually swinging the sword."
- fire_sound = 'sound/magic/Fireball.ogg'
+ fire_sound = 'sound/magic/fireball.ogg'
ammo_type = /obj/item/ammo_casing/magic/spellblade
icon_state = "spellblade"
item_state = "spellblade"
@@ -81,7 +81,7 @@
sharpness = IS_SHARP
max_charges = 4
-/obj/item/weapon/gun/magic/staff/spellblade/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
+/obj/item/weapon/gun/magic/staff/spellblade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
final_block_chance = 0
return ..()
diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm
index acae1e49fed..047ac752e54 100644
--- a/code/modules/projectiles/guns/magic/wand.dm
+++ b/code/modules/projectiles/guns/magic/wand.dm
@@ -60,7 +60,7 @@
/obj/item/weapon/gun/magic/wand/death
name = "wand of death"
desc = "This deadly wand overwhelms the victim's body with pure energy, slaying them without fail."
- fire_sound = 'sound/magic/WandoDeath.ogg'
+ fire_sound = 'sound/magic/wandodeath.ogg'
ammo_type = /obj/item/ammo_casing/magic/death
icon_state = "deathwand"
max_charges = 3 //3, 2, 2, 1
@@ -82,7 +82,7 @@
name = "wand of healing"
desc = "This wand uses healing magics to heal and revive. They are rarely utilized within the Wizard Federation for some reason."
ammo_type = /obj/item/ammo_casing/magic/heal
- fire_sound = 'sound/magic/Staff_Healing.ogg'
+ fire_sound = 'sound/magic/staff_healing.ogg'
icon_state = "revivewand"
max_charges = 10 //10, 5, 5, 4
@@ -105,7 +105,7 @@
desc = "This wand is attuned to chaos and will radically alter the victim's form."
ammo_type = /obj/item/ammo_casing/magic/change
icon_state = "polywand"
- fire_sound = 'sound/magic/Staff_Change.ogg'
+ fire_sound = 'sound/magic/staff_change.ogg'
max_charges = 10 //10, 5, 5, 4
/obj/item/weapon/gun/magic/wand/polymorph/zap_self(mob/living/user)
@@ -121,7 +121,7 @@
name = "wand of teleportation"
desc = "This wand will wrench targets through space and time to move them somewhere else."
ammo_type = /obj/item/ammo_casing/magic/teleport
- fire_sound = 'sound/magic/Wand_Teleport.ogg'
+ fire_sound = 'sound/magic/wand_teleport.ogg'
icon_state = "telewand"
max_charges = 10 //10, 5, 5, 4
no_den_usage = 1
@@ -143,7 +143,7 @@
desc = "This particular wand can create doors in any wall for the unscrupulous wizard who shuns teleportation magics."
ammo_type = /obj/item/ammo_casing/magic/door
icon_state = "doorwand"
- fire_sound = 'sound/magic/Staff_Door.ogg'
+ fire_sound = 'sound/magic/staff_door.ogg'
max_charges = 20 //20, 10, 10, 7
no_den_usage = 1
@@ -159,7 +159,7 @@
/obj/item/weapon/gun/magic/wand/fireball
name = "wand of fireball"
desc = "This wand shoots scorching balls of fire that explode into destructive flames."
- fire_sound = 'sound/magic/Fireball.ogg'
+ fire_sound = 'sound/magic/fireball.ogg'
ammo_type = /obj/item/ammo_casing/magic/fireball
icon_state = "firewand"
max_charges = 8 //8, 4, 4, 3
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index d051ec02216..74d5018ed13 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -31,6 +31,7 @@
var/ricochets = 0
var/ricochets_max = 2
var/ricochet_chance = 30
+ var/ignore_source_check = FALSE
var/damage = 10
var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here
@@ -40,8 +41,8 @@
var/range = 50 //This will de-increment every step. When 0, it will delete the projectile.
//Effects
var/stun = 0
- var/weaken = 0
- var/paralyze = 0
+ var/knockdown = 0
+ var/unconscious = 0
var/irradiate = 0
var/stutter = 0
var/slur = 0
@@ -124,7 +125,7 @@
reagent_note += num2text(R.volume) + ") "
add_logs(firer, L, "shot", src, reagent_note)
- return L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter)
+ return L.apply_effects(stun, knockdown, unconscious, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter)
/obj/item/projectile/proc/vol_by_damage()
if(src.damage)
@@ -138,8 +139,9 @@
if(check_ricochet() && check_ricochet_flag(A) && ricochets < ricochets_max)
ricochets++
if(A.handle_ricochet(src))
+ ignore_source_check = TRUE
return FALSE
- if(firer && !ricochets)
+ if(firer && !ignore_source_check)
if(A == firer || (A == firer.loc && istype(A, /obj/mecha))) //cannot shoot yourself or your mech
loc = A.loc
return FALSE
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index e420be18d0b..4995b1e72fa 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -14,16 +14,12 @@
/obj/item/projectile/bullet/weakbullet2 //detective revolver instastuns, but multiple shots are better for keeping punks down
damage = 15
- weaken = 3
+ knockdown = 30
stamina = 50
/obj/item/projectile/bullet/weakbullet3
damage = 20
-/obj/item/projectile/bullet/carbinebullet
- damage = 20
- range = 5
-
/obj/item/projectile/bullet/toxinbullet
damage = 15
damage_type = TOX
@@ -107,8 +103,7 @@
/obj/item/projectile/bullet/stunshot //taser slugs for shotguns, nothing special
name = "stunshot"
damage = 5
- stun = 5
- weaken = 5
+ knockdown = 100
stutter = 5
jitter = 20
range = 7
@@ -144,19 +139,16 @@
icon = 'icons/obj/meteor.dmi'
icon_state = "dust"
damage = 30
- weaken = 8
- stun = 8
+ knockdown = 160
hitsound = 'sound/effects/meteorimpact.ogg'
/obj/item/projectile/bullet/meteorshot/weak
damage = 10
- weaken = 4
- stun = 4
+ knockdown = 80
/obj/item/projectile/bullet/honker
damage = 0
- weaken = 3
- stun = 3
+ knockdown = 60
forcedodge = 1
nodamage = 1
hitsound = 'sound/items/bikehorn.ogg'
@@ -236,11 +228,11 @@
icon_state = "neurotoxin"
damage = 5
damage_type = TOX
- weaken = 5
+ knockdown = 100
/obj/item/projectile/bullet/neurotoxin/on_hit(atom/target, blocked = 0)
if(isalien(target))
- weaken = 0
+ knockdown = 0
nodamage = 1
. = ..() // Execute the rest of the code.
@@ -272,8 +264,7 @@
/obj/item/projectile/bullet/sniper
speed = 0 //360 alwaysscope.
damage = 70
- stun = 5
- weaken = 5
+ knockdown = 100
dismemberment = 50
armour_penetration = 50
var/breakthings = TRUE
@@ -285,15 +276,13 @@
/obj/item/projectile/bullet/sniper/gang
damage = 55
- stun = 1
- weaken = 1
+ knockdown = 20
dismemberment = 15
armour_penetration = 25
/obj/item/projectile/bullet/sniper/gang/sleeper
nodamage = 1
- stun = 0
- weaken = 0
+ knockdown = 0
dismemberment = 0
breakthings = FALSE
@@ -302,7 +291,7 @@
var/mob/living/L = target
L.blur_eyes(8)
if(L.staminaloss >= 40)
- L.Sleeping(20)
+ L.Sleeping(400)
else
L.adjustStaminaLoss(55)
return 1
@@ -310,24 +299,22 @@
/obj/item/projectile/bullet/sniper/soporific
armour_penetration = 0
nodamage = 1
- stun = 0
dismemberment = 0
- weaken = 0
+ knockdown = 0
breakthings = FALSE
/obj/item/projectile/bullet/sniper/soporific/on_hit(atom/target, blocked = 0)
if((blocked != 100) && isliving(target))
var/mob/living/L = target
- L.Sleeping(20)
+ L.Sleeping(400)
return ..()
/obj/item/projectile/bullet/sniper/haemorrhage
armour_penetration = 15
damage = 15
- stun = 0
dismemberment = 0
- weaken = 0
+ knockdown = 0
breakthings = FALSE
/obj/item/projectile/bullet/sniper/haemorrhage/on_hit(atom/target, blocked = 0)
@@ -343,8 +330,7 @@
damage = 60
forcedodge = 1
dismemberment = 0 //It goes through you cleanly.
- stun = 0
- weaken = 0
+ knockdown = 0
breakthings = FALSE
diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm
index 43cea24737c..a792a37c376 100644
--- a/code/modules/projectiles/projectile/energy.dm
+++ b/code/modules/projectiles/projectile/energy.dm
@@ -13,8 +13,7 @@
icon_state = "spark"
color = "#FFFF00"
nodamage = 1
- stun = 5
- weaken = 5
+ knockdown = 100
stutter = 5
jitter = 20
hitsound = 'sound/weapons/taserhit.ogg'
@@ -28,7 +27,7 @@
var/mob/living/carbon/C = target
if(C.dna && C.dna.check_mutation(HULK))
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
- else if(C.status_flags & CANWEAKEN)
+ else if(C.status_flags & CANKNOCKDOWN)
addtimer(CALLBACK(C, /mob/living/carbon.proc/do_jitter_animation, jitter), 5)
/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet
@@ -91,7 +90,7 @@
name = "energy snare"
icon_state = "e_snare"
nodamage = 1
- weaken = 1
+ knockdown = 20
hitsound = 'sound/weapons/taserhit.ogg'
range = 4
@@ -111,7 +110,7 @@
name = "Energy Bola"
icon_state = "e_snare"
nodamage = 1
- weaken = 0
+ knockdown = 0
hitsound = 'sound/weapons/taserhit.ogg'
range = 10
@@ -142,7 +141,7 @@
icon_state = "toxin"
damage = 5
damage_type = TOX
- weaken = 5
+ knockdown = 100
range = 7
/obj/item/projectile/energy/bolt //ebow bolts
@@ -151,7 +150,7 @@
damage = 8
damage_type = TOX
nodamage = 0
- weaken = 5
+ knockdown = 100
stutter = 5
/obj/item/projectile/energy/bolt/halloween
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index 05bdd7da3fa..0689374c2bf 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -277,6 +277,8 @@
to_chat(new_mob, "Your form morphs into that of a [randomize].")
+ to_chat(new_mob, config.policies["polymorph"])
+
qdel(M)
return new_mob
@@ -412,3 +414,9 @@
exp_light = -1
exp_flash = 4
exp_fire= 5
+
+/obj/item/projectile/magic/aoe/fireball/infernal/on_hit(target)
+ . = ..()
+ var/turf/T = get_turf(target)
+ for(var/i=0, i<50, i+=10)
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, T, -1, exp_heavy, exp_light, exp_flash, FALSE, FALSE, exp_fire), i)
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index 263da91c807..1b00881106e 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -183,12 +183,12 @@
return ..()
if(!gun)
qdel(src)
- gun.create_portal(src)
+ gun.create_portal(src, get_turf(src))
/obj/item/projectile/bullet/frag12
name ="explosive slug"
damage = 25
- weaken = 5
+ knockdown = 50
/obj/item/projectile/bullet/frag12/on_hit(atom/target, blocked = 0)
..()
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index 55a59bed610..fb67439c7c9 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -406,14 +406,14 @@
if(C.mix_sound)
playsound(get_turf(cached_my_atom), C.mix_sound, 80, 1)
for(var/mob/M in seen)
- to_chat(M, "\icon[my_atom] [C.mix_message]")
+ to_chat(M, "[bicon(my_atom)] [C.mix_message]")
if(istype(cached_my_atom, /obj/item/slime_extract))
var/obj/item/slime_extract/ME2 = my_atom
ME2.Uses--
if(ME2.Uses <= 0) // give the notification that the slime core is dead
for(var/mob/M in seen)
- to_chat(M, "\icon[my_atom] \The [my_atom]'s power is consumed in the reaction.")
+ to_chat(M, "[bicon(my_atom)] \The [my_atom]'s power is consumed in the reaction.")
ME2.name = "used slime extract"
ME2.desc = "This extract has been used up."
diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
index b929337a139..712b5e80fec 100644
--- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
+++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
@@ -1,6 +1,6 @@
/obj/machinery/reagentgrinder
name = "All-In-One Grinder"
- desc = "Used to grind things up into raw materials."
+ desc = "From BlenderTech. Will It Blend? Let's test it out!"
icon = 'icons/obj/kitchen.dmi'
icon_state = "juicer1"
layer = BELOW_OBJ_LAYER
@@ -13,8 +13,8 @@
var/operating = FALSE
var/obj/item/weapon/reagent_containers/beaker = null
var/limit = 10
- var/list/blend_items = list (
+ var/static/list/blend_items = list(
//Sheets
/obj/item/stack/sheet/mineral/plasma = list("plasma" = 20),
/obj/item/stack/sheet/metal = list("iron" = 20),
@@ -31,7 +31,6 @@
/obj/item/weapon/grown/nettle/basic = list("sacid" = 0),
/obj/item/weapon/grown/nettle/death = list("facid" = 0, "sacid" = 0),
/obj/item/weapon/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0),
-
//Blender Stuff
/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0),
@@ -42,25 +41,19 @@
/obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0),
/obj/item/weapon/reagent_containers/food/snacks/egg = list("eggyolk" = -5),
-
//Grinder stuff, but only if dry
/obj/item/weapon/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0),
-
-
//All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.!
/obj/item/slime_extract = list(),
/obj/item/weapon/reagent_containers/pill = list(),
/obj/item/weapon/reagent_containers/food = list(),
/obj/item/weapon/reagent_containers/honeycomb = list(),
- /obj/item/toy/crayon = list()
-
- )
-
- var/list/juice_items = list (
+ /obj/item/toy/crayon = list())
+ var/static/list/juice_items = list(
//Juicer Stuff
/obj/item/weapon/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0),
@@ -78,27 +71,24 @@
/obj/item/weapon/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/apple = list("applejuice" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0),
- /obj/item/weapon/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0),
- )
+ /obj/item/weapon/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0))
- var/list/dried_items = list(
+ var/static/list/dried_items = list(
//Grinder stuff, but only if dry,
/obj/item/weapon/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
- /obj/item/weapon/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0)
- )
+ /obj/item/weapon/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0))
var/list/holdingitems = list()
/obj/machinery/reagentgrinder/Initialize()
. = ..()
beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
+ beaker.desc += " May contain blended dust. Don't breathe this in!"
/obj/machinery/reagentgrinder/Destroy()
- if(beaker)
- qdel(beaker)
- beaker = null
+ QDEL_NULL(beaker)
return ..()
/obj/machinery/reagentgrinder/contents_explosion(severity, target)
@@ -501,4 +491,4 @@
if (beaker.reagents.has_reagent("eggyolk"))
var/amount = beaker.reagents.get_reagent_amount("eggyolk")
beaker.reagents.remove_reagent("eggyolk", amount)
- beaker.reagents.add_reagent("mayonnaise", amount)
\ No newline at end of file
+ beaker.reagents.add_reagent("mayonnaise", amount)
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index 31ec27fb79c..85729df0222 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -114,9 +114,10 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/kahlua/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
- M.AdjustSleeping(-2, 0)
+ M.AdjustSleeping(-40, FALSE)
M.Jitter(5)
- return ..()
+ ..()
+ . = 1
/datum/reagent/consumable/ethanol/whiskey
name = "Whiskey"
@@ -145,7 +146,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/thirteenloko/on_mob_life(mob/living/M)
M.drowsyness = max(0,M.drowsyness-7)
- M.AdjustSleeping(-2)
+ M.AdjustSleeping(-40)
if (M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
M.Jitter(5)
@@ -529,7 +530,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW."
/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_life(mob/living/M)
- M.Stun(2, 0)
+ M.Stun(40, 0)
return ..()
/datum/reagent/consumable/ethanol/irish_cream
@@ -1111,10 +1112,10 @@ All effects don't start immediately, but rather get worse over time; the rate is
M.slurring += 3
switch(current_cycle)
if(51 to 200)
- M.Sleeping(5, 0)
+ M.Sleeping(100, FALSE)
. = 1
if(201 to INFINITY)
- M.AdjustSleeping(2, 0)
+ M.AdjustSleeping(40, FALSE)
M.adjustToxLoss(2, 0)
. = 1
..()
@@ -1159,7 +1160,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "A drink that is guaranteed to knock you silly."
/datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/carbon/M)
- M.Weaken(3, 1, 0)
+ M.Knockdown(60, 1, 0)
M.dizziness +=6
switch(current_cycle)
if(15 to 45)
diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
index 85f11b8b572..a3db8f7bc2f 100644
--- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
@@ -274,7 +274,7 @@
/datum/reagent/consumable/coffee/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
- M.AdjustSleeping(-2, 0)
+ M.AdjustSleeping(-40, FALSE)
if (M.bodytemperature < 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = min(310, M.bodytemperature + (25 * TEMPERATURE_DAMAGE_COEFFICIENT))
if(holder.has_reagent("frostoil"))
@@ -297,7 +297,7 @@
M.dizziness = max(0,M.dizziness-2)
M.drowsyness = max(0,M.drowsyness-1)
M.jitteriness = max(0,M.jitteriness-3)
- M.AdjustSleeping(-1, 0)
+ M.AdjustSleeping(-20, FALSE)
if(M.getToxLoss() && prob(20))
M.adjustToxLoss(-1, 0)
if (M.bodytemperature < 310) //310 is the normal bodytemp. 310.055
@@ -336,7 +336,7 @@
/datum/reagent/consumable/icecoffee/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
- M.AdjustSleeping(-2, 0)
+ M.AdjustSleeping(-40, FALSE)
if (M.bodytemperature > 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
M.Jitter(5)
@@ -357,7 +357,7 @@
/datum/reagent/consumable/icetea/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-2)
M.drowsyness = max(0,M.drowsyness-1)
- M.AdjustSleeping(-2, 0)
+ M.AdjustSleeping(-40, FALSE)
if(M.getToxLoss() && prob(20))
M.adjustToxLoss(-1, 0)
if (M.bodytemperature > 310)//310 is the normal bodytemp. 310.055
@@ -396,7 +396,7 @@
M.set_drugginess(30)
M.dizziness +=5
M.drowsyness = 0
- M.AdjustSleeping(-2, 0)
+ M.AdjustSleeping(-40, FALSE)
M.status_flags |= GOTTAGOFAST
if (M.bodytemperature > 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
@@ -415,7 +415,7 @@
/datum/reagent/consumable/spacemountainwind/on_mob_life(mob/living/M)
M.drowsyness = max(0,M.drowsyness-7)
- M.AdjustSleeping(-1, 0)
+ M.AdjustSleeping(-20, FALSE)
if (M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
M.Jitter(5)
@@ -529,7 +529,7 @@
/datum/reagent/consumable/tonic/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
- M.AdjustSleeping(-2, 0)
+ M.AdjustSleeping(-40, FALSE)
if (M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
..()
@@ -563,7 +563,7 @@
/datum/reagent/consumable/soy_latte/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
- M.SetSleeping(0, 0)
+ M.SetSleeping(0, FALSE)
if (M.bodytemperature < 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = min(310, M.bodytemperature + (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
M.Jitter(5)
@@ -585,7 +585,7 @@
/datum/reagent/consumable/cafe_latte/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
- M.SetSleeping(0, 0)
+ M.SetSleeping(0, FALSE)
if (M.bodytemperature < 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = min(310, M.bodytemperature + (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
M.Jitter(5)
diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
index 19bfd20feed..97c3dd8a89f 100644
--- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
@@ -42,9 +42,9 @@
if(prob(1))
var/smoke_message = pick("You feel relaxed.", "You feel calmed.","You feel alert.","You feel rugged.")
to_chat(M, "[smoke_message]")
- M.AdjustParalysis(-1, 0)
- M.AdjustStunned(-1, 0)
- M.AdjustWeakened(-1, 0)
+ M.AdjustStun(-20, 0)
+ M.AdjustKnockdown(-20, 0)
+ M.AdjustUnconscious(-20, 0)
M.adjustStaminaLoss(-0.5*REM, 0)
..()
. = 1
@@ -67,12 +67,12 @@
addiction_threshold = 10
/datum/reagent/drug/crank/on_mob_life(mob/living/M)
- var/high_message = pick("You feel jittery.", "You feel like you gotta go fast.", "You feel like you need to step it up.")
if(prob(5))
+ var/high_message = pick("You feel jittery.", "You feel like you gotta go fast.", "You feel like you need to step it up.")
to_chat(M, "[high_message]")
- M.AdjustParalysis(-1, 0)
- M.AdjustStunned(-1, 0)
- M.AdjustWeakened(-1, 0)
+ M.AdjustStun(-20, 0)
+ M.AdjustKnockdown(-20, 0)
+ M.AdjustUnconscious(-20, 0)
..()
. = 1
@@ -169,9 +169,9 @@
var/high_message = pick("You feel hyper.", "You feel like you need to go faster.", "You feel like you can run the world.")
if(prob(5))
to_chat(M, "[high_message]")
- M.AdjustParalysis(-2, 0)
- M.AdjustStunned(-2, 0)
- M.AdjustWeakened(-2, 0)
+ M.AdjustStun(-40, 0)
+ M.AdjustKnockdown(-40, 0)
+ M.AdjustUnconscious(-40, 0)
M.adjustStaminaLoss(-2, 0)
M.status_flags |= GOTTAGOREALLYFAST
M.Jitter(2)
@@ -247,9 +247,9 @@
var/high_message = pick("You feel amped up.", "You feel ready.", "You feel like you can push it to the limit.")
if(prob(5))
to_chat(M, "[high_message]")
- M.AdjustParalysis(-3, 0)
- M.AdjustStunned(-3, 0)
- M.AdjustWeakened(-3, 0)
+ M.AdjustStun(-60, 0)
+ M.AdjustKnockdown(-60, 0)
+ M.AdjustUnconscious(-60, 0)
M.adjustStaminaLoss(-5, 0)
M.adjustBrainLoss(0.5)
M.adjustToxLoss(0.1, 0)
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 550b27cd11a..1fae98e2f32 100755
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -97,11 +97,11 @@
/datum/reagent/consumable/sugar/overdose_start(mob/living/M)
to_chat(M, "You go into hyperglycaemic shock! Lay off the twinkies!")
- M.AdjustSleeping(30, 0)
+ M.AdjustSleeping(600, FALSE)
. = 1
/datum/reagent/consumable/sugar/overdose_process(mob/living/M)
- M.AdjustSleeping(3, 0)
+ M.AdjustSleeping(40, FALSE)
..()
. = 1
@@ -255,7 +255,7 @@
victim.blind_eyes(2)
victim.confused = max(M.confused, 3)
victim.damageoverlaytemp = 60
- victim.Weaken(3)
+ victim.Knockdown(60)
victim.drop_item()
return
else if ( eyes_covered ) // Eye cover is better than mouth cover
@@ -269,7 +269,7 @@
victim.blind_eyes(3)
victim.confused = max(M.confused, 6)
victim.damageoverlaytemp = 75
- victim.Weaken(5)
+ victim.Knockdown(100)
victim.drop_item()
victim.update_damage_hud()
@@ -532,6 +532,44 @@
color = "#DFDFDF"
taste_description = "mayonnaise"
+/datum/reagent/consumable/tearjuice
+ name = "Tear Juice"
+ id = "tearjuice"
+ description = "A blinding substance extracted from certain onions."
+ color = "#c0c9a0"
+ taste_description = "bitterness"
+
+/datum/reagent/consumable/tearjuice/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
+ if(!istype(M))
+ return
+ var/unprotected = FALSE
+ switch(method)
+ if(INGEST)
+ unprotected = TRUE
+ if(INJECT)
+ unprotected = FALSE
+ else //Touch or vapor
+ if(!M.is_mouth_covered() && !M.is_eyes_covered())
+ unprotected = TRUE
+ if(unprotected)
+ if(!M.getorganslot("eye_sight")) //can't blind somebody with no eyes
+ to_chat(M, "Your eye sockets feel wet.")
+ else
+ if(!M.eye_blurry)
+ to_chat(M, "Tears well up in your eyes!")
+ M.blind_eyes(2)
+ M.blur_eyes(5)
+ ..()
+
+/datum/reagent/consumable/tearjuice/on_mob_life(mob/living/M)
+ ..()
+ if(M.eye_blurry) //Don't worsen vision if it was otherwise fine
+ M.blur_eyes(4)
+ if(prob(10))
+ to_chat(M, "Your eyes sting!")
+ M.blind_eyes(2)
+
+
////Lavaland Flora Reagents////
@@ -544,7 +582,7 @@
/datum/reagent/consumable/entpoly/on_mob_life(mob/living/M)
if(current_cycle >= 10)
- M.Paralyse(2, 0)
+ M.Unconscious(40, 0)
. = 1
if(prob(20))
M.losebreath += 4
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 6d38e85ca86..7f04b944511 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -47,9 +47,9 @@
M.disabilities = 0
M.set_blurriness(0)
M.set_blindness(0)
- M.SetWeakened(0, 0)
- M.SetStunned(0, 0)
- M.SetParalysis(0, 0)
+ M.SetKnockdown(0, 0)
+ M.SetStun(0, 0)
+ M.SetUnconscious(0, 0)
M.silent = 0
M.dizziness = 0
M.drowsyness = 0
@@ -82,9 +82,9 @@
/datum/reagent/medicine/synaptizine/on_mob_life(mob/living/M)
M.drowsyness = max(M.drowsyness-5, 0)
- M.AdjustParalysis(-1, 0)
- M.AdjustStunned(-1, 0)
- M.AdjustWeakened(-1, 0)
+ M.AdjustStun(-20, 0)
+ M.AdjustKnockdown(-20, 0)
+ M.AdjustUnconscious(-20, 0)
if(holder.has_reagent("mindbreaker"))
holder.remove_reagent("mindbreaker", 5)
M.hallucination = max(0, M.hallucination - 10)
@@ -546,9 +546,9 @@
/datum/reagent/medicine/ephedrine/on_mob_life(mob/living/M)
M.status_flags |= GOTTAGOFAST
- M.AdjustParalysis(-1, 0)
- M.AdjustStunned(-1, 0)
- M.AdjustWeakened(-1, 0)
+ M.AdjustStun(-20, 0)
+ M.AdjustKnockdown(-20, 0)
+ M.AdjustUnconscious(-20, 0)
M.adjustStaminaLoss(-1*REM, 0)
..()
. = 1
@@ -621,7 +621,7 @@
if(12 to 24)
M.drowsyness += 1
if(24 to INFINITY)
- M.Sleeping(2, 0)
+ M.Sleeping(40, 0)
. = 1
..()
@@ -757,9 +757,9 @@
M.adjustStaminaLoss(-0.5*REM, 0)
. = 1
if(prob(20))
- M.AdjustParalysis(-1, 0)
- M.AdjustStunned(-1, 0)
- M.AdjustWeakened(-1, 0)
+ M.AdjustStun(-20, 0)
+ M.AdjustKnockdown(-20, 0)
+ M.AdjustUnconscious(-20, 0)
..()
/datum/reagent/medicine/epinephrine/overdose_process(mob/living/M)
@@ -864,9 +864,9 @@
M.adjustToxLoss(-1*REM, 0)
M.adjustBruteLoss(-1*REM, 0)
M.adjustFireLoss(-1*REM, 0)
- M.AdjustParalysis(-3, 0)
- M.AdjustStunned(-3, 0)
- M.AdjustWeakened(-3, 0)
+ M.AdjustStun(-60, 0)
+ M.AdjustKnockdown(-60, 0)
+ M.AdjustUnconscious(-60, 0)
M.adjustStaminaLoss(-5*REM, 0)
..()
. = 1
@@ -888,8 +888,7 @@
metabolization_rate = 0.5 * REAGENTS_METABOLISM
/datum/reagent/medicine/insulin/on_mob_life(mob/living/M)
- if(M.sleeping)
- M.AdjustSleeping(-1, 0)
+ if(M.AdjustSleeping(-20, FALSE))
. = 1
M.reagents.remove_reagent("sugar", 3)
..()
@@ -1102,9 +1101,9 @@
overdose_threshold = 30
/datum/reagent/medicine/changelingAdrenaline/on_mob_life(mob/living/M as mob)
- M.AdjustParalysis(-1, 0)
- M.AdjustStunned(-1, 0)
- M.AdjustWeakened(-1, 0)
+ M.AdjustUnconscious(-20, 0)
+ M.AdjustStun(-20, 0)
+ M.AdjustKnockdown(-20, 0)
M.adjustStaminaLoss(-1, 0)
. = 1
..()
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index f3cc8b86205..cbb38024580 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -247,9 +247,9 @@
/datum/reagent/fuel/unholywater/on_mob_life(mob/living/M)
if(iscultist(M))
M.drowsyness = max(M.drowsyness-5, 0)
- M.AdjustParalysis(-1, 0)
- M.AdjustStunned(-2, 0)
- M.AdjustWeakened(-2, 0)
+ M.AdjustUnconscious(-20, 0)
+ M.AdjustStun(-40, 0)
+ M.AdjustKnockdown(-40, 0)
M.adjustToxLoss(-2, 0)
M.adjustOxyLoss(-2, 0)
M.adjustBruteLoss(-2, 0)
@@ -363,8 +363,8 @@
if(method == INGEST)
if(show_message)
to_chat(M, "That tasted horrible.")
- M.AdjustStunned(2)
- M.AdjustWeakened(2)
+ M.AdjustStun(40)
+ M.AdjustKnockdown(40)
..()
@@ -410,7 +410,7 @@
return
to_chat(H, "You crumple in agony as your flesh wildly morphs into new forms!")
H.visible_message("[H] falls to the ground and screams as [H.p_their()] skin bubbles and froths!") //'froths' sounds painful when used with SKIN.
- H.Weaken(3, 0)
+ H.Knockdown(60, 0)
addtimer(CALLBACK(src, .proc/mutate, H), 30)
return
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index cedec9941b7..17354b692d1 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -165,7 +165,7 @@
/datum/reagent/toxin/zombiepowder/on_mob_life(mob/living/carbon/M)
M.status_flags |= FAKEDEATH
M.adjustOxyLoss(0.5*REM, 0)
- M.Weaken(5, 0)
+ M.Knockdown(100, 0)
M.silent = max(M.silent, 5)
M.tod = worldtime2text()
..()
@@ -275,10 +275,10 @@
M.confused += 2
M.drowsyness += 2
if(10 to 50)
- M.Sleeping(2, 0)
+ M.Sleeping(40, 0)
. = 1
if(51 to INFINITY)
- M.Sleeping(2, 0)
+ M.Sleeping(40, 0)
M.adjustToxLoss((current_cycle - 50)*REM, 0)
. = 1
..()
@@ -294,7 +294,7 @@
M.confused += 1
M.drowsyness += 1
if(20 to INFINITY)
- M.Sleeping(2, 0)
+ M.Sleeping(40, 0)
..()
/datum/reagent/toxin/beer2 //disguised as normal beer for use by emagged brobots
@@ -311,9 +311,9 @@
/datum/reagent/toxin/beer2/on_mob_life(mob/living/M)
switch(current_cycle)
if(1 to 50)
- M.Sleeping(2, 0)
+ M.Sleeping(40, 0)
if(51 to INFINITY)
- M.Sleeping(2, 0)
+ M.Sleeping(40, 0)
M.adjustToxLoss((current_cycle - 50)*REM, 0)
return ..()
@@ -456,7 +456,7 @@
M.adjustToxLoss(1*REM, 0)
. = 1
if(current_cycle >= 18)
- M.Sleeping(2, 0)
+ M.Sleeping(40, 0)
. = 1
..()
@@ -474,7 +474,7 @@
M.losebreath += 1
if(prob(8))
to_chat(M, "You feel horrendously weak!")
- M.Stun(2, 0)
+ M.Stun(40, 0)
M.adjustToxLoss(2*REM, 0)
return ..()
@@ -534,8 +534,7 @@
var/picked_option = rand(1,3)
switch(picked_option)
if(1)
- M.Stun(3, 0)
- M.Weaken(3, 0)
+ M.Knockdown(60, 0)
. = 1
if(2)
M.losebreath += 10
@@ -566,7 +565,7 @@
/datum/reagent/toxin/pancuronium/on_mob_life(mob/living/M)
if(current_cycle >= 10)
- M.Paralyse(2, 0)
+ M.Stun(40, 0)
. = 1
if(prob(20))
M.losebreath += 4
@@ -583,7 +582,7 @@
/datum/reagent/toxin/sodium_thiopental/on_mob_life(mob/living/M)
if(current_cycle >= 10)
- M.Sleeping(2, 0)
+ M.Sleeping(40, 0)
M.adjustStaminaLoss(10*REM, 0)
..()
. = 1
@@ -599,7 +598,7 @@
/datum/reagent/toxin/sulfonal/on_mob_life(mob/living/M)
if(current_cycle >= 22)
- M.Sleeping(2, 0)
+ M.Sleeping(40, 0)
return ..()
/datum/reagent/toxin/amanitin
@@ -613,9 +612,8 @@
/datum/reagent/toxin/amanitin/on_mob_delete(mob/living/M)
var/toxdamage = current_cycle*3*REM
+ M.log_message("has taken [toxdamage] toxin damage from amanitin toxin", INDIVIDUAL_ATTACK_LOG)
M.adjustToxLoss(toxdamage)
- if(M)
- add_logs(M, get_turf(M), "has taken [toxdamage] toxin damage from amanitin toxin")
..()
/datum/reagent/toxin/lipolicide
@@ -663,7 +661,7 @@
.=..()
if(current_cycle >=11 && prob(min(50,current_cycle)) && ishuman(M))
var/mob/living/carbon/human/H = M
- H.vomit(lost_nutrition = 10, blood = prob(10), stun = prob(50), distance = rand(0,4), message = TRUE, toxic = prob(30))
+ H.vomit(10, prob(10), prob(50), rand(0,4), TRUE, prob(30))
for(var/datum/reagent/toxin/R in M.reagents.reagent_list)
if(R != src)
H.reagents.remove_reagent(R.id,1)
@@ -673,7 +671,7 @@
if(current_cycle >=33 && prob(15) && ishuman(M))
var/mob/living/carbon/human/H = M
H.spew_organ()
- H.vomit(lost_nutrition = 0, blood = 1, stun = 1, distance = 4)
+ H.vomit(0, TRUE, TRUE, 4)
to_chat(H, "You feel something lumpy come up as you vomit.")
/datum/reagent/toxin/curare
@@ -687,7 +685,7 @@
/datum/reagent/toxin/curare/on_mob_life(mob/living/M)
if(current_cycle >= 11)
- M.Weaken(3, 0)
+ M.Knockdown(60, 0)
M.adjustOxyLoss(1*REM, 0)
. = 1
..()
@@ -888,7 +886,7 @@
holder.remove_reagent(id, actual_metaboliztion_rate * M.metabolism_efficiency)
M.adjustToxLoss(actual_toxpwr*REM, 0)
if(prob(10))
- M.Weaken(1, 0)
+ M.Knockdown(20, 0)
. = 1
..()
diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm
index 3ba5519a9c0..8cdae1123d8 100644
--- a/code/modules/reagents/chemistry/recipes/others.dm
+++ b/code/modules/reagents/chemistry/recipes/others.dm
@@ -371,7 +371,7 @@
name = "Mix Virus 10"
id = "mixvirus10"
- required_reagents = list("uraniumvirusfood" = 5)
+ required_reagents = list("uraniumvirusfood" = 1)
level_min = 6
level_max = 7
@@ -379,7 +379,7 @@
name = "Mix Virus 11"
id = "mixvirus11"
- required_reagents = list("uraniumplasmavirusfood_unstable" = 5)
+ required_reagents = list("uraniumplasmavirusfood_unstable" = 1)
level_min = 7
level_max = 7
@@ -387,7 +387,7 @@
name = "Mix Virus 12"
id = "mixvirus12"
- required_reagents = list("uraniumplasmavirusfood_stable" = 5)
+ required_reagents = list("uraniumplasmavirusfood_stable" = 1)
level_min = 8
level_max = 8
diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
index 6cfdd80cf53..dc361467a7a 100644
--- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
+++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
@@ -74,7 +74,7 @@
for(var/mob/living/carbon/C in get_hearers_in_view(round(created_volume/48,1),get_turf(holder.my_atom)))
if(iscultist(C))
to_chat(C, "The divine explosion sears you!")
- C.Weaken(2)
+ C.Knockdown(40)
C.adjust_fire_stacks(5)
C.IgniteMob()
..()
@@ -221,9 +221,9 @@
for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/3, location))
if(C.flash_act())
if(get_dist(C, location) < 4)
- C.Weaken(5)
+ C.Knockdown(60)
else
- C.Stun(5)
+ C.Stun(100)
holder.remove_reagent("flash_powder", created_volume*3)
/datum/chemical_reaction/flash_powder_flash
@@ -238,9 +238,9 @@
for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/10, location))
if(C.flash_act())
if(get_dist(C, location) < 4)
- C.Weaken(5)
+ C.Knockdown(60)
else
- C.Stun(5)
+ C.Stun(100)
/datum/chemical_reaction/smoke_powder
name = "smoke_powder"
@@ -296,7 +296,7 @@
var/location = get_turf(holder.my_atom)
playsound(location, 'sound/effects/bang.ogg', 25, 1)
for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/3, location))
- C.soundbang_act(1, 5, rand(0, 5))
+ C.soundbang_act(1, 100, rand(0, 5))
/datum/chemical_reaction/sonic_powder_deafen
name = "sonic_powder_deafen"
@@ -308,7 +308,7 @@
var/location = get_turf(holder.my_atom)
playsound(location, 'sound/effects/bang.ogg', 25, 1)
for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/10, location))
- C.soundbang_act(1, 5, rand(0, 5))
+ C.soundbang_act(1, 100, rand(0, 5))
/datum/chemical_reaction/phlogiston
name = "phlogiston"
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index 5ad154e12b9..c926d19fd53 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -55,7 +55,7 @@
/obj/structure/reagent_dispensers/watertank/high
name = "high-capacity water tank"
- desc = "A highly-pressurized water tank made to hold gargantuan amounts of water.."
+ desc = "A highly pressurized water tank made to hold gargantuan amounts of water."
icon_state = "water_high" //I was gonna clean my room...
tank_volume = 100000
@@ -107,7 +107,7 @@
reagents.trans_to(W, W.max_fuel)
user.visible_message("[user] refills [user.p_their()] [W.name].", "You refill [W].")
playsound(src, 'sound/effects/refill.ogg', 50, 1)
- update_icon()
+ W.update_icon()
else
user.visible_message("[user] catastrophically fails at refilling [user.p_their()] [W.name]!", "That was stupid of you.")
var/message_admins = "[key_name_admin(user)] triggered a fueltank explosion via welding tool."
diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm
index 72e42b500f8..9506c89dbc7 100644
--- a/code/modules/recycling/conveyor2.dm
+++ b/code/modules/recycling/conveyor2.dm
@@ -341,7 +341,7 @@
found = 1
break
if(!found)
- to_chat(user, "\icon[src]The conveyor switch did not detect any linked conveyor belts in range.")
+ to_chat(user, "[bicon(src)]The conveyor switch did not detect any linked conveyor belts in range.")
return
var/obj/machinery/conveyor_switch/NC = new/obj/machinery/conveyor_switch(A, id)
transfer_fingerprints_to(NC)
diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm
index 235cb1d8806..96e227f1999 100644
--- a/code/modules/recycling/disposal-construction.dm
+++ b/code/modules/recycling/disposal-construction.dm
@@ -231,7 +231,7 @@
if(anchored)
var/obj/item/weapon/weldingtool/W = I
if(W.remove_fuel(0,user))
- playsound(loc, 'sound/items/Welder2.ogg', 100, 1)
+ playsound(loc, 'sound/items/welder2.ogg', 100, 1)
to_chat(user, "You start welding the [nicetype] in place...")
if(do_after(user, 8*I.toolspeed, target = src))
if(!loc || !W.isOn())
diff --git a/code/modules/recycling/disposal-structures.dm b/code/modules/recycling/disposal-structures.dm
index 6ea1d958b3c..4d5d760dc30 100644
--- a/code/modules/recycling/disposal-structures.dm
+++ b/code/modules/recycling/disposal-structures.dm
@@ -301,7 +301,7 @@
var/obj/item/weapon/weldingtool/W = I
if(can_be_deconstructed(user))
if(W.remove_fuel(0,user))
- playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder2.ogg', 100, 1)
to_chat(user, "You start slicing the disposal pipe...")
// check if anything changed over 2 seconds
if(do_after(user,30, target = src))
@@ -707,7 +707,7 @@
else if(istype(I,/obj/item/weapon/weldingtool) && mode==1)
var/obj/item/weapon/weldingtool/W = I
if(W.remove_fuel(0,user))
- playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder2.ogg', 100, 1)
to_chat(user, "You start slicing the floorweld off \the [src]...")
if(do_after(user,20*I.toolspeed, target = src))
if(!src || !W.isOn()) return
diff --git a/code/modules/recycling/disposal-unit.dm b/code/modules/recycling/disposal-unit.dm
index 626a3f2549f..5e117000d8d 100644
--- a/code/modules/recycling/disposal-unit.dm
+++ b/code/modules/recycling/disposal-unit.dm
@@ -86,7 +86,7 @@
else if(istype(I,/obj/item/weapon/weldingtool) && panel_open)
var/obj/item/weapon/weldingtool/W = I
if(W.remove_fuel(0,user))
- playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1)
+ playsound(src.loc, 'sound/items/welder2.ogg', 100, 1)
to_chat(user, "You start slicing the floorweld off \the [src]...")
if(do_after(user,20*I.toolspeed, target = src) && panel_open)
if(!W.isOn())
diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm
index 3cb462c9c83..ae5449d90f8 100644
--- a/code/modules/research/circuitprinter.dm
+++ b/code/modules/research/circuitprinter.dm
@@ -5,7 +5,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
*/
/obj/machinery/r_n_d/circuit_imprinter
- name = "Circuit Imprinter"
+ name = "circuit imprinter"
desc = "Manufactures circuit boards for the construction of machines."
icon_state = "circuit_imprinter"
container_type = OPENCONTAINER
diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm
index 7fbc8309a8f..283c94fd483 100644
--- a/code/modules/research/designs/autolathe_designs.dm
+++ b/code/modules/research/designs/autolathe_designs.dm
@@ -216,7 +216,7 @@
/datum/design/rglass
name = "Reinforced Glass"
id = "rglass"
- build_type = AUTOLATHE
+ build_type = AUTOLATHE | SMELTER
materials = list(MAT_METAL = 1000, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
build_path = /obj/item/stack/sheet/rglass
category = list("initial","Construction")
@@ -235,7 +235,7 @@
name = "Compressed Matter Cartridge"
id = "rcd_ammo"
build_type = AUTOLATHE
- materials = list(MAT_METAL = 3000, MAT_GLASS=2000)
+ materials = list(MAT_METAL = 12000, MAT_GLASS=8000)
build_path = /obj/item/weapon/rcd_ammo
category = list("initial","Construction")
@@ -783,7 +783,7 @@
materials = list(MAT_METAL = 2000, MAT_GLASS = 1000)
build_path = /obj/item/device/modular_computer/tablet
category = list("initial","Misc")
-
+
/datum/design/slime_scanner
name = "Slime Scanner"
id = "slime_scanner"
@@ -791,4 +791,3 @@
materials = list(MAT_METAL = 300, MAT_GLASS = 200)
build_path = /obj/item/device/slime_scanner
category = list("initial", "Misc")
-
\ No newline at end of file
diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm
index 9267c5c7f98..51485380cec 100644
--- a/code/modules/research/designs/mechfabricator_designs.dm
+++ b/code/modules/research/designs/mechfabricator_designs.dm
@@ -763,7 +763,6 @@
name = "Flash"
desc = "When a problem arises, SCIENCE is the solution."
id = "sflash"
- req_tech = list("magnets" = 3, "combat" = 2)
build_type = MECHFAB
materials = list(MAT_METAL = 750, MAT_GLASS = 750)
construction_time = 100
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index f72458af4ea..0f267aa3118 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -190,6 +190,17 @@
build_path = /obj/item/organ/eyes/robotic/shield
category = list("Misc", "Medical Designs")
+/datum/design/cyberimp_gloweyes
+ name = "Luminescent Eyes"
+ desc = "A pair of cybernetic eyes that can emit multicolored light"
+ id = "ci-gloweyes"
+ req_tech = list("materials" = 3, "biotech" = 3, "engineering" = 4)
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 40
+ materials = list(MAT_METAL = 600, MAT_GLASS = 1000)
+ build_path = /obj/item/organ/eyes/robotic/glow
+ category = list("Misc", "Medical Designs")
+
/datum/design/cyberimp_breather
name = "Breathing Tube Implant"
desc = "This simple implant adds an internals connector to your back, allowing you to use internals without a mask and protecting you from being choked."
@@ -357,22 +368,22 @@
build_path = /obj/item/weapon/implantcase/sad_trombone
category = list("Medical Designs")
-/datum/design/implant_freedom
- name = "Freedom Implant Case"
+/datum/design/implant_chem
+ name = "Chemical Implant Case"
desc = "A glass case containing an implant."
- id = "implant_freedom"
- req_tech = list("combat" = 6, "biotech" = 5, "magnets" = 3, "syndicate" = 3)
+ id = "implant_chem"
+ req_tech = list("materials" = 3, "biotech" = 5,)
build_type = PROTOLATHE
- materials = list(MAT_METAL = 800, MAT_GLASS = 500, MAT_GOLD = 500)
- build_path = /obj/item/weapon/implantcase/freedom
+ materials = list(MAT_GLASS = 700)
+ build_path = /obj/item/weapon/implantcase/chem
category = list("Medical Designs")
-/datum/design/implant_adrenalin
- name = "Adrenalin Implant Case"
+/datum/design/implant_tracking
+ name = "Tracking Implant Case"
desc = "A glass case containing an implant."
- id = "implant_adrenalin"
- req_tech = list("biotech" = 6, "combat" = 6, "syndicate" = 6)
+ id = "implant_tracking"
+ req_tech = list("materials" = 2, "biotech" = 3, "magnets" = 3, "programming" = 2)
build_type = PROTOLATHE
- materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_GOLD = 500, MAT_URANIUM = 600, MAT_DIAMOND = 600)
- build_path = /obj/item/weapon/implantcase/adrenaline
+ materials = list(MAT_METAL = 500, MAT_GLASS = 500)
+ build_path = /obj/item/weapon/implantcase/track
category = list("Medical Designs")
diff --git a/code/modules/research/designs/smelting_designs.dm b/code/modules/research/designs/smelting_designs.dm
index 9367b38da7a..5c9c0f68313 100644
--- a/code/modules/research/designs/smelting_designs.dm
+++ b/code/modules/research/designs/smelting_designs.dm
@@ -4,7 +4,7 @@
name = "Plasma + Iron alloy"
id = "plasteel"
build_type = SMELTER
- materials = list(MAT_METAL = MINERAL_MATERIAL_AMOUNT / 2, MAT_PLASMA = MINERAL_MATERIAL_AMOUNT / 2)
+ materials = list(MAT_METAL = MINERAL_MATERIAL_AMOUNT, MAT_PLASMA = MINERAL_MATERIAL_AMOUNT)
build_path = /obj/item/stack/sheet/plasteel
category = list("initial")
@@ -13,7 +13,7 @@
name = "Plasma + Titanium alloy"
id = "plastitanium"
build_type = SMELTER
- materials = list(MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT / 2, MAT_PLASMA = MINERAL_MATERIAL_AMOUNT / 2)
+ materials = list(MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT, MAT_PLASMA = MINERAL_MATERIAL_AMOUNT)
build_path = /obj/item/stack/sheet/mineral/plastitanium
category = list("initial")
diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm
index 4f950f178f0..872ccd359de 100644
--- a/code/modules/research/destructive_analyzer.dm
+++ b/code/modules/research/destructive_analyzer.dm
@@ -8,7 +8,7 @@ It is used to destroy hand-held objects and advance technological research. Cont
Note: Must be placed within 3 tiles of the R&D Console
*/
/obj/machinery/r_n_d/destructive_analyzer
- name = "Destructive Analyzer"
+ name = "destructive analyzer"
desc = "Learn science by destroying things!"
icon_state = "d_analyzer"
var/decon_mod = 0
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index d34e6723cbc..5e93cdac8f0 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -16,7 +16,8 @@
#define FAIL 8
/obj/machinery/r_n_d/experimentor
- name = "E.X.P.E.R.I-MENTOR"
+ name = "\improper E.X.P.E.R.I-MENTOR"
+ desc = "A \"replacement\" for the deconstructive analyzer with a slight tendency to catastrophically fail."
icon = 'icons/obj/machines/heavy_lathe.dmi'
icon_state = "h_lathe"
density = 1
diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm
index 0abe4e952c1..84432e8e442 100644
--- a/code/modules/research/protolathe.dm
+++ b/code/modules/research/protolathe.dm
@@ -8,7 +8,7 @@ Note: Must be placed west/left of and R&D console to function.
*/
/obj/machinery/r_n_d/protolathe
- name = "Protolathe"
+ name = "protolathe"
desc = "Converts raw materials into useful objects."
icon_state = "protolathe"
container_type = OPENCONTAINER
diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm
index 0c32efbb64d..d7230c737cf 100644
--- a/code/modules/research/stock_parts.dm
+++ b/code/modules/research/stock_parts.dm
@@ -39,8 +39,8 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi
max_w_class = WEIGHT_CLASS_NORMAL
max_combined_w_class = 800
works_from_distance = 1
- pshoom_or_beepboopblorpzingshadashwoosh = 'sound/items/PSHOOM.ogg'
- alt_sound = 'sound/items/PSHOOM_2.ogg'
+ pshoom_or_beepboopblorpzingshadashwoosh = 'sound/items/pshoom.ogg'
+ alt_sound = 'sound/items/pshoom_2.ogg'
/obj/item/weapon/storage/part_replacer/bluespace/content_can_dump(atom/dest_object, mob/user)
if(Adjacent(user))
diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm
index 131eb138f59..f2546ea465e 100644
--- a/code/modules/research/xenobiology/xenobio_camera.dm
+++ b/code/modules/research/xenobiology/xenobio_camera.dm
@@ -22,7 +22,6 @@
desc = "A computer used for remotely handling slimes."
networks = list("SS13")
circuit = /obj/item/weapon/circuitboard/computer/xenobiology
- off_action = new/datum/action/innate/camera_off/xenobio
var/datum/action/innate/slime_place/slime_place_action = new
var/datum/action/innate/slime_pick_up/slime_up_action = new
var/datum/action/innate/feed_slime/feed_slime_action = new
@@ -45,23 +44,27 @@
eyeobj.icon_state = "camera_target"
/obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/user)
- off_action.target = user
- off_action.Grant(user)
+ ..()
- jump_action.target = user
- jump_action.Grant(user)
+ if(slime_up_action)
+ slime_up_action.target = src
+ slime_up_action.Grant(user)
+ actions += slime_up_action
- slime_up_action.target = src
- slime_up_action.Grant(user)
+ if(slime_place_action)
+ slime_place_action.target = src
+ slime_place_action.Grant(user)
+ actions += slime_place_action
- slime_place_action.target = src
- slime_place_action.Grant(user)
+ if(feed_slime_action)
+ feed_slime_action.target = src
+ feed_slime_action.Grant(user)
+ actions += feed_slime_action
- feed_slime_action.target = src
- feed_slime_action.Grant(user)
-
- monkey_recycle_action.target = src
- monkey_recycle_action.Grant(user)
+ if(monkey_recycle_action)
+ monkey_recycle_action.target = src
+ monkey_recycle_action.Grant(user)
+ actions += monkey_recycle_action
/obj/machinery/computer/camera_advanced/xenobio/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeycube))
@@ -83,30 +86,6 @@
return
..()
-/datum/action/innate/camera_off/xenobio/Activate()
- if(!target || !isliving(target))
- return
- var/mob/living/C = target
- var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
- var/obj/machinery/computer/camera_advanced/xenobio/origin = remote_eye.origin
- origin.current_user = null
- origin.jump_action.Remove(C)
- origin.slime_place_action.Remove(C)
- origin.slime_up_action.Remove(C)
- origin.feed_slime_action.Remove(C)
- origin.monkey_recycle_action.Remove(C)
- //All of this stuff below could probably be a proc for all advanced cameras, only the action removal needs to be camera specific
- C.reset_perspective(null)
- if(C.client)
- C.client.images -= remote_eye.user_image
- for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks)
- chunk.remove(remote_eye)
- remote_eye.eye_user = null
- C.remote_control = null
- C.unset_machine()
- Remove(C)
-
-
/datum/action/innate/slime_place
name = "Place Slimes"
button_icon_state = "slime_down"
diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm
index 708a155fb3c..94c99878bf8 100644
--- a/code/modules/research/xenobiology/xenobiology.dm
+++ b/code/modules/research/xenobiology/xenobiology.dm
@@ -401,10 +401,10 @@
if(L.gender == MALE)
L.gender = FEMALE
- L.visible_message("[L] suddenly looks more feminine!")
+ L.visible_message("[L] suddenly looks more feminine!", "You suddenly feel more feminine!")
else
L.gender = MALE
- L.visible_message("[L] suddenly looks more masculine!")
+ L.visible_message("[L] suddenly looks more masculine!", "You suddenly feel more masculine!")
L.regenerate_icons()
qdel(src)
@@ -561,21 +561,23 @@
/obj/effect/timestop/Initialize()
. = ..()
- for(var/mob/living/M in GLOB.player_list)
- for(var/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop/T in M.mind.spell_list) //People who can stop time are immune to timestop
- immune |= M
+ for(var/M in GLOB.living_mob_list)
+ var/mob/living/L = M
+ for(var/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop/T in L.mind.spell_list) //People who can stop time are immune to timestop
+ immune |= L
timestop()
/obj/effect/timestop/proc/timestop()
- playsound(get_turf(src), 'sound/magic/TIMEPARADOX2.ogg', 100, 1, -1)
+ set waitfor = FALSE
+ playsound(get_turf(src), 'sound/magic/timeparadox2.ogg', 100, 1, -1)
for(var/i in 1 to duration-1)
for(var/atom/A in orange (freezerange, src.loc))
if(isliving(A))
var/mob/living/M = A
if(M in immune)
continue
- M.Stun(10, 1, 1)
+ M.Stun(200, 1, 1)
M.anchored = 1
if(ishostile(M))
var/mob/living/simple_animal/hostile/H = M
@@ -605,7 +607,7 @@
/obj/effect/timestop/proc/unfreeze_mob(mob/living/M)
- M.AdjustStunned(-10, 1, 1)
+ M.AdjustStun(-200, 1, 1)
M.anchored = 0
if(ishostile(M))
var/mob/living/simple_animal/hostile/H = M
diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm
index 8ead387a8e9..805d46b9c72 100644
--- a/code/modules/ruins/lavaland_ruin_code.dm
+++ b/code/modules/ruins/lavaland_ruin_code.dm
@@ -133,7 +133,7 @@
death = FALSE
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "sleeper_s"
- flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Continue your research as best you can, and try to keep a low profile. Do not abandon the base without good cause. The base is rigged with explosives should the worst happen, do not let the base fall into enemy hands!"
+ flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Continue your research as best you can, and try to keep a low profile. DON'T abandon the base without good cause. The base is rigged with explosives should the worst happen, do not let the base fall into enemy hands!"
id_access_list = list(GLOB.access_syndicate)
outfit = /datum/outfit/lavaland_syndicate
@@ -148,13 +148,14 @@
back = /obj/item/weapon/storage/backpack
r_pocket = /obj/item/weapon/gun/ballistic/automatic/pistol
id = /obj/item/weapon/card/id
+ implants = list(/obj/item/weapon/implant/weapons_auth)
/datum/outfit/lavaland_syndicate/post_equip(mob/living/carbon/human/H)
H.faction |= "syndicate"
/obj/effect/mob_spawn/human/lavaland_syndicate/comms
name = "Syndicate Comms Agent"
- flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Monitor enemy activity as best you can, and try to keep a low profile. Do not abandon the base without good cause. Use the communication equipment to provide support to any field agents, and sow disinformation to throw Nanotrasen off your trail. Do not let the base fall into enemy hands!"
+ flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Monitor enemy activity as best you can, and try to keep a low profile. DON'T abandon the base without good cause. Use the communication equipment to provide support to any field agents, and sow disinformation to throw Nanotrasen off your trail. Do not let the base fall into enemy hands!"
outfit = /datum/outfit/lavaland_syndicate/comms
/datum/outfit/lavaland_syndicate/comms
diff --git a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm
index c59850198e3..aab6403acd1 100644
--- a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm
+++ b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm
@@ -12,6 +12,15 @@
loot = list(/obj/effect/gibspawner, /obj/item/device/assembly/signaler/anomaly)
del_on_death = 1
var/meat_counter
+ var/obj/effect/light_emitter/tendril/emitted_light
+
+/mob/living/simple_animal/hostile/spawner/ash_walker/Initialize()
+ . = ..()
+ emitted_light = new(loc)
+
+/mob/living/simple_animal/hostile/spawner/ash_walker/Destroy()
+ QDEL_NULL(emitted_light)
+ . = ..()
/mob/living/simple_animal/hostile/spawner/ash_walker/Life()
..()
@@ -23,7 +32,7 @@
for(var/mob/living/H in view(src,1)) //Only for corpse right next to/on same tile
if(H.stat)
visible_message("Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs.")
- playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1)
+ playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, 1)
if(ismegafauna(H))
meat_counter += 20
else
diff --git a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm
index 2938f9263cf..aedb1237c20 100644
--- a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm
+++ b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm
@@ -35,7 +35,7 @@
visible_message("Locks along the door begin clicking open from within...")
var/volume = 60
for(var/i in 1 to 3)
- playsound(src, 'sound/items/Deconstruct.ogg', volume, 0)
+ playsound(src, 'sound/items/deconstruct.ogg', volume, 0)
volume += 20
sleep(10)
sleep(10)
diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm
index 006943ade52..22320c35f21 100644
--- a/code/modules/security_levels/keycard_authentication.dm
+++ b/code/modules/security_levels/keycard_authentication.dm
@@ -40,6 +40,7 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new)
data["auth_required"] = event_source ? event_source.event : 0
data["red_alert"] = (seclevel2num(get_security_level()) >= SEC_LEVEL_RED) ? 1 : 0
data["emergency_maint"] = GLOB.emergency_access
+ data["bsa_unlock"] = GLOB.bsa_unlock
return data
/obj/machinery/keycard_auth/ui_status(mob/user)
@@ -67,6 +68,10 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new)
event_source.trigger_event(usr)
event_source = null
. = TRUE
+ if("bsa_unlock")
+ if(!event_source)
+ sendEvent("Bluespace Artillery Unlock")
+ . = TRUE
/obj/machinery/keycard_auth/proc/sendEvent(event_type)
triggerer = usr
@@ -95,11 +100,13 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new)
switch(event)
if("Red Alert")
set_security_level(SEC_LEVEL_RED)
- SSblackbox.inc("alert_keycard_auth_red",1)
+ SSblackbox.inc("alert_keycard_auth_red",)
if("Emergency Maintenance Access")
make_maint_all_access()
- SSblackbox.inc("alert_keycard_auth_maint",1)
-
+ SSblackbox.inc("alert_keycard_auth_maint")
+ if("Bluespace Artillery Unlock")
+ toggle_bluespace_artillery()
+ SSblackbox.inc("alert_keycard_auth_bsa")
GLOBAL_VAR_INIT(emergency_access, FALSE)
/proc/make_maint_all_access()
@@ -117,3 +124,7 @@ GLOBAL_VAR_INIT(emergency_access, FALSE)
D.update_icon(0)
minor_announce("Access restrictions in maintenance areas have been restored.", "Attention! Station-wide emergency rescinded:")
GLOB.emergency_access = FALSE
+
+/proc/toggle_bluespace_artillery()
+ GLOB.bsa_unlock = !GLOB.bsa_unlock
+ minor_announce("Bluespace Artillery firing protocols have been [GLOB.bsa_unlock? "unlocked" : "locked"]", "Weapons Systems Update:")
diff --git a/code/modules/server_tools/server_tools.dm b/code/modules/server_tools/server_tools.dm
index 725c9f82c09..0f05d467a3f 100644
--- a/code/modules/server_tools/server_tools.dm
+++ b/code/modules/server_tools/server_tools.dm
@@ -5,23 +5,27 @@ GLOBAL_PROTECT(reboot_mode)
return params[SERVICE_WORLD_PARAM]
/world/proc/ExportService(command)
- return shell("python code/modules/server_tools/nudge.py \"[command]\"") == 0
+ return RunningService() && shell("python code/modules/server_tools/nudge.py \"[command]\"") == 0
/world/proc/IRCBroadcast(msg)
ExportService("[SERVICE_REQUEST_IRC_BROADCAST] [msg]")
+/world/proc/ServiceEndProcess()
+ log_world("Sending shutdown request!");
+ sleep(1) //flush the buffers
+ ExportService(SERVICE_REQUEST_KILL_PROCESS)
+
//called at the exact moment the world is supposed to reboot
/world/proc/ServiceReboot()
switch(GLOB.reboot_mode)
if(REBOOT_MODE_HARD)
to_chat(src, "Hard reboot triggered, you will automatically reconnect...")
- log_world("Sending shutdown request!");
- sleep(1) //flush the buffers
- ExportService(SERVICE_REQUEST_KILL_PROCESS)
+ ServiceEndProcess()
if(REBOOT_MODE_SHUTDOWN)
to_chat(src, "The server is shutting down...")
- log_world("Deleting world")
- qdel(src)
+ ServiceEndProcess()
+ else
+ ExportService(SERVICE_REQUEST_WORLD_REBOOT) //just let em know
/world/proc/ServiceCommand(list/params)
var/sCK = RunningService()
@@ -64,7 +68,12 @@ GLOBAL_PROTECT(reboot_mode)
var/status = "Admins: [allmins.len] (Active: [english_list(adm["present"])] AFK: [english_list(adm["afk"])] Stealth: [english_list(adm["stealth"])] Skipped: [english_list(adm["noflags"])]). "
status += "Players: [GLOB.clients.len] (Active: [get_active_player_count(0,1,0)]). Mode: [SSticker.mode ? SSticker.mode.name : "Not started"]."
return status
-
+ if(SERVICE_CMD_IRC_CHECK)
+ var/rtod = REALTIMEOFDAY
+ if(rtod - last_irc_status < IRC_STATUS_THROTTLE)
+ return
+ last_irc_status = rtod
+ return "[GLOB.clients.len] players on [SSmapping.config.map_name], Mode: [GLOB.master_mode]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [config.server ? config.server : "byond://[address]:[port]"]"
if(SERVICE_CMD_ADMIN_MSG)
return IrcPm(params[SERVICE_CMD_PARAM_TARGET], params[SERVICE_CMD_PARAM_MESSAGE], params[SERVICE_CMD_PARAM_SENDER])
diff --git a/code/modules/shuttle/arrivals.dm b/code/modules/shuttle/arrivals.dm
index 9aa0041a657..25dfa135975 100644
--- a/code/modules/shuttle/arrivals.dm
+++ b/code/modules/shuttle/arrivals.dm
@@ -43,16 +43,16 @@
console = locate(/obj/machinery/requests_console) in A
areas += A
- if(GLOB.latejoin.len)
+ if(SSjob.latejoin_trackers.len)
WARNING("Map contains predefined latejoin spawn points and an arrivals shuttle. Using the arrivals shuttle.")
if(!new_latejoin.len)
WARNING("Arrivals shuttle contains no chairs for spawn points. Reverting to latejoin landmarks.")
- if(!GLOB.latejoin.len)
+ if(!SSjob.latejoin_trackers.len)
WARNING("No latejoin landmarks exist. Players will spawn unbuckled on the shuttle.")
return
- GLOB.latejoin = new_latejoin
+ SSjob.latejoin_trackers = new_latejoin
/obj/docking_port/mobile/arrivals/dockRoundstart()
SSshuttle.generate_transit_dock(src)
@@ -109,7 +109,7 @@
Launch(FALSE)
/obj/docking_port/mobile/arrivals/proc/CheckTurfsPressure()
- for(var/I in GLOB.latejoin)
+ for(var/I in SSjob.latejoin_trackers)
var/turf/open/T = get_turf(I)
var/pressure = T.air.return_pressure()
if(pressure < HAZARD_LOW_PRESSURE || pressure > HAZARD_HIGH_PRESSURE) //simple safety check
diff --git a/code/modules/shuttle/assault_pod.dm b/code/modules/shuttle/assault_pod.dm
index 37cd0238b30..399a4abd4d9 100644
--- a/code/modules/shuttle/assault_pod.dm
+++ b/code/modules/shuttle/assault_pod.dm
@@ -13,7 +13,7 @@
/obj/docking_port/mobile/assault_pod/dock(obj/docking_port/stationary/S1)
..()
if(!istype(S1, /obj/docking_port/stationary/transit))
- playsound(get_turf(src.loc), 'sound/effects/Explosion1.ogg',50,1)
+ playsound(get_turf(src.loc), 'sound/effects/explosion1.ogg',50,1)
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index e1ed63793d3..4c0dde7cf0b 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -230,14 +230,14 @@
else
SSshuttle.emergencyLastCallLoc = null
- priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/AI/shuttlecalled.ogg', "Priority")
+ priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/ai/shuttlecalled.ogg', "Priority")
/obj/docking_port/mobile/emergency/cancel(area/signalOrigin)
if(mode != SHUTTLE_CALL)
return
if(SSshuttle.emergencyNoRecall)
return
-
+
invertTimer()
mode = SHUTTLE_RECALL
@@ -245,7 +245,7 @@
SSshuttle.emergencyLastCallLoc = signalOrigin
else
SSshuttle.emergencyLastCallLoc = null
- priority_announce("The emergency shuttle has been recalled.[SSshuttle.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/AI/shuttlerecalled.ogg', "Priority")
+ priority_announce("The emergency shuttle has been recalled.[SSshuttle.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/ai/shuttlerecalled.ogg', "Priority")
/obj/docking_port/mobile/emergency/proc/is_hijacked()
var/has_people = FALSE
@@ -296,7 +296,7 @@
mode = SHUTTLE_DOCKED
setTimer(SSshuttle.emergencyDockTime)
send2irc("Server", "The Emergency Shuttle has docked with the station.")
- priority_announce("The Emergency Shuttle has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority")
+ priority_announce("The Emergency Shuttle has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.", null, 'sound/ai/shuttledock.ogg', "Priority")
if(SSdbcore.Connect())
var/datum/DBQuery/query_round_shuttle_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET shuttle_name = '[name]' WHERE id = [GLOB.round_id]")
query_round_shuttle_name.Execute()
@@ -402,6 +402,16 @@
mode = SHUTTLE_ENDGAME
timer = 0
+/obj/docking_port/mobile/emergency/transit_failure()
+ ..()
+ message_admins("Moving emergency shuttle directly to centcom dock to prevent deadlock.")
+
+ mode = SHUTTLE_ESCAPE
+ launch_status = ENDGAME_LAUNCHED
+ setTimer(SSshuttle.emergencyEscapeTime)
+ priority_announce("The Emergency Shuttle preparing for direct jump. Estimate [timeLeft(600)] minutes until the shuttle docks at Central Command.", null, null, "Priority")
+
+
/obj/docking_port/mobile/pod
name = "escape pod"
id = "pod"
diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm
index b5571164ffd..f9ae5996a21 100644
--- a/code/modules/shuttle/on_move.dm
+++ b/code/modules/shuttle/on_move.dm
@@ -52,7 +52,7 @@
if(!.)
return
if(!buckled && knockdown)
- Weaken(3)
+ Knockdown(60)
/obj/effect/abstract/proximity_checker/onShuttleMove()
//timer so it only happens once
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index 96db9d0ac39..dcd296e9b1a 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -313,6 +313,9 @@
message_admins(msg)
return FALSE
+/obj/docking_port/mobile/proc/transit_failure()
+ message_admins("Shuttle [src] repeatedly failed to create transit zone.")
+
//call the shuttle to destination S
/obj/docking_port/mobile/proc/request(obj/docking_port/stationary/S)
if(!check_dock(S))
diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm
index 72e7b5bb3f3..855e74fc6b9 100644
--- a/code/modules/shuttle/special.dm
+++ b/code/modules/shuttle/special.dm
@@ -104,7 +104,7 @@
// Existing sleepers
for(var/i in found)
var/mob/living/L = i
- L.SetSleeping(10)
+ L.SetSleeping(200)
// Missing sleepers
for(var/i in sleepers - found)
@@ -192,7 +192,7 @@
// No climbing on the bar please
var/mob/living/M = AM
var/throwtarget = get_edge_target_turf(src, boot_dir)
- M.Weaken(2)
+ M.Knockdown(40)
M.throw_at(throwtarget, 5, 1,src)
to_chat(M, "No climbing on the bar please.")
else
diff --git a/code/modules/shuttle/transit.dm b/code/modules/shuttle/transit.dm
deleted file mode 100644
index 7bf217d1ff7..00000000000
--- a/code/modules/shuttle/transit.dm
+++ /dev/null
@@ -1,14 +0,0 @@
-/obj/effect/landmark/transit
- name = "transit space marker"
- desc = "This indicates where transit space begins and ends."
- invisibility = FALSE
- icon = 'icons/effects/effects.dmi'
- icon_state = "at_shield1"
-
-/obj/effect/landmark/transit/Initialize()
- . = ..()
- GLOB.transit_markers += src
-
-/obj/effect/landmark/transit/Destroy()
- GLOB.transit_markers -= src
- . = ..()
diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm
index f022e0338fe..42d57e30c73 100644
--- a/code/modules/spells/spell.dm
+++ b/code/modules/spells/spell.dm
@@ -134,7 +134,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
return 0
var/turf/T = get_turf(user)
- if(T.z == ZLEVEL_CENTCOM && (!centcom_cancast || SSticker.mode.name == "ragin' mages")) //Certain spells are not allowed on the centcom zlevel
+ if(T.z == ZLEVEL_CENTCOM && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel
to_chat(user, "You can't cast this spell here.")
return 0
@@ -347,12 +347,12 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
target.adjustToxLoss(amount)
if("oxyloss")
target.adjustOxyLoss(amount)
- if("stunned")
- target.AdjustStunned(amount)
- if("weakened")
- target.AdjustWeakened(amount)
- if("paralysis")
- target.AdjustParalysis(amount)
+ if("stun")
+ target.AdjustStun(amount)
+ if("knockdown")
+ target.AdjustKnockdown(amount)
+ if("unconscious")
+ target.AdjustUnconscious(amount)
else
target.vars[type] += amount //I bear no responsibility for the runtimes that'll happen if you try to adjust non-numeric or even non-existant vars
@@ -507,7 +507,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
invocation = "Victus sano!"
invocation_type = "whisper"
school = "restoration"
- sound = 'sound/magic/Staff_Healing.ogg'
+ sound = 'sound/magic/staff_healing.ogg'
/obj/effect/proc_holder/spell/self/basic_heal/cast(mob/living/carbon/human/user) //Note the lack of "list/targets" here. Instead, use a "user" var depending on mob requirements.
//Also, notice the lack of a "for()" statement that looks through the targets. This is, again, because the spell can only have a single target.
diff --git a/code/modules/spells/spell_types/aimed.dm b/code/modules/spells/spell_types/aimed.dm
index b06f69c1898..94597de40f6 100644
--- a/code/modules/spells/spell_types/aimed.dm
+++ b/code/modules/spells/spell_types/aimed.dm
@@ -105,7 +105,7 @@
projectile_type = /obj/item/projectile/magic/aoe/fireball
base_icon_state = "fireball"
action_icon_state = "fireball0"
- sound = 'sound/magic/Fireball.ogg'
+ sound = 'sound/magic/fireball.ogg'
active_msg = "You prepare to cast your fireball spell!"
deactive_msg = "You extinguish your fireball... for now."
active = FALSE
diff --git a/code/modules/spells/spell_types/area_teleport.dm b/code/modules/spells/spell_types/area_teleport.dm
index 5a06351f885..7381cdf48f3 100644
--- a/code/modules/spells/spell_types/area_teleport.dm
+++ b/code/modules/spells/spell_types/area_teleport.dm
@@ -5,8 +5,8 @@
var/randomise_selection = 0 //if it lets the usr choose the teleport loc or picks it from the list
var/invocation_area = 1 //if the invocation appends the selected area
- var/sound1 = 'sound/weapons/ZapBang.ogg'
- var/sound2 = 'sound/weapons/ZapBang.ogg'
+ var/sound1 = 'sound/weapons/zapbang.ogg'
+ var/sound2 = 'sound/weapons/zapbang.ogg'
/obj/effect/proc_holder/spell/targeted/area_teleport/perform(list/targets, recharge = 1,mob/living/user = usr)
var/thearea = before_cast(targets)
diff --git a/code/modules/spells/spell_types/barnyard.dm b/code/modules/spells/spell_types/barnyard.dm
index b8dd330a668..d21b54b0704 100644
--- a/code/modules/spells/spell_types/barnyard.dm
+++ b/code/modules/spells/spell_types/barnyard.dm
@@ -32,7 +32,7 @@
return
var/list/masks = list(/obj/item/clothing/mask/spig, /obj/item/clothing/mask/cowmask, /obj/item/clothing/mask/horsehead)
- var/list/mSounds = list('sound/magic/PigHead_curse.ogg', 'sound/magic/CowHead_Curse.ogg', 'sound/magic/HorseHead_curse.ogg')
+ var/list/mSounds = list('sound/magic/pighead_curse.ogg', 'sound/magic/cowhead_curse.ogg', 'sound/magic/horsehead_curse.ogg')
var/randM = rand(1,3)
diff --git a/code/modules/spells/spell_types/charge.dm b/code/modules/spells/spell_types/charge.dm
index c37166a2446..9cc3e3b5a8d 100644
--- a/code/modules/spells/spell_types/charge.dm
+++ b/code/modules/spells/spell_types/charge.dm
@@ -44,8 +44,8 @@
charged_item = I
break
else
- to_chat(L, "Glowing red letters appear on the front cover...")
- to_chat(L, "[pick("NICE TRY BUT NO!","CLEVER BUT NOT CLEVER ENOUGH!", "SUCH FLAGRANT CHEESING IS WHY WE ACCEPTED YOUR APPLICATION!", "CUTE!", "YOU DIDN'T THINK IT'D BE THAT EASY, DID YOU?")]")
+ to_chat(L, "Glowing red letters appear on the front cover...")
+ to_chat(L, "[pick("NICE TRY BUT NO!","CLEVER BUT NOT CLEVER ENOUGH!", "SUCH FLAGRANT CHEESING IS WHY WE ACCEPTED YOUR APPLICATION!", "CUTE! VERY CUTE!", "YOU DIDN'T THINK IT'D BE THAT EASY, DID YOU?")]")
burnt_out = 1
else if(istype(item, /obj/item/weapon/gun/magic))
var/obj/item/weapon/gun/magic/I = item
@@ -95,5 +95,5 @@
else if(burnt_out)
to_chat(L, "[charged_item] doesn't seem to be reacting to the spell...")
else
- playsound(get_turf(L), 'sound/magic/Charge.ogg', 50, 1)
+ playsound(get_turf(L), 'sound/magic/charge.ogg', 50, 1)
to_chat(L, "[charged_item] suddenly feels very warm!")
diff --git a/code/modules/spells/spell_types/devil.dm b/code/modules/spells/spell_types/devil.dm
index 85a279b3098..78d568c39ee 100644
--- a/code/modules/spells/spell_types/devil.dm
+++ b/code/modules/spells/spell_types/devil.dm
@@ -103,18 +103,14 @@
/obj/effect/proc_holder/spell/targeted/infernal_jaunt/cast(list/targets, mob/living/user = usr)
if(istype(user))
if(istype(user.loc, /obj/effect/dummy/slaughter/))
- var/continuing = 0
- if(istype(get_area(user), /area/shuttle/)) // Can always phase in in a shuttle.
- continuing = 1
- else
- for(var/mob/living/C in orange(2, get_turf(user.loc))) //Can also phase in when nearby a potential buyer.
- if (C.owns_soul())
- continuing = 1
- break
- if(continuing)
+ if(valid_location(user))
to_chat(user, "You are now phasing in.")
if(do_mob(user,user,150))
- user.infernalphasein()
+ if(valid_location(user))
+ user.infernalphasein()
+ else
+ to_chat(user, "You are no longer near a potential signer.")
+
else
to_chat(user, "You can only re-appear near a potential signer.")
revert_cast()
@@ -132,6 +128,14 @@
return
revert_cast()
+/obj/effect/proc_holder/spell/targeted/infernal_jaunt/proc/valid_location(mob/living/user = usr)
+ if(istype(get_area(user), /area/shuttle/)) // Can always phase in in a shuttle.
+ return TRUE
+ else
+ for(var/mob/living/C in orange(2, get_turf(user))) //Can also phase in when nearby a potential buyer.
+ if (C.owns_soul())
+ return TRUE
+ return FALSE
/mob/living/proc/infernalphaseout()
dust_animation()
@@ -196,8 +200,7 @@
if(locate(/datum/objective/sintouched) in H.mind.objectives)
continue
H.influenceSin()
- H.Weaken(2)
- H.Stun(2)
+ H.Knockdown(400)
/obj/effect/proc_holder/spell/targeted/summon_dancefloor
diff --git a/code/modules/spells/spell_types/devil_boons.dm b/code/modules/spells/spell_types/devil_boons.dm
index e8fcc730108..75b6597f074 100644
--- a/code/modules/spells/spell_types/devil_boons.dm
+++ b/code/modules/spells/spell_types/devil_boons.dm
@@ -18,7 +18,7 @@
new /obj/item/weapon/coin/gold(user.loc),
new /obj/item/weapon/coin/diamond(user.loc),
new /obj/item/weapon/coin/silver(user.loc),
- new /obj/item/clothing/tie/medal/gold(user.loc),
+ new /obj/item/clothing/accessory/medal/gold(user.loc),
new /obj/item/stack/sheet/mineral/gold(user.loc),
new /obj/item/stack/sheet/mineral/silver(user.loc),
new /obj/item/stack/sheet/mineral/diamond(user.loc),
diff --git a/code/modules/spells/spell_types/emplosion.dm b/code/modules/spells/spell_types/emplosion.dm
index 23f35ff9c5e..761121f540f 100644
--- a/code/modules/spells/spell_types/emplosion.dm
+++ b/code/modules/spells/spell_types/emplosion.dm
@@ -6,7 +6,7 @@
var/emp_light = 3
action_icon_state = "emp"
- sound = 'sound/weapons/ZapBang.ogg'
+ sound = 'sound/weapons/zapbang.ogg'
/obj/effect/proc_holder/spell/targeted/emplosion/cast(list/targets,mob/user = usr)
playsound(get_turf(user), sound, 50,1)
diff --git a/code/modules/spells/spell_types/ethereal_jaunt.dm b/code/modules/spells/spell_types/ethereal_jaunt.dm
index 4d881d5bd53..01b5eb82422 100644
--- a/code/modules/spells/spell_types/ethereal_jaunt.dm
+++ b/code/modules/spells/spell_types/ethereal_jaunt.dm
@@ -18,7 +18,7 @@
action_icon_state = "jaunt"
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/cast(list/targets,mob/user = usr) //magnets, so mostly hardcoded
- playsound(get_turf(user), 'sound/magic/Ethereal_Enter.ogg', 50, 1, -1)
+ playsound(get_turf(user), 'sound/magic/ethereal_enter.ogg', 50, 1, -1)
for(var/mob/living/target in targets)
INVOKE_ASYNC(src, .proc/do_jaunt, target)
@@ -49,7 +49,7 @@
jaunt_steam(mobloc)
target.canmove = 0
holder.reappearing = 1
- playsound(get_turf(target), 'sound/magic/Ethereal_Exit.ogg', 50, 1, -1)
+ playsound(get_turf(target), 'sound/magic/ethereal_exit.ogg', 50, 1, -1)
sleep(25 - jaunt_in_time)
new jaunt_in_type(mobloc, target.dir)
sleep(jaunt_in_time)
diff --git a/code/modules/spells/spell_types/forcewall.dm b/code/modules/spells/spell_types/forcewall.dm
index 8b2a40fe591..7581ba5f3b5 100644
--- a/code/modules/spells/spell_types/forcewall.dm
+++ b/code/modules/spells/spell_types/forcewall.dm
@@ -6,7 +6,7 @@
clothes_req = 0
invocation = "TARCOL MINTI ZHERI"
invocation_type = "shout"
- sound = 'sound/magic/ForceWall.ogg'
+ sound = 'sound/magic/forcewall.ogg'
action_icon_state = "shield"
range = -1
include_user = 1
diff --git a/code/modules/spells/spell_types/godhand.dm b/code/modules/spells/spell_types/godhand.dm
index 26c543537e6..f1543d16918 100644
--- a/code/modules/spells/spell_types/godhand.dm
+++ b/code/modules/spells/spell_types/godhand.dm
@@ -42,7 +42,7 @@
name = "\improper disintegrating touch"
desc = "This hand of mine glows with an awesome power!"
catchphrase = "EI NATH!!"
- on_use_sound = 'sound/magic/Disintegrate.ogg'
+ on_use_sound = 'sound/magic/disintegrate.ogg'
icon_state = "disintegrate"
item_state = "disintegrate"
@@ -58,7 +58,7 @@
name = "\improper petrifying touch"
desc = "That's the bottom line, because flesh to stone said so!"
catchphrase = "STAUN EI!!"
- on_use_sound = 'sound/magic/FleshToStone.ogg'
+ on_use_sound = 'sound/magic/fleshtostone.ogg'
icon_state = "fleshtostone"
item_state = "fleshtostone"
@@ -69,6 +69,6 @@
to_chat(user, "You can't reach out!")
return
var/mob/living/M = target
- M.Stun(2)
+ M.Stun(40)
M.petrify()
..()
diff --git a/code/modules/spells/spell_types/inflict_handler.dm b/code/modules/spells/spell_types/inflict_handler.dm
index f3a48330bf6..6a8c82e7377 100644
--- a/code/modules/spells/spell_types/inflict_handler.dm
+++ b/code/modules/spells/spell_types/inflict_handler.dm
@@ -1,10 +1,10 @@
/obj/effect/proc_holder/spell/targeted/inflict_handler
name = "Inflict Handler"
- desc = "This spell blinds and/or destroys/damages/heals and/or weakens/stuns the target."
+ desc = "This spell blinds and/or destroys/damages/heals and/or knockdowns/stuns the target."
- var/amt_weakened = 0
- var/amt_paralysis = 0
- var/amt_stunned = 0
+ var/amt_knockdown = 0
+ var/amt_unconscious = 0
+ var/amt_stun = 0
//set to negatives for healing
var/amt_dam_fire = 0
@@ -37,9 +37,9 @@
target.adjustToxLoss(amt_dam_tox)
target.adjustOxyLoss(amt_dam_oxy)
//disabling
- target.Weaken(amt_weakened)
- target.Paralyse(amt_paralysis)
- target.Stun(amt_stunned)
+ target.Knockdown(amt_knockdown)
+ target.Unconscious(amt_unconscious)
+ target.Stun(amt_stun)
target.blind_eyes(amt_eye_blind)
target.blur_eyes(amt_eye_blurry)
diff --git a/code/modules/spells/spell_types/knock.dm b/code/modules/spells/spell_types/knock.dm
index 5eabf9ac0ac..6fda1702a64 100644
--- a/code/modules/spells/spell_types/knock.dm
+++ b/code/modules/spells/spell_types/knock.dm
@@ -13,7 +13,7 @@
action_icon_state = "knock"
/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets,mob/user = usr)
- user << sound('sound/magic/Knock.ogg')
+ user << sound('sound/magic/knock.ogg')
for(var/turf/T in targets)
for(var/obj/machinery/door/door in T.contents)
INVOKE_ASYNC(src, .proc/open_door, door)
diff --git a/code/modules/spells/spell_types/lichdom.dm b/code/modules/spells/spell_types/lichdom.dm
index 50f51a0b3b9..0442b2c02a8 100644
--- a/code/modules/spells/spell_types/lichdom.dm
+++ b/code/modules/spells/spell_types/lichdom.dm
@@ -134,7 +134,7 @@
lich.hardset_dna(null,null,lich.real_name,null,/datum/species/skeleton)
to_chat(lich, "Your bones clatter and shutter as you are pulled back into this world!")
var/turf/body_turf = get_turf(old_body)
- lich.Weaken(10+10*resurrections)
+ lich.Knockdown(200 + 200*resurrections)
resurrections++
if(old_body && old_body.loc)
if(iscarbon(old_body))
diff --git a/code/modules/spells/spell_types/lightning.dm b/code/modules/spells/spell_types/lightning.dm
index 3a84f73ef91..5726849a98b 100644
--- a/code/modules/spells/spell_types/lightning.dm
+++ b/code/modules/spells/spell_types/lightning.dm
@@ -67,10 +67,10 @@
var/mob/living/carbon/current = target
if(bounces < 1)
current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1)
- playsound(get_turf(current), 'sound/magic/LightningShock.ogg', 50, 1, -1)
+ playsound(get_turf(current), 'sound/magic/lightningshock.ogg', 50, 1, -1)
else
current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1)
- playsound(get_turf(current), 'sound/magic/LightningShock.ogg', 50, 1, -1)
+ playsound(get_turf(current), 'sound/magic/lightningshock.ogg', 50, 1, -1)
var/list/possible_targets = new
for(var/mob/living/M in view_or_range(range,target,"view"))
if(user == M || target == M && los_check(current,M)) // || origin == M ? Not sure double shockings is good or not
diff --git a/code/modules/spells/spell_types/mime.dm b/code/modules/spells/spell_types/mime.dm
index 0a84b4bca05..79935d0b2a8 100644
--- a/code/modules/spells/spell_types/mime.dm
+++ b/code/modules/spells/spell_types/mime.dm
@@ -90,7 +90,7 @@
/obj/effect/proc_holder/spell/aimed/finger_guns
name = "Finger Guns"
- desc = "Shoot a mimed bullet from your fingers that does a stun and some damage."
+ desc = "Shoot a mimed bullet from your fingers that stuns and does some damage."
school = "mime"
panel = "Mime"
charge_max = 300
diff --git a/code/modules/spells/spell_types/mind_transfer.dm b/code/modules/spells/spell_types/mind_transfer.dm
index 491496f0447..426217e89db 100644
--- a/code/modules/spells/spell_types/mind_transfer.dm
+++ b/code/modules/spells/spell_types/mind_transfer.dm
@@ -10,8 +10,8 @@
range = 1
cooldown_min = 200 //100 deciseconds reduction per rank
var/list/protected_roles = list("Wizard","Changeling","Cultist") //which roles are immune to the spell
- var/paralysis_amount_caster = 20 //how much the caster is paralysed for after the spell
- var/paralysis_amount_victim = 20 //how much the victim is paralysed for after the spell
+ var/unconscious_amount_caster = 400 //how much the caster is stunned for after the spell
+ var/unconscious_amount_victim = 400 //how much the victim is stunned for after the spell
action_icon_state = "mindswap"
@@ -72,8 +72,8 @@ Also, you never added distance checking after target is selected. I've went ahea
//MIND TRANSFER END
- //Here we paralyze both mobs and knock them out for a time.
- caster.Paralyse(paralysis_amount_caster)
- victim.Paralyse(paralysis_amount_victim)
- caster << sound('sound/magic/MandSwap.ogg')
- victim << sound('sound/magic/MandSwap.ogg')// only the caster and victim hear the sounds, that way no one knows for sure if the swap happened
+ //Here we knock both mobs out for a time.
+ caster.Unconscious(unconscious_amount_caster)
+ victim.Unconscious(unconscious_amount_victim)
+ caster << sound('sound/magic/mandswap.ogg')
+ victim << sound('sound/magic/mandswap.ogg')// only the caster and victim hear the sounds, that way no one knows for sure if the swap happened
diff --git a/code/modules/spells/spell_types/rightandwrong.dm b/code/modules/spells/spell_types/rightandwrong.dm
index 93d6b4c1dad..50f0e5e2dcb 100644
--- a/code/modules/spells/spell_types/rightandwrong.dm
+++ b/code/modules/spells/spell_types/rightandwrong.dm
@@ -124,7 +124,7 @@
if("gravgun")
G = new /obj/item/weapon/gun/energy/gravity_gun(get_turf(H))
G.unlock()
- playsound(get_turf(H),'sound/magic/Summon_guns.ogg', 50, 1)
+ playsound(get_turf(H),'sound/magic/summon_guns.ogg', 50, 1)
else
switch (randomizemagic)
@@ -199,7 +199,7 @@
if("bloodcontract")
new /obj/item/blood_contract(get_turf(H))
to_chat(H, "You suddenly feel lucky.")
- playsound(get_turf(H),'sound/magic/Summon_Magic.ogg', 50, 1)
+ playsound(get_turf(H),'sound/magic/summon_magic.ogg', 50, 1)
/proc/summonevents()
diff --git a/code/modules/spells/spell_types/rod_form.dm b/code/modules/spells/spell_types/rod_form.dm
index 5046da7c34d..dc77615307f 100644
--- a/code/modules/spells/spell_types/rod_form.dm
+++ b/code/modules/spells/spell_types/rod_form.dm
@@ -17,6 +17,7 @@
var/obj/effect/immovablerod/wizard/W = new(start, get_ranged_target_turf(M, M.dir, (15 + spell_level * 3)))
W.wizard = M
W.max_distance += spell_level * 3 //You travel farther when you upgrade the spell
+ W.damage_bonus += spell_level * 20 //You do more damage when you upgrade the spell
W.start_turf = start
M.forceMove(W)
M.notransform = 1
@@ -26,6 +27,7 @@
/obj/effect/immovablerod/wizard
var/max_distance = 13
+ var/damage_bonus = 0
var/mob/living/wizard
var/turf/start_turf
notify = FALSE
@@ -41,3 +43,7 @@
wizard.notransform = 0
wizard.forceMove(get_turf(src))
return ..()
+
+/obj/effect/immovablerod/wizard/penetrate(mob/living/L)
+ L.visible_message("[L] is penetrated by an immovable rod!" , "The rod penetrates you!" , "You hear a CLANG!")
+ L.adjustBruteLoss(70 + damage_bonus)
diff --git a/code/modules/spells/spell_types/summonitem.dm b/code/modules/spells/spell_types/summonitem.dm
index b2a5aaf697c..90c7730f5a7 100644
--- a/code/modules/spells/spell_types/summonitem.dm
+++ b/code/modules/spells/spell_types/summonitem.dm
@@ -103,10 +103,10 @@
if(!L.put_in_hands(item_to_retrieve))
item_to_retrieve.loc = L.loc
item_to_retrieve.loc.visible_message("The [item_to_retrieve.name] suddenly appears!")
- playsound(get_turf(L), 'sound/magic/SummonItems_generic.ogg', 50, 1)
+ playsound(get_turf(L), 'sound/magic/summonitems_generic.ogg', 50, 1)
else
item_to_retrieve.loc.visible_message("The [item_to_retrieve.name] suddenly appears in [L]'s hand!")
- playsound(get_turf(L), 'sound/magic/SummonItems_generic.ogg', 50, 1)
+ playsound(get_turf(L), 'sound/magic/summonitems_generic.ogg', 50, 1)
if(message)
diff --git a/code/modules/spells/spell_types/the_traps.dm b/code/modules/spells/spell_types/the_traps.dm
index 169a38bb957..7402dbfbc88 100644
--- a/code/modules/spells/spell_types/the_traps.dm
+++ b/code/modules/spells/spell_types/the_traps.dm
@@ -1,6 +1,6 @@
/obj/effect/proc_holder/spell/aoe_turf/conjure/the_traps
name = "The Traps!"
- desc = "Summon a number of traps to confuse and weaken your enemies, and possibly you."
+ desc = "Summon a number of traps to confuse and knockdown your enemies, and possibly you."
charge_max = 250
cooldown_min = 50
diff --git a/code/modules/spells/spell_types/touch_attacks.dm b/code/modules/spells/spell_types/touch_attacks.dm
index 1baf51826d3..caedacb59e8 100644
--- a/code/modules/spells/spell_types/touch_attacks.dm
+++ b/code/modules/spells/spell_types/touch_attacks.dm
@@ -58,4 +58,4 @@
cooldown_min = 200 //100 deciseconds reduction per rank
action_icon_state = "statue"
- sound = 'sound/magic/FleshToStone.ogg'
\ No newline at end of file
+ sound = 'sound/magic/fleshtostone.ogg'
\ No newline at end of file
diff --git a/code/modules/spells/spell_types/turf_teleport.dm b/code/modules/spells/spell_types/turf_teleport.dm
index 7a27e26ec31..51b2f5e5ecc 100644
--- a/code/modules/spells/spell_types/turf_teleport.dm
+++ b/code/modules/spells/spell_types/turf_teleport.dm
@@ -8,8 +8,8 @@
var/include_space = 0 //whether it includes space tiles in possible teleport locations
var/include_dense = 0 //whether it includes dense tiles in possible teleport locations
- var/sound1 = 'sound/weapons/ZapBang.ogg'
- var/sound2 = 'sound/weapons/ZapBang.ogg'
+ var/sound1 = 'sound/weapons/zapbang.ogg'
+ var/sound2 = 'sound/weapons/zapbang.ogg'
/obj/effect/proc_holder/spell/targeted/turf_teleport/cast(list/targets,mob/user = usr)
playsound(get_turf(user), sound1, 50,1)
diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm
index f62259f67b5..03be2d4d0ba 100644
--- a/code/modules/spells/spell_types/wizard.dm
+++ b/code/modules/spells/spell_types/wizard.dm
@@ -25,11 +25,11 @@
proj_trail_icon_state = "magicmd"
action_icon_state = "magicm"
- sound = 'sound/magic/MAGIC_MISSILE.ogg'
+ sound = 'sound/magic/magic_missile.ogg'
/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile
- amt_weakened = 3
- sound = 'sound/magic/MM_Hit.ogg'
+ amt_knockdown = 3
+ sound = 'sound/magic/mm_hit.ogg'
/obj/effect/proc_holder/spell/targeted/genetic/mutate
name = "Mutate"
@@ -48,7 +48,7 @@
cooldown_min = 300 //25 deciseconds reduction per rank
action_icon_state = "mutate"
- sound = 'sound/magic/Mutate.ogg'
+ sound = 'sound/magic/mutate.ogg'
/obj/effect/proc_holder/spell/targeted/smoke
@@ -100,7 +100,7 @@
emp_heavy = 6
emp_light = 10
- sound = 'sound/magic/Disable_Tech.ogg'
+ sound = 'sound/magic/disable_tech.ogg'
/obj/effect/proc_holder/spell/targeted/turf_teleport/blink
name = "Blink"
@@ -148,8 +148,8 @@
smoke_spread = 1
smoke_amt = 2
- sound1 = 'sound/magic/Teleport_diss.ogg'
- sound2 = 'sound/magic/Teleport_app.ogg'
+ sound1 = 'sound/magic/teleport_diss.ogg'
+ sound2 = 'sound/magic/teleport_app.ogg'
/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop
name = "Stop Time"
@@ -177,7 +177,7 @@
range = 1
summon_type = list(/mob/living/simple_animal/hostile/carp)
- cast_sound = 'sound/magic/Summon_Karp.ogg'
+ cast_sound = 'sound/magic/summon_karp.ogg'
/obj/effect/proc_holder/spell/aoe_turf/conjure/construct
@@ -194,7 +194,7 @@
summon_type = list(/obj/structure/constructshell)
action_icon_state = "artificer"
- cast_sound = 'sound/magic/SummonItems_generic.ogg'
+ cast_sound = 'sound/magic/summonitems_generic.ogg'
/obj/effect/proc_holder/spell/aoe_turf/conjure/creature
@@ -210,7 +210,7 @@
range = 3
summon_type = list(/mob/living/simple_animal/hostile/creature)
- cast_sound = 'sound/magic/SummonItems_generic.ogg'
+ cast_sound = 'sound/magic/summonitems_generic.ogg'
/obj/effect/proc_holder/spell/targeted/trigger/blind
name = "Blind"
@@ -239,12 +239,12 @@
/obj/effect/proc_holder/spell/targeted/inflict_handler/blind
amt_eye_blind = 10
amt_eye_blurry = 20
- sound = 'sound/magic/Blind.ogg'
+ sound = 'sound/magic/blind.ogg'
/obj/effect/proc_holder/spell/targeted/genetic/blind
mutations = list(BLINDMUT)
duration = 300
- sound = 'sound/magic/Blind.ogg'
+ sound = 'sound/magic/blind.ogg'
/obj/effect/proc_holder/spell/aoe_turf/repulse
name = "Repulse"
desc = "This spell throws everything around the user away."
@@ -255,13 +255,13 @@
range = 5
cooldown_min = 150
selection_type = "view"
- sound = 'sound/magic/Repulse.ogg'
+ sound = 'sound/magic/repulse.ogg'
var/maxthrow = 5
var/sparkle_path = /obj/effect/temp_visual/gravpush
action_icon_state = "repulse"
-/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets,mob/user = usr, var/stun_amt = 2)
+/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets,mob/user = usr, var/stun_amt = 20)
var/list/thrownatoms = list()
var/atom/throwtarget
var/distfromcaster
@@ -280,21 +280,21 @@
if(distfromcaster == 0)
if(isliving(AM))
var/mob/living/M = AM
- M.Weaken(5)
+ M.Knockdown(100)
M.adjustBruteLoss(5)
to_chat(M, "You're slammed into the floor by [user]!")
else
new sparkle_path(get_turf(AM), get_dir(user, AM)) //created sparkles will disappear on their own
if(isliving(AM))
var/mob/living/M = AM
- M.Weaken(stun_amt)
+ M.Knockdown(stun_amt)
to_chat(M, "You're thrown back by [user]!")
AM.throw_at(throwtarget, ((Clamp((maxthrow - (Clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time.
/obj/effect/proc_holder/spell/aoe_turf/repulse/xeno //i fixed conflicts only to find out that this is in the WIZARD file instead of the xeno file?!
name = "Tail Sweep"
desc = "Throw back attackers with a sweep of your tail."
- sound = 'sound/magic/Tail_swing.ogg'
+ sound = 'sound/magic/tail_swing.ogg'
charge_max = 150
clothes_req = 0
range = 2
@@ -309,7 +309,7 @@
var/mob/living/carbon/C = user
playsound(C.loc, 'sound/voice/hiss5.ogg', 80, 1, 1)
C.spin(6,1)
- ..(targets, user, 3)
+ ..(targets, user, 30)
/obj/effect/proc_holder/spell/targeted/sacred_flame
name = "Sacred Flame"
@@ -323,7 +323,7 @@
include_user = 1
selection_type = "view"
action_icon_state = "sacredflame"
- sound = 'sound/magic/Fireball.ogg'
+ sound = 'sound/magic/fireball.ogg'
/obj/effect/proc_holder/spell/targeted/sacred_flame/cast(list/targets, mob/user = usr)
for(var/mob/living/L in targets)
diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm
index 5f808035fd3..23e43f87e32 100644
--- a/code/modules/station_goals/bsa.dm
+++ b/code/modules/station_goals/bsa.dm
@@ -258,6 +258,7 @@
data["ready"] = cannon ? cannon.ready : FALSE
data["connected"] = cannon
data["notice"] = notice
+ data["unlocked"] = GLOB.bsa_unlock
if(target)
data["target"] = get_target_name()
return data
@@ -326,7 +327,7 @@
var/datum/effect_system/smoke_spread/s = new
s.set_up(4,get_turf(centerpiece))
s.start()
- var/obj/machinery/bsa/full/cannon = new(get_turf(centerpiece),cannon_direction=centerpiece.get_cannon_direction())
+ var/obj/machinery/bsa/full/cannon = new(get_turf(centerpiece),centerpiece.get_cannon_direction())
qdel(centerpiece.front)
qdel(centerpiece.back)
qdel(centerpiece)
diff --git a/code/modules/station_goals/station_goal.dm b/code/modules/station_goals/station_goal.dm
index 30146592055..4a9bc424386 100644
--- a/code/modules/station_goals/station_goal.dm
+++ b/code/modules/station_goals/station_goal.dm
@@ -12,7 +12,7 @@
var/report_message = "Complete this goal."
/datum/station_goal/proc/send_report()
- priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", 'sound/AI/commandreport.ogg')
+ priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", 'sound/ai/commandreport.ogg')
print_command_report(get_report(),"Nanotrasen Directive [pick(GLOB.phonetic_alphabet)] \Roman[rand(1,50)]", announce=FALSE)
on_report()
diff --git a/code/modules/stock_market/computer.dm b/code/modules/stock_market/computer.dm
index 5299debf24f..9cef9b30483 100644
--- a/code/modules/stock_market/computer.dm
+++ b/code/modules/stock_market/computer.dm
@@ -235,7 +235,7 @@ a.updated {
if (!amt)
return
if (!S.buyShares(logged_in, amt))
- to_chat(user, "<Could not complete transaction.")
+ to_chat(user, "Could not complete transaction.")
return
var/total = amt * S.current_value
diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm
index ff2a3f03120..29727bf6a2e 100644
--- a/code/modules/surgery/organs/augments_internal.dm
+++ b/code/modules/surgery/organs/augments_internal.dm
@@ -1,4 +1,5 @@
-#define STUN_SET_AMOUNT 2
+#define STUN_SET_AMOUNT 40
+#define STUN_CHECK_AMOUNT 2
/obj/item/organ/cyberimp
name = "cybernetic implant"
@@ -31,7 +32,7 @@
/obj/item/organ/cyberimp/brain/emp_act(severity)
if(!owner)
return
- var/stun_amount = 5 + (severity-1 ? 0 : 5)
+ var/stun_amount = 200/severity
owner.Stun(stun_amount)
to_chat(owner, "Your body seizes up!")
return stun_amount
@@ -107,10 +108,10 @@
if(crit_fail)
return
- if(owner.stunned > STUN_SET_AMOUNT)
- owner.stunned = STUN_SET_AMOUNT
- if(owner.weakened > STUN_SET_AMOUNT)
- owner.weakened = STUN_SET_AMOUNT
+ if(owner.AmountStun() > STUN_SET_AMOUNT)
+ owner.SetStun(STUN_SET_AMOUNT)
+ if(owner.knockdown > STUN_CHECK_AMOUNT)
+ owner.SetKnockdown(STUN_SET_AMOUNT)
/obj/item/organ/cyberimp/brain/anti_stun/emp_act(severity)
if(crit_fail)
diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm
index fd6a3466bd9..75298342f4d 100644
--- a/code/modules/surgery/organs/ears.dm
+++ b/code/modules/surgery/organs/ears.dm
@@ -49,6 +49,9 @@
/obj/item/organ/ears/proc/minimumDeafTicks(value)
deaf = max(deaf, value)
+/obj/item/organ/ears/invincible/adjustEarDamage(ddmg, ddeaf)
+ return
+
/mob/proc/restoreEars()
@@ -70,3 +73,24 @@
var/obj/item/organ/ears/ears = getorgan(/obj/item/organ/ears)
if(ears)
ears.minimumDeafTicks(value)
+
+
+/obj/item/organ/ears/cat
+ name = "cat ears"
+ icon = 'icons/obj/clothing/hats.dmi'
+ icon_state = "kitty"
+
+/obj/item/organ/ears/cat/adjustEarDamage(ddmg, ddeaf)
+ ..(ddmg*2,ddeaf*2)
+
+/obj/item/organ/ears/cat/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE)
+ ..()
+ color = H.hair_color
+ H.dna.features["ears"] = "Cat"
+ H.update_body()
+
+/obj/item/organ/ears/cat/Remove(mob/living/carbon/human/H, special = 0)
+ ..()
+ color = H.hair_color
+ H.dna.features["ears"] = "None"
+ H.update_body()
\ No newline at end of file
diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm
index 86480c70bf9..9c0eedc5ca1 100644
--- a/code/modules/surgery/organs/eyes.dm
+++ b/code/modules/surgery/organs/eyes.dm
@@ -130,7 +130,6 @@
eye.forceMove(src)
..()
-
// Welding shield implant
/obj/item/organ/eyes/robotic/shield
name = "shielded robotic eyes"
@@ -140,3 +139,176 @@
/obj/item/organ/eyes/robotic/shield/emp_act(severity)
return
+
+#define RGB2EYECOLORSTRING(definitionvar) ("[copytext(definitionvar,2,3)][copytext(definitionvar,4,5)][copytext(definitionvar,6,7)]")
+
+/obj/item/organ/eyes/robotic/glow
+ name = "High Luminosity Eyes"
+ desc = "Special glowing eyes, used by snowflakes who want to be special."
+ origin_tech = "materials=3;biotech=3;engineering=3;magnets=4"
+ eye_color = "000"
+ actions_types = list(/datum/action/item_action/organ_action/use, /datum/action/item_action/organ_action/toggle)
+ var/current_color_string = "#ffffff"
+ var/active = FALSE
+ var/max_light_beam_distance = 5
+ var/light_beam_distance = 5
+ var/light_object_range = 1
+ var/light_object_power = 2
+ var/list/obj/effect/abstract/eye_lighting/eye_lighting
+ var/obj/effect/abstract/eye_lighting/on_mob
+ var/image/mob_overlay
+
+/obj/item/organ/eyes/robotic/glow/Initialize()
+ . = ..()
+ mob_overlay = image('icons/mob/human_face.dmi', "eyes_glow_gs")
+
+/obj/item/organ/eyes/robotic/glow/Destroy()
+ terminate_effects()
+ . = ..()
+
+/obj/item/organ/eyes/robotic/glow/Remove()
+ terminate_effects()
+ . = ..()
+
+/obj/item/organ/eyes/robotic/glow/proc/terminate_effects()
+ if(owner && active)
+ deactivate()
+ active = FALSE
+ clear_visuals(TRUE)
+ STOP_PROCESSING(SSfastprocess, src)
+
+/obj/item/organ/eyes/robotic/glow/ui_action_click(owner, action)
+ if(istype(action, /datum/action/item_action/organ_action/toggle))
+ toggle_active()
+ else if(istype(action, /datum/action/item_action/organ_action/use))
+ prompt_for_controls(owner)
+
+/obj/item/organ/eyes/robotic/glow/proc/toggle_active()
+ if(active)
+ deactivate()
+ else
+ activate()
+
+/obj/item/organ/eyes/robotic/glow/proc/prompt_for_controls(mob/user)
+ var/C = input(owner, "Select Color", "Select color", "#ffffff") as null|color
+ if(!C || QDELETED(src) || QDELETED(user) || QDELETED(owner) || owner != user)
+ return
+ var/range = input(user, "Enter range (0 - [max_light_beam_distance])", "Range Select", 0) as null|num
+
+ set_distance(Clamp(range, 0, max_light_beam_distance))
+ assume_rgb(C)
+
+/obj/item/organ/eyes/robotic/glow/proc/assume_rgb(newcolor)
+ current_color_string = newcolor
+ eye_color = RGB2EYECOLORSTRING(current_color_string)
+ sync_light_effects()
+ cycle_mob_overlay()
+ if(!QDELETED(owner) && ishuman(owner)) //Other carbon mobs don't have eye color.
+ owner.dna.species.handle_body(owner)
+
+/obj/item/organ/eyes/robotic/glow/proc/cycle_mob_overlay()
+ remove_mob_overlay()
+ mob_overlay.color = current_color_string
+ add_mob_overlay()
+
+/obj/item/organ/eyes/robotic/glow/proc/add_mob_overlay()
+ if(!QDELETED(owner))
+ owner.add_overlay(mob_overlay)
+
+/obj/item/organ/eyes/robotic/glow/proc/remove_mob_overlay()
+ if(!QDELETED(owner))
+ owner.cut_overlay(mob_overlay)
+
+/obj/item/organ/eyes/robotic/glow/emp_act()
+ if(active)
+ deactivate(silent = TRUE)
+
+/obj/item/organ/eyes/robotic/glow/on_mob_move()
+ if(QDELETED(owner) || !active)
+ return
+ update_visuals()
+
+/obj/item/organ/eyes/robotic/glow/on_mob_turn()
+ if(QDELETED(owner) || !active)
+ return
+ update_visuals()
+
+/obj/item/organ/eyes/robotic/glow/proc/activate(silent = FALSE)
+ start_visuals()
+ if(!silent)
+ to_chat(owner, "Your [src] clicks and makes a whining noise, before shooting out a beam of light!")
+ active = TRUE
+ cycle_mob_overlay()
+
+/obj/item/organ/eyes/robotic/glow/proc/deactivate(silent = FALSE)
+ clear_visuals()
+ if(!silent)
+ to_chat(owner, "Your [src] shuts off!")
+ active = FALSE
+ remove_mob_overlay()
+
+/obj/item/organ/eyes/robotic/glow/proc/update_visuals()
+ if((LAZYLEN(eye_lighting) < light_beam_distance) || !on_mob)
+ regenerate_light_effects()
+ var/turf/scanfrom = get_turf(owner)
+ var/scandir = owner.dir
+ if(!istype(scanfrom))
+ clear_visuals()
+ var/turf/scanning = scanfrom
+ var/stop = FALSE
+ on_mob.forceMove(scanning)
+ for(var/i in 1 to light_beam_distance)
+ scanning = get_step(scanning, scandir)
+ if(scanning.opacity || scanning.has_opaque_atom)
+ stop = TRUE
+ var/obj/effect/abstract/eye_lighting/L = LAZYACCESS(eye_lighting, i)
+ if(stop)
+ L.forceMove(src)
+ else
+ L.forceMove(scanning)
+
+/obj/item/organ/eyes/robotic/glow/proc/clear_visuals(delete_everything = FALSE)
+ if(delete_everything)
+ QDEL_LIST(eye_lighting)
+ QDEL_NULL(on_mob)
+ else
+ for(var/i in eye_lighting)
+ var/obj/effect/abstract/eye_lighting/L = i
+ L.forceMove(src)
+ if(!QDELETED(on_mob))
+ on_mob.forceMove(src)
+
+/obj/item/organ/eyes/robotic/glow/proc/start_visuals()
+ if(!islist(eye_lighting))
+ regenerate_light_effects()
+ if((eye_lighting.len < light_beam_distance) || !on_mob)
+ regenerate_light_effects()
+ sync_light_effects()
+ update_visuals()
+
+/obj/item/organ/eyes/robotic/glow/proc/set_distance(dist)
+ light_beam_distance = dist
+ regenerate_light_effects()
+
+/obj/item/organ/eyes/robotic/glow/proc/regenerate_light_effects()
+ clear_visuals(TRUE)
+ on_mob = new(src)
+ for(var/i in 1 to light_beam_distance)
+ LAZYADD(eye_lighting,new /obj/effect/abstract/eye_lighting(src))
+ sync_light_effects()
+
+/obj/item/organ/eyes/robotic/glow/proc/sync_light_effects()
+ for(var/I in eye_lighting)
+ var/obj/effect/abstract/eye_lighting/L = I
+ L.set_light(light_object_range, light_object_power, current_color_string)
+ if(on_mob)
+ on_mob.set_light(1, 1, current_color_string)
+
+/obj/effect/abstract/eye_lighting
+ var/obj/item/organ/eyes/robotic/glow/parent
+
+/obj/effect/abstract/eye_lighting/Initialize()
+ . = ..()
+ parent = loc
+ if(!istype(parent))
+ return INITIALIZE_HINT_QDEL
diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm
index 675f10b3e9d..4a529409c9a 100644
--- a/code/modules/surgery/organs/lungs.dm
+++ b/code/modules/surgery/organs/lungs.dm
@@ -113,7 +113,7 @@
if(!H.co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so.
H.co2overloadtime = world.time
else if(world.time - H.co2overloadtime > 120)
- H.Paralyse(3)
+ H.Unconscious(60)
H.adjustOxyLoss(3) // Lets hurt em a little, let them know we mean business
if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good!
H.adjustOxyLoss(8)
@@ -179,10 +179,10 @@
// N2O
var/SA_pp = breath.get_breath_partial_pressure(breath_gases["n2o"][MOLES])
- if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit
- H.Paralyse(3) // 3 gives them one second to wake up and run away a bit!
+ if(SA_pp > SA_para_min) // Enough to make us stunned for a bit
+ H.Unconscious(60) // 60 gives them one second to wake up and run away a bit!
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
- H.Sleeping(max(H.sleeping+2, 10))
+ H.Sleeping(max(H.AmountSleeping() + 40, 200))
else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
if(prob(20))
H.emote(pick("giggle", "laugh"))
diff --git a/code/modules/surgery/organs/tails.dm b/code/modules/surgery/organs/tails.dm
new file mode 100644
index 00000000000..99d1ed24426
--- /dev/null
+++ b/code/modules/surgery/organs/tails.dm
@@ -0,0 +1,23 @@
+/obj/item/organ/tail
+ name = "tail"
+ desc = "What did you cut this off of?"
+ zone = "groin"
+ slot = "tail"
+
+/obj/item/organ/tail/cat
+ name = "cat tail"
+ desc = "Who's wagging now?"
+ icon_state = "severedtail"
+
+/obj/item/organ/tail/cat/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE)
+ ..()
+ color = H.hair_color
+ H.dna.features["tail_human"] = "Cat"
+ H.update_body()
+
+/obj/item/organ/ears/cat/Remove(mob/living/carbon/human/H, special = 0)
+ ..()
+ H.endTailWag()
+ H.dna.features["tail_human"] = "None"
+ color = H.hair_color
+ H.update_body()
diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm
index b4154c8e9c8..1293b569d32 100644
--- a/code/modules/surgery/organs/vocal_cords.dm
+++ b/code/modules/surgery/organs/vocal_cords.dm
@@ -210,7 +210,7 @@
message = copytext(message, 0, 1)+copytext(message, 1 + length(found_string), length(message) + 1)
var/static/regex/stun_words = regex("stop|wait|stand still|hold on|halt")
- var/static/regex/weaken_words = regex("drop|fall|trip|weaken")
+ var/static/regex/knockdown_words = regex("drop|fall|trip|knockdown")
var/static/regex/sleep_words = regex("sleep|slumber|rest")
var/static/regex/vomit_words = regex("vomit|throw up")
var/static/regex/silence_words = regex("shut up|silence|ssh|quiet|hush")
@@ -258,26 +258,26 @@
cooldown = COOLDOWN_STUN
for(var/V in listeners)
var/mob/living/L = V
- L.Stun(3 * power_multiplier)
+ L.Stun(60 * power_multiplier)
- //WEAKEN
- else if(findtext(message, weaken_words))
+ //KNOCKDOWN
+ else if(findtext(message, knockdown_words))
cooldown = COOLDOWN_STUN
for(var/V in listeners)
var/mob/living/L = V
- L.Weaken(3 * power_multiplier)
+ L.Knockdown(60 * power_multiplier)
//SLEEP
else if((findtext(message, sleep_words)))
cooldown = COOLDOWN_STUN
for(var/mob/living/carbon/C in listeners)
- C.Sleeping(2 * power_multiplier)
+ C.Sleeping(40 * power_multiplier)
//VOMIT
else if((findtext(message, vomit_words)))
cooldown = COOLDOWN_STUN
for(var/mob/living/carbon/C in listeners)
- C.vomit(10 * power_multiplier)
+ C.vomit(10 * power_multiplier, distance = power_multiplier)
//SILENCE
else if((findtext(message, silence_words)))
@@ -292,7 +292,7 @@
cooldown = COOLDOWN_MEME
for(var/V in listeners)
var/mob/living/L = V
- new /obj/effect/hallucination/delusion(get_turf(L),L,duration=150 * power_multiplier,skip_nearby=0)
+ new /obj/effect/hallucination/delusion(get_turf(L),L,null,150 * power_multiplier,0)
//WAKE UP
else if((findtext(message, wakeup_words)))
@@ -486,9 +486,9 @@
var/mob/living/L = V
if(L.resting)
L.lay_down() //aka get up
- L.SetStunned(0)
- L.SetWeakened(0)
- L.SetParalysis(0) //i said get up i don't care if you're being tazed
+ L.SetStun(0)
+ L.SetKnockdown(0)
+ L.SetUnconscious(0) //i said get up i don't care if you're being tazed
//SIT
else if((findtext(message, sit_words)))
@@ -555,7 +555,7 @@
addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, get_turf(user), 'sound/items/bikehorn.ogg', 300, 1), 25)
if(user.mind && user.mind.assigned_role == "Clown")
for(var/mob/living/carbon/C in listeners)
- C.slip(0,7 * power_multiplier)
+ C.slip(140 * power_multiplier)
cooldown = COOLDOWN_MEME
//RIGHT ROUND
diff --git a/code/modules/surgery/prosthetic_replacement.dm b/code/modules/surgery/prosthetic_replacement.dm
index 4be7b84a6c6..af1d6e47431 100644
--- a/code/modules/surgery/prosthetic_replacement.dm
+++ b/code/modules/surgery/prosthetic_replacement.dm
@@ -82,7 +82,7 @@
target_zone == "r_arm" ? target.put_in_r_hand(new_arm) : target.put_in_l_hand(new_arm)
return 1
else if(istype(tool, /obj/item/weapon/melee/synthetic_arm_blade))
- var/obj/item/weapon/melee/arm_blade/new_arm = new(target, silent = TRUE, synthetic = TRUE)
+ var/obj/item/weapon/melee/arm_blade/new_arm = new(target,TRUE,TRUE)
target_zone == "r_arm" ? target.put_in_r_hand(new_arm) : target.put_in_l_hand(new_arm)
return 1
diff --git a/code/modules/uplink/uplink.dm b/code/modules/uplink/uplink.dm
index 6e70077063d..19350669c64 100644
--- a/code/modules/uplink/uplink.dm
+++ b/code/modules/uplink/uplink.dm
@@ -19,6 +19,7 @@ GLOBAL_LIST_EMPTY(uplinks)
var/spent_telecrystals = 0
var/purchase_log = ""
var/list/uplink_items
+ var/hidden_crystals = 0
/obj/item/device/uplink/Initialize()
. = ..()
@@ -57,7 +58,8 @@ GLOBAL_LIST_EMPTY(uplinks)
/obj/item/device/uplink/interact(mob/user)
active = TRUE
- ui_interact(user)
+ if(user)
+ ui_interact(user)
/obj/item/device/uplink/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
@@ -119,6 +121,8 @@ GLOBAL_LIST_EMPTY(uplinks)
. = TRUE
if("lock")
active = FALSE
+ telecrystals += hidden_crystals
+ hidden_crystals = 0
SStgui.close_uis(src)
if("select")
selected_cat = params["category"]
diff --git a/code/modules/uplink/uplink_item.dm b/code/modules/uplink/uplink_item.dm
index 14d9aeeec63..5c646f76f30 100644
--- a/code/modules/uplink/uplink_item.dm
+++ b/code/modules/uplink/uplink_item.dm
@@ -110,10 +110,10 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
var/obj/item/weapon/storage/box/B = A
if(istype(B) && B.contents.len > 0)
for(var/obj/item/I in B)
- U.purchase_log += "\icon[I]"
+ U.purchase_log += "[bicon(I)]"
else
if(purchase_log_vis)
- U.purchase_log += "\icon[A]"
+ U.purchase_log += "[bicon(A)]"
if(limited_stock > 0)
limited_stock -= 1
@@ -145,26 +145,26 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/nukeoffer/c20r
name = "C-20r bundle"
desc = "Old faithful: The classic C-20r, bundled with two magazines, and a (surplus) suppressor at discount price."
- item = /obj/item/weapon/storage/backpack/dufflebag/syndie/c20rbundle
+ item = /obj/item/weapon/storage/backpack/duffelbag/syndie/c20rbundle
cost = 14 // normally 16
/datum/uplink_item/nukeoffer/bulldog
name = "Bulldog bundle"
desc = "Lean and mean: Optimised for people that want to get up close and personal. Contains the popular \
Bulldog shotgun, two 12g drums, and a pair of Thermal imaging goggles."
- item = /obj/item/weapon/storage/backpack/dufflebag/syndie/bulldogbundle
+ item = /obj/item/weapon/storage/backpack/duffelbag/syndie/bulldogbundle
cost = 13 // normally 16
/datum/uplink_item/nukeoffer/medical
name = "Medical bundle"
desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a Donksoft machine gun, \
a box of ammo, and a pair of magboots to rescue your friends in no-gravity environments."
- item = /obj/item/weapon/storage/backpack/dufflebag/syndie/med/medicalbundle
+ item = /obj/item/weapon/storage/backpack/duffelbag/syndie/med/medicalbundle
cost = 15 // normally 20
/datum/uplink_item/nukeoffer/sniper
name = "Sniper bundle"
- desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, a hollowpoint \
+ desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, a hollow-point \
haemorrhage magazine, a soporific knockout magazine, a free surplus supressor, and a worn out suit and tie."
item = /obj/item/weapon/storage/briefcase/sniperbundle
cost = 20 // normally 26
@@ -173,13 +173,13 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
name = "Bioterror bundle"
desc = "For the madman: Contains Bioterror spray, Bioterror grenade, chemicals, syringe gun, box of syringes,\
Donksoft assault rifle, and some darts. Remember: Seal suit and equip internals before use."
- item = /obj/item/weapon/storage/backpack/dufflebag/syndie/med/bioterrorbundle
+ item = /obj/item/weapon/storage/backpack/duffelbag/syndie/med/bioterrorbundle
cost = 30 // normally 42
/datum/uplink_item/nukeoffer/firestarter
name = "Spetsnaz Pyro bundle"
desc = "For systematic suppression of carbon lifeforms in close range: Contains a specialist Pyrotechnic equipment, foreign pistol, two magazines, a pipebomb, and a stimulant syringe."
- item = /obj/item/weapon/storage/backpack/dufflebag/syndie/firestarter
+ item = /obj/item/weapon/storage/backpack/duffelbag/syndie/firestarter
cost = 30
// Dangerous Items
@@ -202,7 +202,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/dangerous/shotgun
name = "Bulldog Shotgun"
- desc = "A fully-loaded semi-automatic drum-fed shotgun. Compatiable with all 12g rounds. Designed for close \
+ desc = "A fully-loaded semi-automatic drum-fed shotgun. Compatible with all 12g rounds. Designed for close \
quarter anti-personnel engagements."
item = /obj/item/weapon/gun/ballistic/automatic/shotgun/bulldog
cost = 8
@@ -241,7 +241,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/dangerous/sniper
name = "Sniper Rifle"
- desc = "Ranged fury, Syndicate style. guaranteed to cause shock and awe or your TC back!"
+ desc = "Ranged fury, Syndicate style. Guaranteed to cause shock and awe or your TC back!"
item = /obj/item/weapon/gun/ballistic/automatic/sniper_rifle/syndicate
cost = 16
surplus = 25
@@ -260,7 +260,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
fit into a pocket or slip into a bag unnoticed. It will synthesize \
and fire bolts tipped with a paralyzing toxin that will briefly stun \
targets and cause them to slur as if inebriated. It can produce an \
- infinite amount of bolts, but takes time to automatically recharge \
+ infinite number of bolts, but takes time to automatically recharge \
after each shot."
item = /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow
cost = 12
@@ -297,7 +297,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/dangerous/powerfist
name = "Power Fist"
desc = "The power-fist is a metal gauntlet with a built-in piston-ram powered by an external gas supply.\
- Upon hitting a target, the piston-ram will extend foward to make contact for some serious damage. \
+ Upon hitting a target, the piston-ram will extend forward to make contact for some serious damage. \
Using a wrench on the piston valve will allow you to tweak the amount of gas used per punch to \
deal extra damage and hit targets further. Use a screwdriver to take out any attached tanks."
item = /obj/item/weapon/melee/powerfist
@@ -455,23 +455,23 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/shotgun/bag
- name = "12g Ammo Duffelbag"
- desc = "A duffelbag filled with enough 12g ammo to supply an entire team, at a discounted price."
- item = /obj/item/weapon/storage/backpack/dufflebag/syndie/ammo/shotgun
+ name = "12g Ammo Duffel Bag"
+ desc = "A duffel bag filled with enough 12g ammo to supply an entire team, at a discounted price."
+ item = /obj/item/weapon/storage/backpack/duffelbag/syndie/ammo/shotgun
cost = 12
/datum/uplink_item/ammo/smg
name = ".45 SMG Magazine"
- desc = "An additional 20-round .45 magazine sutable for use with the C-20r submachine gun. \
+ desc = "An additional 20-round .45 magazine suitable for use with the C-20r submachine gun. \
These bullets pack a lot of punch that can knock most targets down, but do limited overall damage."
item = /obj/item/ammo_box/magazine/smgm45
cost = 3
include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/gang)
/datum/uplink_item/ammo/smg/bag
- name = ".45 Ammo Duffelbag"
- desc = "A duffelbag filled with enough .45 ammo to supply an entire team, at a discounted price."
- item = /obj/item/weapon/storage/backpack/dufflebag/syndie/ammo/smg
+ name = ".45 Ammo Duffel Bag"
+ desc = "A duffel bag filled with enough .45 ammo to supply an entire team, at a discounted price."
+ item = /obj/item/weapon/storage/backpack/duffelbag/syndie/ammo/smg
cost = 20
include_modes = list(/datum/game_mode/nuclear)
@@ -591,7 +591,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/support/mauler
name = "Mauler Exosuit"
- desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targetting, thrust vectoring, \
+ desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targeting, thrust vectoring, \
and deployable smoke."
item = /obj/mecha/combat/marauder/mauler/loaded
cost = 140
@@ -686,7 +686,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
detonate PDAs of crewmembers who have their message feature enabled. \
The concussive effect from the explosion will knock the recipient out for a short period, and deafen \
them for longer. Beware, it has a chance to detonate your PDA."
- item = /obj/item/weapon/cartridge/syndicate
+ item = /obj/item/weapon/cartridge/virus/syndicate
cost = 6
/datum/uplink_item/stealthy_weapons/suppressor
@@ -744,6 +744,15 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
exclude_modes = list(/datum/game_mode/nuclear)
player_minimum = 20
+/datum/uplink_item/stealthy_tools/frame
+ name = "F.R.A.M.E. PDA Cartridge"
+ desc = "When inserted into a personal digital assistant, this cartridge gives you five PDA viruses which \
+ when used cause the targeted PDA to become a new uplink with zero TCs, and immediately become unlocked. \
+ You will receive the unlock code upon activating the virus, and the new uplink may be charged with \
+ telecrystals normally."
+ item = /obj/item/weapon/cartridge/virus/frame
+ cost = 4
+
/datum/uplink_item/stealthy_tools/syndigaloshes/nuke
name = "Stealthy No-Slip Chameleon Shoes"
desc = "These shoes will allow the wearer to run on wet floors and slippery objects without falling down. \
@@ -837,7 +846,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/suits/space_suit
name = "Syndicate Space Suit"
desc = "This red and black syndicate space suit is less encumbering than Nanotrasen variants, \
- fits inside bags, and has a weapon slot. Nanotrasen crewmembers are trained to report red space suit \
+ fits inside bags, and has a weapon slot. Nanotrasen crew members are trained to report red space suit \
sightings, however."
item = /obj/item/weapon/storage/box/syndie_kit/space
cost = 4
@@ -856,15 +865,17 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/suits/hardsuit/elite
name = "Elite Syndicate Hardsuit"
- desc = "An advanced hardsuit with superior armor and mobility to the standard Syndicate Hardsuit."
+ desc = "An upgraded, elite version of the syndicate hardsuit. It features fireproofing, and also \
+ provides the user with superior armor and mobility compared to the standard syndicate hardsuit."
item = /obj/item/clothing/suit/space/hardsuit/syndi/elite
cost = 8
include_modes = list(/datum/game_mode/nuclear)
exclude_modes = list()
/datum/uplink_item/suits/hardsuit/shielded
- name = "Shielded Hardsuit"
- desc = "An advanced hardsuit with built in energy shielding. The shields will rapidly recharge when not under fire."
+ name = "Shielded Syndicate Hardsuit"
+ desc = "An upgraded version of the standard syndicate hardsuit. It features a built-in energy shielding system. \
+ The shields can handle up to three impacts within a short duration and will rapidly recharge while not under fire."
item = /obj/item/clothing/suit/space/hardsuit/shielded/syndi
cost = 30
include_modes = list(/datum/game_mode/nuclear)
@@ -890,10 +901,10 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
cost = 1
/datum/uplink_item/device_tools/surgerybag
- name = "Syndicate Surgery Dufflebag"
- desc = "The Syndicate surgery dufflebag is a toolkit containing all surgery tools, surgical drapes, \
+ name = "Syndicate Surgery Duffel Bag"
+ desc = "The Syndicate surgery duffel bag is a toolkit containing all surgery tools, surgical drapes, \
a Syndicate brand MMI, a straitjacket, and a muzzle."
- item = /obj/item/weapon/storage/backpack/dufflebag/syndie/surgery
+ item = /obj/item/weapon/storage/backpack/duffelbag/syndie/surgery
cost = 3
/datum/uplink_item/device_tools/military_belt
@@ -923,7 +934,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/device_tools/thermal
name = "Thermal Imaging Glasses"
- desc = "These goggles can be turned to resemble common eyewears throughout the station. \
+ desc = "These goggles can be turned to resemble common eyewear found throughout the station. \
They allow you to see organisms through walls by capturing the upper portion of the infrared light spectrum, \
emitted as heat and light by objects. Hotter objects, such as warm bodies, cybernetic organisms \
and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks."
@@ -999,7 +1010,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/device_tools/c4bag
name = "Bag of C-4 explosives"
desc = "Because sometimes quantity is quality. Contains 10 C-4 plastic explosives."
- item = /obj/item/weapon/storage/backpack/dufflebag/syndie/c4
+ item = /obj/item/weapon/storage/backpack/duffelbag/syndie/c4
cost = 9 //10% discount!
cant_discount = TRUE
@@ -1007,7 +1018,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
name = "Bag of X-4 explosives"
desc = "Contains 3 X-4 plastic explosives. Similar, but more powerful than C-4. X-4 can be placed on a solid surface, such as a wall or window, and it will \
blast through the wall, injuring anything on the opposite side, while being safer to the user. For when you want a wider, deeper, hole."
- item = /obj/item/weapon/storage/backpack/dufflebag/syndie/x4
+ item = /obj/item/weapon/storage/backpack/duffelbag/syndie/x4
cost = 4 //
cant_discount = TRUE
@@ -1059,7 +1070,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
cost = 3
/datum/uplink_item/device_tools/assault_pod
- name = "Assault Pod Targetting Device"
+ name = "Assault Pod Targeting Device"
desc = "Use to select the landing zone of your assault pod."
item = /obj/item/device/assault_pod
cost = 30
@@ -1349,8 +1360,8 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/badass/bundle
name = "Syndicate Bundle"
- desc = "Syndicate Bundles are specialised groups of items that arrive in a plain box. \
- These items are collectively worth more than 20 telecrystals, but you do not know which specialisation \
+ desc = "Syndicate Bundles are specialized groups of items that arrive in a plain box. \
+ These items are collectively worth more than 20 telecrystals, but you do not know which specialization \
you will receive."
item = /obj/item/weapon/storage/box/syndicate
cost = 20
@@ -1383,7 +1394,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
continue
crate_value -= I.cost
new I.item(C)
- U.purchase_log += "\icon[I.item]"
+ U.purchase_log += "[bicon(I.item)]"
SSblackbox.add_details("traitor_uplink_items_bought", "[name]|[cost]")
return C
diff --git a/code/modules/vehicles/scooter.dm b/code/modules/vehicles/scooter.dm
index 25723067841..3c343441017 100644
--- a/code/modules/vehicles/scooter.dm
+++ b/code/modules/vehicles/scooter.dm
@@ -6,7 +6,7 @@
/obj/vehicle/scooter/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/wrench))
to_chat(user, "You begin to remove the handlebars...")
- playsound(get_turf(user), 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(get_turf(user), 'sound/items/ratchet.ogg', 50, 1)
if(do_after(user, 40*I.toolspeed, target = src))
var/obj/vehicle/scooter/skateboard/S = new /obj/vehicle/scooter/skateboard(get_turf(src))
new /obj/item/stack/rods(get_turf(src),2)
@@ -55,7 +55,7 @@
var/atom/throw_target = get_edge_target_turf(H, pick(GLOB.cardinal))
unbuckle_mob(H)
H.throw_at(throw_target, 4, 3)
- H.Weaken(5)
+ H.Knockdown(100)
H.adjustStaminaLoss(40)
visible_message("[src] crashes into [A], sending [H] flying!")
playsound(src, 'sound/effects/bang.ogg', 50, 1)
@@ -84,7 +84,7 @@
if(istype(I, /obj/item/weapon/wrench))
to_chat(user, "You deconstruct [src].")
new /obj/item/stack/rods(get_turf(src),10)
- playsound(get_turf(user), 'sound/items/Ratchet.ogg', 50, 1)
+ playsound(get_turf(user), 'sound/items/ratchet.ogg', 50, 1)
qdel(src)
return
diff --git a/code/modules/vehicles/speedbike.dm b/code/modules/vehicles/speedbike.dm
index ed3598dd86f..a70d6e88e8b 100644
--- a/code/modules/vehicles/speedbike.dm
+++ b/code/modules/vehicles/speedbike.dm
@@ -48,7 +48,7 @@
playsound(src, 'sound/effects/bang.ogg', 50, 1)
if(ishuman(A))
var/mob/living/carbon/human/H = A
- H.Weaken(5)
+ H.Knockdown(100)
H.adjustStaminaLoss(30)
H.apply_damage(rand(20,35), BRUTE)
if(!crash_all)
diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm
index c93699a2acd..e977ac4600f 100644
--- a/code/modules/zombie/organs.dm
+++ b/code/modules/zombie/organs.dm
@@ -6,7 +6,7 @@
icon_state = "blacktumor"
origin_tech = "biotech=5"
var/datum/species/old_species = /datum/species/human
- var/living_transformation_time = 3
+ var/living_transformation_time = 30
var/converts_living = FALSE
var/revive_time_min = 450
@@ -51,7 +51,7 @@
if(owner.stat != DEAD && !converts_living)
return
if(!iszombie(owner))
- to_chat(owner, "You can feel your heart stopping, but something isn't right... \
+ to_chat(owner, "You can feel your heart stopping, but something isn't right... \
life has not abandoned your broken form. You can only feel a deep and immutable hunger that \
not even death can stop, you will rise again!")
var/revive_time = rand(revive_time_min, revive_time_max)
@@ -76,6 +76,6 @@
owner.grab_ghost()
owner.visible_message("[owner] suddenly convulses, as [owner.p_they()][stand_up ? " stagger to [owner.p_their()] feet and" : ""] gain a ravenous hunger in [owner.p_their()] eyes!", "You HUNGER!")
playsound(owner.loc, 'sound/hallucinations/far_noise.ogg', 50, 1)
- owner.do_jitter_animation(living_transformation_time * 10)
+ owner.do_jitter_animation(living_transformation_time)
owner.Stun(living_transformation_time)
to_chat(owner, "You are now a zombie!")
diff --git a/code/world.dm b/code/world.dm
index 7b81dfd7831..1709d02c5e9 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -29,11 +29,11 @@
SetupLogs()
if(!RunningService()) //tgs2 support
- GLOB.revdata.DownloadPRDetails()
+ GLOB.revdata.DownloadPRDetails()
load_motd()
load_admins()
- load_menu()
+ LoadVerbs(/datum/verbs/menu)
if(config.usewhitelist)
load_whitelist()
LoadBans()
@@ -60,7 +60,7 @@
if(config.sql_enabled)
if(SSdbcore.Connect())
log_world("Database connection established.")
- var/datum/DBQuery/query_round_start = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (start_datetime, server_ip, server_port) VALUES (Now(), COALESCE(INET_ATON('[world.internet_address]'), 0), '[world.port]')")
+ var/datum/DBQuery/query_round_start = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (start_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')")
query_round_start.Execute()
var/datum/DBQuery/query_round_last_id = SSdbcore.NewQuery("SELECT LAST_INSERT_ID()")
query_round_last_id.Execute()
@@ -91,21 +91,25 @@
log_game("Round ID: [GLOB.round_id]")
/world/Topic(T, addr, master, key)
- if(config && config.log_world_topic)
+ var/list/input = params2list(T)
+
+ var/pinging = ("ping" in input)
+ var/playing = ("players" in input)
+
+ if(!pinging && !playing && config && config.log_world_topic)
GLOB.world_game_log << "TOPIC: \"[T]\", from:[addr], master:[master], key:[key]"
- var/list/input = params2list(T)
if(input[SERVICE_CMD_PARAM_KEY])
return ServiceCommand(input)
var/key_valid = (global.comms_allowed && input["key"] == global.comms_key)
- if("ping" in input)
+ if(pinging)
var/x = 1
for (var/client/C in GLOB.clients)
x++
return x
- else if("players" in input)
+ else if(playing)
var/n = 0
for(var/mob/M in GLOB.player_list)
if(M.client)
@@ -245,7 +249,6 @@
s += "[station_name()]";
s += " ("
s += "" //Change this to wherever you want the hub to link to.
-// s += "[game_version]"
s += "Default" //Replace this with something else. Or ever better, delete it and uncomment the game version.
s += ""
s += ")"
diff --git a/config/game_options.txt b/config/game_options.txt
index fca46c529d1..82986412d43 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -46,7 +46,7 @@ ROBOT_DELAY 0
MONKEY_DELAY 0
ALIEN_DELAY 0
SLIME_DELAY 0
-ANIMAL_DELAY 0
+ANIMAL_DELAY 1
## NAMES ###
@@ -87,10 +87,10 @@ PROBABILITY CHANGELING 2
PROBABILITY WIZARD 4
PROBABILITY MALFUNCTION 1
PROBABILITY BLOB 2
-PROBABILITY RAGINMAGES 2
PROBABILITY MONKEY 0
PROBABILITY METEOR 0
PROBABILITY EXTENDED 0
+PROBABILITY SECRET_EXTENDED 0
PROBABILITY DEVIL 0
PROBABILITY DEVIL_AGENTS 0
@@ -103,7 +103,7 @@ PROBABILITY SANDBOX 0
CONTINUOUS TRAITOR
CONTINUOUS TRAITORCHAN
-CONTINUOUS DOUBLE_AGENTS
+CONTINUOUS INTERNAL_AFFAIRS
#CONTINUOUS NUCLEAR
#CONTINUOUS REVOLUTION
CONTINUOUS GANG
@@ -114,13 +114,13 @@ CONTINUOUS WIZARD
CONTINUOUS MALFUNCTION
CONTINUOUS BLOB
CONTINUOUS ABDUCTION
-#CONTINUOUS RAGINMAGES
#CONTINUOUS MONKEY
##Note: do not toggle continuous off for these modes, as they have no antagonists and would thus end immediately!
CONTINUOUS METEOR
CONTINUOUS EXTENDED
+CONTINUOUS SECRET_EXTENDED
## Toggles for allowing midround antagonists (aka mulligan antagonists).
@@ -128,7 +128,7 @@ CONTINUOUS EXTENDED
MIDROUND_ANTAG TRAITOR
MIDROUND_ANTAG TRAITORCHAN
-MIDROUND_ANTAG DOUBLE_AGENTS
+MIDROUND_ANTAG INTERNAL_AFFAIRS
#MIDROUND_ANTAG NUCLEAR
#MIDROUND_ANTAG REVOLUTION
#MIDROUND_ANTAG GANG
@@ -139,7 +139,6 @@ MIDROUND_ANTAG WIZARD
MIDROUND_ANTAG MALFUNCTION
MIDROUND_ANTAG BLOB
MIDROUND_ANTAG ABDUCTION
-#MIDROUND_ANTAG RAGINMAGES
#MIDROUND_ANTAG MONKEY
## Uncomment these for overrides of the minimum / maximum number of players in a round type.
diff --git a/config/lavaruinblacklist.txt b/config/lavaruinblacklist.txt
index 5afb96f6cdc..aec26764a59 100644
--- a/config/lavaruinblacklist.txt
+++ b/config/lavaruinblacklist.txt
@@ -14,7 +14,6 @@
#_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm
#_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm
#_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm
-#_maps/RandomRuins/LavaRuins/lavaland_surface_surface_ueg_crash1.dmm
##SIN
#_maps/RandomRuins/LavaRuins/lavaland_surface_envy.dmm
diff --git a/config/policies.txt b/config/policies.txt
new file mode 100644
index 00000000000..1d01782c4cc
--- /dev/null
+++ b/config/policies.txt
@@ -0,0 +1,5 @@
+## SERVER POLICIES ##
+# Each line is pure html that gets sent to the user under certain conditions
+
+# When a mob is polymorphed
+POLYMORPH Note that you are allowed to act as an antagonist while transformed into a hostile mob, unless you volunteered for or sought out transformation.
diff --git a/html/changelog.html b/html/changelog.html
index d1484f70302..ae5dfc159af 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -55,6 +55,433 @@
-->
+
20 June 2017
+
Bawhoppen updated:
+
+
Grenade belts and bandoliers will no longer obscure half the screen when they're completely filled.
+
+
LanCartwright updated:
+
+
Removed loot drops from Syndicate Simple mobs.
+
+
Tacolizard updated:
+
+
Some items now have custom force strings in their tooltips.
+
items with no force can still use a custom force string.
+
+
Xhuis updated:
+
+
The station's heaters and freezers have been sternly reprimanded and will now drop the correct circuit boards and cable coils.
+
The straight jacket now takes five seconds to put on.
+
The display cases in luxury shelter capsules will no longer spawn unobtainable, abstract offhand objects.
+
Disablers now have an in-hand sprite.
+
+
nicbn updated:
+
+
Changed cryo sprites to Bay cryopods, which show the person inside of them.
+
+
+
19 June 2017
+
Expletive updated:
+
+
Paper frames can be created using wood and paper, and can be used to create decorative structures.
+
Natural paper can now be crafted
+
KorPhaeron can now start a maid cafe, if they so desire.
+
Thanks to the invention of "Bill slots", vending machines can now accept space cash.
+
The Clown and Mime can now find their unique crayons stored inside their PDAs
+
+
LanCartwright updated:
+
+
1D4 into Lavaland Mining base crate.
+
+
RandomMarine updated:
+
+
Bonfires now work on lavaland!
+
+
Tacolizard updated:
+
+
Repurposed the action button tooltip code to add tooltips with the examine details of all held and equipped items. Hover your mouse over any item equipped, held or in your inventory to examine it.
+
Examine tooltips can be toggled with the 'toggle-examine-tooltips' verb, which can be typed or accessed from the OOC menu.
+
You can change the delay before a tooltip appears with the 'set-examine-tooltip-delay' verb, also accessible via the OOC menu. The default delay is 500ms.
+
+
+
18 June 2017
+
Expletive updated:
+
+
Stacks of space cash now tell you their total value and their value per bill when you examine them.
+
+
RandomMarine updated:
+
+
Compressed matter cartridge production costs now reflect their material worth at basic efficiency.
+
Compressed matter cartridges can now be exported.
+
+
Xhuis updated:
+
+
Puny windows will no longer stop the progress of Ratvar.
+
+
+
17 June 2017
+
Cyberboss updated:
+
+
NT now provides education on the proper response for experiencing the excrutiating pain of varying degree burns (You scream when burning)
+
+
Expletive updated:
+
+
The Captain now starts with a deluxe fountain pen in their PDA.
+
The quartermaster, curator, research director, lawyer, and bartender start with normal fountain pens in their PDAs.
+
Cargo can order fountain pens via the Calligraphy Crate.
+
Nerds on the station will be pleased to know they now have pocket protectors.
+
Cryo cells work properly on mobs with varying max health values.
+
+
Joan updated:
+
+
Cultists must be human to run for Cult Master status.
+
The Hierophant is a little less chaotic and murdery on average.
+
+
LanCartwright updated:
+
+
Penguins, penguin chicks, penguin eggs.
+
Penguin family to Winter Wonderland.
+
+
MrStonedOne and Lummox JR updated:
+
+
Fixed icon scaling and size preferences not loading (Technically size preferences were loading because byond saves that locally, but that's not reliable because ss13 shares a hub)
+
+
QualityVan updated:
+
+
The botany vending machine now has a stock of onion seeds
+
+
RandomMarine updated:
+
+
RCDs now always use matter consistent with the material needed when building.
+
Floors now cost 3 or 1 matter to build, based on if a lattice exists on the tile.
+
Reinforced windows cost 12 matter. Normal windows cost 8 matter. (Both up/down from 10)
+
Glass airlocks cost 20 matter.
+
RCDs are faster at building grilles and plain glass windows.
+
+
Steelpoint updated:
+
+
Slightly reshuffles the Head of Security's, and Research Directors, locker to place fluff items below essential items.
+
+
Tacolizard updated:
+
+
Flashes no longer have a tech requirement
+
+
That Really Good Soda Flavor updated:
+
+
High luminosity eyes will have material science instead of an error research type
+
+
Thunder12345 and Improvedname updated:
+
+
You can now turn severed cat tails and ears into genuine kitty ears
+
Cat tails can now be used to make a cat o' nine tails, similarly to the liz o' nine tails.
+
+
Xhuis updated:
+
+
The names of the hand drill, jaws of life, and emitter are now lowercase.
+
The descriptions of the hand drill, jaws of life, and emitter have been changed to be more descriptive and less lengthy.
+
Tablets with IDs in them now show the ID's name when examining someone with that tablet in their ID slot, similar to a PDA would.
+
+
bandit updated:
+
+
Default short/medium/long brig times are now, in order, 2, 3, and 5 minutes.
+
+
+
14 June 2017
+
Expletive updated:
+
+
The medalboxes are now fancy.
+
New sprites for opened medal boxes.
+
+
Joan updated:
+
+
Being converted to clockcult will briefly cause your world to turn yellow and you to hear the machines of Reebe, matching the description in the messages.
+
The messages for being converted and for failing conversion to clockcult have been updated.
+
+
Tacolizard updated:
+
+
Flamethrowers no longer say they're being ignited when you extinguish them
+
+
+
13 June 2017
+
Expletive updated:
+
+
Paper planes are now the same color as the paper used to make them.
+
Flashdarks can no longer be used to examine head based organs.
+
+
Fox McCloud updated:
+
+
Tweaked game options animal speed value to match live server
+
+
Joan updated:
+
+
Renamed AI liquid dispensers to foam dispensers.
+
Foam dispensers now activate immediately when clicked, rather than forcing the user to go through a menu. They also have better visual, message, and examine feedback on if they can be activated.
+
+
MrStonedOne updated:
+
+
Added some code to detect the byond bug causing clients to send phantom actions shortly after connection. It will attempt to fix or work around the issue.
+
+
Nanotrasen Robotics Department updated:
+
+
To aid in general-purpose cleaning and maintaining of station faculties, all janitor cyborgs are now outfitted with a screwdriver, crowbar, and floor tile synthesizer.
+
+
WJohnston updated:
+
+
Survival bunker ruin's power now works, mostly.
+
+
shizcalev updated:
+
+
"Radiation immune species are now incompatible with the radiation based genetics DNA scanner/modifier."
+
+
+
11 June 2017
+
Expletive updated:
+
+
Glass tables are shinier
+
+
Nanotrasen Consistency Affairs updated:
+
+
You no longer see yourself in place of the user when examining active Spirit Sight runes.
+
+
Shadowlight213 updated:
+
+
Cloning dismembered heads and brains now respects husking and other clone preventing disabilities.
+
+
WJohn updated:
+
+
It is now easier to wire the powernet into box's telecomms SMES cell.
+
+
Xhuis updated:
+
+
You can now pin papers and photos to airlocks. Anyone examining the airlock from up close can see the details. You can cut them down with wirecutters.
+
+
lordpidey updated:
+
+
Added F.R.A.M.E. cartridge to uplinks. This PDA cartridge contains 5 viruses, which when used will unlock the target's PDA into a syndicate uplink, in addition, you will receive the code needed to unlock the uplink again, if you so desire.
+
If you use telecrystals on a F.R.A.M.E. cartridge, the next time it is used, it will also give those crystals to the target uplink.
+
+
octareenroon91 updated:
+
+
Mecha tools now respond to MMI control signals as intended.
+
+
shizcalev updated:
+
+
"Species immune to radiation are no longer compatible targets of radiation based DNA injectors."
+
"A gun's firing pin will no longer malfunction when placed into your own mouth. Phew!"
+
"Bedsheets capes are now slightly more accurate. Be jealous of the clown and their sexy cape!"
+
+
+
09 June 2017
+
Nanotrasen Shiny Object Appreciation Club updated:
+
+
The RD and HoS now receive medal lockboxes in their lockers, containing science and security medals, respectively.
+
+
Tacolizard and Cyberboss, idea by RandomMarine updated:
+
+
You can now add a commendation message when pinning a medal on someone.
+
Medal commendations will be displayed when the round ends.
+
Refactored the outfit datum to allow accessories as part of an outfit.
+
The Captain spawns with the Medal of Captaincy again.
+
+
TrustyGun updated:
+
+
Some of the clown's toys have been moved into a crate in the theater. If you think you are missing something, check in there.
+
Wooden crates have been added. You can construct them with 6 wooden planks, and deconstruct them the same way as regular crates
+
+
oranges updated:
+
+
Security minor and major crime descriptors are now a single line input, making it easier to add them
+
Medical record descriptions are single inputs now
+
+
+
08 June 2017
+
4dplanner updated:
+
+
traitors show up on antagHUD
+
+
Expletive updated:
+
+
The detective's flask has Hearty Punch instead of whiskey.
+
The Detective's fedora no longer clips with hair.
+
Adds 91 new sprites to fix clipping issues with the Detective's fedora and hair.
+
Change the standard fedora to match the detective and treasure hunter variants.
+
Detective, Treasure Hunter, and standard fedoras now all benefit from new sprites.
+
+
Joan updated:
+
+
Tinkerer's Daemons are no longer totally disabled if you drop below the servant requirement.
+
Instead, Tinkerer's Daemons will disable until the number of active daemons is equal to or less than one-fifth of the living Servants.
+
Tinkerer's Daemons produce components very slightly slower.
+
Added Prolonging Prism as an application scripture.
+
Prolonging Prism will delay the arrival of an emergency shuttle by 2 minutes at the cost of 2500W of power plus 75W for every 10 CV and 750W for every previous activation. In addition to the high cost, it very obviously affects the shuttle dock and leaves an obvious trail to the prism.
+
Script scripture now requires 6 Servants to unlock, from 5, and Application scripture now requires 9 Servants to unlock, from 8.
+
+
Lzimann + Cyberboss updated:
+
+
Ported goonchat. Much less laggy and crashy than BYOND chat. + Frills!
+
+
NanoTrasen Public Relations Department updated:
+
+
A mining accident has released large amounts of space dust, which is starting to drift near our stations. Don't panic, it's probably safe.
+
+
Nanotrasen Plastic Surgery Advert updated:
+
+
Are you a mutant? Were you born hideously deformed? Do you have ears growing out of the top of your head? Or even a tail? Don't worry, with our patented surgical techniques, Nanotrasen's highly trained medical staff can make you normal! Schedule an appointment, and one of our surgeons can see you same day.
+
Cat ears now give you double the ear damage.
+
+
QualityVan updated:
+
+
Cremators now still work when there's only one thing in them
+
The ORM now uses the intended amount of resources when making alloys
+
Cyborgs can no longer alt-click their material stacks to split them
+
+
Robustin updated:
+
+
The blood cult can only attempt to summon Nar-Sie in one of three rooms that are randomly selected at round-start.
+
+
Shadowlight213 updated:
+
+
Tracking implants and chem implants have been added to rnd
+
Adrenaline and freedom implants have been removed from rnd
+
+
Xhuis updated:
+
+
Defibrillator paddles will no longer stick to your hands, and will snap back onto the unit if you drop them somehow.
+
+
lzimann updated:
+
+
Xeno queens can no longer be maids
+
+
oranges updated:
+
+
Added stungloves to the brain damage lines
+
+
+
07 June 2017
+
Expletive updated:
+
+
New plasma medals have been added to the Captain's medal box. Don't get them too warm.
+
New sprites for plasma medals.
+
Icon and worn sprites for all medals and the lawyer's badge have been improved. Worn medals more closely match their icons.
+
The bone talisman is an accessory again, so it's not useless.
+
It also has a new worn sprite, based on an arm band.
+
Ties have been removed from accessories.dmi and vice versa. Same for the explorer's webbing sprites that were in there. ties.dmi is now neck.dmi, and has sprites for scarves, ties, sthetoscopes, etc.
+
Examining an accessory now tells you how to use it.
+
+
Joan updated:
+
+
Renamed Volt Void to Volt Blaster.
+
Volt Blaster does not consume power when firing and does not cause backlash if you don't fire.
+
Volt Blaster does 25 damage, from 20-40 depending on power, and has 5 shots, from 4, over its duration.
+
+
QualityVan updated:
+
+
Surplus rifles are no longer invisible while unloaded
+
+
Shadowlight213 updated:
+
+
The Changeling Transformation Sting is once again stealthy. However, it no longer transfers mutations.
+
The chemical cost of Transformation Sting has been increased to 50
+
+
+
06 June 2017
+
Joan updated:
+
+
Added a new unique Kinetic Accelerator module to necropolis chests.
+
Renames Clockwork Proselytizers to Replica Fabricators.
+
Replica Fabricators can directly consume floor tiles, rods, metal, and plasteel for power instead of needing to convert to brass first.
+
Cogscarabs can no longer use guns.
+
KA modkits in necropolis chests are now design discs with designs for those modkits, to force miners to bring back minerals.
+
+
PKPenguin321 updated:
+
+
The fake pits that the arcade machines can vend now vend properly, for real this time.
+
+
Robustin updated:
+
+
The cult master has finally acquired their 3rd spell, Eldritch Pulse. This ability allows the cult master to quickly teleport any cultist or cult structure in visual range to another tile in visual range. This spell has an obvious spell effect that will indicate where the target has gone but without explicitly revealing who the master is. This spell should assist with moving obstinate cultists off an important rune, getting wandering cultists back onto an important rune, save a cultist from an untimely arrest/summary execution, assist in getting your allies into secure areas, etc.
+
The void torch now only works on items that have been placed on surfaces, this prevents the inventory bugs associated with this item.
+
+
thefastfoodguy updated:
+
+
you can burn your brains out with a flashlight if you're tired of life
+
+
+
05 June 2017
+
Expletive updated:
+
+
The Ore Redemption Machine has been ported to TGUI. New features include the addition of "Release All" and "Smelt All" buttons.
+
The Ore Redemption Machine now be loaded with sheets of material.
+
The Ore Redemption Machine can now 'smelt' Reinforced Glass.
+
+
Joan updated:
+
+
Only human and silicon servants can help recite multi-invoker scriptures. This means cogscarabs, clockwork marauders, and anima fragments DO NOT COUNT for scriptures that require multiple invokers.
+
Clockcult scripture tiers can no longer be lost by dipping below their requirements once they are unlocked.
+
Removes Revenant scriptures entirely.
+
+
MMMiracles updated:
+
+
Deepstorage ruin has been redone to be more self-sufficient and up to better mapping standards.
+
+
+
04 June 2017
+
Expletive updated:
+
+
Many stacks now update their sprite based on their amount.
+
Stacks will now weigh less if they're less than full.
+
Added new icon states for glass, reinforced glass, metal, plasteel, plastic, plasma, plastitanium, titanium, gold, silver, adamantine, brass, bruise packs, ointment, gauze, cloth, leather, wet leather, hairless hide, human hide, ash drake hide, goliath hide, bones, sandstone blocks, and snow blocks.
+
Some lavaland stacks' max amounts have been reduced.
+
Bulldog Shotguns should update their sprite properly when you remove the magazine.
+
Riot suits no longer hide jumpsuits.
+
+
Joan updated:
+
+
Rod Form now costs 2 points, from 3.
+
Rod Form now does 70 damage, from 160, but gains 20 damage, per upgrade, when upgraded. This means you'll need to spend 6 points on it to instantly crit people from full health.
+
+
Swindly updated:
+
+
Chemical grenades are no longer permanently disabled after being unlocked by wirecutters after being primed.
+
+
+
03 June 2017
+
Expletive updated:
+
+
Chem Dispensers now store their power in their batteries.
+
Instead of being based on battery and capacitor ratings, recharge delay for portable chem dispensers is now based on their capacitor and matter bin ratings.
+
The Seed Vault's chemical dispenser now has all the chemicals a pod person could want.
+
The crafting menu now has subcategories!
+
Food recipe categories have been combined as subcategories of the Foods category.
+
Weaponry and Ammunition have been combined as subcategories of the Weaponry category.
+
+
Improvedname updated:
+
+
Janitors now start with a flyswatter
+
+
Mothership Epsilon updated:
+
+
All your base are belong to us.
+
+
Penguaro updated:
+
+
[Box] Removes extra/unattached vent from Xeno Lab
+
+
Planned Spaceparenthood updated:
+
+
We would like to apologize for mislabeled cloning pod buttons.
+
+
WJohnston updated:
+
+
Deltastation's south nuke op shuttle location should no longer be possible to teleport into by moving off the map and back on, and moved the rest closer to the station.
+
+
p440 updated:
+
+
Fixed duping cable coils with magic APC terminals
+
Fixed invalid icon state for empty APCs
+
+
02 June 2017
Cyberboss updated:
@@ -1226,244 +1653,6 @@
APCs hacked by a malfunctioning AI are no longer immune to alien attacks.
Fixed bug where flashlight eyes weren't emitting light.
-
-
18 April 2017
-
BeeSting12 updated:
-
-
Cerestation's shuttle now has a recharger.
-
Centcomm's thunderdome airlocks have been removed due to contestants breaking out.
-
Deltastation's chemistry lab now has a pill bottle closet.
-
The shield wall generators in xenobiology on Deltastation, Boxstation, Metastation, and Pubbystation can now be locked and unlocked by scientists.
-
-
Davidj361 updated:
-
-
Spawned humans no longer spawn eyeless (sprite)
-
-
MMMiracles (Cerestation) updated:
-
-
Departments have been given head offices for a more secure place to chill in their departments.
-
There is now a theatre on the service asteroid.
-
Maintenance visuals and loot have been overhauled to be more visually interesting and have more scattered bits of loot.
-
Various fixes with missing APCs, camera coverage, and misc things.
-
-
QualityVan updated:
-
-
Some foam guns can now be suppressed
-
-
coiax updated:
-
-
Drone, monkey and swarmer language now have distinctive colours when spoken.
-
Since drones are allowed to interact with pAIs, pAIs in mobile chassis form are no longer distorted to drone viewpoints.
-
The shuttle's arrival can no longer be delayed after Nar-Sie's arrival. The End cannot be delayed.
-
-
-
15 April 2017
-
Cyberboss updated:
-
-
Holopads can no longer be interacted with while unpowered
-
-
Davidj361 updated:
-
-
Monkeys won't pickup items or rob you while they are in your stomach, neither walk out of your stomach.
-
You can't cheat with eyewear/eye-implants when using advanced cameras
-
Mutant digitigrade legs re-added to the ashwalker species
-
-
Robustin updated:
-
-
The Prototype Emitter, will function like an ordinary emitter while also charging a secondary power supply that will allow a buckled user to manually fire the emitter. Returning to automatic fire will have the emitter continue to fire at the last target struck by manual fire.
-
The Engineering Dance Machine, along with assorted effects/sounds.
-
-
coiax updated:
-
-
Plasmamen no longer burn to death while inside a cloning pod.
-
-
-
13 April 2017
-
Cyberboss updated:
-
-
Fixed the incorrectly named Brig APC on Box Station=
-
Fixed simple animal attack grammar
-
Roundstart department head announcements have been fixed
-
Brig cell doors now properly require the correct access
-
Fixed a bug preventing chameleon stamps from being picked up
-
Fixed a bug where honey frames couldn't be picked up
-
Photocopied papers will now retain their stamps
-
-
Davidj361 updated:
-
-
Made it so chemsprayers, peppersprays, extinguishers don't spray when you click your inventory items
-
Spray guns now actually have their range change when changing modes between spray and stream
-
Krav maga now gets its abilities toggled if you click the same ability twice
-
Added a link to the bottom right of paper when writing that shows help for paper writing
-
Fixed the shift+middle-click pointing shortcut to work for cyborgs as the functionality wasn't even there
-
Bodies in body bags get cremated properly now
-
-
RemieRichards updated:
-
-
Constructing lattice no longer prevents space transitions.
-
-
Robustin updated:
-
-
Ranged RCD added to the game
-
Rapid Lighting Device (also ranged) has been added. It can create wall, floor, and temporary lights of any color you desire.
-
-
coiax updated:
-
-
Cigarette branding has been fixed.
-
Uplift Smooth brand cigarettes now taste minty as advertised.
-
You can no longer inject cigarette packets to inject all cigarettes simultaneously.
-
-
powergaming research director updated:
-
-
woops i dropped the emp protection module when i made your cns rebooters today, guess they're vulnerable again!
-
-
-
11 April 2017
-
BeeSting12 updated:
-
-
"the herpes of arts and crafts" is now "The herpes of arts and crafts."
-
-
Cyberboss updated:
-
-
Runes no longer make you/themselves/random atoms yuge
-
-
JJRcop updated:
-
-
Refactors whisper, now all living mobs can use it
-
Prefix any message with # to whisper, for example, "# Man, that guy is weird.", you can still use the whisper verb if you whish.
-
This is compatible with languages, for example "#,r That HoS is a problem, we should kill him"
-
Removes #a #b #c etc radio codes, as well as :w and .w, which used to be whisper.
-
-
MrStonedOne updated:
-
-
Nightvision was heavily modified.
-
Nightvision has been given 3 levels of nightvisionness. (some, most, and full)
-
ghosts, aliens, guardians, night vision eyes, and statues were given all 3 levels in a cycling toggle
-
thermals, and hud+NV goggles give "some" nightvisionness
-
standalone masons are unchanged.
-
Nightvision goggles (that aren't also sec huds or medhuds or the like) give "most" nightvisionness. Nightvision masons also give "most" nightvisionness
-
Most simple mobs with the ability to see in the dark were given "most" nightvisionness, others got full nightvisionness.
-
Fixed certain ghost only things disappearing when disabling darkness.
-
Fixed ash storms not being visible when using things that modified your ability to see darkness
-
fix a bug with the new github web processor
-
-
Shadowlight213 updated:
-
-
The anime admin button will no longer cause equipped items to drop.
-
-
coiax updated:
-
-
Examining a ghost determines whether it is visible.
-
-
-
09 April 2017
-
4dplanner updated:
-
-
Gas analyzers can now detect more gases in pipes
-
-
Joan updated:
-
-
Fixed a bug where getting caught between two shield generators as they activated wouldn't cause you to gib and die.
-
-
QV updated:
-
-
Refactored the way limbs that aren't limbs work
-
-
octareenroon91 updated:
-
-
Hackable wires should work as intended again.
-
-
-
07 April 2017
-
Qbopper updated:
-
-
Secure lockers will no longer have multiple lines about being broken.
-
-
-
05 April 2017
-
Cyberboss updated:
-
-
Cardboard boxes and bodybags can no longer be anchored
-
-
Penguaro updated:
-
-
[Box] A fire alarm has been added to the Lawyer's office.
-
[Box] Adds access for Scientists to Starboard Maintenance Areas outside of Toxins.
-
[Box] Adjusted Science doors to more logical access codes.
-
-
QV updated:
-
-
Fixed taking max suffocation damage whenever oxygen was slightly low
-
-
RemieRichards updated:
-
-
Using TK on the supermatter will burn your head off violently, don't do this.
-
Examining clothing with pockets will now give information about the pockets: number of slots, how it is interacted with (backpack, etc.), if it has quickdraw (Alt-Click) support and whether or not it is silent to interact with.
-
-
coiax updated:
-
-
Emergency shuttles will now forget early launch authorizations if they cannot launch due to a hostile environment.
-
-
-
02 April 2017
-
BeeSting12 updated:
-
-
Metastation's northeast radiation collector is now connected to the grid. Nanotrasen would like to apologize for any inconvenience caused to engineers, but copper is expensive.
-
Boxstation's HoP office now has a PDA tech.
-
-
Cyberboss updated:
-
-
Firedoors no longer operate automatically without power
-
Blood and other decals will no longer remain on turfs they shouldn't
-
The splashscreen is working again
-
False alarms are now guaranteed to actually announce something
-
-
Incoming5643 updated:
-
-
Lighting visuals have been changed slightly to reduce it's cost to the client. If you had trouble running the new lighting, it might run a little better now.
-
-
MMMiracles (CereStation) updated:
-
-
Added a patrol path for bots, includes 2 round-start securitrons placed on opposite sites of station.
-
Due to map size, mulebots are still somewhat unreliable on longer distances. Disposals are still advised, but mule bots are now technically an option for delivery.
-
Added multiple status displays, extinguishers, and appropriate newscasters to hallways.
-
A drone dispenser is now located underneath Engineering in maintenance.
-
Each security checkpoint now has a disposal chute that directs to a waiting cell in the Brig for rapid processing of criminals. Why run half-way across the station with some petty thief when you can just shove him in the criminal chute and have the warden deal with him?
-
Security's mail chute no longer leads into the armory. This was probably not the best idea in hindsight.
-
Virology has a bathroom now.
-
Genetics monkey pen is a bit more green now.
-
Lawyer now has access the brig cells so he can complain more effectively.
-
Xenobio kill chamber is now in range of a camera.
-
Removed rogue bits of Vault area.
-
Medbay escape pod no longer juts out far enough to block the disposal's path.
-
Captain's spare ID is now real and not just a gold ID card.
-
-
Penguaro updated:
-
-
[Meta] The Chapel Security Hatches were very intimidating. They have been changed to more inviting glass doors.
-
[Meta] The maintenance tunnels in the Xeno Lab now have radiation shielding. The Slime Euthanization Chamber will not have radiation shielding at this time as dead slimes will not mind radiation.
-
-
coiax updated:
-
-
Adds seperate languages to the game. Now Ratvarian, Drone, Machine, Swarmer, Human (now called Galactic Common), Slime and Monkey are separate languages. Each languages has its own comma prefix, for example, Galcom has the ,0 prefix, while Ratvarian has the ,r prefix. If you don't understand a language when it is spoken to you, you will hear a scrambled version that will vary depending on the language that you're not understanding.
-
This does not change who can understand what.
-
Removed the talk wheel feature.
-
Clicking the speech bubble icon now opens the Language Menu, allowing you to review which languages you speak, their keys, and letting you set which language you speak by default. Admins have additional abilities to add and remove languages from mobs using this menu.
-
-
ktccd updated:
-
-
Ninja suits have received a new software update, making them able to **actually steal tech levels** from R&D consoles and servers, thus avoid being forced to honourably kill themselves for failing their objective.
-
-
-
01 April 2017
-
Cyberboss updated:
-
-
The contents of the shelterpod smart fridge work again
-
-
XDTM updated:
-
-
Facehuggers no longer rip masks from people protected by helmets.
-
GoonStation 13 Development Team
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 7a7a427142d..676b6fc8074 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -11627,3 +11627,356 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
octareenroon91:
- bugfix: Attempts to add items to a storage container beyond its slots limit will
now obtain a failure message again.
+2017-06-03:
+ Expletive:
+ - tweak: Chem Dispensers now store their power in their batteries.
+ - tweak: Instead of being based on battery and capacitor ratings, recharge delay
+ for portable chem dispensers is now based on their capacitor and matter bin
+ ratings.
+ - tweak: The Seed Vault's chemical dispenser now has all the chemicals a pod person
+ could want.
+ - rscadd: The crafting menu now has subcategories!
+ - rscadd: Food recipe categories have been combined as subcategories of the Foods
+ category.
+ - rscadd: Weaponry and Ammunition have been combined as subcategories of the Weaponry
+ category.
+ Improvedname:
+ - rscadd: Janitors now start with a flyswatter
+ Mothership Epsilon:
+ - tweak: All your base are belong to us.
+ Penguaro:
+ - bugfix: '[Box] Removes extra/unattached vent from Xeno Lab'
+ Planned Spaceparenthood:
+ - bugfix: We would like to apologize for mislabeled cloning pod buttons.
+ WJohnston:
+ - bugfix: Deltastation's south nuke op shuttle location should no longer be possible
+ to teleport into by moving off the map and back on, and moved the rest closer
+ to the station.
+ p440:
+ - bugfix: Fixed duping cable coils with magic APC terminals
+ - bugfix: Fixed invalid icon state for empty APCs
+2017-06-04:
+ Expletive:
+ - rscadd: Many stacks now update their sprite based on their amount.
+ - rscadd: Stacks will now weigh less if they're less than full.
+ - imageadd: Added new icon states for glass, reinforced glass, metal, plasteel,
+ plastic, plasma, plastitanium, titanium, gold, silver, adamantine, brass, bruise
+ packs, ointment, gauze, cloth, leather, wet leather, hairless hide, human hide,
+ ash drake hide, goliath hide, bones, sandstone blocks, and snow blocks.
+ - tweak: Some lavaland stacks' max amounts have been reduced.
+ - bugfix: Bulldog Shotguns should update their sprite properly when you remove the
+ magazine.
+ - bugfix: Riot suits no longer hide jumpsuits.
+ Joan:
+ - balance: Rod Form now costs 2 points, from 3.
+ - balance: Rod Form now does 70 damage, from 160, but gains 20 damage, per upgrade,
+ when upgraded. This means you'll need to spend 6 points on it to instantly crit
+ people from full health.
+ Swindly:
+ - balance: Chemical grenades are no longer permanently disabled after being unlocked
+ by wirecutters after being primed.
+2017-06-05:
+ Expletive:
+ - rscadd: The Ore Redemption Machine has been ported to TGUI. New features include
+ the addition of "Release All" and "Smelt All" buttons.
+ - rscadd: The Ore Redemption Machine now be loaded with sheets of material.
+ - rscadd: The Ore Redemption Machine can now 'smelt' Reinforced Glass.
+ Joan:
+ - balance: Only human and silicon servants can help recite multi-invoker scriptures.
+ This means cogscarabs, clockwork marauders, and anima fragments DO NOT COUNT
+ for scriptures that require multiple invokers.
+ - balance: Clockcult scripture tiers can no longer be lost by dipping below their
+ requirements once they are unlocked.
+ - rscdel: Removes Revenant scriptures entirely.
+ MMMiracles:
+ - tweak: Deepstorage ruin has been redone to be more self-sufficient and up to better
+ mapping standards.
+2017-06-06:
+ Joan:
+ - rscadd: Added a new unique Kinetic Accelerator module to necropolis chests.
+ - spellcheck: Renames Clockwork Proselytizers to Replica Fabricators.
+ - balance: Replica Fabricators can directly consume floor tiles, rods, metal, and
+ plasteel for power instead of needing to convert to brass first.
+ - balance: Cogscarabs can no longer use guns.
+ - tweak: KA modkits in necropolis chests are now design discs with designs for those
+ modkits, to force miners to bring back minerals.
+ PKPenguin321:
+ - bugfix: The fake pits that the arcade machines can vend now vend properly, for
+ real this time.
+ Robustin:
+ - rscadd: The cult master has finally acquired their 3rd spell, Eldritch Pulse.
+ This ability allows the cult master to quickly teleport any cultist or cult
+ structure in visual range to another tile in visual range. This spell has an
+ obvious spell effect that will indicate where the target has gone but without
+ explicitly revealing who the master is. This spell should assist with moving
+ obstinate cultists off an important rune, getting wandering cultists back onto
+ an important rune, save a cultist from an untimely arrest/summary execution,
+ assist in getting your allies into secure areas, etc.
+ - bugfix: The void torch now only works on items that have been placed on surfaces,
+ this prevents the inventory bugs associated with this item.
+ thefastfoodguy:
+ - tweak: you can burn your brains out with a flashlight if you're tired of life
+2017-06-07:
+ Expletive:
+ - rscadd: New plasma medals have been added to the Captain's medal box. Don't get
+ them too warm.
+ - imageadd: New sprites for plasma medals.
+ - imageadd: Icon and worn sprites for all medals and the lawyer's badge have been
+ improved. Worn medals more closely match their icons.
+ - tweak: The bone talisman is an accessory again, so it's not useless.
+ - imageadd: It also has a new worn sprite, based on an arm band.
+ - imagedel: Ties have been removed from accessories.dmi and vice versa. Same for
+ the explorer's webbing sprites that were in there. ties.dmi is now neck.dmi,
+ and has sprites for scarves, ties, sthetoscopes, etc.
+ - tweak: Examining an accessory now tells you how to use it.
+ Joan:
+ - spellcheck: Renamed Volt Void to Volt Blaster.
+ - tweak: Volt Blaster does not consume power when firing and does not cause backlash
+ if you don't fire.
+ - balance: Volt Blaster does 25 damage, from 20-40 depending on power, and has 5
+ shots, from 4, over its duration.
+ QualityVan:
+ - bugfix: Surplus rifles are no longer invisible while unloaded
+ Shadowlight213:
+ - balance: The Changeling Transformation Sting is once again stealthy. However,
+ it no longer transfers mutations.
+ - balance: The chemical cost of Transformation Sting has been increased to 50
+2017-06-08:
+ 4dplanner:
+ - bugfix: traitors show up on antagHUD
+ Expletive:
+ - tweak: The detective's flask has Hearty Punch instead of whiskey.
+ - bugfix: The Detective's fedora no longer clips with hair.
+ - imageadd: Adds 91 new sprites to fix clipping issues with the Detective's fedora
+ and hair.
+ - imageadd: Change the standard fedora to match the detective and treasure hunter
+ variants.
+ - tweak: Detective, Treasure Hunter, and standard fedoras now all benefit from new
+ sprites.
+ Joan:
+ - balance: Tinkerer's Daemons are no longer totally disabled if you drop below the
+ servant requirement.
+ - balance: Instead, Tinkerer's Daemons will disable until the number of active daemons
+ is equal to or less than one-fifth of the living Servants.
+ - tweak: Tinkerer's Daemons produce components very slightly slower.
+ - rscadd: Added Prolonging Prism as an application scripture.
+ - balance: Prolonging Prism will delay the arrival of an emergency shuttle by 2
+ minutes at the cost of 2500W of power plus 75W for every 10 CV and 750W for
+ every previous activation. In addition to the high cost, it very obviously affects
+ the shuttle dock and leaves an obvious trail to the prism.
+ - balance: Script scripture now requires 6 Servants to unlock, from 5, and Application
+ scripture now requires 9 Servants to unlock, from 8.
+ Lzimann + Cyberboss:
+ - experiment: Ported goonchat. Much less laggy and crashy than BYOND chat. + Frills!
+ NanoTrasen Public Relations Department:
+ - rscadd: A mining accident has released large amounts of space dust, which is starting
+ to drift near our stations. Don't panic, it's probably safe.
+ Nanotrasen Plastic Surgery Advert:
+ - rscadd: Are you a mutant? Were you born hideously deformed? Do you have ears growing
+ out of the top of your head? Or even a tail? Don't worry, with our patented
+ surgical techniques, Nanotrasen's highly trained medical staff can make you
+ normal! Schedule an appointment, and one of our surgeons can see you same day.
+ - balance: Cat ears now give you double the ear damage.
+ QualityVan:
+ - bugfix: Cremators now still work when there's only one thing in them
+ - bugfix: The ORM now uses the intended amount of resources when making alloys
+ - rscdel: Cyborgs can no longer alt-click their material stacks to split them
+ Robustin:
+ - balance: The blood cult can only attempt to summon Nar-Sie in one of three rooms
+ that are randomly selected at round-start.
+ Shadowlight213:
+ - rscadd: Tracking implants and chem implants have been added to rnd
+ - rscdel: Adrenaline and freedom implants have been removed from rnd
+ Xhuis:
+ - tweak: Defibrillator paddles will no longer stick to your hands, and will snap
+ back onto the unit if you drop them somehow.
+ lzimann:
+ - rscdel: Xeno queens can no longer be maids
+ oranges:
+ - rscadd: Added stungloves to the brain damage lines
+2017-06-09:
+ Nanotrasen Shiny Object Appreciation Club:
+ - rscadd: The RD and HoS now receive medal lockboxes in their lockers, containing
+ science and security medals, respectively.
+ Tacolizard and Cyberboss, idea by RandomMarine:
+ - rscadd: You can now add a commendation message when pinning a medal on someone.
+ - rscadd: Medal commendations will be displayed when the round ends.
+ - tweak: Refactored the outfit datum to allow accessories as part of an outfit.
+ - bugfix: The Captain spawns with the Medal of Captaincy again.
+ TrustyGun:
+ - rscadd: Some of the clown's toys have been moved into a crate in the theater.
+ If you think you are missing something, check in there.
+ - rscadd: Wooden crates have been added. You can construct them with 6 wooden planks,
+ and deconstruct them the same way as regular crates
+ oranges:
+ - tweak: Security minor and major crime descriptors are now a single line input,
+ making it easier to add them
+ - tweak: Medical record descriptions are single inputs now
+2017-06-11:
+ Expletive:
+ - imageadd: Glass tables are shinier
+ Nanotrasen Consistency Affairs:
+ - bugfix: You no longer see yourself in place of the user when examining active
+ Spirit Sight runes.
+ Shadowlight213:
+ - bugfix: Cloning dismembered heads and brains now respects husking and other clone
+ preventing disabilities.
+ WJohn:
+ - bugfix: It is now easier to wire the powernet into box's telecomms SMES cell.
+ Xhuis:
+ - rscadd: You can now pin papers and photos to airlocks. Anyone examining the airlock
+ from up close can see the details. You can cut them down with wirecutters.
+ lordpidey:
+ - rscadd: Added F.R.A.M.E. cartridge to uplinks. This PDA cartridge contains 5
+ viruses, which when used will unlock the target's PDA into a syndicate uplink,
+ in addition, you will receive the code needed to unlock the uplink again, if
+ you so desire.
+ - rscadd: If you use telecrystals on a F.R.A.M.E. cartridge, the next time it is
+ used, it will also give those crystals to the target uplink.
+ octareenroon91:
+ - bugfix: Mecha tools now respond to MMI control signals as intended.
+ shizcalev:
+ - tweak: '"Species immune to radiation are no longer compatible targets of radiation
+ based DNA injectors."'
+ - bugfix: '"A gun''s firing pin will no longer malfunction when placed into your
+ own mouth. Phew!"'
+ - imageadd: '"Bedsheets capes are now slightly more accurate. Be jealous of the
+ clown and their sexy cape!"'
+2017-06-13:
+ Expletive:
+ - tweak: Paper planes are now the same color as the paper used to make them.
+ - bugfix: Flashdarks can no longer be used to examine head based organs.
+ Fox McCloud:
+ - tweak: Tweaked game options animal speed value to match live server
+ Joan:
+ - spellcheck: Renamed AI liquid dispensers to foam dispensers.
+ - tweak: Foam dispensers now activate immediately when clicked, rather than forcing
+ the user to go through a menu. They also have better visual, message, and examine
+ feedback on if they can be activated.
+ MrStonedOne:
+ - experiment: Added some code to detect the byond bug causing clients to send phantom
+ actions shortly after connection. It will attempt to fix or work around the
+ issue.
+ Nanotrasen Robotics Department:
+ - rscadd: To aid in general-purpose cleaning and maintaining of station faculties,
+ all janitor cyborgs are now outfitted with a screwdriver, crowbar, and floor
+ tile synthesizer.
+ WJohnston:
+ - bugfix: Survival bunker ruin's power now works, mostly.
+ shizcalev:
+ - tweak: '"Radiation immune species are now incompatible with the radiation based
+ genetics DNA scanner/modifier."'
+2017-06-14:
+ Expletive:
+ - rscadd: The medalboxes are now fancy.
+ - imageadd: New sprites for opened medal boxes.
+ Joan:
+ - tweak: Being converted to clockcult will briefly cause your world to turn yellow
+ and you to hear the machines of Reebe, matching the description in the messages.
+ - spellcheck: The messages for being converted and for failing conversion to clockcult
+ have been updated.
+ Tacolizard:
+ - bugfix: Flamethrowers no longer say they're being ignited when you extinguish
+ them
+2017-06-17:
+ Cyberboss:
+ - tweak: NT now provides education on the proper response for experiencing the excrutiating
+ pain of varying degree burns (You scream when burning)
+ Expletive:
+ - rscadd: The Captain now starts with a deluxe fountain pen in their PDA.
+ - rscadd: The quartermaster, curator, research director, lawyer, and bartender start
+ with normal fountain pens in their PDAs.
+ - rscadd: Cargo can order fountain pens via the Calligraphy Crate.
+ - rscadd: Nerds on the station will be pleased to know they now have pocket protectors.
+ - bugfix: Cryo cells work properly on mobs with varying max health values.
+ Joan:
+ - rscdel: Cultists must be human to run for Cult Master status.
+ - tweak: The Hierophant is a little less chaotic and murdery on average.
+ LanCartwright:
+ - rscadd: Penguins, penguin chicks, penguin eggs.
+ - rscadd: Penguin family to Winter Wonderland.
+ MrStonedOne and Lummox JR:
+ - bugfix: Fixed icon scaling and size preferences not loading (Technically size
+ preferences were loading because byond saves that locally, but that's not reliable
+ because ss13 shares a hub)
+ QualityVan:
+ - rscadd: The botany vending machine now has a stock of onion seeds
+ RandomMarine:
+ - tweak: RCDs now always use matter consistent with the material needed when building.
+ - tweak: Floors now cost 3 or 1 matter to build, based on if a lattice exists on
+ the tile.
+ - tweak: Reinforced windows cost 12 matter. Normal windows cost 8 matter. (Both
+ up/down from 10)
+ - tweak: Glass airlocks cost 20 matter.
+ - tweak: RCDs are faster at building grilles and plain glass windows.
+ Steelpoint:
+ - tweak: Slightly reshuffles the Head of Security's, and Research Directors, locker
+ to place fluff items below essential items.
+ Tacolizard:
+ - rscdel: Flashes no longer have a tech requirement
+ That Really Good Soda Flavor:
+ - bugfix: High luminosity eyes will have material science instead of an error research
+ type
+ Thunder12345 and Improvedname:
+ - rscadd: You can now turn severed cat tails and ears into genuine kitty ears
+ - rscadd: Cat tails can now be used to make a cat o' nine tails, similarly to the
+ liz o' nine tails.
+ Xhuis:
+ - spellcheck: The names of the hand drill, jaws of life, and emitter are now lowercase.
+ - spellcheck: The descriptions of the hand drill, jaws of life, and emitter have
+ been changed to be more descriptive and less lengthy.
+ - rscadd: Tablets with IDs in them now show the ID's name when examining someone
+ with that tablet in their ID slot, similar to a PDA would.
+ bandit:
+ - tweak: Default short/medium/long brig times are now, in order, 2, 3, and 5 minutes.
+2017-06-18:
+ Expletive:
+ - tweak: Stacks of space cash now tell you their total value and their value per
+ bill when you examine them.
+ RandomMarine:
+ - tweak: Compressed matter cartridge production costs now reflect their material
+ worth at basic efficiency.
+ - bugfix: Compressed matter cartridges can now be exported.
+ Xhuis:
+ - bugfix: Puny windows will no longer stop the progress of Ratvar.
+2017-06-19:
+ Expletive:
+ - rscadd: Paper frames can be created using wood and paper, and can be used to create
+ decorative structures.
+ - rscadd: Natural paper can now be crafted
+ - rscadd: KorPhaeron can now start a maid cafe, if they so desire.
+ - rscadd: Thanks to the invention of "Bill slots", vending machines can now accept
+ space cash.
+ - tweak: The Clown and Mime can now find their unique crayons stored inside their
+ PDAs
+ LanCartwright:
+ - rscadd: 1D4 into Lavaland Mining base crate.
+ RandomMarine:
+ - tweak: Bonfires now work on lavaland!
+ Tacolizard:
+ - rscadd: Repurposed the action button tooltip code to add tooltips with the examine
+ details of all held and equipped items. Hover your mouse over any item equipped,
+ held or in your inventory to examine it.
+ - rscadd: Examine tooltips can be toggled with the 'toggle-examine-tooltips' verb,
+ which can be typed or accessed from the OOC menu.
+ - rscadd: You can change the delay before a tooltip appears with the 'set-examine-tooltip-delay'
+ verb, also accessible via the OOC menu. The default delay is 500ms.
+2017-06-20:
+ Bawhoppen:
+ - bugfix: Grenade belts and bandoliers will no longer obscure half the screen when
+ they're completely filled.
+ LanCartwright:
+ - rscdel: Removed loot drops from Syndicate Simple mobs.
+ Tacolizard:
+ - rscadd: Some items now have custom force strings in their tooltips.
+ - bugfix: items with no force can still use a custom force string.
+ Xhuis:
+ - bugfix: The station's heaters and freezers have been sternly reprimanded and will
+ now drop the correct circuit boards and cable coils.
+ - rscadd: The straight jacket now takes five seconds to put on.
+ - bugfix: The display cases in luxury shelter capsules will no longer spawn unobtainable,
+ abstract offhand objects.
+ - bugfix: Disablers now have an in-hand sprite.
+ nicbn:
+ - imageadd: Changed cryo sprites to Bay cryopods, which show the person inside of
+ them.
diff --git a/html/changelogs/AutoChangeLog-pr-27921.yml b/html/changelogs/AutoChangeLog-pr-27921.yml
deleted file mode 100644
index 64afe8dd664..00000000000
--- a/html/changelogs/AutoChangeLog-pr-27921.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "p440"
-delete-after: True
-changes:
- - bugfix: "Fixed duping cable coils with magic APC terminals"
- - bugfix: "Fixed invalid icon state for empty APCs"
diff --git a/html/changelogs/AutoChangeLog-pr-27933.yml b/html/changelogs/AutoChangeLog-pr-27933.yml
deleted file mode 100644
index ff9831d7708..00000000000
--- a/html/changelogs/AutoChangeLog-pr-27933.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Expletive"
-delete-after: True
-changes:
- - tweak: "Chem Dispensers now store their power in their batteries."
- - tweak: "Instead of being based on battery and capacitor ratings, recharge delay for portable chem dispensers is now based on their capacitor and matter bin ratings."
diff --git a/html/changelogs/AutoChangeLog-pr-27935.yml b/html/changelogs/AutoChangeLog-pr-27935.yml
deleted file mode 100644
index ca20c41324c..00000000000
--- a/html/changelogs/AutoChangeLog-pr-27935.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Expletive"
-delete-after: True
-changes:
- - tweak: "The Seed Vault's chemical dispenser now has all the chemicals a pod person could want."
diff --git a/html/changelogs/AutoChangeLog-pr-27952.yml b/html/changelogs/AutoChangeLog-pr-27952.yml
deleted file mode 100644
index 91ca2cc9325..00000000000
--- a/html/changelogs/AutoChangeLog-pr-27952.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Penguaro"
-delete-after: True
-changes:
- - bugfix: "[Box] Removes extra/unattached vent from Xeno Lab"
diff --git a/html/changelogs/AutoChangeLog-pr-27959.yml b/html/changelogs/AutoChangeLog-pr-27959.yml
deleted file mode 100644
index ce5a9bc89d3..00000000000
--- a/html/changelogs/AutoChangeLog-pr-27959.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Improvedname"
-delete-after: True
-changes:
- - rscadd: "Janitors now start with a flyswatter"
diff --git a/html/changelogs/AutoChangeLog-pr-28101.yml b/html/changelogs/AutoChangeLog-pr-28101.yml
new file mode 100644
index 00000000000..a2dde6cb237
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-28101.yml
@@ -0,0 +1,8 @@
+author: "Lordpidey"
+delete-after: True
+changes:
+ - bugfix: "True and arch devils are no longer deaf."
+ - bugfix: "Fixed some edge cases with devils getting two sets of spells."
+ - bugfix: "True/arch devils can now instabreak cuffs."
+ - rscadd: "The codex gigas now indicates if a devil is ascendable or not."
+ - tweak: "Hellfire has been buffed, it now explodes multiple times."
diff --git a/html/changelogs/AutoChangeLog-pr-28334.yml b/html/changelogs/AutoChangeLog-pr-28334.yml
new file mode 100644
index 00000000000..b816dbc2b5c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-28334.yml
@@ -0,0 +1,5 @@
+author: "Nanotrasen Robotics Department"
+delete-after: True
+changes:
+ - tweak: "Traitor AIs' malfunction modules have received a firmware update and are more responsive, with HUD buttons and more sensible menus."
+ - tweak: "Overload and Override Machines now function differently; instead of right-clicking a machine to choose a context menu option, you activate the ability, which lets you left-click on a machine to overload or override it. This also changes your cursor."
diff --git a/html/changelogs/AutoChangeLog-pr-28533.yml b/html/changelogs/AutoChangeLog-pr-28533.yml
new file mode 100644
index 00000000000..73dc66d70b5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-28533.yml
@@ -0,0 +1,4 @@
+author: "bandit"
+delete-after: True
+changes:
+ - rscadd: "Nanotrasen researchers have made the breakthrough discovery that Lavaland's plants are, in fact, plants, and can be harvested with seed extractors."
diff --git a/html/changelogs/AutoChangeLog-pr-28546.yml b/html/changelogs/AutoChangeLog-pr-28546.yml
new file mode 100644
index 00000000000..efb539e88fe
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-28546.yml
@@ -0,0 +1,4 @@
+author: "Expletive"
+delete-after: True
+changes:
+ - tweak: "Flame thrower plasma tanks can be removed with alt-click."
diff --git a/html/changelogs/AutoChangeLog-pr-28588.yml b/html/changelogs/AutoChangeLog-pr-28588.yml
new file mode 100644
index 00000000000..42cdd01f42e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-28588.yml
@@ -0,0 +1,5 @@
+author: "Ergovisavi"
+delete-after: True
+changes:
+ - tweak: "Nanofrost setting and metal foam synthesizer on the Atmos watertank backpack changed to \"Resin\", which is a solid, but transparent structure similar to metal foam that scrubs the air of toxins, regulates temperature, etc"
+ - tweak: "Atmos holobarrier device swapped out for an Atmos holo-firelock device, which creates holographic firelocks that prevent atmospheric changes from going over them"
diff --git a/html/changelogs/AutoChangeLog-pr-28611.yml b/html/changelogs/AutoChangeLog-pr-28611.yml
new file mode 100644
index 00000000000..e243779e238
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-28611.yml
@@ -0,0 +1,4 @@
+author: "Bawhoppen"
+delete-after: True
+changes:
+ - rscadd: "Dressers are now constructable, and unanchorable with a wrench."
diff --git a/html/changelogs/AutoChangeLog-pr-28613.yml b/html/changelogs/AutoChangeLog-pr-28613.yml
new file mode 100644
index 00000000000..61f0e5790bf
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-28613.yml
@@ -0,0 +1,4 @@
+author: "ohnopigeons"
+delete-after: True
+changes:
+ - bugfix: "After a janitorial audit Nanotrasen has decided to further cut costs by removing the janicart's secret space propulsion functionality"
diff --git a/html/changelogs/AutoChangeLog-pr-28627.yml b/html/changelogs/AutoChangeLog-pr-28627.yml
new file mode 100644
index 00000000000..77ac512926b
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-28627.yml
@@ -0,0 +1,6 @@
+author: "Xhuis"
+delete-after: True
+changes:
+ - rscadd: "Alt-clicking the Show/Hide Actions button will now reset the positions of all action buttons."
+ - rscadd: "Hints to the two shortcuts for action buttons are now included in the Show/Hide Actions button's tooltip."
+ - rscadd: "(As a reminder, that's shift-click to reset the clicked button, and alt-clicking the Show/Hide Actions button to reset it and all the others!)"
diff --git a/html/changelogs/AutoChangeLog-pr-28631.yml b/html/changelogs/AutoChangeLog-pr-28631.yml
new file mode 100644
index 00000000000..e06adf226d1
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-28631.yml
@@ -0,0 +1,4 @@
+author: "ClosingBracket"
+delete-after: True
+changes:
+ - spellcheck: "Fixes small typographical errors on flight suits and implanters."
diff --git a/html/changelogs/AutoChangeLog-pr-28642.yml b/html/changelogs/AutoChangeLog-pr-28642.yml
new file mode 100644
index 00000000000..06aee1641f0
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-28642.yml
@@ -0,0 +1,5 @@
+author: "Xhuis"
+delete-after: True
+changes:
+ - spellcheck: "The names of several objects, such as the holopad and biogenerator, have been lowercased."
+ - spellcheck: "Added some descriptions to a few objects that lacked them."
diff --git a/html/changelogs/AutoChangeLog-pr-28645.yml b/html/changelogs/AutoChangeLog-pr-28645.yml
new file mode 100644
index 00000000000..090d32f8bc3
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-28645.yml
@@ -0,0 +1,4 @@
+author: "Xhuis"
+delete-after: True
+changes:
+ - rscadd: "Tablets now have a built-in flashlight! It can even change colors, as long as they're light enough in hue."
diff --git a/icons/BadAss.dmi b/icons/badass.dmi
similarity index 100%
rename from icons/BadAss.dmi
rename to icons/badass.dmi
diff --git a/icons/effects/119x268.dmi b/icons/effects/119x268.dmi
new file mode 100644
index 00000000000..6685901db46
Binary files /dev/null and b/icons/effects/119x268.dmi differ
diff --git a/icons/effects/166x195.dmi b/icons/effects/166x195.dmi
new file mode 100644
index 00000000000..ef49baf9f54
Binary files /dev/null and b/icons/effects/166x195.dmi differ
diff --git a/icons/effects/187x381.dmi b/icons/effects/187x381.dmi
deleted file mode 100644
index dd43297db53..00000000000
Binary files a/icons/effects/187x381.dmi and /dev/null differ
diff --git a/icons/effects/211x247.dmi b/icons/effects/211x247.dmi
deleted file mode 100644
index 35b25ffe146..00000000000
Binary files a/icons/effects/211x247.dmi and /dev/null differ
diff --git a/icons/effects/237x321.dmi b/icons/effects/237x321.dmi
new file mode 100644
index 00000000000..089c08d9a20
Binary files /dev/null and b/icons/effects/237x321.dmi differ
diff --git a/icons/effects/254x361.dmi b/icons/effects/254x361.dmi
deleted file mode 100644
index 4fd6543c32d..00000000000
Binary files a/icons/effects/254x361.dmi and /dev/null differ
diff --git a/icons/effects/274x385.dmi b/icons/effects/274x385.dmi
new file mode 100644
index 00000000000..9a8ba55f915
Binary files /dev/null and b/icons/effects/274x385.dmi differ
diff --git a/icons/effects/340x428.dmi b/icons/effects/340x428.dmi
deleted file mode 100644
index eb735c0ba92..00000000000
Binary files a/icons/effects/340x428.dmi and /dev/null differ
diff --git a/icons/effects/64x64.dmi b/icons/effects/64x64.dmi
index 361cfff40c0..d80b077988a 100644
Binary files a/icons/effects/64x64.dmi and b/icons/effects/64x64.dmi differ
diff --git a/icons/effects/cult_effects.dmi b/icons/effects/cult_effects.dmi
index 58a2d3c9c97..925950b9a39 100644
Binary files a/icons/effects/cult_effects.dmi and b/icons/effects/cult_effects.dmi differ
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index eab44acdd79..885ad621311 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/effects/overload_machine_target.dmi b/icons/effects/overload_machine_target.dmi
new file mode 100644
index 00000000000..8bc67cdab6c
Binary files /dev/null and b/icons/effects/overload_machine_target.dmi differ
diff --git a/icons/effects/override_machine_target.dmi b/icons/effects/override_machine_target.dmi
new file mode 100644
index 00000000000..77dbb4ba32b
Binary files /dev/null and b/icons/effects/override_machine_target.dmi differ
diff --git a/icons/effects/parallax.dmi b/icons/effects/parallax.dmi
old mode 100644
new mode 100755
index a770bf8667d..b7a003d1bb0
Binary files a/icons/effects/parallax.dmi and b/icons/effects/parallax.dmi differ
diff --git a/icons/effects/station_explosion.dmi b/icons/effects/station_explosion.dmi
index 385818b0117..d8ced1f544b 100644
Binary files a/icons/effects/station_explosion.dmi and b/icons/effects/station_explosion.dmi differ
diff --git a/icons/effects/throw_target.dmi b/icons/effects/throw_target.dmi
new file mode 100644
index 00000000000..660eafbf2b1
Binary files /dev/null and b/icons/effects/throw_target.dmi differ
diff --git a/icons/emoji.dmi b/icons/emoji.dmi
old mode 100755
new mode 100644
diff --git a/icons/mob/accessories.dmi b/icons/mob/accessories.dmi
new file mode 100644
index 00000000000..716a21b4376
Binary files /dev/null and b/icons/mob/accessories.dmi differ
diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi
index c8fc98d4f50..6b13ec2e2e9 100644
Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ
diff --git a/icons/mob/actions_AI.dmi b/icons/mob/actions_AI.dmi
new file mode 100644
index 00000000000..3a789984e64
Binary files /dev/null and b/icons/mob/actions_AI.dmi differ
diff --git a/icons/mob/AI.dmi b/icons/mob/ai.dmi
similarity index 100%
rename from icons/mob/AI.dmi
rename to icons/mob/ai.dmi
diff --git a/icons/mob/alienqueen.dmi b/icons/mob/alienqueen.dmi
index 4b84210c5a7..115bd17cb0b 100644
Binary files a/icons/mob/alienqueen.dmi and b/icons/mob/alienqueen.dmi differ
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index 2bdb8196014..55d36996b7c 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/drone.dmi b/icons/mob/drone.dmi
index 6115935c3d9..2e9899fba0f 100644
Binary files a/icons/mob/drone.dmi and b/icons/mob/drone.dmi differ
diff --git a/icons/mob/Easter.dmi b/icons/mob/easter.dmi
similarity index 100%
rename from icons/mob/Easter.dmi
rename to icons/mob/easter.dmi
diff --git a/icons/mob/EvilPope.dmi b/icons/mob/evilpope.dmi
similarity index 100%
rename from icons/mob/EvilPope.dmi
rename to icons/mob/evilpope.dmi
diff --git a/icons/mob/hair_extensions.dmi b/icons/mob/hair_extensions.dmi
index cf74d73796c..bd2adda94bd 100644
Binary files a/icons/mob/hair_extensions.dmi and b/icons/mob/hair_extensions.dmi differ
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index 26101a5dbc2..64d7c72e600 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi
index 47c2d91707d..c8ab9f0e0a7 100644
Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ
diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi
index 68f8caac6bd..2fb1c07f773 100644
Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ
diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi
index 262c802ca1c..aa0bd962d1f 100644
Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ
diff --git a/icons/mob/neck.dmi b/icons/mob/neck.dmi
index de13308f370..7c9173f05b9 100644
Binary files a/icons/mob/neck.dmi and b/icons/mob/neck.dmi differ
diff --git a/icons/mob/OnFire.dmi b/icons/mob/onfire.dmi
similarity index 100%
rename from icons/mob/OnFire.dmi
rename to icons/mob/onfire.dmi
diff --git a/icons/mob/penguins.dmi b/icons/mob/penguins.dmi
new file mode 100644
index 00000000000..fae32b6bcca
Binary files /dev/null and b/icons/mob/penguins.dmi differ
diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi
deleted file mode 100644
index 19b36bfc948..00000000000
Binary files a/icons/mob/ties.dmi and /dev/null differ
diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi
index a3dd1e21bd2..6e620cd92d8 100644
Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ
diff --git a/icons/obj/biogenerator.dmi b/icons/obj/biogenerator.dmi
index 02cf868a31f..7989d6f355f 100644
Binary files a/icons/obj/biogenerator.dmi and b/icons/obj/biogenerator.dmi differ
diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi
index e91e4c0d83a..1169888b344 100644
Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ
diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi
index a7c80ba5361..dc6f1e61439 100644
Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ
diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi
new file mode 100644
index 00000000000..5586afe6b8d
Binary files /dev/null and b/icons/obj/clothing/accessories.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index f170cf7f967..97e6e3a7532 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi
index 9606e11d63e..0f3668ce102 100644
Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ
diff --git a/icons/obj/clothing/ties.dmi b/icons/obj/clothing/ties.dmi
deleted file mode 100644
index 83c1ffedf20..00000000000
Binary files a/icons/obj/clothing/ties.dmi and /dev/null differ
diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi
index 327d2749f76..deb0908fed5 100644
Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ
diff --git a/icons/obj/crates.dmi b/icons/obj/crates.dmi
index 35414eeb3d3..69bf29e33c8 100644
Binary files a/icons/obj/crates.dmi and b/icons/obj/crates.dmi differ
diff --git a/icons/obj/cryo_mobs.dmi b/icons/obj/cryo_mobs.dmi
new file mode 100644
index 00000000000..0707110de46
Binary files /dev/null and b/icons/obj/cryo_mobs.dmi differ
diff --git a/icons/obj/Cryogenic2.dmi b/icons/obj/cryogenic2.dmi
similarity index 100%
rename from icons/obj/Cryogenic2.dmi
rename to icons/obj/cryogenic2.dmi
diff --git a/icons/obj/cryogenics.dmi b/icons/obj/cryogenics.dmi
index 1159725b91a..114fd7a38d7 100644
Binary files a/icons/obj/cryogenics.dmi and b/icons/obj/cryogenics.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index eb402008662..808de694466 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/doors/airlocks/external/overlays.dmi b/icons/obj/doors/airlocks/external/overlays.dmi
index 1e155b0c335..5bfa24a6bef 100644
Binary files a/icons/obj/doors/airlocks/external/overlays.dmi and b/icons/obj/doors/airlocks/external/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/hatch/overlays.dmi b/icons/obj/doors/airlocks/hatch/overlays.dmi
index cbed19b1ab5..45f18136da5 100644
Binary files a/icons/obj/doors/airlocks/hatch/overlays.dmi and b/icons/obj/doors/airlocks/hatch/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/station/overlays.dmi b/icons/obj/doors/airlocks/station/overlays.dmi
index 3db448e7154..a489f40be97 100644
Binary files a/icons/obj/doors/airlocks/station/overlays.dmi and b/icons/obj/doors/airlocks/station/overlays.dmi differ
diff --git a/icons/obj/doors/Door2x1glassfull.dmi b/icons/obj/doors/door2x1glassfull.dmi
similarity index 100%
rename from icons/obj/doors/Door2x1glassfull.dmi
rename to icons/obj/doors/door2x1glassfull.dmi
diff --git a/icons/obj/doors/Doorf.dmi b/icons/obj/doors/doorf.dmi
similarity index 100%
rename from icons/obj/doors/Doorf.dmi
rename to icons/obj/doors/doorf.dmi
diff --git a/icons/obj/doors/Doorfire.dmi b/icons/obj/doors/doorfire.dmi
similarity index 100%
rename from icons/obj/doors/Doorfire.dmi
rename to icons/obj/doors/doorfire.dmi
diff --git a/icons/obj/doors/Doorfireglass.dmi b/icons/obj/doors/doorfireglass.dmi
similarity index 100%
rename from icons/obj/doors/Doorfireglass.dmi
rename to icons/obj/doors/doorfireglass.dmi
diff --git a/icons/obj/doors/DoorHazard.dmi b/icons/obj/doors/doorhazard.dmi
similarity index 100%
rename from icons/obj/doors/DoorHazard.dmi
rename to icons/obj/doors/doorhazard.dmi
diff --git a/icons/obj/doors/mineral_doors.dmi b/icons/obj/doors/mineral_doors.dmi
index 92158d86451..7682252a6d2 100644
Binary files a/icons/obj/doors/mineral_doors.dmi and b/icons/obj/doors/mineral_doors.dmi differ
diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi
index e7c0e8d2638..863f447e932 100644
Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ
diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi
index a6849c2d955..2860c160085 100644
Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ
diff --git a/icons/obj/hydroponics/equipment.dmi b/icons/obj/hydroponics/equipment.dmi
index b0de3ddda27..ad5f8bc8635 100644
Binary files a/icons/obj/hydroponics/equipment.dmi and b/icons/obj/hydroponics/equipment.dmi differ
diff --git a/icons/obj/hydroponics/growing_fruits.dmi b/icons/obj/hydroponics/growing_fruits.dmi
index ac8adc5a069..7207733b14f 100644
Binary files a/icons/obj/hydroponics/growing_fruits.dmi and b/icons/obj/hydroponics/growing_fruits.dmi differ
diff --git a/icons/obj/hydroponics/growing_mushrooms.dmi b/icons/obj/hydroponics/growing_mushrooms.dmi
index 7a0eedbdae7..3a10c0dab84 100644
Binary files a/icons/obj/hydroponics/growing_mushrooms.dmi and b/icons/obj/hydroponics/growing_mushrooms.dmi differ
diff --git a/icons/obj/hydroponics/growing_vegetables.dmi b/icons/obj/hydroponics/growing_vegetables.dmi
index 070d3531a21..9fc1520175e 100644
Binary files a/icons/obj/hydroponics/growing_vegetables.dmi and b/icons/obj/hydroponics/growing_vegetables.dmi differ
diff --git a/icons/obj/hydroponics/harvest.dmi b/icons/obj/hydroponics/harvest.dmi
index 55a06a36fab..0aff0a2cbdd 100644
Binary files a/icons/obj/hydroponics/harvest.dmi and b/icons/obj/hydroponics/harvest.dmi differ
diff --git a/icons/obj/hydroponics/seeds.dmi b/icons/obj/hydroponics/seeds.dmi
index 34c2c270a83..8ce90d87d47 100644
Binary files a/icons/obj/hydroponics/seeds.dmi and b/icons/obj/hydroponics/seeds.dmi differ
diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi
index bffa20e6aab..f5fa993651c 100644
Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ
diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi
index 811c95536af..a8f7708c46f 100644
Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ
diff --git a/icons/obj/lavaland/ash_flora.dmi b/icons/obj/lavaland/ash_flora.dmi
index b9ebfbfb662..9a9382ce1ea 100644
Binary files a/icons/obj/lavaland/ash_flora.dmi and b/icons/obj/lavaland/ash_flora.dmi differ
diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi
index 5840476924c..2048725e565 100644
Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ
diff --git a/icons/obj/machines/mining_machines.dmi b/icons/obj/machines/mining_machines.dmi
index 6e77127dab0..28d608125d7 100644
Binary files a/icons/obj/machines/mining_machines.dmi and b/icons/obj/machines/mining_machines.dmi differ
diff --git a/icons/obj/machines/research.dmi b/icons/obj/machines/research.dmi
index 84f8c96a5b1..cd74eed322e 100644
Binary files a/icons/obj/machines/research.dmi and b/icons/obj/machines/research.dmi differ
diff --git a/icons/obj/machines/washing_machine.dmi b/icons/obj/machines/washing_machine.dmi
index b41571477e2..9af19b83e8b 100644
Binary files a/icons/obj/machines/washing_machine.dmi and b/icons/obj/machines/washing_machine.dmi differ
diff --git a/icons/obj/mining.dmi b/icons/obj/mining.dmi
index a5fe40431ed..3de64f610a1 100644
Binary files a/icons/obj/mining.dmi and b/icons/obj/mining.dmi differ
diff --git a/icons/obj/modular_laptop.dmi b/icons/obj/modular_laptop.dmi
index 2daeee0c7a4..7026f52ee0d 100644
Binary files a/icons/obj/modular_laptop.dmi and b/icons/obj/modular_laptop.dmi differ
diff --git a/icons/obj/nuke_tools.dmi b/icons/obj/nuke_tools.dmi
index 11f90a3825a..2c10b5424ff 100644
Binary files a/icons/obj/nuke_tools.dmi and b/icons/obj/nuke_tools.dmi differ
diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi
index ca0e225d7ee..3757957d9a3 100644
Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ
diff --git a/icons/obj/power.dmi b/icons/obj/power.dmi
index 4fefb18a9b4..890ca25399f 100644
Binary files a/icons/obj/power.dmi and b/icons/obj/power.dmi differ
diff --git a/icons/obj/robotics.dmi b/icons/obj/robotics.dmi
index d59a4c8f8d2..8d0627aa958 100644
Binary files a/icons/obj/robotics.dmi and b/icons/obj/robotics.dmi differ
diff --git a/icons/obj/smooth_structures/glass_table.dmi b/icons/obj/smooth_structures/glass_table.dmi
index 3fa90ea0642..112499f3801 100644
Binary files a/icons/obj/smooth_structures/glass_table.dmi and b/icons/obj/smooth_structures/glass_table.dmi differ
diff --git a/icons/obj/smooth_structures/paperframes.dmi b/icons/obj/smooth_structures/paperframes.dmi
new file mode 100644
index 00000000000..5ac2c27dd51
Binary files /dev/null and b/icons/obj/smooth_structures/paperframes.dmi differ
diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi
index 8af4294eb68..28dd158ff78 100644
Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ
diff --git a/icons/obj/stock_parts.dmi b/icons/obj/stock_parts.dmi
index 6589aabb869..50f0ad3ef74 100644
Binary files a/icons/obj/stock_parts.dmi and b/icons/obj/stock_parts.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index 19e2cc0e483..3e156064b3f 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/icons/obj/tiles.dmi b/icons/obj/tiles.dmi
index 1c0ac03abec..8b439d2bad3 100644
Binary files a/icons/obj/tiles.dmi and b/icons/obj/tiles.dmi differ
diff --git a/icons/obj/virology.dmi b/icons/obj/virology.dmi
index 01b6e591e34..882e54402cf 100644
Binary files a/icons/obj/virology.dmi and b/icons/obj/virology.dmi differ
diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi
index af46d20f325..cfd5156520f 100644
Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ
diff --git a/icons/turf/floors/Chasms.dmi b/icons/turf/floors/chasms.dmi
similarity index 100%
rename from icons/turf/floors/Chasms.dmi
rename to icons/turf/floors/chasms.dmi
diff --git a/interface/menu.dm b/interface/menu.dm
index 4bebd5b2023..eca97d669d2 100644
--- a/interface/menu.dm
+++ b/interface/menu.dm
@@ -1,5 +1,5 @@
/*
-/datum/menu/Example/verb/Example()
+/datum/verbs/menu/Example/verb/Example()
set name = "" //if this starts with @ the verb is not created and name becomes the command to invoke.
set desc = "" //desc is the text given to this entry in the menu
//You can not use src in these verbs. It will be the menu at compile time, but the client at runtime.
@@ -7,126 +7,40 @@
GLOBAL_LIST_EMPTY(menulist)
-/world/proc/load_menu()
- for (var/typepath in subtypesof(/datum/menu))
- new typepath()
-
-/datum/menu
- var/name
- var/list/children
- var/datum/menu/myparent
- var/list/verblist
+/datum/verbs/menu
var/checkbox = CHECKBOX_NONE //checkbox type.
var/default //default checked type.
//Set to true to append our children to our parent,
//Rather then add us as a node (used for having more then one checkgroups in the same menu)
- var/abstract = FALSE
-/datum/menu/New()
- var/ourentry = GLOB.menulist[type]
- children = list()
- verblist = list()
- if (ourentry)
- if (islist(ourentry)) //some of our childern already loaded
- Add_children(ourentry)
- else
- stack_trace("Menu item double load: [type]")
- qdel(src)
- return
+/datum/verbs/menu/GetList()
+ return GLOB.menulist
- GLOB.menulist[type] = src
+/datum/verbs/menu/HandleVerb(list/entry, verbpath, client/C)
+ var/datum/verbs/menu/verb_true_parent = GLOB.menulist[verblist[verbpath]]
+ var/true_checkbox = verb_true_parent.checkbox
+ if (true_checkbox != CHECKBOX_NONE)
+ var/checkedverb = verb_true_parent.Get_checked(C)
+ if (true_checkbox == CHECKBOX_GROUP)
+ if (verbpath == checkedverb)
+ entry["is-checked"] = TRUE
+ else
+ entry["is-checked"] = FALSE
+ else if (true_checkbox == CHECKBOX_TOGGLE)
+ entry["is-checked"] = checkedverb
- Load_verbs(type, typesof("[type]/verb"))
+ entry["command"] = ".updatemenuchecked \"[verb_true_parent.type]\" \"[verbpath]\"\n[entry["command"]]"
+ entry["can-check"] = TRUE
+ entry["group"] = "[verb_true_parent.type]"
+ return list2params(entry)
- var/datum/menu/parent = GLOB.menulist[parent_type]
- if (!parent)
- GLOB.menulist[parent_type] = list(src)
- else if (islist(parent))
- parent += src
- else
- parent.Add_children(list(src))
-
-/datum/menu/proc/Set_parent(datum/menu/parent)
- myparent = parent
- if (abstract)
- myparent.Add_children(children)
- var/list/verblistoftypes = list()
- for(var/thing in verblist)
- LAZYADD(verblistoftypes[verblist[thing]], thing)
-
- for(var/verbparenttype in verblistoftypes)
- myparent.Load_verbs(verbparenttype, verblistoftypes[verbparenttype])
-
-/datum/menu/proc/Add_children(list/kids)
- if (abstract && myparent)
- myparent.Add_children(kids)
- return
-
- for(var/thing in kids)
- var/datum/menu/menuitem = thing
- menuitem.Set_parent(src)
- if (!menuitem.abstract)
- children += menuitem
-
-/datum/menu/proc/Load_verbs(verb_parent_type, list/verbs)
- if (abstract && myparent)
- myparent.Load_verbs(verb_parent_type, verbs)
- return
-
- for (var/verbpath in verbs)
- verblist[verbpath] = verb_parent_type
-
-/datum/menu/proc/Generate_list(client/C)
- . = list()
- if (length(children))
- for (var/thing in children)
- var/datum/menu/child = thing
- var/list/childlist = child.Generate_list(C)
- if (childlist)
- var/childname = "[child]"
- if (childname == "[child.type]")
- var/list/tree = splittext(childname, "/")
- childname = tree[tree.len]
- .[child.type] = "parent=[url_encode(type)];name=[url_encode(childname)]"
- . += childlist
-
-
-
- for (var/thing in verblist)
- var/atom/verb/verbpath = thing
- if (!verbpath)
- stack_trace("Bad VERB in [type] verblist: [english_list(verblist)]")
- var/list/entry = list()
- entry["parent"] = "[type]"
- entry["name"] = verbpath.desc
- if (copytext(verbpath.name,1,2) == "@")
- entry["command"] = copytext(verbpath.name,2)
- else
- entry["command"] = replacetext(verbpath.name, " ", "-")
- var/datum/menu/verb_true_parent = GLOB.menulist[verblist[verbpath]]
- var/true_checkbox = verb_true_parent.checkbox
- if (true_checkbox != CHECKBOX_NONE)
- var/checkedverb = verb_true_parent.Get_checked(C)
- if (true_checkbox == CHECKBOX_GROUP)
- if (verbpath == checkedverb)
- entry["is-checked"] = TRUE
- else
- entry["is-checked"] = FALSE
- else if (true_checkbox == CHECKBOX_TOGGLE)
- entry["is-checked"] = checkedverb
-
- entry["command"] = ".updatemenuchecked \"[verb_true_parent.type]\" \"[verbpath]\"\n[entry["command"]]"
- entry["can-check"] = TRUE
- entry["group"] = "[verb_true_parent.type]"
- .[verbpath] = list2params(entry)
-
-/datum/menu/proc/Get_checked(client/C)
+/datum/verbs/menu/proc/Get_checked(client/C)
return C.prefs.menuoptions[type] || default || FALSE
-/datum/menu/proc/Load_checked(client/C) //Loads the checked menu item into a new client. Used by icon menus to invoke the checked item.
+/datum/verbs/menu/proc/Load_checked(client/C) //Loads the checked menu item into a new client. Used by icon menus to invoke the checked item.
return
-/datum/menu/proc/Set_checked(client/C, verbpath)
+/datum/verbs/menu/proc/Set_checked(client/C, verbpath)
if (checkbox == CHECKBOX_GROUP)
C.prefs.menuoptions[type] = verbpath
C.prefs.save_preferences()
@@ -142,7 +56,7 @@ GLOBAL_LIST_EMPTY(menulist)
verbpath = text2path(verbpath)
if (!menutype || !verbpath)
return
- var/datum/menu/M = GLOB.menulist[menutype]
+ var/datum/verbs/menu/M = GLOB.menulist[menutype]
if (!M)
return
if (!(verbpath in typesof("[menutype]/verb")))
@@ -150,54 +64,55 @@ GLOBAL_LIST_EMPTY(menulist)
M.Set_checked(src, verbpath)
-/datum/menu/Icon/Load_checked(client/C) //So we can be lazy, we invoke the "checked" menu item on menu load.
+/datum/verbs/menu/Icon/Load_checked(client/C) //So we can be lazy, we invoke the "checked" menu item on menu load.
var/atom/verb/verbpath = Get_checked(C)
if (!verbpath || !(verbpath in typesof("[type]/verb")))
return
+
if (copytext(verbpath.name,1,2) == "@")
- winset(C, null, "command = [copytext(verbpath.name,2)]")
+ winset(C, null, list2params(list("command" = copytext(verbpath.name,2))))
else
- winset(C, null, "command = [replacetext(verbpath.name, " ", "-")]")
+ winset(C, null, list2params(list("command" = replacetext(verbpath.name, " ", "-"))))
-/datum/menu/Icon/Size
+/datum/verbs/menu/Icon/Size
checkbox = CHECKBOX_GROUP
- default = /datum/menu/Icon/Size/verb/iconstretchtofit
+ default = /datum/verbs/menu/Icon/Size/verb/iconstretchtofit
-/datum/menu/Icon/Size/verb/iconstretchtofit()
+/datum/verbs/menu/Icon/Size/verb/iconstretchtofit()
set name = "@.winset \"mapwindow.map.icon-size=0\""
set desc = "&Auto (stretch-to-fit)"
-/datum/menu/Icon/Size/verb/icon96()
+/datum/verbs/menu/Icon/Size/verb/icon96()
set name = "@.winset \"mapwindow.map.icon-size=96\""
set desc = "&96x96 (3x)"
-/datum/menu/Icon/Size/verb/icon64()
+/datum/verbs/menu/Icon/Size/verb/icon64()
set name = "@.winset \"mapwindow.map.icon-size=64\""
set desc = "&64x64 (2x)"
-/datum/menu/Icon/Size/verb/icon48()
+/datum/verbs/menu/Icon/Size/verb/icon48()
set name = "@.winset \"mapwindow.map.icon-size=48\""
set desc = "&48x48 (1.5x)"
-/datum/menu/Icon/Size/verb/icon32()
+/datum/verbs/menu/Icon/Size/verb/icon32()
set name = "@.winset \"mapwindow.map.icon-size=32\""
set desc = "&32x32 (1x)"
-/datum/menu/Icon/Scaling
+/datum/verbs/menu/Icon/Scaling
checkbox = CHECKBOX_GROUP
name = "Scaling Mode"
- default = /datum/menu/Icon/Scaling/verb/NN
+ default = /datum/verbs/menu/Icon/Scaling/verb/NN
-/datum/menu/Icon/Scaling/verb/NN()
+/datum/verbs/menu/Icon/Scaling/verb/NN()
set name = "@.winset \"mapwindow.map.zoom-mode=distort\""
set desc = "Nearest Neighbor"
-/datum/menu/Icon/Scaling/verb/PS()
+/datum/verbs/menu/Icon/Scaling/verb/PS()
set name = "@.winset \"mapwindow.map.zoom-mode=normal\""
set desc = "Point Sampling"
-/datum/menu/Icon/Scaling/verb/BL()
+/datum/verbs/menu/Icon/Scaling/verb/BL()
set name = "@.winset \"mapwindow.map.zoom-mode=blur\""
set desc = "Bilinear"
diff --git a/interface/skin.dmf b/interface/skin.dmf
index a596cd77076..20cc91bb0c8 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -1582,8 +1582,8 @@ window "outputwindow"
macro = ""
menu = ""
on-close = ""
- elem "output"
- type = OUTPUT
+ elem "browseroutput"
+ type = BROWSER
pos = 0,0
size = 640x480
anchor1 = 0,0
@@ -1594,20 +1594,20 @@ window "outputwindow"
text-color = #000000
background-color = #ffffff
is-visible = true
- is-disabled = false
+ is-disabled = true
is-transparent = false
- is-default = true
+ is-default = false
border = none
drop-zone = false
right-click = false
- saved-params = "max-lines"
+ saved-params = ""
on-size = ""
- link-color = #0000ff
- visited-color = #ff00ff
- style = ""
- enable-http-images = false
- max-lines = 1000
- image = ""
+ show-history = false
+ show-url = false
+ auto-format = false
+ use-title = false
+ on_show = ""
+ on_hide = ""
window "statwindow"
elem "statwindow"
@@ -1682,4 +1682,3 @@ window "statwindow"
on-tab = ""
prefix-color = none
suffix-color = none
-
diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm
index 10c39a2eb82..6f38560b92d 100644
--- a/interface/stylesheet.dm
+++ b/interface/stylesheet.dm
@@ -1,3 +1,11 @@
+/// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+/// !!!!!!!!!!HEY LISTEN!!!!!!!!!!!!!!!!!!!!!!!!
+/// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+// If you modify this file you ALSO need to modify code/modules/goonchat/browserAssets/browserOutput.css
+// BUT you have to use PX font sizes with are on a x8 scale of these font sizes
+// Sample font-size: DM: 8 CSS: 64px
+
/client/script = {"",a.insertBefore(n.lastChild,a.firstChild)}function r(){var t=x.elements;return"string"==typeof t?t.split(" "):t}function i(t,e){var n=x.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof t&&(t=t.join(" ")),x.elements=n+" "+t,c(e)}function o(t){var e=y[t[g]];return e||(e={},b++,t[g]=b,y[b]=e),e}function s(t,e,a){if(e||(e=n),f)return e.createElement(t);a||(a=o(e));var r;return r=a.cache[t]?a.cache[t].cloneNode():v.test(t)?(a.cache[t]=a.createElem(t)).cloneNode():a.createElem(t),!r.canHaveChildren||m.test(t)||r.tagUrn?r:a.frag.appendChild(r)}function u(t,e){if(t||(t=n),f)return t.createDocumentFragment();e=e||o(t);for(var a=e.frag.cloneNode(),i=0,s=r(),u=s.length;u>i;i++)a.createElement(s[i]);return a}function p(t,e){e.cache||(e.cache={},e.createElem=t.createElement,e.createFrag=t.createDocumentFragment,e.frag=e.createFrag()),t.createElement=function(n){return x.shivMethods?s(n,t,e):e.createElem(n)},t.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-:]+/g,function(t){return e.createElem(t),e.frag.createElement(t),'c("'+t+'")'})+");return n}")(x,e.frag)}function c(t){t||(t=n);var e=o(t);return!x.shivCSS||l||e.hasCSS||(e.hasCSS=!!a(t,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),f||p(t,e),t}var l,f,d="3.7.3-pre",h=t.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,v=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,g="_html5shiv",b=0,y={};!function(){try{var t=n.createElement("a");t.innerHTML="",l="hidden"in t,f=1==t.childNodes.length||function(){n.createElement("a");var t=n.createDocumentFragment();return void 0===t.cloneNode||void 0===t.createDocumentFragment||void 0===t.createElement}()}catch(e){l=!0,f=!0}}();var x={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:d,shivCSS:h.shivCSS!==!1,supportsUnknownElements:f,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:c,createElement:s,createDocumentFragment:u,addElements:i};t.html5=x,c(n),"object"==typeof e&&e.exports&&(e.exports=x)}("undefined"!=typeof window?window:this,document)},{}],194:[function(t,e,n){(function(t){(function(t){!function(t){function e(t,e,n,a){for(var i,o=n.slice(),s=r(e,t),u=0,p=o.length;p>u&&(handler=o[u],"object"==typeof handler?"function"==typeof handler.handleEvent&&handler.handleEvent(s):handler.call(t,s),!s.stoppedImmediatePropagation);u++);return i=!s.stoppedPropagation,a&&i&&t.parentNode?t.parentNode.dispatchEvent(s):!s.defaultPrevented}function n(t,e){return{configurable:!0,get:t,set:e}}function a(t,e,a){var r=b(e||t,a);v(t,"textContent",n(function(){return r.get.call(this)},function(t){r.set.call(this,t)}))}function r(t,e){return t.currentTarget=e,t.eventPhase=t.target===t.currentTarget?2:3,t}function i(t,e){for(var n=t.length;n--&&t[n]!==e;);return n}function o(){if("BR"===this.tagName)return"\n";for(var t=this.firstChild,e=[];t;)8!==t.nodeType&&7!==t.nodeType&&e.push(t.textContent),t=t.nextSibling;return e.join("")}function s(t){var e=document.createEvent("Event");e.initEvent("input",!0,!0),(t.srcElement||t.fromElement||document).dispatchEvent(e)}function u(t){!f&&k.test(document.readyState)&&(f=!f,document.detachEvent(d,u),t=document.createEvent("Event"),t.initEvent(h,!0,!0),document.dispatchEvent(t))}function p(t){for(var e;e=this.lastChild;)this.removeChild(e);null!=t&&this.appendChild(document.createTextNode(t))}function c(e,n){return n||(n=t.event),n.target||(n.target=n.srcElement||n.fromElement||document),n.timeStamp||(n.timeStamp=(new Date).getTime()),n}if(!document.createEvent){var l=!0,f=!1,d="onreadystatechange",h="DOMContentLoaded",m="__IE8__"+Math.random(),v=Object.defineProperty||function(t,e,n){t[e]=n.value},g=Object.defineProperties||function(e,n){for(var a in n)if(y.call(n,a))try{v(e,a,n[a])}catch(r){t.console&&console.log(a+" failed on object:",e,r.message)}},b=Object.getOwnPropertyDescriptor,y=Object.prototype.hasOwnProperty,x=t.Element.prototype,_=t.Text.prototype,w=/^[a-z]+$/,k=/loaded|complete/,E={},S=document.createElement("div"),C=document.documentElement,P=C.removeAttribute,A=C.setAttribute;a(t.HTMLCommentElement.prototype,x,"nodeValue"),a(t.HTMLScriptElement.prototype,null,"text"),a(_,null,"nodeValue"),a(t.HTMLTitleElement.prototype,null,"text"),v(t.HTMLStyleElement.prototype,"textContent",function(t){return n(function(){return t.get.call(this.styleSheet)},function(e){t.set.call(this.styleSheet,e)})}(b(t.CSSStyleSheet.prototype,"cssText"))),g(x,{textContent:{get:o,set:p},firstElementChild:{get:function(){for(var t=this.childNodes||[],e=0,n=t.length;n>e;e++)if(1==t[e].nodeType)return t[e]}},lastElementChild:{get:function(){for(var t=this.childNodes||[],e=t.length;e--;)if(1==t[e].nodeType)return t[e]}},oninput:{get:function(){return this._oninput||null},set:function(t){this._oninput&&(this.removeEventListener("input",this._oninput),this._oninput=t,t&&this.addEventListener("input",t))}},previousElementSibling:{get:function(){for(var t=this.previousSibling;t&&1!=t.nodeType;)t=t.previousSibling;return t}},nextElementSibling:{get:function(){for(var t=this.nextSibling;t&&1!=t.nodeType;)t=t.nextSibling;return t}},childElementCount:{get:function(){for(var t=0,e=this.childNodes||[],n=e.length;n--;t+=1==e[n].nodeType);return t}},addEventListener:{value:function(t,n,a){if("function"==typeof n||"object"==typeof n){var r,o,u=this,p="on"+t,l=u[m]||v(u,m,{value:{}})[m],f=l[p]||(l[p]={}),d=f.h||(f.h=[]);if(!y.call(f,"w")){if(f.w=function(t){return t[m]||e(u,c(u,t),d,!1)},!y.call(E,p))if(w.test(t)){try{r=document.createEventObject(),r[m]=!0,9!=u.nodeType&&(null==u.parentNode&&S.appendChild(u),(o=u.getAttribute(p))&&P.call(u,p)),u.fireEvent(p,r),E[p]=!0}catch(r){for(E[p]=!1;S.hasChildNodes();)S.removeChild(S.firstChild)}null!=o&&A.call(u,p,o)}else E[p]=!1;(f.n=E[p])&&u.attachEvent(p,f.w)}i(d,n)<0&&d[a?"unshift":"push"](n),"input"===t&&u.attachEvent("onkeyup",s)}}},dispatchEvent:{value:function(t){var n,a=this,r="on"+t.type,i=a[m],o=i&&i[r],s=!!o;return t.target||(t.target=a),s?o.n?a.fireEvent(r,t):e(a,t,o.h,!0):(n=a.parentNode)?n.dispatchEvent(t):!0,!t.defaultPrevented}},removeEventListener:{value:function(t,e,n){if("function"==typeof e||"object"==typeof e){var a=this,r="on"+t,o=a[m],s=o&&o[r],u=s&&s.h,p=u?i(u,e):-1;p>-1&&u.splice(p,1)}}}}),g(_,{addEventListener:{value:x.addEventListener},dispatchEvent:{value:x.dispatchEvent},removeEventListener:{value:x.removeEventListener}}),g(t.XMLHttpRequest.prototype,{addEventListener:{value:function(t,e,n){var a=this,r="on"+t,o=a[m]||v(a,m,{value:{}})[m],s=o[r]||(o[r]={}),u=s.h||(s.h=[]);i(u,e)<0&&(a[r]||(a[r]=function(){var e=document.createEvent("Event");e.initEvent(t,!0,!0),a.dispatchEvent(e)}),u[n?"unshift":"push"](e))}},dispatchEvent:{value:function(t){var n=this,a="on"+t.type,r=n[m],i=r&&r[a],o=!!i;return o&&(i.n?n.fireEvent(a,t):e(n,t,i.h,!0))}},removeEventListener:{value:x.removeEventListener}}),g(t.Event.prototype,{bubbles:{value:!0,writable:!0},cancelable:{value:!0,writable:!0},preventDefault:{value:function(){this.cancelable&&(this.defaultPrevented=!0,this.returnValue=!1)}},stopPropagation:{value:function(){this.stoppedPropagation=!0,this.cancelBubble=!0}},stopImmediatePropagation:{value:function(){this.stoppedImmediatePropagation=!0,this.stopPropagation()}},initEvent:{value:function(t,e,n){this.type=t,this.bubbles=!!e,this.cancelable=!!n,this.bubbles||this.stopPropagation()}}}),g(t.HTMLDocument.prototype,{defaultView:{get:function(){return this.parentWindow}},textContent:{get:function(){return 11===this.nodeType?o.call(this):null},set:function(t){11===this.nodeType&&p.call(this,t)}},addEventListener:{value:function(e,n,a){var r=this;x.addEventListener.call(r,e,n,a),l&&e===h&&!k.test(r.readyState)&&(l=!1,r.attachEvent(d,u),t==top&&!function i(t){try{r.documentElement.doScroll("left"),u()}catch(e){setTimeout(i,50)}}())}},dispatchEvent:{value:x.dispatchEvent},removeEventListener:{value:x.removeEventListener},createEvent:{value:function(t){var e;if("Event"!==t)throw Error("unsupported "+t);return e=document.createEventObject(),e.timeStamp=(new Date).getTime(),e}}}),g(t.Window.prototype,{getComputedStyle:{value:function(){function t(t){this._=t}function e(){}var n=/^(?:[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/,a=/^(top|right|bottom|left)$/,r=/\-([a-z])/g,i=function(t,e){return e.toUpperCase()};return t.prototype.getPropertyValue=function(t){var e,o,s,u=this._,p=u.style,c=u.currentStyle,l=u.runtimeStyle;return t=("float"===t?"style-float":t).replace(r,i),e=c?c[t]:p[t],n.test(e)&&!a.test(t)&&(o=p.left,s=l&&l.left,s&&(l.left=c.left),p.left="fontSize"===t?"1em":e,e=p.pixelLeft+"px",p.left=o,s&&(l.left=s)),null==e?e:e+""||"auto"},e.prototype.getPropertyValue=function(){return null},function(n,a){return a?new e(n):new t(n)}}()},addEventListener:{value:function(n,a,r){var o,s=t,u="on"+n;s[u]||(s[u]=function(t){return e(s,c(s,t),o,!1)}),o=s[u][m]||(s[u][m]=[]),i(o,a)<0&&o[r?"unshift":"push"](a)}},dispatchEvent:{value:function(e){var n=t["on"+e.type];return n?n.call(t,e)!==!1&&!e.defaultPrevented:!0}},removeEventListener:{value:function(e,n,a){var r="on"+e,o=(t[r]||Object)[m],s=o?i(o,n):-1;s>-1&&o.splice(s,1)}}}),function(t,e,n){for(n=0;n=s)return(0,u["default"])({points:n});for(var l=1;s-1>=l;l++)i.push((0,p.times)(a,(0,p.minus)(n[l],n[l-1])));for(var f=[(0,p.plus)(n[0],c(i[0],i[1]))],l=1;s-2>=l;l++)f.push((0,p.minus)(n[l],(0,p.average)([i[l],i[l-1]])));f.push((0,p.minus)(n[s-1],c(i[s-2],i[s-3])));var d=f[0],h=f[1],m=n[0],v=n[1],g=(e=(0,o["default"])()).moveto.apply(e,r(m)).curveto(d[0],d[1],h[0],h[1],v[0],v[1]);return{path:(0,p.range)(2,s).reduce(function(t,e){var a=f[e],r=n[e];return t.smoothcurveto(a[0],a[1],r[0],r[1])},g),centroid:(0,p.average)(n)}},e.exports=n["default"]},{198:198,199:199,200:200}],196:[function(t,e,n){"use strict";function a(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),i=t(197),o=a(i),s=t(198),u=1e-5,p=function(t,e){var n=t.map(e),a=n.sort(function(t,e){var n=r(t,2),a=n[0],i=(n[1],r(e,2)),o=i[0];i[1];return a-o}),i=a.length,o=a[0][0],p=a[i-1][0],c=(0,s.minBy)(a,function(t){return t[1]}),l=(0,s.maxBy)(a,function(t){return t[1]});return o==p&&(p+=u),c==l&&(l+=u),{points:a,xmin:o,xmax:p,ymin:c,ymax:l}};n["default"]=function(t){var e=t.data,n=t.xaccessor,a=t.yaccessor,i=t.width,u=t.height,c=t.closed,l=t.min,f=t.max;n||(n=function(t){var e=r(t,2),n=e[0];e[1];return n}),a||(a=function(t){var e=r(t,2),n=(e[0],e[1]);return n});var d=function(t){return[n(t),a(t)]},h=e.map(function(t){return p(t,d)}),m=(0,s.minBy)(h,function(t){return t.xmin}),v=(0,s.maxBy)(h,function(t){return t.xmax}),g=null==l?(0,s.minBy)(h,function(t){return t.ymin}):l,b=null==f?(0,s.maxBy)(h,function(t){return t.ymax}):f;c&&(g=Math.min(g,0),b=Math.max(b,0));var y=c?0:g,x=(0,o["default"])([m,v],[0,i]),_=(0,o["default"])([g,b],[u,0]),w=function(t){var e=r(t,2),n=e[0],a=e[1];return[x(n),_(a)]};return{arranged:h,scale:w,xscale:x,yscale:_,base:y}},e.exports=n["default"]},{197:197,198:198}],197:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function i(t,e){var n=a(t,2),r=n[0],o=n[1],s=a(e,2),u=s[0],p=s[1],c=function(t){return u+(p-u)*(t-r)/(o-r)};return c.inverse=function(){return i([u,p],[r,o])},c};n["default"]=r,e.exports=n["default"]},{}],198:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function(t){return t.reduce(function(t,e){return t+e},0)},i=function(t){return t.reduce(function(t,e){return Math.min(t,e)})},o=function(t){return t.reduce(function(t,e){return Math.max(t,e)})},s=function(t,e){return t.reduce(function(t,n){return t+e(n)},0)},u=function(t,e){return t.reduce(function(t,n){return Math.min(t,e(n))},1/0)},p=function(t,e){return t.reduce(function(t,n){return Math.max(t,e(n))},-(1/0))},c=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],u=o[1];return[r+s,i+u]},l=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],u=o[1];return[r-s,i-u]},f=function(t,e){var n=a(e,2),r=n[0],i=n[1];return[t*r,t*i]},d=function(t){var e=a(t,2),n=e[0],r=e[1];return Math.sqrt(n*n+r*r)},h=function(t){return t.reduce(c,[0,0])},m=function(t){return f(1/t.length,t.reduce(c))},v=function(t,e){return f(t,[Math.sin(e),-Math.cos(e)])},g=function(t,e){var n=t||{};for(var a in n){var r=n[a];e[a]=r(e.index,e.item,e.group)}return e},b=function(t,e,n){for(var a=[],r=t;e>r;r++)a.push(r);return n&&a.push(e),a},y=function(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=Object.keys(t)[Symbol.iterator]();!(a=(o=s.next()).done);a=!0){var u=o.value,p=t[u];n.push(e(u,p))}}catch(c){r=!0,i=c}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n},x=function(t){return y(t,function(t,e){return[t,e]})},_=function(t){return t};n.sum=r,n.min=i,n.max=o,n.sumBy=s,n.minBy=u,n.maxBy=p,n.plus=c,n.minus=l,n.times=f,n.id=_,n.length=d,n.sumVectors=h,n.average=m,n.onCircle=v,n.enhance=g,n.range=b,n.mapObject=y,n.pairs=x,n["default"]={sum:r,min:i,max:o,sumBy:s,minBy:u,maxBy:p,plus:c,minus:l,times:f,id:_,length:d,sumVectors:h,average:m,onCircle:v,enhance:g,range:b,mapObject:y,pairs:x}},{}],199:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function i(t){var e=t||[],n=function(t,e){var n=t.slice(0,t.length);return n.push(e),n},r=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],u=o[1];return r===s&&i===u},o=function(t,e){for(var n=t.length;"0"===t.charAt(n-1);)n-=1;return"."===t.charAt(n-1)&&(n-=1),t.substr(0,n)},s=function(t,e){var n=t.toFixed(e);return o(n)},u=function(t){var e=t.command,n=t.params,a=n.map(function(t){return s(t,6)});return e+" "+a.join(" ")},p=function(t,e){var n=t.command,r=t.params,i=a(e,2),o=i[0],s=i[1];switch(n){case"M":return[r[0],r[1]];case"L":return[r[0],r[1]];case"H":return[r[0],s];case"V":return[o,r[0]];case"Z":return null;case"C":return[r[4],r[5]];case"S":return[r[2],r[3]];case"Q":return[r[2],r[3]];case"T":return[r[0],r[1]];case"A":return[r[5],r[6]]}},c=function(t,e){return function(n){var a="object"==typeof n?t.map(function(t){return n[t]}):arguments;return e.apply(null,a)}},l=function(t){return i(n(e,t))};return{moveto:c(["x","y"],function(t,e){return l({command:"M",params:[t,e]})}),lineto:c(["x","y"],function(t,e){return l({command:"L",params:[t,e]})}),hlineto:c(["x"],function(t){return l({command:"H",params:[t]})}),vlineto:c(["y"],function(t){return l({command:"V",params:[t]})}),closepath:function(){return l({command:"Z",params:[]})},curveto:c(["x1","y1","x2","y2","x","y"],function(t,e,n,a,r,i){return l({command:"C",params:[t,e,n,a,r,i]})}),smoothcurveto:c(["x2","y2","x","y"],function(t,e,n,a){return l({command:"S",params:[t,e,n,a]})}),qcurveto:c(["x1","y1","x","y"],function(t,e,n,a){return l({command:"Q",params:[t,e,n,a]})}),smoothqcurveto:c(["x","y"],function(t,e){return l({command:"T",params:[t,e]})}),arc:c(["rx","ry","xrot","largeArcFlag","sweepFlag","x","y"],function(t,e,n,a,r,i,o){return l({command:"A",params:[t,e,n,a,r,i,o]})}),print:function(){return e.map(u).join(" ")},points:function(){var t=[],n=[0,0],a=!0,r=!1,i=void 0;try{for(var o,s=e[Symbol.iterator]();!(a=(o=s.next()).done);a=!0){var u=o.value,c=p(u,n);n=c,c&&t.push(c)}}catch(l){r=!0,i=l}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return t},instructions:function(){return e.slice(0,e.length)},connect:function(t){var e=this.points(),n=e[e.length-1],a=t.points()[0],o=t.instructions().slice(1);return r(n,a)||o.unshift({command:"L",params:a}),i(this.instructions().concat(o))}}};n["default"]=function(){return r()},e.exports=n["default"]},{}],200:[function(t,e,n){"use strict";function a(t){return t&&t.__esModule?t:{"default":t}}function r(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e1)for(var n=1;n1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];for(var r,i;i=n.shift();)for(r in i)Ro.call(i,r)&&(t[r]=i[r]);return t}function r(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];return n.forEach(function(e){for(var n in e)!e.hasOwnProperty(n)||n in t||(t[n]=e[n])}),t}function i(t){return"[object Array]"===Mo.call(t)}function o(t){return Lo.test(Mo.call(t))}function s(t,e){return null===t&&null===e?!0:"object"==typeof t||"object"==typeof e?!1:t===e}function u(t){return!isNaN(parseFloat(t))&&isFinite(t)}function p(t){return t&&"[object Object]"===Mo.call(t)}function c(t,e){return t.replace(/%s/g,function(){return e.shift()})}function l(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];throw t=c(t,n),Error(t)}function f(){Rv.DEBUG&&Oo.apply(null,arguments)}function d(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];t=c(t,n),To(t,n)}function h(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];t=c(t,n),No[t]||(No[t]=!0,To(t,n))}function m(){Rv.DEBUG&&d.apply(null,arguments)}function v(){Rv.DEBUG&&h.apply(null,arguments)}function g(t,e,n){var a=b(t,e,n);return a?a[t][n]:null}function b(t,e,n){for(;e;){if(n in e[t])return e;if(e.isolated)return null;e=e.parent}}function y(t){return function(){return t}}function x(t){var e,n,a,r,i,o;for(e=t.split("."),(n=zo[e.length])||(n=_(e.length)),i=[],a=function(t,n){return t?"*":e[n]},r=n.length;r--;)o=n[r].map(a).join("."),i.hasOwnProperty(o)||(i.push(o),i[o]=!0);return i}function _(t){var e,n,a,r,i,o,s,u,p="";if(!zo[t]){for(a=[];p.length=i;i+=1){for(n=i.toString(2);n.lengtho;o++)u.push(r(n[o]));a[i]=u}zo[t]=a}return zo[t]}function w(t,e,n,a){var r=t[e];if(!r||!r.equalsOrStartsWith(a)&&r.equalsOrStartsWith(n))return t[e]=r?r.replace(n,a):a,!0}function k(t){var e=t.slice(2);return"i"===t[1]&&u(e)?+e:e}function E(t){return null==t?t:(Qo.hasOwnProperty(t)||(Qo[t]=new Ko(t)),Qo[t])}function S(t,e){function n(e,n){var a,r,o;return n.isRoot?o=[].concat(Object.keys(t.viewmodel.data),Object.keys(t.viewmodel.mappings),Object.keys(t.viewmodel.computations)):(a=t.viewmodel.wrapped[n.str],r=a?a.get():t.viewmodel.get(n),o=r?Object.keys(r):null),o&&o.forEach(function(t){"_ractive"===t&&i(r)||e.push(n.join(t))}),e}var a,r,o;for(a=e.str.split("."),o=[Yo];r=a.shift();)"*"===r?o=o.reduce(n,[]):o[0]===Yo?o[0]=E(r):o=o.map(C(r));return o}function C(t){return function(e){return e.join(t)}}function P(t){return t?t.replace(Wo,".$1"):""}function A(t,e,n){if("string"!=typeof e||!u(n))throw Error("Bad arguments");var a=void 0,r=void 0;if(/\*/.test(e))return r={},S(t,E(P(e))).forEach(function(e){var a=t.viewmodel.get(e);if(!u(a))throw Error(Xo);r[e.str]=a+n}),t.set(r);if(a=t.get(e),!u(a))throw Error(Xo);return t.set(e,+a+n)}function O(t,e){return Jo(this,t,void 0===e?1:+e)}
-function T(t){this.event=t,this.method="on"+t,this.deprecate=as[t]}function j(t,e){var n=t.indexOf(e);-1===n&&t.push(e)}function R(t,e){for(var n=0,a=t.length;a>n;n++)if(t[n]==e)return!0;return!1}function M(t,e){var n;if(!i(t)||!i(e))return!1;if(t.length!==e.length)return!1;for(n=t.length;n--;)if(t[n]!==e[n])return!1;return!0}function L(t){return"string"==typeof t?[t]:void 0===t?[]:t}function N(t){return t[t.length-1]}function D(t,e){var n=t.indexOf(e);-1!==n&&t.splice(n,1)}function F(t){for(var e=[],n=t.length;n--;)e[n]=t[n];return e}function I(t){setTimeout(t,0)}function B(t,e){return function(){for(var n;n=t.shift();)n(e)}}function q(t,e,n,a){var r;if(e===t)throw new TypeError("A promise's fulfillment handler cannot return the same promise");if(e instanceof rs)e.then(n,a);else if(!e||"object"!=typeof e&&"function"!=typeof e)n(e);else{try{r=e.then}catch(i){return void a(i)}if("function"==typeof r){var o,s,u;s=function(e){o||(o=!0,q(t,e,n,a))},u=function(t){o||(o=!0,a(t))};try{r.call(e,s,u)}catch(i){if(!o)return a(i),void(o=!0)}}else n(e)}}function U(t,e,n){var a;return e=P(e),"~/"===e.substr(0,2)?(a=E(e.substring(2)),z(t,a.firstKey,n)):"."===e[0]?(a=G(cs(n),e),a&&z(t,a.firstKey,n)):a=V(t,E(e),n),a}function G(t,e){var n;if(void 0!=t&&"string"!=typeof t&&(t=t.str),"."===e)return E(t);if(n=t?t.split("."):[],"../"===e.substr(0,3)){for(;"../"===e.substr(0,3);){if(!n.length)throw Error('Could not resolve reference - too many "../" prefixes');n.pop(),e=e.substring(3)}return n.push(e),E(n.join("."))}return E(t?t+e.replace(/^\.\//,"."):e.replace(/^\.\/?/,""))}function V(t,e,n,a){var r,i,o,s,u;if(e.isRoot)return e;for(i=e.firstKey;n;)if(r=n.context,n=n.parent,r&&(s=!0,o=t.viewmodel.get(r),o&&("object"==typeof o||"function"==typeof o)&&i in o))return r.join(e.str);return W(t.viewmodel,i)?e:t.parent&&!t.isolated&&(s=!0,n=t.component.parentFragment,i=E(i),u=V(t.parent,i,n,!0))?(t.viewmodel.map(i,{origin:t.parent.viewmodel,keypath:u}),e):a||s?void 0:(t.viewmodel.set(e,void 0),e)}function z(t,e){var n;!t.parent||t.isolated||W(t.viewmodel,e)||(e=E(e),(n=V(t.parent,e,t.component.parentFragment,!0))&&t.viewmodel.map(e,{origin:t.parent.viewmodel,keypath:n}))}function W(t,e){return""===e||e in t.data||e in t.computations||e in t.mappings}function H(t){t.teardown()}function Q(t){t.unbind()}function K(t){t.unrender()}function $(t){t.cancel()}function Y(t){t.detach()}function J(t){t.detachNodes()}function X(t){!t.ready||t.outros.length||t.outroChildren||(t.outrosComplete||(t.parent?t.parent.decrementOutros(t):t.detachNodes(),t.outrosComplete=!0),t.intros.length||t.totalChildren||("function"==typeof t.callback&&t.callback(),t.parent&&t.parent.decrementTotal()))}function Z(){for(var t,e,n;ds.ractives.length;)e=ds.ractives.pop(),n=e.viewmodel.applyChanges(),n&&gs.fire(e,n);for(tt(),t=0;t=0;i--)r=t._subs[e[i]],r&&(s=gt(t,r,n,a)&&s);if(Vs.dequeue(t),t.parent&&s){if(o&&t.component){var u=t.component.name+"."+e[e.length-1];e=E(u).wildcardMatches(),n&&(n.component=t)}vt(t.parent,e,n,a)}}function gt(t,e,n,a){var r=null,i=!1;n&&!n._noArg&&(a=[n].concat(a)),e=e.slice();for(var o=0,s=e.length;s>o;o+=1)e[o].apply(t,a)===!1&&(i=!0);return n&&!n._noArg&&i&&(r=n.original)&&(r.preventDefault&&r.preventDefault(),r.stopPropagation&&r.stopPropagation()),!i}function bt(t){var e={args:Array.prototype.slice.call(arguments,1)};zs(this,t,e)}function yt(t){var e;return t=E(P(t)),e=this.viewmodel.get(t,Qs),void 0===e&&this.parent&&!this.isolated&&ls(this,t.str,this.component.parentFragment)&&(e=this.viewmodel.get(t)),e}function xt(e,n){if(!this.fragment.rendered)throw Error("The API has changed - you must call `ractive.render(target[, anchor])` to render your Ractive instance. Once rendered you can use `ractive.insert()`.");if(e=t(e),n=t(n)||null,!e)throw Error("You must specify a valid target to insert into");e.insertBefore(this.detach(),n),this.el=e,(e.__ractive_instances__||(e.__ractive_instances__=[])).push(this),this.detached=null,_t(this)}function _t(t){$s.fire(t),t.findAllComponents("*").forEach(function(t){_t(t.instance)})}function wt(t,e,n){var a,r;return t=E(P(t)),a=this.viewmodel.get(t),i(a)&&i(e)?(r=bs.start(this,!0),this.viewmodel.merge(t,a,e,n),bs.end(),r):this.set(t,e,n&&n.complete)}function kt(t,e){var n,a;return n=S(t,e),a={},n.forEach(function(e){a[e.str]=t.get(e.str)}),a}function Et(t,e,n,a){var r,i,o;e=E(P(e)),a=a||cu,e.isPattern?(r=new uu(t,e,n,a),t.viewmodel.patternObservers.push(r),i=!0):r=new Zs(t,e,n,a),r.init(a.init),t.viewmodel.register(e,r,i?"patternObservers":"observers"),r.ready=!0;var s={cancel:function(){var n;o||(i?(n=t.viewmodel.patternObservers.indexOf(r),t.viewmodel.patternObservers.splice(n,1),t.viewmodel.unregister(e,r,"patternObservers")):t.viewmodel.unregister(e,r,"observers"),o=!0)}};return t._observers.push(s),s}function St(t,e,n){var a,r,i,o;if(p(t)){n=e,r=t,a=[];for(t in r)r.hasOwnProperty(t)&&(e=r[t],a.push(this.observe(t,e,n)));return{cancel:function(){for(;a.length;)a.pop().cancel()}}}if("function"==typeof t)return n=e,e=t,t="",pu(this,t,e,n);if(i=t.split(" "),1===i.length)return pu(this,t,e,n);for(a=[],o=i.length;o--;)t=i[o],t&&a.push(pu(this,t,e,n));return{cancel:function(){for(;a.length;)a.pop().cancel()}}}function Ct(t,e,n){var a=this.observe(t,function(){e.apply(this,arguments),a.cancel()},{init:!1,defer:n&&n.defer});return a}function Pt(t,e){var n,a=this;if(t)n=t.split(" ").map(du).filter(hu),n.forEach(function(t){var n,r;(n=a._subs[t])&&(e?(r=n.indexOf(e),-1!==r&&n.splice(r,1)):a._subs[t]=[])});else for(t in this._subs)delete this._subs[t];return this}function At(t,e){var n,a,r,i=this;if("object"==typeof t){n=[];for(a in t)t.hasOwnProperty(a)&&n.push(this.on(a,t[a]));return{cancel:function(){for(var t;t=n.pop();)t.cancel()}}}return r=t.split(" ").map(du).filter(hu),r.forEach(function(t){(i._subs[t]||(i._subs[t]=[])).push(e)}),{cancel:function(){return i.off(t,e)}}}function Ot(t,e){var n=this.on(t,function(){e.apply(this,arguments),n.cancel()});return n}function Tt(t,e,n){var a,r,i,o,s,u,p=[];if(a=jt(t,e,n),!a)return null;for(r=t.length,s=a.length-2-a[1],i=Math.min(r,a[0]),o=i+a[1],u=0;i>u;u+=1)p.push(u);for(;o>u;u+=1)p.push(-1);for(;r>u;u+=1)p.push(u+s);return 0!==s?p.touchedFrom=a[0]:p.touchedFrom=t.length,p}function jt(t,e,n){switch(e){case"splice":for(void 0!==n[0]&&n[0]<0&&(n[0]=t.length+Math.max(n[0],-t.length));n.length<2;)n.push(0);return n[1]=Math.min(n[1],t.length-n[0]),n;case"sort":case"reverse":return null;case"pop":return t.length?[t.length-1,1]:[0,0];case"push":return[t.length,0].concat(n);case"shift":return[0,t.length?1:0];case"unshift":return[0,0].concat(n)}}function Rt(e,n){var a,r,i,o=this;if(i=this.transitionsEnabled,this.noIntro&&(this.transitionsEnabled=!1),a=bs.start(this,!0),bs.scheduleTask(function(){return ju.fire(o)},!0),this.fragment.rendered)throw Error("You cannot call ractive.render() on an already rendered instance! Call ractive.unrender() first");if(e=t(e)||this.el,n=t(n)||this.anchor,this.el=e,this.anchor=n,!this.append&&e){var s=e.__ractive_instances__;s&&s.length&&Mt(s),e.innerHTML=""}return this.cssId&&Ou.apply(),e&&((r=e.__ractive_instances__)?r.push(this):e.__ractive_instances__=[this],n?e.insertBefore(this.fragment.render(),n):e.appendChild(this.fragment.render())),bs.end(),this.transitionsEnabled=i,a.then(function(){return Ru.fire(o)})}function Mt(t){t.splice(0,t.length).forEach(H)}function Lt(t,e){for(var n=t.slice(),a=e.length;a--;)~n.indexOf(e[a])||n.push(e[a]);return n}function Nt(t,e){var n,a,r;return a='[data-ractive-css~="{'+e+'}"]',r=function(t){var e,n,r,i,o,s,u,p=[];for(e=[];n=Iu.exec(t);)e.push({str:n[0],base:n[1],modifiers:n[2]});for(i=e.map(Ft),u=e.length;u--;)s=i.slice(),r=e[u],s[u]=r.base+a+r.modifiers||"",o=i.slice(),o[u]=a+" "+o[u],p.push(s.join(" "),o.join(" "));return p.join(", ")},n=qu.test(t)?t.replace(qu,a):t.replace(Fu,"").replace(Du,function(t,e){var n,a;return Bu.test(e)?t:(n=e.split(",").map(Dt),a=n.map(r).join(", ")+" ",t.replace(e,a))})}function Dt(t){return t.trim?t.trim():t.replace(/^\s+/,"").replace(/\s+$/,"")}function Ft(t){return t.str}function It(t){t&&t.constructor!==Object&&("function"==typeof t||("object"!=typeof t?l("data option must be an object or a function, `"+t+"` is not valid"):m("If supplied, options.data should be a plain JavaScript object - using a non-POJO as the root object may work, but is discouraged")))}function Bt(t,e){It(e);var n="function"==typeof t,a="function"==typeof e;return e||n||(e={}),n||a?function(){var r=a?qt(e,this):e,i=n?qt(t,this):t;return Ut(r,i)}:Ut(e,t)}function qt(t,e){var n=t.call(e);if(n)return"object"!=typeof n&&l("Data function must return an object"),n.constructor!==Object&&v("Data function returned something other than a plain JavaScript object. This might work, but is strongly discouraged"),n}function Ut(t,e){if(t&&e){for(var n in e)n in t||(t[n]=e[n]);return t}return t||e}function Gt(t){var e=Eo(Ku);return e.parse=function(e,n){return Vt(e,n||t)},e}function Vt(t,e){if(!Hu)throw Error("Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser");return Hu(t,e||this.options)}function zt(t,e){var n;if(!Xi){if(e&&e.noThrow)return;throw Error("Cannot retrieve template #"+t+" as Ractive is not running in a browser.")}if(Wt(t)&&(t=t.substring(1)),!(n=document.getElementById(t))){if(e&&e.noThrow)return;throw Error("Could not find template element with id #"+t)}if("SCRIPT"!==n.tagName.toUpperCase()){if(e&&e.noThrow)return;throw Error("Template element with id #"+t+", must be a i;)c(r,a=t[i++])&&(~S(o,a)||o.push(a));return o}},B=function(){};i(i.S,"Object",{getPrototypeOf:r.getProto=r.getProto||function(t){return t=g(t),c(t,k)?t[k]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?C:null},getOwnPropertyNames:r.getNames=r.getNames||I(D,D.length,!0),create:r.create=r.create||function(t,e){var n;return null!==t?(B.prototype=h(t),n=new B,B.prototype=null,n[k]=t):n=F(),void 0===e?n:R(n,e)},keys:r.getKeys=r.getKeys||I(L,N,!1)});var q=function(t,e,n){if(!(e in M)){for(var a=[],r=0;e>r;r++)a[r]="a["+r+"]";M[e]=Function("F,a","return new F("+a.join(",")+")")}return M[e](t,n)};i(i.P,"Function",{bind:function(t){var e=m(this),n=A.call(arguments,1),a=function(){var r=n.concat(A.call(arguments));return this instanceof a?q(e,r.length,r):f(e,r,t)};return v(e.prototype)&&(a.prototype=e.prototype),a}}),i(i.P+i.F*d(function(){u&&A.call(u)}),"Array",{slice:function(t,e){var n=_(this.length),a=l(this);if(e=void 0===e?n:e,"Array"==a)return A.call(this,t,e);for(var r=x(t,n),i=x(e,n),o=_(i-r),s=Array(o),u=0;o>u;u++)s[u]="String"==a?this.charAt(r+u):this[r+u];return s}}),i(i.P+i.F*(w!=Object),"Array",{join:function(t){return O.call(w(this),void 0===t?",":t)}}),i(i.S,"Array",{isArray:t(36)});var U=function(t){return function(e,n){m(e);var a=w(this),r=_(a.length),i=t?r-1:0,o=t?-1:1;if(arguments.length<2)for(;;){if(i in a){n=a[i],i+=o;break}if(i+=o,t?0>i:i>=r)throw TypeError("Reduce of empty array with no initial value")}for(;t?i>=0:r>i;i+=o)i in a&&(n=e(n,a[i],i,this));return n}},G=function(t){return function(e){return t(this,e,arguments[1])}};i(i.P,"Array",{forEach:r.each=r.each||G(E(0)),map:G(E(1)),filter:G(E(2)),some:G(E(3)),every:G(E(4)),reduce:U(!1),reduceRight:U(!0),indexOf:G(S),lastIndexOf:function(t,e){var n=b(this),a=_(n.length),r=a-1;for(arguments.length>1&&(r=Math.min(r,y(e))),0>r&&(r=_(a+r));r>=0;r--)if(r in n&&n[r]===t)return r;return-1}}),i(i.S,"Date",{now:function(){return+new Date}});var V=function(t){return t>9?t:"0"+t};i(i.P+i.F*(d(function(){return"0385-07-25T07:06:39.999Z"!=new Date(-5e13-1).toISOString()})||!d(function(){new Date(NaN).toISOString()})),"Date",{toISOString:function(){if(!isFinite(this))throw RangeError("Invalid time value");var t=this,e=t.getUTCFullYear(),n=t.getUTCMilliseconds(),a=0>e?"-":e>9999?"+":"";return a+("00000"+Math.abs(e)).slice(a?-6:-4)+"-"+V(t.getUTCMonth()+1)+"-"+V(t.getUTCDate())+"T"+V(t.getUTCHours())+":"+V(t.getUTCMinutes())+":"+V(t.getUTCSeconds())+"."+(n>99?n:"0"+V(n))+"Z"}})},{11:11,19:19,2:2,20:20,22:22,24:24,30:30,32:32,33:33,34:34,36:36,38:38,4:4,46:46,59:59,7:7,76:76,77:77,78:78,79:79,8:8,80:80,82:82}],86:[function(t,e,n){var a=t(22);a(a.P,"Array",{copyWithin:t(5)}),t(3)("copyWithin")},{22:22,3:3,5:5}],87:[function(t,e,n){var a=t(22);a(a.P,"Array",{fill:t(6)}),t(3)("fill")},{22:22,3:3,6:6}],88:[function(t,e,n){"use strict";var a=t(22),r=t(8)(6),i="findIndex",o=!0;i in[]&&Array(1)[i](function(){o=!1}),a(a.P+a.F*o,"Array",{findIndex:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0)}}),t(3)(i)},{22:22,3:3,8:8}],89:[function(t,e,n){"use strict";var a=t(22),r=t(8)(5),i="find",o=!0;i in[]&&Array(1)[i](function(){o=!1}),a(a.P+a.F*o,"Array",{find:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0)}}),t(3)(i)},{22:22,3:3,8:8}],90:[function(t,e,n){"use strict";var a=t(17),r=t(22),i=t(80),o=t(40),s=t(35),u=t(79),p=t(84);r(r.S+r.F*!t(43)(function(t){Array.from(t)}),"Array",{from:function(t){var e,n,r,c,l=i(t),f="function"==typeof this?this:Array,d=arguments,h=d.length,m=h>1?d[1]:void 0,v=void 0!==m,g=0,b=p(l);if(v&&(m=a(m,h>2?d[2]:void 0,2)),void 0==b||f==Array&&s(b))for(e=u(l.length),n=new f(e);e>g;g++)n[g]=v?m(l[g],g):l[g];else for(c=b.call(l),n=new f;!(r=c.next()).done;g++)n[g]=v?o(c,m,[r.value,g],!0):r.value;return n.length=g,n}})},{17:17,22:22,35:35,40:40,43:43,79:79,80:80,84:84}],91:[function(t,e,n){"use strict";var a=t(3),r=t(44),i=t(45),o=t(78);e.exports=t(42)(Array,"Array",function(t,e){this._t=o(t),this._i=0,this._k=e},function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,r(1)):"keys"==e?r(0,n):"values"==e?r(0,t[n]):r(0,[n,t[n]])},"values"),i.Arguments=i.Array,a("keys"),a("values"),a("entries")},{3:3,42:42,44:44,45:45,78:78}],92:[function(t,e,n){"use strict";var a=t(22);a(a.S+a.F*t(24)(function(){function t(){}return!(Array.of.call(t)instanceof t)}),"Array",{of:function(){for(var t=0,e=arguments,n=e.length,a=new("function"==typeof this?this:Array)(n);n>t;)a[t]=e[t++];return a.length=n,a}})},{22:22,24:24}],93:[function(t,e,n){t(65)("Array")},{65:65}],94:[function(t,e,n){"use strict";var a=t(46),r=t(38),i=t(83)("hasInstance"),o=Function.prototype;i in o||a.setDesc(o,i,{value:function(t){if("function"!=typeof this||!r(t))return!1;if(!r(this.prototype))return t instanceof this;for(;t=a.getProto(t);)if(this.prototype===t)return!0;return!1}})},{38:38,46:46,83:83}],95:[function(t,e,n){var a=t(46).setDesc,r=t(59),i=t(30),o=Function.prototype,s=/^\s*function ([^ (]*)/,u="name";u in o||t(19)&&a(o,u,{configurable:!0,get:function(){var t=(""+this).match(s),e=t?t[1]:"";return i(this,u)||a(this,u,r(5,e)),e}})},{19:19,30:30,46:46,59:59}],96:[function(t,e,n){"use strict";var a=t(12);t(15)("Map",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{get:function(t){var e=a.getEntry(this,t);return e&&e.v},set:function(t,e){return a.def(this,0===t?0:t,e)}},a,!0)},{12:12,15:15}],97:[function(t,e,n){var a=t(22),r=t(50),i=Math.sqrt,o=Math.acosh;a(a.S+a.F*!(o&&710==Math.floor(o(Number.MAX_VALUE))),"Math",{acosh:function(t){return(t=+t)<1?NaN:t>94906265.62425156?Math.log(t)+Math.LN2:r(t-1+i(t-1)*i(t+1))}})},{22:22,50:50}],98:[function(t,e,n){function a(t){return isFinite(t=+t)&&0!=t?0>t?-a(-t):Math.log(t+Math.sqrt(t*t+1)):t}var r=t(22);r(r.S,"Math",{asinh:a})},{22:22}],99:[function(t,e,n){var a=t(22);a(a.S,"Math",{atanh:function(t){return 0==(t=+t)?t:Math.log((1+t)/(1-t))/2}})},{22:22}],100:[function(t,e,n){var a=t(22),r=t(51);a(a.S,"Math",{cbrt:function(t){return r(t=+t)*Math.pow(Math.abs(t),1/3)}})},{22:22,51:51}],101:[function(t,e,n){var a=t(22);a(a.S,"Math",{clz32:function(t){return(t>>>=0)?31-Math.floor(Math.log(t+.5)*Math.LOG2E):32}})},{22:22}],102:[function(t,e,n){var a=t(22),r=Math.exp;a(a.S,"Math",{cosh:function(t){return(r(t=+t)+r(-t))/2}})},{22:22}],103:[function(t,e,n){var a=t(22);a(a.S,"Math",{expm1:t(49)})},{22:22,49:49}],104:[function(t,e,n){var a=t(22),r=t(51),i=Math.pow,o=i(2,-52),s=i(2,-23),u=i(2,127)*(2-s),p=i(2,-126),c=function(t){return t+1/o-1/o};a(a.S,"Math",{fround:function(t){var e,n,a=Math.abs(t),i=r(t);return p>a?i*c(a/p/s)*p*s:(e=(1+s/o)*a,n=e-(e-a),n>u||n!=n?i*(1/0):i*n)}})},{22:22,51:51}],105:[function(t,e,n){var a=t(22),r=Math.abs;a(a.S,"Math",{hypot:function(t,e){for(var n,a,i=0,o=0,s=arguments,u=s.length,p=0;u>o;)n=r(s[o++]),n>p?(a=p/n,i=i*a*a+1,p=n):n>0?(a=n/p,i+=a*a):i+=n;return p===1/0?1/0:p*Math.sqrt(i)}})},{22:22}],106:[function(t,e,n){var a=t(22),r=Math.imul;a(a.S+a.F*t(24)(function(){return-5!=r(4294967295,5)||2!=r.length}),"Math",{imul:function(t,e){var n=65535,a=+t,r=+e,i=n&a,o=n&r;return 0|i*o+((n&a>>>16)*o+i*(n&r>>>16)<<16>>>0)}})},{22:22,24:24}],107:[function(t,e,n){var a=t(22);a(a.S,"Math",{log10:function(t){return Math.log(t)/Math.LN10}})},{22:22}],108:[function(t,e,n){var a=t(22);a(a.S,"Math",{log1p:t(50)})},{22:22,50:50}],109:[function(t,e,n){var a=t(22);a(a.S,"Math",{log2:function(t){return Math.log(t)/Math.LN2}})},{22:22}],110:[function(t,e,n){var a=t(22);a(a.S,"Math",{sign:t(51)})},{22:22,51:51}],111:[function(t,e,n){var a=t(22),r=t(49),i=Math.exp;a(a.S+a.F*t(24)(function(){return-2e-17!=!Math.sinh(-2e-17)}),"Math",{sinh:function(t){return Math.abs(t=+t)<1?(r(t)-r(-t))/2:(i(t-1)-i(-t-1))*(Math.E/2)}})},{22:22,24:24,49:49}],112:[function(t,e,n){var a=t(22),r=t(49),i=Math.exp;a(a.S,"Math",{tanh:function(t){var e=r(t=+t),n=r(-t);return e==1/0?1:n==1/0?-1:(e-n)/(i(t)+i(-t))}})},{22:22,49:49}],113:[function(t,e,n){var a=t(22);a(a.S,"Math",{trunc:function(t){return(t>0?Math.floor:Math.ceil)(t)}})},{22:22}],114:[function(t,e,n){"use strict";var a=t(46),r=t(29),i=t(30),o=t(11),s=t(81),u=t(24),p=t(74).trim,c="Number",l=r[c],f=l,d=l.prototype,h=o(a.create(d))==c,m="trim"in String.prototype,v=function(t){
+var e=s(t,!1);if("string"==typeof e&&e.length>2){e=m?e.trim():p(e,3);var n,a,r,i=e.charCodeAt(0);if(43===i||45===i){if(n=e.charCodeAt(2),88===n||120===n)return NaN}else if(48===i){switch(e.charCodeAt(1)){case 66:case 98:a=2,r=49;break;case 79:case 111:a=8,r=55;break;default:return+e}for(var o,u=e.slice(2),c=0,l=u.length;l>c;c++)if(o=u.charCodeAt(c),48>o||o>r)return NaN;return parseInt(u,a)}}return+e};l(" 0o1")&&l("0b1")&&!l("+0x1")||(l=function(t){var e=arguments.length<1?0:t,n=this;return n instanceof l&&(h?u(function(){d.valueOf.call(n)}):o(n)!=c)?new f(v(e)):v(e)},a.each.call(t(19)?a.getNames(f):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),function(t){i(f,t)&&!i(l,t)&&a.setDesc(l,t,a.getDesc(f,t))}),l.prototype=d,d.constructor=l,t(61)(r,c,l))},{11:11,19:19,24:24,29:29,30:30,46:46,61:61,74:74,81:81}],115:[function(t,e,n){var a=t(22);a(a.S,"Number",{EPSILON:Math.pow(2,-52)})},{22:22}],116:[function(t,e,n){var a=t(22),r=t(29).isFinite;a(a.S,"Number",{isFinite:function(t){return"number"==typeof t&&r(t)}})},{22:22,29:29}],117:[function(t,e,n){var a=t(22);a(a.S,"Number",{isInteger:t(37)})},{22:22,37:37}],118:[function(t,e,n){var a=t(22);a(a.S,"Number",{isNaN:function(t){return t!=t}})},{22:22}],119:[function(t,e,n){var a=t(22),r=t(37),i=Math.abs;a(a.S,"Number",{isSafeInteger:function(t){return r(t)&&i(t)<=9007199254740991}})},{22:22,37:37}],120:[function(t,e,n){var a=t(22);a(a.S,"Number",{MAX_SAFE_INTEGER:9007199254740991})},{22:22}],121:[function(t,e,n){var a=t(22);a(a.S,"Number",{MIN_SAFE_INTEGER:-9007199254740991})},{22:22}],122:[function(t,e,n){var a=t(22);a(a.S,"Number",{parseFloat:parseFloat})},{22:22}],123:[function(t,e,n){var a=t(22);a(a.S,"Number",{parseInt:parseInt})},{22:22}],124:[function(t,e,n){var a=t(22);a(a.S+a.F,"Object",{assign:t(53)})},{22:22,53:53}],125:[function(t,e,n){var a=t(38);t(54)("freeze",function(t){return function(e){return t&&a(e)?t(e):e}})},{38:38,54:54}],126:[function(t,e,n){var a=t(78);t(54)("getOwnPropertyDescriptor",function(t){return function(e,n){return t(a(e),n)}})},{54:54,78:78}],127:[function(t,e,n){t(54)("getOwnPropertyNames",function(){return t(28).get})},{28:28,54:54}],128:[function(t,e,n){var a=t(80);t(54)("getPrototypeOf",function(t){return function(e){return t(a(e))}})},{54:54,80:80}],129:[function(t,e,n){var a=t(38);t(54)("isExtensible",function(t){return function(e){return a(e)?t?t(e):!0:!1}})},{38:38,54:54}],130:[function(t,e,n){var a=t(38);t(54)("isFrozen",function(t){return function(e){return a(e)?t?t(e):!1:!0}})},{38:38,54:54}],131:[function(t,e,n){var a=t(38);t(54)("isSealed",function(t){return function(e){return a(e)?t?t(e):!1:!0}})},{38:38,54:54}],132:[function(t,e,n){var a=t(22);a(a.S,"Object",{is:t(63)})},{22:22,63:63}],133:[function(t,e,n){var a=t(80);t(54)("keys",function(t){return function(e){return t(a(e))}})},{54:54,80:80}],134:[function(t,e,n){var a=t(38);t(54)("preventExtensions",function(t){return function(e){return t&&a(e)?t(e):e}})},{38:38,54:54}],135:[function(t,e,n){var a=t(38);t(54)("seal",function(t){return function(e){return t&&a(e)?t(e):e}})},{38:38,54:54}],136:[function(t,e,n){var a=t(22);a(a.S,"Object",{setPrototypeOf:t(64).set})},{22:22,64:64}],137:[function(t,e,n){"use strict";var a=t(10),r={};r[t(83)("toStringTag")]="z",r+""!="[object z]"&&t(61)(Object.prototype,"toString",function(){return"[object "+a(this)+"]"},!0)},{10:10,61:61,83:83}],138:[function(t,e,n){"use strict";var a,r=t(46),i=t(48),o=t(29),s=t(17),u=t(10),p=t(22),c=t(38),l=t(4),f=t(2),d=t(69),h=t(27),m=t(64).set,v=t(63),g=t(83)("species"),b=t(68),y=t(52),x="Promise",_=o.process,w="process"==u(_),k=o[x],E=function(){},S=function(t){var e,n=new k(E);return t&&(n.constructor=function(t){t(E,E)}),(e=k.resolve(n))["catch"](E),e===n},C=function(){function e(t){var n=new k(t);return m(n,e.prototype),n}var n=!1;try{if(n=k&&k.resolve&&S(),m(e,k),e.prototype=r.create(k.prototype,{constructor:{value:e}}),e.resolve(5).then(function(){})instanceof e||(n=!1),n&&t(19)){var a=!1;k.resolve(r.setDesc({},"then",{get:function(){a=!0}})),n=a}}catch(i){n=!1}return n}(),P=function(t,e){return i&&t===k&&e===a?!0:v(t,e)},A=function(t){var e=l(t)[g];return void 0!=e?e:t},O=function(t){var e;return c(t)&&"function"==typeof(e=t.then)?e:!1},T=function(t){var e,n;this.promise=new t(function(t,a){if(void 0!==e||void 0!==n)throw TypeError("Bad Promise constructor");e=t,n=a}),this.resolve=f(e),this.reject=f(n)},j=function(t){try{t()}catch(e){return{error:e}}},R=function(t,e){if(!t.n){t.n=!0;var n=t.c;y(function(){for(var a=t.v,r=1==t.s,i=0,s=function(e){var n,i,o=r?e.ok:e.fail,s=e.resolve,u=e.reject;try{o?(r||(t.h=!0),n=o===!0?a:o(a),n===e.promise?u(TypeError("Promise-chain cycle")):(i=O(n))?i.call(n,s,u):s(n)):u(a)}catch(p){u(p)}};n.length>i;)s(n[i++]);n.length=0,t.n=!1,e&&setTimeout(function(){var e,n,r=t.p;M(r)&&(w?_.emit("unhandledRejection",a,r):(e=o.onunhandledrejection)?e({promise:r,reason:a}):(n=o.console)&&n.error&&n.error("Unhandled promise rejection",a)),t.a=void 0},1)})}},M=function(t){var e,n=t._d,a=n.a||n.c,r=0;if(n.h)return!1;for(;a.length>r;)if(e=a[r++],e.fail||!M(e.promise))return!1;return!0},L=function(t){var e=this;e.d||(e.d=!0,e=e.r||e,e.v=t,e.s=2,e.a=e.c.slice(),R(e,!0))},D=function(t){var e,n=this;if(!n.d){n.d=!0,n=n.r||n;try{if(n.p===t)throw TypeError("Promise can't be resolved itself");(e=O(t))?y(function(){var a={r:n,d:!1};try{e.call(t,s(D,a,1),s(L,a,1))}catch(r){L.call(a,r)}}):(n.v=t,n.s=1,R(n,!1))}catch(a){L.call({r:n,d:!1},a)}}};C||(k=function(t){f(t);var e=this._d={p:d(this,k,x),c:[],a:void 0,s:0,d:!1,v:void 0,h:!1,n:!1};try{t(s(D,e,1),s(L,e,1))}catch(n){L.call(e,n)}},t(60)(k.prototype,{then:function(t,e){var n=new T(b(this,k)),a=n.promise,r=this._d;return n.ok="function"==typeof t?t:!0,n.fail="function"==typeof e&&e,r.c.push(n),r.a&&r.a.push(n),r.s&&R(r,!1),a},"catch":function(t){return this.then(void 0,t)}})),p(p.G+p.W+p.F*!C,{Promise:k}),t(66)(k,x),t(65)(x),a=t(16)[x],p(p.S+p.F*!C,x,{reject:function(t){var e=new T(this),n=e.reject;return n(t),e.promise}}),p(p.S+p.F*(!C||S(!0)),x,{resolve:function(t){if(t instanceof k&&P(t.constructor,this))return t;var e=new T(this),n=e.resolve;return n(t),e.promise}}),p(p.S+p.F*!(C&&t(43)(function(t){k.all(t)["catch"](function(){})})),x,{all:function(t){var e=A(this),n=new T(e),a=n.resolve,i=n.reject,o=[],s=j(function(){h(t,!1,o.push,o);var n=o.length,s=Array(n);n?r.each.call(o,function(t,r){var o=!1;e.resolve(t).then(function(t){o||(o=!0,s[r]=t,--n||a(s))},i)}):a(s)});return s&&i(s.error),n.promise},race:function(t){var e=A(this),n=new T(e),a=n.reject,r=j(function(){h(t,!1,function(t){e.resolve(t).then(n.resolve,a)})});return r&&a(r.error),n.promise}})},{10:10,16:16,17:17,19:19,2:2,22:22,27:27,29:29,38:38,4:4,43:43,46:46,48:48,52:52,60:60,63:63,64:64,65:65,66:66,68:68,69:69,83:83}],139:[function(t,e,n){var a=t(22),r=Function.apply,i=t(4);a(a.S,"Reflect",{apply:function(t,e,n){return r.call(t,e,i(n))}})},{22:22,4:4}],140:[function(t,e,n){var a=t(46),r=t(22),i=t(2),o=t(4),s=t(38),u=Function.bind||t(16).Function.prototype.bind;r(r.S+r.F*t(24)(function(){function t(){}return!(Reflect.construct(function(){},[],t)instanceof t)}),"Reflect",{construct:function(t,e){i(t),o(e);var n=arguments.length<3?t:i(arguments[2]);if(t==n){switch(e.length){case 0:return new t;case 1:return new t(e[0]);case 2:return new t(e[0],e[1]);case 3:return new t(e[0],e[1],e[2]);case 4:return new t(e[0],e[1],e[2],e[3])}var r=[null];return r.push.apply(r,e),new(u.apply(t,r))}var p=n.prototype,c=a.create(s(p)?p:Object.prototype),l=Function.apply.call(t,c,e);return s(l)?l:c}})},{16:16,2:2,22:22,24:24,38:38,4:4,46:46}],141:[function(t,e,n){var a=t(46),r=t(22),i=t(4);r(r.S+r.F*t(24)(function(){Reflect.defineProperty(a.setDesc({},1,{value:1}),1,{value:2})}),"Reflect",{defineProperty:function(t,e,n){i(t);try{return a.setDesc(t,e,n),!0}catch(r){return!1}}})},{22:22,24:24,4:4,46:46}],142:[function(t,e,n){var a=t(22),r=t(46).getDesc,i=t(4);a(a.S,"Reflect",{deleteProperty:function(t,e){var n=r(i(t),e);return n&&!n.configurable?!1:delete t[e]}})},{22:22,4:4,46:46}],143:[function(t,e,n){"use strict";var a=t(22),r=t(4),i=function(t){this._t=r(t),this._i=0;var e,n=this._k=[];for(e in t)n.push(e)};t(41)(i,"Object",function(){var t,e=this,n=e._k;do if(e._i>=n.length)return{value:void 0,done:!0};while(!((t=n[e._i++])in e._t));return{value:t,done:!1}}),a(a.S,"Reflect",{enumerate:function(t){return new i(t)}})},{22:22,4:4,41:41}],144:[function(t,e,n){var a=t(46),r=t(22),i=t(4);r(r.S,"Reflect",{getOwnPropertyDescriptor:function(t,e){return a.getDesc(i(t),e)}})},{22:22,4:4,46:46}],145:[function(t,e,n){var a=t(22),r=t(46).getProto,i=t(4);a(a.S,"Reflect",{getPrototypeOf:function(t){return r(i(t))}})},{22:22,4:4,46:46}],146:[function(t,e,n){function a(t,e){var n,o,p=arguments.length<3?t:arguments[2];return u(t)===p?t[e]:(n=r.getDesc(t,e))?i(n,"value")?n.value:void 0!==n.get?n.get.call(p):void 0:s(o=r.getProto(t))?a(o,e,p):void 0}var r=t(46),i=t(30),o=t(22),s=t(38),u=t(4);o(o.S,"Reflect",{get:a})},{22:22,30:30,38:38,4:4,46:46}],147:[function(t,e,n){var a=t(22);a(a.S,"Reflect",{has:function(t,e){return e in t}})},{22:22}],148:[function(t,e,n){var a=t(22),r=t(4),i=Object.isExtensible;a(a.S,"Reflect",{isExtensible:function(t){return r(t),i?i(t):!0}})},{22:22,4:4}],149:[function(t,e,n){var a=t(22);a(a.S,"Reflect",{ownKeys:t(56)})},{22:22,56:56}],150:[function(t,e,n){var a=t(22),r=t(4),i=Object.preventExtensions;a(a.S,"Reflect",{preventExtensions:function(t){r(t);try{return i&&i(t),!0}catch(e){return!1}}})},{22:22,4:4}],151:[function(t,e,n){var a=t(22),r=t(64);r&&a(a.S,"Reflect",{setPrototypeOf:function(t,e){r.check(t,e);try{return r.set(t,e),!0}catch(n){return!1}}})},{22:22,64:64}],152:[function(t,e,n){function a(t,e,n){var o,c,l=arguments.length<4?t:arguments[3],f=r.getDesc(u(t),e);if(!f){if(p(c=r.getProto(t)))return a(c,e,n,l);f=s(0)}return i(f,"value")?f.writable!==!1&&p(l)?(o=r.getDesc(l,e)||s(0),o.value=n,r.setDesc(l,e,o),!0):!1:void 0===f.set?!1:(f.set.call(l,n),!0)}var r=t(46),i=t(30),o=t(22),s=t(59),u=t(4),p=t(38);o(o.S,"Reflect",{set:a})},{22:22,30:30,38:38,4:4,46:46,59:59}],153:[function(t,e,n){var a=t(46),r=t(29),i=t(39),o=t(26),s=r.RegExp,u=s,p=s.prototype,c=/a/g,l=/a/g,f=new s(c)!==c;!t(19)||f&&!t(24)(function(){return l[t(83)("match")]=!1,s(c)!=c||s(l)==l||"/a/i"!=s(c,"i")})||(s=function(t,e){var n=i(t),a=void 0===e;return this instanceof s||!n||t.constructor!==s||!a?f?new u(n&&!a?t.source:t,e):u((n=t instanceof s)?t.source:t,n&&a?o.call(t):e):t},a.each.call(a.getNames(u),function(t){t in s||a.setDesc(s,t,{configurable:!0,get:function(){return u[t]},set:function(e){u[t]=e}})}),p.constructor=s,s.prototype=p,t(61)(r,"RegExp",s)),t(65)("RegExp")},{19:19,24:24,26:26,29:29,39:39,46:46,61:61,65:65,83:83}],154:[function(t,e,n){var a=t(46);t(19)&&"g"!=/./g.flags&&a.setDesc(RegExp.prototype,"flags",{configurable:!0,get:t(26)})},{19:19,26:26,46:46}],155:[function(t,e,n){t(25)("match",1,function(t,e){return function(n){"use strict";var a=t(this),r=void 0==n?void 0:n[e];return void 0!==r?r.call(n,a):RegExp(n)[e](a+"")}})},{25:25}],156:[function(t,e,n){t(25)("replace",2,function(t,e,n){return function(a,r){"use strict";var i=t(this),o=void 0==a?void 0:a[e];return void 0!==o?o.call(a,i,r):n.call(i+"",a,r)}})},{25:25}],157:[function(t,e,n){t(25)("search",1,function(t,e){return function(n){"use strict";var a=t(this),r=void 0==n?void 0:n[e];return void 0!==r?r.call(n,a):RegExp(n)[e](a+"")}})},{25:25}],158:[function(t,e,n){t(25)("split",2,function(t,e,n){return function(a,r){"use strict";var i=t(this),o=void 0==a?void 0:a[e];return void 0!==o?o.call(a,i,r):n.call(i+"",a,r)}})},{25:25}],159:[function(t,e,n){"use strict";var a=t(12);t(15)("Set",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return a.def(this,t=0===t?0:t,t)}},a)},{12:12,15:15}],160:[function(t,e,n){"use strict";var a=t(22),r=t(70)(!1);a(a.P,"String",{codePointAt:function(t){return r(this,t)}})},{22:22,70:70}],161:[function(t,e,n){"use strict";var a=t(22),r=t(79),i=t(71),o="endsWith",s=""[o];a(a.P+a.F*t(23)(o),"String",{endsWith:function(t){var e=i(this,t,o),n=arguments,a=n.length>1?n[1]:void 0,u=r(e.length),p=void 0===a?u:Math.min(r(a),u),c=t+"";return s?s.call(e,c,p):e.slice(p-c.length,p)===c}})},{22:22,23:23,71:71,79:79}],162:[function(t,e,n){var a=t(22),r=t(76),i=String.fromCharCode,o=String.fromCodePoint;a(a.S+a.F*(!!o&&1!=o.length),"String",{fromCodePoint:function(t){for(var e,n=[],a=arguments,o=a.length,s=0;o>s;){if(e=+a[s++],r(e,1114111)!==e)throw RangeError(e+" is not a valid code point");n.push(65536>e?i(e):i(((e-=65536)>>10)+55296,e%1024+56320))}return n.join("")}})},{22:22,76:76}],163:[function(t,e,n){"use strict";var a=t(22),r=t(71),i="includes";a(a.P+a.F*t(23)(i),"String",{includes:function(t){return!!~r(this,t,i).indexOf(t,arguments.length>1?arguments[1]:void 0)}})},{22:22,23:23,71:71}],164:[function(t,e,n){"use strict";var a=t(70)(!0);t(42)(String,"String",function(t){this._t=t+"",this._i=0},function(){var t,e=this._t,n=this._i;return n>=e.length?{value:void 0,done:!0}:(t=a(e,n),this._i+=t.length,{value:t,done:!1})})},{42:42,70:70}],165:[function(t,e,n){var a=t(22),r=t(78),i=t(79);a(a.S,"String",{raw:function(t){for(var e=r(t.raw),n=i(e.length),a=arguments,o=a.length,s=[],u=0;n>u;)s.push(e[u++]+""),o>u&&s.push(a[u]+"");return s.join("")}})},{22:22,78:78,79:79}],166:[function(t,e,n){var a=t(22);a(a.P,"String",{repeat:t(73)})},{22:22,73:73}],167:[function(t,e,n){"use strict";var a=t(22),r=t(79),i=t(71),o="startsWith",s=""[o];a(a.P+a.F*t(23)(o),"String",{startsWith:function(t){var e=i(this,t,o),n=arguments,a=r(Math.min(n.length>1?n[1]:void 0,e.length)),u=t+"";return s?s.call(e,u,a):e.slice(a,a+u.length)===u}})},{22:22,23:23,71:71,79:79}],168:[function(t,e,n){"use strict";t(74)("trim",function(t){return function(){return t(this,3)}})},{74:74}],169:[function(t,e,n){"use strict";var a=t(46),r=t(29),i=t(30),o=t(19),s=t(22),u=t(61),p=t(24),c=t(67),l=t(66),f=t(82),d=t(83),h=t(47),m=t(28),v=t(21),g=t(36),b=t(4),y=t(78),x=t(59),_=a.getDesc,w=a.setDesc,k=a.create,E=m.get,S=r.Symbol,C=r.JSON,P=C&&C.stringify,A=!1,O=d("_hidden"),T=a.isEnum,j=c("symbol-registry"),R=c("symbols"),M="function"==typeof S,L=Object.prototype,D=o&&p(function(){return 7!=k(w({},"a",{get:function(){return w(this,"a",{value:7}).a}})).a})?function(t,e,n){var a=_(L,e);a&&delete L[e],w(t,e,n),a&&t!==L&&w(L,e,a)}:w,N=function(t){var e=R[t]=k(S.prototype);return e._k=t,o&&A&&D(L,t,{configurable:!0,set:function(e){i(this,O)&&i(this[O],t)&&(this[O][t]=!1),D(this,t,x(1,e))}}),e},F=function(t){return"symbol"==typeof t},I=function(t,e,n){return n&&i(R,e)?(n.enumerable?(i(t,O)&&t[O][e]&&(t[O][e]=!1),n=k(n,{enumerable:x(0,!1)})):(i(t,O)||w(t,O,x(1,{})),t[O][e]=!0),D(t,e,n)):w(t,e,n)},B=function(t,e){b(t);for(var n,a=v(e=y(e)),r=0,i=a.length;i>r;)I(t,n=a[r++],e[n]);return t},q=function(t,e){return void 0===e?k(t):B(k(t),e)},U=function(t){var e=T.call(this,t);return e||!i(this,t)||!i(R,t)||i(this,O)&&this[O][t]?e:!0},G=function(t,e){var n=_(t=y(t),e);return!n||!i(R,e)||i(t,O)&&t[O][e]||(n.enumerable=!0),n},V=function(t){for(var e,n=E(y(t)),a=[],r=0;n.length>r;)i(R,e=n[r++])||e==O||a.push(e);return a},z=function(t){for(var e,n=E(y(t)),a=[],r=0;n.length>r;)i(R,e=n[r++])&&a.push(R[e]);return a},W=function(t){if(void 0!==t&&!F(t)){for(var e,n,a=[t],r=1,i=arguments;i.length>r;)a.push(i[r++]);return e=a[1],"function"==typeof e&&(n=e),(n||!g(e))&&(e=function(t,e){return n&&(e=n.call(this,t,e)),F(e)?void 0:e}),a[1]=e,P.apply(C,a)}},H=p(function(){var t=S();return"[null]"!=P([t])||"{}"!=P({a:t})||"{}"!=P(Object(t))});M||(S=function(){if(F(this))throw TypeError("Symbol is not a constructor");return N(f(arguments.length>0?arguments[0]:void 0))},u(S.prototype,"toString",function(){return this._k}),F=function(t){return t instanceof S},a.create=q,a.isEnum=U,a.getDesc=G,a.setDesc=I,a.setDescs=B,a.getNames=m.get=V,a.getSymbols=z,o&&!t(48)&&u(L,"propertyIsEnumerable",U,!0));var Q={"for":function(t){return i(j,t+="")?j[t]:j[t]=S(t)},keyFor:function(t){return h(j,t)},useSetter:function(){A=!0},useSimple:function(){A=!1}};a.each.call("hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),function(t){var e=d(t);Q[t]=M?e:N(e)}),A=!0,s(s.G+s.W,{Symbol:S}),s(s.S,"Symbol",Q),s(s.S+s.F*!M,"Object",{create:q,defineProperty:I,defineProperties:B,getOwnPropertyDescriptor:G,getOwnPropertyNames:V,getOwnPropertySymbols:z}),C&&s(s.S+s.F*(!M||H),"JSON",{stringify:W}),l(S,"Symbol"),l(Math,"Math",!0),l(r.JSON,"JSON",!0)},{19:19,21:21,22:22,24:24,28:28,29:29,30:30,36:36,4:4,46:46,47:47,48:48,59:59,61:61,66:66,67:67,78:78,82:82,83:83}],170:[function(t,e,n){"use strict";var a=t(46),r=t(61),i=t(14),o=t(38),s=t(30),u=i.frozenStore,p=i.WEAK,c=Object.isExtensible||o,l={},f=t(15)("WeakMap",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{get:function(t){if(o(t)){if(!c(t))return u(this).get(t);if(s(t,p))return t[p][this._i]}},set:function(t,e){return i.def(this,t,e)}},i,!0,!0);7!=(new f).set((Object.freeze||Object)(l),7).get(l)&&a.each.call(["delete","has","get","set"],function(t){var e=f.prototype,n=e[t];r(e,t,function(e,a){if(o(e)&&!c(e)){var r=u(this)[t](e,a);return"set"==t?this:r}return n.call(this,e,a)})})},{14:14,15:15,30:30,38:38,46:46,61:61}],171:[function(t,e,n){"use strict";var a=t(14);t(15)("WeakSet",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return a.def(this,t,!0)}},a,!1,!0)},{14:14,15:15}],172:[function(t,e,n){"use strict";var a=t(22),r=t(7)(!0);a(a.P,"Array",{includes:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0)}}),t(3)("includes")},{22:22,3:3,7:7}],173:[function(t,e,n){var a=t(22);a(a.P,"Map",{toJSON:t(13)("Map")})},{13:13,22:22}],174:[function(t,e,n){var a=t(22),r=t(55)(!0);a(a.S,"Object",{entries:function(t){return r(t)}})},{22:22,55:55}],175:[function(t,e,n){var a=t(46),r=t(22),i=t(56),o=t(78),s=t(59);r(r.S,"Object",{getOwnPropertyDescriptors:function(t){for(var e,n,r=o(t),u=a.setDesc,p=a.getDesc,c=i(r),l={},f=0;c.length>f;)n=p(r,e=c[f++]),e in l?u(l,e,s(0,n)):l[e]=n;return l}})},{22:22,46:46,56:56,59:59,78:78}],176:[function(t,e,n){var a=t(22),r=t(55)(!1);a(a.S,"Object",{values:function(t){return r(t)}})},{22:22,55:55}],177:[function(t,e,n){var a=t(22),r=t(62)(/[\\^$*+?.()|[\]{}]/g,"\\$&");a(a.S,"RegExp",{escape:function(t){return r(t)}})},{22:22,62:62}],178:[function(t,e,n){var a=t(22);a(a.P,"Set",{toJSON:t(13)("Set")})},{13:13,22:22}],179:[function(t,e,n){"use strict";var a=t(22),r=t(70)(!0);a(a.P,"String",{at:function(t){return r(this,t)}})},{22:22,70:70}],180:[function(t,e,n){"use strict";var a=t(22),r=t(72);a(a.P,"String",{padLeft:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0,!0)}})},{22:22,72:72}],181:[function(t,e,n){"use strict";var a=t(22),r=t(72);a(a.P,"String",{padRight:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0,!1)}})},{22:22,72:72}],182:[function(t,e,n){"use strict";t(74)("trimLeft",function(t){return function(){return t(this,1)}})},{74:74}],183:[function(t,e,n){"use strict";t(74)("trimRight",function(t){return function(){return t(this,2)}})},{74:74}],184:[function(t,e,n){var a=t(46),r=t(22),i=t(17),o=t(16).Array||Array,s={},u=function(t,e){a.each.call(t.split(","),function(t){void 0==e&&t in o?s[t]=o[t]:t in[]&&(s[t]=i(Function.call,[][t],e))})};u("pop,reverse,shift,keys,values,entries",1),u("indexOf,every,some,forEach,map,filter,find,findIndex,includes",3),u("join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill"),r(r.S,"Array",s)},{16:16,17:17,22:22,46:46}],185:[function(t,e,n){t(91);var a=t(29),r=t(31),i=t(45),o=t(83)("iterator"),s=a.NodeList,u=a.HTMLCollection,p=s&&s.prototype,c=u&&u.prototype,l=i.NodeList=i.HTMLCollection=i.Array;p&&!p[o]&&r(p,o,l),c&&!c[o]&&r(c,o,l)},{29:29,31:31,45:45,83:83,91:91}],186:[function(t,e,n){var a=t(22),r=t(75);a(a.G+a.B,{setImmediate:r.set,clearImmediate:r.clear})},{22:22,75:75}],187:[function(t,e,n){var a=t(29),r=t(22),i=t(33),o=t(57),s=a.navigator,u=!!s&&/MSIE .\./.test(s.userAgent),p=function(t){return u?function(e,n){return t(i(o,[].slice.call(arguments,2),"function"==typeof e?e:Function(e)),n)}:t};r(r.G+r.B+r.F*u,{setTimeout:p(a.setTimeout),setInterval:p(a.setInterval)})},{22:22,29:29,33:33,57:57}],188:[function(t,e,n){t(85),t(169),t(124),t(132),t(136),t(137),t(125),t(135),t(134),t(130),t(131),t(129),t(126),t(128),t(133),t(127),t(95),t(94),t(114),t(115),t(116),t(117),t(118),t(119),t(120),t(121),t(122),t(123),t(97),t(98),t(99),t(100),t(101),t(102),t(103),t(104),t(105),t(106),t(107),t(108),t(109),t(110),t(111),t(112),t(113),t(162),t(165),t(168),t(164),t(160),t(161),t(163),t(166),t(167),t(90),t(92),t(91),t(93),t(86),t(87),t(89),t(88),t(153),t(154),t(155),t(156),t(157),t(158),t(138),t(96),t(159),t(170),t(171),t(139),t(140),t(141),t(142),t(143),t(146),t(144),t(145),t(147),t(148),t(149),t(150),t(152),t(151),t(172),t(179),t(180),t(181),t(182),t(183),t(177),t(175),t(176),t(174),t(173),t(178),t(184),t(187),t(186),t(185),e.exports=t(16)},{100:100,101:101,102:102,103:103,104:104,105:105,106:106,107:107,108:108,109:109,110:110,111:111,112:112,113:113,114:114,115:115,116:116,117:117,118:118,119:119,120:120,121:121,122:122,123:123,124:124,125:125,126:126,127:127,128:128,129:129,130:130,131:131,132:132,133:133,134:134,135:135,136:136,137:137,138:138,139:139,140:140,141:141,142:142,143:143,144:144,145:145,146:146,147:147,148:148,149:149,150:150,151:151,152:152,153:153,154:154,155:155,156:156,157:157,158:158,159:159,16:16,160:160,161:161,162:162,163:163,164:164,165:165,166:166,167:167,168:168,169:169,170:170,171:171,172:172,173:173,174:174,175:175,176:176,177:177,178:178,179:179,180:180,181:181,182:182,183:183,184:184,185:185,186:186,187:187,85:85,86:86,87:87,88:88,89:89,90:90,91:91,92:92,93:93,94:94,95:95,96:96,97:97,98:98,99:99}],189:[function(t,e,n){(function(n){(function(t,n){!function(n){"use strict";function a(t,e,n,a){var r=Object.create((e||i).prototype),o=new h(a||[]);return r._invoke=l(t,n,o),r}function r(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(a){return{type:"throw",arg:a}}}function i(){}function o(){}function s(){}function u(t){["next","throw","return"].forEach(function(e){t[e]=function(t){return this._invoke(e,t)}})}function p(t){this.arg=t}function c(e){function n(t,n){var a=e[t](n),r=a.value;return r instanceof p?Promise.resolve(r.arg).then(i,o):Promise.resolve(r).then(function(t){return a.value=t,a})}function a(t,e){function a(){return n(t,e)}return r=r?r.then(a,a):new Promise(function(t){t(a())})}"object"==typeof t&&t.domain&&(n=t.domain.bind(n));var r,i=n.bind(e,"next"),o=n.bind(e,"throw");n.bind(e,"return");this._invoke=a}function l(t,e,n){var a=w;return function(i,o){if(a===E)throw Error("Generator is already running");if(a===S){if("throw"===i)throw o;return v()}for(;;){var s=n.delegate;if(s){if("return"===i||"throw"===i&&s.iterator[i]===g){n.delegate=null;var u=s.iterator["return"];if(u){var p=r(u,s.iterator,o);if("throw"===p.type){i="throw",o=p.arg;continue}}if("return"===i)continue}var p=r(s.iterator[i],s.iterator,o);if("throw"===p.type){n.delegate=null,i="throw",o=p.arg;continue}i="next",o=g;var c=p.arg;if(!c.done)return a=k,c;n[s.resultName]=c.value,n.next=s.nextLoc,n.delegate=null}if("next"===i)n._sent=o,a===k?n.sent=o:n.sent=g;else if("throw"===i){if(a===w)throw a=S,o;n.dispatchException(o)&&(i="next",o=g)}else"return"===i&&n.abrupt("return",o);a=E;var p=r(t,e,n);if("normal"===p.type){a=n.done?S:k;var c={value:p.arg,done:n.done};if(p.arg!==C)return c;n.delegate&&"next"===i&&(o=g)}else"throw"===p.type&&(a=S,i="throw",o=p.arg)}}}function f(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function d(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function h(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(f,this),this.reset(!0)}function m(t){if(t){var e=t[y];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,a=function r(){for(;++n=0;--a){var r=this.tryEntries[a],i=r.completion;if("root"===r.tryLoc)return e("end");if(r.tryLoc<=this.prev){var o=b.call(r,"catchLoc"),s=b.call(r,"finallyLoc");if(o&&s){if(this.prev=0;--n){var a=this.tryEntries[n];if(a.tryLoc<=this.prev&&b.call(a,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),d(n),C}},"catch":function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var a=n.completion;if("throw"===a.type){var r=a.arg;d(n)}return r}}throw Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:m(t),resultName:e,nextLoc:n},C}}}("object"==typeof n?n:"object"==typeof window?window:"object"==typeof self?self:this)}).call(this,t(202),void 0!==n?n:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{202:202}],190:[function(t,e,n){!function(t){"use strict";function e(){return c.createDocumentFragment()}function n(t){return c.createElement(t)}function a(t){if(1===t.length)return r(t[0]);for(var n=e(),a=B.call(t),i=0;i-1}}([].indexOf||function(t){for(q=this.length;q--&&this[q]!==t;);return q}),item:function(t){return this[t]||null},remove:function(){for(var t,e=0;e=u?e(i):document.fonts.load(p(i,i.family),s).then(function(e){1<=e.length?t(i):setTimeout(f,25)},function(){e(i)})};f()}else n(function(){function n(){var e;(e=-1!=v&&-1!=g||-1!=v&&-1!=b||-1!=g&&-1!=b)&&((e=v!=g&&v!=b&&g!=b)||(null===l&&(e=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent),l=!!e&&(536>parseInt(e[1],10)||536===parseInt(e[1],10)&&11>=parseInt(e[2],10))),e=l&&(v==y&&g==y&&b==y||v==x&&g==x&&b==x||v==_&&g==_&&b==_)),e=!e),e&&(null!==w.parentNode&&w.parentNode.removeChild(w),clearTimeout(k),t(i))}function f(){if((new Date).getTime()-c>=u)null!==w.parentNode&&w.parentNode.removeChild(w),e(i);else{var t=document.hidden;(!0===t||void 0===t)&&(v=d.a.offsetWidth,g=h.a.offsetWidth,b=m.a.offsetWidth,n()),k=setTimeout(f,50)}}var d=new a(s),h=new a(s),m=new a(s),v=-1,g=-1,b=-1,y=-1,x=-1,_=-1,w=document.createElement("div"),k=0;w.dir="ltr",r(d,p(i,"sans-serif")),r(h,p(i,"serif")),r(m,p(i,"monospace")),w.appendChild(d.a),w.appendChild(h.a),w.appendChild(m.a),document.body.appendChild(w),y=d.a.offsetWidth,x=h.a.offsetWidth,_=m.a.offsetWidth,f(),o(d,function(t){v=t,n()}),r(d,p(i,'"'+i.family+'",sans-serif')),o(h,function(t){g=t,n()}),r(h,p(i,'"'+i.family+'",serif')),o(m,function(t){b=t,n()}),r(m,p(i,'"'+i.family+'",monospace'))})})},window.FontFaceObserver=s,window.FontFaceObserver.prototype.check=s.prototype.a,void 0!==e&&(e.exports=window.FontFaceObserver)}()},{}],193:[function(t,e,n){!function(t,n){function a(t,e){var n=t.createElement("p"),a=t.getElementsByTagName("head")[0]||t.documentElement;return n.innerHTML="x",a.insertBefore(n.lastChild,a.firstChild)}function r(){var t=x.elements;return"string"==typeof t?t.split(" "):t}function i(t,e){var n=x.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof t&&(t=t.join(" ")),x.elements=n+" "+t,c(e)}function o(t){var e=y[t[g]];return e||(e={},b++,t[g]=b,y[b]=e),e}function s(t,e,a){if(e||(e=n),f)return e.createElement(t);a||(a=o(e));var r;return r=a.cache[t]?a.cache[t].cloneNode():v.test(t)?(a.cache[t]=a.createElem(t)).cloneNode():a.createElem(t),!r.canHaveChildren||m.test(t)||r.tagUrn?r:a.frag.appendChild(r)}function u(t,e){if(t||(t=n),f)return t.createDocumentFragment();e=e||o(t);for(var a=e.frag.cloneNode(),i=0,s=r(),u=s.length;u>i;i++)a.createElement(s[i]);return a}function p(t,e){e.cache||(e.cache={},e.createElem=t.createElement,e.createFrag=t.createDocumentFragment,e.frag=e.createFrag()),t.createElement=function(n){return x.shivMethods?s(n,t,e):e.createElem(n)},t.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-:]+/g,function(t){return e.createElem(t),e.frag.createElement(t),'c("'+t+'")'})+");return n}")(x,e.frag)}function c(t){t||(t=n);var e=o(t);return!x.shivCSS||l||e.hasCSS||(e.hasCSS=!!a(t,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),f||p(t,e),t}var l,f,d="3.7.3-pre",h=t.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,v=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,g="_html5shiv",b=0,y={};!function(){try{var t=n.createElement("a");t.innerHTML="",l="hidden"in t,f=1==t.childNodes.length||function(){n.createElement("a");var t=n.createDocumentFragment();return void 0===t.cloneNode||void 0===t.createDocumentFragment||void 0===t.createElement}()}catch(e){l=!0,f=!0}}();var x={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:d,shivCSS:h.shivCSS!==!1,supportsUnknownElements:f,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:c,createElement:s,createDocumentFragment:u,addElements:i};t.html5=x,c(n),"object"==typeof e&&e.exports&&(e.exports=x)}("undefined"!=typeof window?window:this,document)},{}],194:[function(t,e,n){(function(t){(function(t){!function(t){function e(t,e,n,a){for(var i,o=n.slice(),s=r(e,t),u=0,p=o.length;p>u&&(handler=o[u],"object"==typeof handler?"function"==typeof handler.handleEvent&&handler.handleEvent(s):handler.call(t,s),!s.stoppedImmediatePropagation);u++);return i=!s.stoppedPropagation,a&&i&&t.parentNode?t.parentNode.dispatchEvent(s):!s.defaultPrevented}function n(t,e){return{configurable:!0,get:t,set:e}}function a(t,e,a){var r=b(e||t,a);v(t,"textContent",n(function(){return r.get.call(this)},function(t){r.set.call(this,t)}))}function r(t,e){return t.currentTarget=e,t.eventPhase=t.target===t.currentTarget?2:3,t}function i(t,e){for(var n=t.length;n--&&t[n]!==e;);return n}function o(){if("BR"===this.tagName)return"\n";for(var t=this.firstChild,e=[];t;)8!==t.nodeType&&7!==t.nodeType&&e.push(t.textContent),t=t.nextSibling;return e.join("")}function s(t){var e=document.createEvent("Event");e.initEvent("input",!0,!0),(t.srcElement||t.fromElement||document).dispatchEvent(e)}function u(t){!f&&k.test(document.readyState)&&(f=!f,document.detachEvent(d,u),t=document.createEvent("Event"),t.initEvent(h,!0,!0),document.dispatchEvent(t))}function p(t){for(var e;e=this.lastChild;)this.removeChild(e);null!=t&&this.appendChild(document.createTextNode(t))}function c(e,n){return n||(n=t.event),n.target||(n.target=n.srcElement||n.fromElement||document),n.timeStamp||(n.timeStamp=(new Date).getTime()),n}if(!document.createEvent){var l=!0,f=!1,d="onreadystatechange",h="DOMContentLoaded",m="__IE8__"+Math.random(),v=Object.defineProperty||function(t,e,n){t[e]=n.value},g=Object.defineProperties||function(e,n){for(var a in n)if(y.call(n,a))try{v(e,a,n[a])}catch(r){t.console&&console.log(a+" failed on object:",e,r.message)}},b=Object.getOwnPropertyDescriptor,y=Object.prototype.hasOwnProperty,x=t.Element.prototype,_=t.Text.prototype,w=/^[a-z]+$/,k=/loaded|complete/,E={},S=document.createElement("div"),C=document.documentElement,P=C.removeAttribute,A=C.setAttribute;a(t.HTMLCommentElement.prototype,x,"nodeValue"),a(t.HTMLScriptElement.prototype,null,"text"),a(_,null,"nodeValue"),a(t.HTMLTitleElement.prototype,null,"text"),v(t.HTMLStyleElement.prototype,"textContent",function(t){return n(function(){return t.get.call(this.styleSheet)},function(e){t.set.call(this.styleSheet,e)})}(b(t.CSSStyleSheet.prototype,"cssText"))),g(x,{textContent:{get:o,set:p},firstElementChild:{get:function(){for(var t=this.childNodes||[],e=0,n=t.length;n>e;e++)if(1==t[e].nodeType)return t[e]}},lastElementChild:{get:function(){for(var t=this.childNodes||[],e=t.length;e--;)if(1==t[e].nodeType)return t[e]}},oninput:{get:function(){return this._oninput||null},set:function(t){this._oninput&&(this.removeEventListener("input",this._oninput),this._oninput=t,t&&this.addEventListener("input",t))}},previousElementSibling:{get:function(){for(var t=this.previousSibling;t&&1!=t.nodeType;)t=t.previousSibling;return t}},nextElementSibling:{get:function(){for(var t=this.nextSibling;t&&1!=t.nodeType;)t=t.nextSibling;return t}},childElementCount:{get:function(){for(var t=0,e=this.childNodes||[],n=e.length;n--;t+=1==e[n].nodeType);return t}},addEventListener:{value:function(t,n,a){if("function"==typeof n||"object"==typeof n){var r,o,u=this,p="on"+t,l=u[m]||v(u,m,{value:{}})[m],f=l[p]||(l[p]={}),d=f.h||(f.h=[]);if(!y.call(f,"w")){if(f.w=function(t){return t[m]||e(u,c(u,t),d,!1)},!y.call(E,p))if(w.test(t)){try{r=document.createEventObject(),r[m]=!0,9!=u.nodeType&&(null==u.parentNode&&S.appendChild(u),(o=u.getAttribute(p))&&P.call(u,p)),u.fireEvent(p,r),E[p]=!0}catch(r){for(E[p]=!1;S.hasChildNodes();)S.removeChild(S.firstChild)}null!=o&&A.call(u,p,o)}else E[p]=!1;(f.n=E[p])&&u.attachEvent(p,f.w)}i(d,n)<0&&d[a?"unshift":"push"](n),"input"===t&&u.attachEvent("onkeyup",s)}}},dispatchEvent:{value:function(t){var n,a=this,r="on"+t.type,i=a[m],o=i&&i[r],s=!!o;return t.target||(t.target=a),s?o.n?a.fireEvent(r,t):e(a,t,o.h,!0):(n=a.parentNode)?n.dispatchEvent(t):!0,!t.defaultPrevented}},removeEventListener:{value:function(t,e,n){if("function"==typeof e||"object"==typeof e){var a=this,r="on"+t,o=a[m],s=o&&o[r],u=s&&s.h,p=u?i(u,e):-1;p>-1&&u.splice(p,1)}}}}),g(_,{addEventListener:{value:x.addEventListener},dispatchEvent:{value:x.dispatchEvent},removeEventListener:{value:x.removeEventListener}}),g(t.XMLHttpRequest.prototype,{addEventListener:{value:function(t,e,n){var a=this,r="on"+t,o=a[m]||v(a,m,{value:{}})[m],s=o[r]||(o[r]={}),u=s.h||(s.h=[]);i(u,e)<0&&(a[r]||(a[r]=function(){var e=document.createEvent("Event");e.initEvent(t,!0,!0),a.dispatchEvent(e)}),u[n?"unshift":"push"](e))}},dispatchEvent:{value:function(t){var n=this,a="on"+t.type,r=n[m],i=r&&r[a],o=!!i;return o&&(i.n?n.fireEvent(a,t):e(n,t,i.h,!0))}},removeEventListener:{value:x.removeEventListener}}),g(t.Event.prototype,{bubbles:{value:!0,writable:!0},cancelable:{value:!0,writable:!0},preventDefault:{value:function(){this.cancelable&&(this.defaultPrevented=!0,this.returnValue=!1)}},stopPropagation:{value:function(){this.stoppedPropagation=!0,this.cancelBubble=!0}},stopImmediatePropagation:{value:function(){this.stoppedImmediatePropagation=!0,this.stopPropagation()}},initEvent:{value:function(t,e,n){this.type=t,this.bubbles=!!e,this.cancelable=!!n,this.bubbles||this.stopPropagation()}}}),g(t.HTMLDocument.prototype,{defaultView:{get:function(){return this.parentWindow}},textContent:{get:function(){return 11===this.nodeType?o.call(this):null},set:function(t){11===this.nodeType&&p.call(this,t)}},addEventListener:{value:function(e,n,a){var r=this;x.addEventListener.call(r,e,n,a),l&&e===h&&!k.test(r.readyState)&&(l=!1,r.attachEvent(d,u),t==top&&!function i(t){try{r.documentElement.doScroll("left"),u()}catch(e){setTimeout(i,50)}}())}},dispatchEvent:{value:x.dispatchEvent},removeEventListener:{value:x.removeEventListener},createEvent:{value:function(t){var e;if("Event"!==t)throw Error("unsupported "+t);return e=document.createEventObject(),e.timeStamp=(new Date).getTime(),e}}}),g(t.Window.prototype,{getComputedStyle:{value:function(){function t(t){this._=t}function e(){}var n=/^(?:[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/,a=/^(top|right|bottom|left)$/,r=/\-([a-z])/g,i=function(t,e){return e.toUpperCase()};return t.prototype.getPropertyValue=function(t){var e,o,s,u=this._,p=u.style,c=u.currentStyle,l=u.runtimeStyle;return t=("float"===t?"style-float":t).replace(r,i),e=c?c[t]:p[t],n.test(e)&&!a.test(t)&&(o=p.left,s=l&&l.left,s&&(l.left=c.left),p.left="fontSize"===t?"1em":e,e=p.pixelLeft+"px",p.left=o,s&&(l.left=s)),null==e?e:e+""||"auto"},e.prototype.getPropertyValue=function(){return null},function(n,a){return a?new e(n):new t(n)}}()},addEventListener:{value:function(n,a,r){var o,s=t,u="on"+n;s[u]||(s[u]=function(t){return e(s,c(s,t),o,!1)}),o=s[u][m]||(s[u][m]=[]),i(o,a)<0&&o[r?"unshift":"push"](a)}},dispatchEvent:{value:function(e){var n=t["on"+e.type];return n?n.call(t,e)!==!1&&!e.defaultPrevented:!0}},removeEventListener:{value:function(e,n,a){var r="on"+e,o=(t[r]||Object)[m],s=o?i(o,n):-1;s>-1&&o.splice(s,1)}}}),function(t,e,n){for(n=0;n=s)return(0,u["default"])({points:n});for(var l=1;s-1>=l;l++)i.push((0,p.times)(a,(0,p.minus)(n[l],n[l-1])));for(var f=[(0,p.plus)(n[0],c(i[0],i[1]))],l=1;s-2>=l;l++)f.push((0,p.minus)(n[l],(0,p.average)([i[l],i[l-1]])));f.push((0,p.minus)(n[s-1],c(i[s-2],i[s-3])));var d=f[0],h=f[1],m=n[0],v=n[1],g=(e=(0,o["default"])()).moveto.apply(e,r(m)).curveto(d[0],d[1],h[0],h[1],v[0],v[1]);return{path:(0,p.range)(2,s).reduce(function(t,e){var a=f[e],r=n[e];return t.smoothcurveto(a[0],a[1],r[0],r[1])},g),centroid:(0,p.average)(n)}},e.exports=n["default"]},{198:198,199:199,200:200}],196:[function(t,e,n){"use strict";function a(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),i=t(197),o=a(i),s=t(198),u=1e-5,p=function(t,e){var n=t.map(e),a=n.sort(function(t,e){var n=r(t,2),a=n[0],i=(n[1],r(e,2)),o=i[0];i[1];return a-o}),i=a.length,o=a[0][0],p=a[i-1][0],c=(0,s.minBy)(a,function(t){return t[1]}),l=(0,s.maxBy)(a,function(t){return t[1]});return o==p&&(p+=u),c==l&&(l+=u),{points:a,xmin:o,xmax:p,ymin:c,ymax:l}};n["default"]=function(t){var e=t.data,n=t.xaccessor,a=t.yaccessor,i=t.width,u=t.height,c=t.closed,l=t.min,f=t.max;n||(n=function(t){var e=r(t,2),n=e[0];e[1];return n}),a||(a=function(t){var e=r(t,2),n=(e[0],e[1]);return n});var d=function(t){return[n(t),a(t)]},h=e.map(function(t){return p(t,d)}),m=(0,s.minBy)(h,function(t){return t.xmin}),v=(0,s.maxBy)(h,function(t){return t.xmax}),g=null==l?(0,s.minBy)(h,function(t){return t.ymin}):l,b=null==f?(0,s.maxBy)(h,function(t){return t.ymax}):f;c&&(g=Math.min(g,0),b=Math.max(b,0));var y=c?0:g,x=(0,o["default"])([m,v],[0,i]),_=(0,o["default"])([g,b],[u,0]),w=function(t){var e=r(t,2),n=e[0],a=e[1];return[x(n),_(a)]};return{arranged:h,scale:w,xscale:x,yscale:_,base:y}},e.exports=n["default"]},{197:197,198:198}],197:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function i(t,e){var n=a(t,2),r=n[0],o=n[1],s=a(e,2),u=s[0],p=s[1],c=function(t){return u+(p-u)*(t-r)/(o-r)};return c.inverse=function(){return i([u,p],[r,o])},c};n["default"]=r,e.exports=n["default"]},{}],198:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function(t){return t.reduce(function(t,e){return t+e},0)},i=function(t){return t.reduce(function(t,e){return Math.min(t,e)})},o=function(t){return t.reduce(function(t,e){return Math.max(t,e)})},s=function(t,e){return t.reduce(function(t,n){return t+e(n)},0)},u=function(t,e){return t.reduce(function(t,n){return Math.min(t,e(n))},1/0)},p=function(t,e){return t.reduce(function(t,n){return Math.max(t,e(n))},-(1/0))},c=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],u=o[1];return[r+s,i+u]},l=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],u=o[1];return[r-s,i-u]},f=function(t,e){var n=a(e,2),r=n[0],i=n[1];return[t*r,t*i]},d=function(t){var e=a(t,2),n=e[0],r=e[1];return Math.sqrt(n*n+r*r)},h=function(t){return t.reduce(c,[0,0])},m=function(t){return f(1/t.length,t.reduce(c))},v=function(t,e){return f(t,[Math.sin(e),-Math.cos(e)])},g=function(t,e){var n=t||{};for(var a in n){var r=n[a];e[a]=r(e.index,e.item,e.group)}return e},b=function(t,e,n){for(var a=[],r=t;e>r;r++)a.push(r);return n&&a.push(e),a},y=function(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=Object.keys(t)[Symbol.iterator]();!(a=(o=s.next()).done);a=!0){var u=o.value,p=t[u];n.push(e(u,p))}}catch(c){r=!0,i=c}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n},x=function(t){return y(t,function(t,e){return[t,e]})},_=function(t){return t};n.sum=r,n.min=i,n.max=o,n.sumBy=s,n.minBy=u,n.maxBy=p,n.plus=c,n.minus=l,n.times=f,n.id=_,n.length=d,n.sumVectors=h,n.average=m,n.onCircle=v,n.enhance=g,n.range=b,n.mapObject=y,n.pairs=x,n["default"]={sum:r,min:i,max:o,sumBy:s,minBy:u,maxBy:p,plus:c,minus:l,times:f,id:_,length:d,sumVectors:h,average:m,onCircle:v,enhance:g,range:b,mapObject:y,pairs:x}},{}],199:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function i(t){var e=t||[],n=function(t,e){var n=t.slice(0,t.length);return n.push(e),n},r=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],u=o[1];return r===s&&i===u},o=function(t,e){for(var n=t.length;"0"===t.charAt(n-1);)n-=1;return"."===t.charAt(n-1)&&(n-=1),t.substr(0,n)},s=function(t,e){var n=t.toFixed(e);return o(n)},u=function(t){var e=t.command,n=t.params,a=n.map(function(t){return s(t,6)});return e+" "+a.join(" ")},p=function(t,e){var n=t.command,r=t.params,i=a(e,2),o=i[0],s=i[1];switch(n){case"M":return[r[0],r[1]];case"L":return[r[0],r[1]];case"H":return[r[0],s];case"V":return[o,r[0]];case"Z":return null;case"C":return[r[4],r[5]];case"S":return[r[2],r[3]];case"Q":return[r[2],r[3]];case"T":return[r[0],r[1]];case"A":return[r[5],r[6]]}},c=function(t,e){return function(n){var a="object"==typeof n?t.map(function(t){return n[t]}):arguments;return e.apply(null,a)}},l=function(t){return i(n(e,t))};return{moveto:c(["x","y"],function(t,e){return l({command:"M",params:[t,e]})}),lineto:c(["x","y"],function(t,e){return l({command:"L",params:[t,e]})}),hlineto:c(["x"],function(t){return l({command:"H",params:[t]})}),vlineto:c(["y"],function(t){return l({command:"V",params:[t]})}),closepath:function(){return l({command:"Z",params:[]})},curveto:c(["x1","y1","x2","y2","x","y"],function(t,e,n,a,r,i){return l({command:"C",params:[t,e,n,a,r,i]})}),smoothcurveto:c(["x2","y2","x","y"],function(t,e,n,a){return l({command:"S",params:[t,e,n,a]})}),qcurveto:c(["x1","y1","x","y"],function(t,e,n,a){return l({command:"Q",params:[t,e,n,a]})}),smoothqcurveto:c(["x","y"],function(t,e){return l({command:"T",params:[t,e]})}),arc:c(["rx","ry","xrot","largeArcFlag","sweepFlag","x","y"],function(t,e,n,a,r,i,o){return l({command:"A",params:[t,e,n,a,r,i,o]})}),print:function(){return e.map(u).join(" ")},points:function(){var t=[],n=[0,0],a=!0,r=!1,i=void 0;try{for(var o,s=e[Symbol.iterator]();!(a=(o=s.next()).done);a=!0){var u=o.value,c=p(u,n);n=c,c&&t.push(c)}}catch(l){r=!0,i=l}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return t},instructions:function(){return e.slice(0,e.length)},connect:function(t){var e=this.points(),n=e[e.length-1],a=t.points()[0],o=t.instructions().slice(1);return r(n,a)||o.unshift({command:"L",params:a}),i(this.instructions().concat(o))}}};n["default"]=function(){return r()},e.exports=n["default"]},{}],200:[function(t,e,n){"use strict";function a(t){return t&&t.__esModule?t:{"default":t}}function r(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e1)for(var n=1;n1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];for(var r,i;i=n.shift();)for(r in i)Ro.call(i,r)&&(t[r]=i[r]);return t}function r(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];return n.forEach(function(e){for(var n in e)!e.hasOwnProperty(n)||n in t||(t[n]=e[n])}),t}function i(t){return"[object Array]"===Mo.call(t)}function o(t){return Lo.test(Mo.call(t))}function s(t,e){return null===t&&null===e?!0:"object"==typeof t||"object"==typeof e?!1:t===e}function u(t){return!isNaN(parseFloat(t))&&isFinite(t)}function p(t){return t&&"[object Object]"===Mo.call(t)}function c(t,e){return t.replace(/%s/g,function(){return e.shift()})}function l(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];throw t=c(t,n),Error(t)}function f(){Rv.DEBUG&&Oo.apply(null,arguments)}function d(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];t=c(t,n),To(t,n)}function h(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];t=c(t,n),Do[t]||(Do[t]=!0,To(t,n))}function m(){Rv.DEBUG&&d.apply(null,arguments)}function v(){Rv.DEBUG&&h.apply(null,arguments)}function g(t,e,n){var a=b(t,e,n);return a?a[t][n]:null}function b(t,e,n){for(;e;){if(n in e[t])return e;if(e.isolated)return null;e=e.parent}}function y(t){return function(){return t}}function x(t){var e,n,a,r,i,o;for(e=t.split("."),(n=zo[e.length])||(n=_(e.length)),i=[],a=function(t,n){return t?"*":e[n]},r=n.length;r--;)o=n[r].map(a).join("."),i.hasOwnProperty(o)||(i.push(o),i[o]=!0);return i}function _(t){var e,n,a,r,i,o,s,u,p="";if(!zo[t]){for(a=[];p.length=i;i+=1){for(n=i.toString(2);n.lengtho;o++)u.push(r(n[o]));a[i]=u}zo[t]=a}return zo[t]}function w(t,e,n,a){var r=t[e];if(!r||!r.equalsOrStartsWith(a)&&r.equalsOrStartsWith(n))return t[e]=r?r.replace(n,a):a,!0}function k(t){var e=t.slice(2);return"i"===t[1]&&u(e)?+e:e}function E(t){return null==t?t:(Qo.hasOwnProperty(t)||(Qo[t]=new Ko(t)),Qo[t])}function S(t,e){function n(e,n){var a,r,o;return n.isRoot?o=[].concat(Object.keys(t.viewmodel.data),Object.keys(t.viewmodel.mappings),Object.keys(t.viewmodel.computations)):(a=t.viewmodel.wrapped[n.str],r=a?a.get():t.viewmodel.get(n),o=r?Object.keys(r):null),o&&o.forEach(function(t){"_ractive"===t&&i(r)||e.push(n.join(t))}),e}var a,r,o;for(a=e.str.split("."),o=[Yo];r=a.shift();)"*"===r?o=o.reduce(n,[]):o[0]===Yo?o[0]=E(r):o=o.map(C(r));return o}function C(t){return function(e){return e.join(t)}}function P(t){return t?t.replace(Wo,".$1"):""}function A(t,e,n){if("string"!=typeof e||!u(n))throw Error("Bad arguments");var a=void 0,r=void 0;if(/\*/.test(e))return r={},S(t,E(P(e))).forEach(function(e){var a=t.viewmodel.get(e);if(!u(a))throw Error(Xo);r[e.str]=a+n}),t.set(r);if(a=t.get(e),!u(a))throw Error(Xo);
+return t.set(e,+a+n)}function O(t,e){return Jo(this,t,void 0===e?1:+e)}function T(t){this.event=t,this.method="on"+t,this.deprecate=as[t]}function j(t,e){var n=t.indexOf(e);-1===n&&t.push(e)}function R(t,e){for(var n=0,a=t.length;a>n;n++)if(t[n]==e)return!0;return!1}function M(t,e){var n;if(!i(t)||!i(e))return!1;if(t.length!==e.length)return!1;for(n=t.length;n--;)if(t[n]!==e[n])return!1;return!0}function L(t){return"string"==typeof t?[t]:void 0===t?[]:t}function D(t){return t[t.length-1]}function N(t,e){var n=t.indexOf(e);-1!==n&&t.splice(n,1)}function F(t){for(var e=[],n=t.length;n--;)e[n]=t[n];return e}function I(t){setTimeout(t,0)}function B(t,e){return function(){for(var n;n=t.shift();)n(e)}}function q(t,e,n,a){var r;if(e===t)throw new TypeError("A promise's fulfillment handler cannot return the same promise");if(e instanceof rs)e.then(n,a);else if(!e||"object"!=typeof e&&"function"!=typeof e)n(e);else{try{r=e.then}catch(i){return void a(i)}if("function"==typeof r){var o,s,u;s=function(e){o||(o=!0,q(t,e,n,a))},u=function(t){o||(o=!0,a(t))};try{r.call(e,s,u)}catch(i){if(!o)return a(i),void(o=!0)}}else n(e)}}function U(t,e,n){var a;return e=P(e),"~/"===e.substr(0,2)?(a=E(e.substring(2)),z(t,a.firstKey,n)):"."===e[0]?(a=G(cs(n),e),a&&z(t,a.firstKey,n)):a=V(t,E(e),n),a}function G(t,e){var n;if(void 0!=t&&"string"!=typeof t&&(t=t.str),"."===e)return E(t);if(n=t?t.split("."):[],"../"===e.substr(0,3)){for(;"../"===e.substr(0,3);){if(!n.length)throw Error('Could not resolve reference - too many "../" prefixes');n.pop(),e=e.substring(3)}return n.push(e),E(n.join("."))}return E(t?t+e.replace(/^\.\//,"."):e.replace(/^\.\/?/,""))}function V(t,e,n,a){var r,i,o,s,u;if(e.isRoot)return e;for(i=e.firstKey;n;)if(r=n.context,n=n.parent,r&&(s=!0,o=t.viewmodel.get(r),o&&("object"==typeof o||"function"==typeof o)&&i in o))return r.join(e.str);return W(t.viewmodel,i)?e:t.parent&&!t.isolated&&(s=!0,n=t.component.parentFragment,i=E(i),u=V(t.parent,i,n,!0))?(t.viewmodel.map(i,{origin:t.parent.viewmodel,keypath:u}),e):a||s?void 0:(t.viewmodel.set(e,void 0),e)}function z(t,e){var n;!t.parent||t.isolated||W(t.viewmodel,e)||(e=E(e),(n=V(t.parent,e,t.component.parentFragment,!0))&&t.viewmodel.map(e,{origin:t.parent.viewmodel,keypath:n}))}function W(t,e){return""===e||e in t.data||e in t.computations||e in t.mappings}function H(t){t.teardown()}function Q(t){t.unbind()}function K(t){t.unrender()}function $(t){t.cancel()}function Y(t){t.detach()}function J(t){t.detachNodes()}function X(t){!t.ready||t.outros.length||t.outroChildren||(t.outrosComplete||(t.parent?t.parent.decrementOutros(t):t.detachNodes(),t.outrosComplete=!0),t.intros.length||t.totalChildren||("function"==typeof t.callback&&t.callback(),t.parent&&t.parent.decrementTotal()))}function Z(){for(var t,e,n;ds.ractives.length;)e=ds.ractives.pop(),n=e.viewmodel.applyChanges(),n&&gs.fire(e,n);for(tt(),t=0;t=0;i--)r=t._subs[e[i]],r&&(s=gt(t,r,n,a)&&s);if(Vs.dequeue(t),t.parent&&s){if(o&&t.component){var u=t.component.name+"."+e[e.length-1];e=E(u).wildcardMatches(),n&&(n.component=t)}vt(t.parent,e,n,a)}}function gt(t,e,n,a){var r=null,i=!1;n&&!n._noArg&&(a=[n].concat(a)),e=e.slice();for(var o=0,s=e.length;s>o;o+=1)e[o].apply(t,a)===!1&&(i=!0);return n&&!n._noArg&&i&&(r=n.original)&&(r.preventDefault&&r.preventDefault(),r.stopPropagation&&r.stopPropagation()),!i}function bt(t){var e={args:Array.prototype.slice.call(arguments,1)};zs(this,t,e)}function yt(t){var e;return t=E(P(t)),e=this.viewmodel.get(t,Qs),void 0===e&&this.parent&&!this.isolated&&ls(this,t.str,this.component.parentFragment)&&(e=this.viewmodel.get(t)),e}function xt(e,n){if(!this.fragment.rendered)throw Error("The API has changed - you must call `ractive.render(target[, anchor])` to render your Ractive instance. Once rendered you can use `ractive.insert()`.");if(e=t(e),n=t(n)||null,!e)throw Error("You must specify a valid target to insert into");e.insertBefore(this.detach(),n),this.el=e,(e.__ractive_instances__||(e.__ractive_instances__=[])).push(this),this.detached=null,_t(this)}function _t(t){$s.fire(t),t.findAllComponents("*").forEach(function(t){_t(t.instance)})}function wt(t,e,n){var a,r;return t=E(P(t)),a=this.viewmodel.get(t),i(a)&&i(e)?(r=bs.start(this,!0),this.viewmodel.merge(t,a,e,n),bs.end(),r):this.set(t,e,n&&n.complete)}function kt(t,e){var n,a;return n=S(t,e),a={},n.forEach(function(e){a[e.str]=t.get(e.str)}),a}function Et(t,e,n,a){var r,i,o;e=E(P(e)),a=a||cu,e.isPattern?(r=new uu(t,e,n,a),t.viewmodel.patternObservers.push(r),i=!0):r=new Zs(t,e,n,a),r.init(a.init),t.viewmodel.register(e,r,i?"patternObservers":"observers"),r.ready=!0;var s={cancel:function(){var n;o||(i?(n=t.viewmodel.patternObservers.indexOf(r),t.viewmodel.patternObservers.splice(n,1),t.viewmodel.unregister(e,r,"patternObservers")):t.viewmodel.unregister(e,r,"observers"),o=!0)}};return t._observers.push(s),s}function St(t,e,n){var a,r,i,o;if(p(t)){n=e,r=t,a=[];for(t in r)r.hasOwnProperty(t)&&(e=r[t],a.push(this.observe(t,e,n)));return{cancel:function(){for(;a.length;)a.pop().cancel()}}}if("function"==typeof t)return n=e,e=t,t="",pu(this,t,e,n);if(i=t.split(" "),1===i.length)return pu(this,t,e,n);for(a=[],o=i.length;o--;)t=i[o],t&&a.push(pu(this,t,e,n));return{cancel:function(){for(;a.length;)a.pop().cancel()}}}function Ct(t,e,n){var a=this.observe(t,function(){e.apply(this,arguments),a.cancel()},{init:!1,defer:n&&n.defer});return a}function Pt(t,e){var n,a=this;if(t)n=t.split(" ").map(du).filter(hu),n.forEach(function(t){var n,r;(n=a._subs[t])&&(e?(r=n.indexOf(e),-1!==r&&n.splice(r,1)):a._subs[t]=[])});else for(t in this._subs)delete this._subs[t];return this}function At(t,e){var n,a,r,i=this;if("object"==typeof t){n=[];for(a in t)t.hasOwnProperty(a)&&n.push(this.on(a,t[a]));return{cancel:function(){for(var t;t=n.pop();)t.cancel()}}}return r=t.split(" ").map(du).filter(hu),r.forEach(function(t){(i._subs[t]||(i._subs[t]=[])).push(e)}),{cancel:function(){return i.off(t,e)}}}function Ot(t,e){var n=this.on(t,function(){e.apply(this,arguments),n.cancel()});return n}function Tt(t,e,n){var a,r,i,o,s,u,p=[];if(a=jt(t,e,n),!a)return null;for(r=t.length,s=a.length-2-a[1],i=Math.min(r,a[0]),o=i+a[1],u=0;i>u;u+=1)p.push(u);for(;o>u;u+=1)p.push(-1);for(;r>u;u+=1)p.push(u+s);return 0!==s?p.touchedFrom=a[0]:p.touchedFrom=t.length,p}function jt(t,e,n){switch(e){case"splice":for(void 0!==n[0]&&n[0]<0&&(n[0]=t.length+Math.max(n[0],-t.length));n.length<2;)n.push(0);return n[1]=Math.min(n[1],t.length-n[0]),n;case"sort":case"reverse":return null;case"pop":return t.length?[t.length-1,1]:[0,0];case"push":return[t.length,0].concat(n);case"shift":return[0,t.length?1:0];case"unshift":return[0,0].concat(n)}}function Rt(e,n){var a,r,i,o=this;if(i=this.transitionsEnabled,this.noIntro&&(this.transitionsEnabled=!1),a=bs.start(this,!0),bs.scheduleTask(function(){return ju.fire(o)},!0),this.fragment.rendered)throw Error("You cannot call ractive.render() on an already rendered instance! Call ractive.unrender() first");if(e=t(e)||this.el,n=t(n)||this.anchor,this.el=e,this.anchor=n,!this.append&&e){var s=e.__ractive_instances__;s&&s.length&&Mt(s),e.innerHTML=""}return this.cssId&&Ou.apply(),e&&((r=e.__ractive_instances__)?r.push(this):e.__ractive_instances__=[this],n?e.insertBefore(this.fragment.render(),n):e.appendChild(this.fragment.render())),bs.end(),this.transitionsEnabled=i,a.then(function(){return Ru.fire(o)})}function Mt(t){t.splice(0,t.length).forEach(H)}function Lt(t,e){for(var n=t.slice(),a=e.length;a--;)~n.indexOf(e[a])||n.push(e[a]);return n}function Dt(t,e){var n,a,r;return a='[data-ractive-css~="{'+e+'}"]',r=function(t){var e,n,r,i,o,s,u,p=[];for(e=[];n=Iu.exec(t);)e.push({str:n[0],base:n[1],modifiers:n[2]});for(i=e.map(Ft),u=e.length;u--;)s=i.slice(),r=e[u],s[u]=r.base+a+r.modifiers||"",o=i.slice(),o[u]=a+" "+o[u],p.push(s.join(" "),o.join(" "));return p.join(", ")},n=qu.test(t)?t.replace(qu,a):t.replace(Fu,"").replace(Nu,function(t,e){var n,a;return Bu.test(e)?t:(n=e.split(",").map(Nt),a=n.map(r).join(", ")+" ",t.replace(e,a))})}function Nt(t){return t.trim?t.trim():t.replace(/^\s+/,"").replace(/\s+$/,"")}function Ft(t){return t.str}function It(t){t&&t.constructor!==Object&&("function"==typeof t||("object"!=typeof t?l("data option must be an object or a function, `"+t+"` is not valid"):m("If supplied, options.data should be a plain JavaScript object - using a non-POJO as the root object may work, but is discouraged")))}function Bt(t,e){It(e);var n="function"==typeof t,a="function"==typeof e;return e||n||(e={}),n||a?function(){var r=a?qt(e,this):e,i=n?qt(t,this):t;return Ut(r,i)}:Ut(e,t)}function qt(t,e){var n=t.call(e);if(n)return"object"!=typeof n&&l("Data function must return an object"),n.constructor!==Object&&v("Data function returned something other than a plain JavaScript object. This might work, but is strongly discouraged"),n}function Ut(t,e){if(t&&e){for(var n in e)n in t||(t[n]=e[n]);return t}return t||e}function Gt(t){var e=Eo(Ku);return e.parse=function(e,n){return Vt(e,n||t)},e}function Vt(t,e){if(!Hu)throw Error("Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser");return Hu(t,e||this.options)}function zt(t,e){var n;if(!Xi){if(e&&e.noThrow)return;throw Error("Cannot retrieve template #"+t+" as Ractive is not running in a browser.")}if(Wt(t)&&(t=t.substring(1)),!(n=document.getElementById(t))){if(e&&e.noThrow)return;throw Error("Could not find template element with id #"+t)}if("SCRIPT"!==n.tagName.toUpperCase()){if(e&&e.noThrow)return;throw Error("Template element with id #"+t+", must be a