Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit611
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
desc = "Dash somewhere with supernatural speed. Those nearby may be knocked away, stunned, or left empty-handed."
|
||||
button_icon_state = "power_speed"
|
||||
bloodcost = 6
|
||||
cooldown = 50
|
||||
cooldown = 120
|
||||
target_range = 15
|
||||
power_activates_immediately = TRUE
|
||||
message_Trigger = ""//"Whom will you subvert to your will?"
|
||||
|
||||
@@ -28,8 +28,7 @@
|
||||
action.Remove(user)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/changeling/Click()
|
||||
var/mob/user = usr
|
||||
/obj/effect/proc_holder/changeling/Trigger(mob/user)
|
||||
if(!user || !user.mind || !user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
return
|
||||
try_to_sting(user)
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
desc = "Stabby stabby."
|
||||
var/sting_icon = null
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/Click()
|
||||
var/mob/user = usr
|
||||
/obj/effect/proc_holder/changeling/sting/Trigger(mob/user)
|
||||
if(!user || !user.mind)
|
||||
return
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
@@ -74,8 +73,7 @@
|
||||
action_icon_state = "ling_sting_transform"
|
||||
action_background_icon_state = "bg_ling"
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/transformation/Click()
|
||||
var/mob/user = usr
|
||||
/obj/effect/proc_holder/changeling/sting/transformation/Trigger(mob/user)
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling.chosen_sting)
|
||||
unset_sting(user)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
var/span_for_name = "heavy_brass"
|
||||
var/span_for_message = "brass"
|
||||
|
||||
/datum/action/innate/hierophant/IsAvailable()
|
||||
/datum/action/innate/hierophant/IsAvailable(silent = FALSE)
|
||||
if(!is_servant_of_ratvar(owner))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/obj/item/clockwork/weapon/weapon_type //The type of weapon to create
|
||||
var/obj/item/clockwork/weapon/weapon
|
||||
|
||||
/datum/action/innate/call_weapon/IsAvailable()
|
||||
/datum/action/innate/call_weapon/IsAvailable(silent = FALSE)
|
||||
if(!is_servant_of_ratvar(owner))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -232,7 +232,7 @@
|
||||
background_icon_state = "bg_clock"
|
||||
buttontooltipstyle = "clockcult"
|
||||
|
||||
/datum/action/innate/eminence/IsAvailable()
|
||||
/datum/action/innate/eminence/IsAvailable(silent = FALSE)
|
||||
if(!iseminence(owner))
|
||||
qdel(src)
|
||||
return
|
||||
@@ -283,7 +283,7 @@
|
||||
desc = "Initiates a mass recall, warping all servants to the Ark after a short delay. This can only be used once."
|
||||
button_icon_state = "Spatial Gateway"
|
||||
|
||||
/datum/action/innate/eminence/mass_recall/IsAvailable()
|
||||
/datum/action/innate/eminence/mass_recall/IsAvailable(silent = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
/obj/item/clothing/head/helmet/space,
|
||||
/obj/item/clothing/shoes/magboots)) //replace this only if ratvar is up
|
||||
|
||||
/datum/action/innate/clockwork_armaments/IsAvailable()
|
||||
/datum/action/innate/clockwork_armaments/IsAvailable(silent = FALSE)
|
||||
if(!is_servant_of_ratvar(owner))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
qdel(X)
|
||||
..()
|
||||
|
||||
/datum/action/innate/cult/blood_magic/IsAvailable()
|
||||
/datum/action/innate/cult/blood_magic/IsAvailable(silent = FALSE)
|
||||
if(!iscultist(owner))
|
||||
return FALSE
|
||||
return ..()
|
||||
@@ -118,7 +118,7 @@
|
||||
hand_magic = null
|
||||
..()
|
||||
|
||||
/datum/action/innate/cult/blood_spell/IsAvailable()
|
||||
/datum/action/innate/cult/blood_spell/IsAvailable(silent = FALSE)
|
||||
if(!iscultist(owner) || owner.incapacitated() || !charges)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
buttontooltipstyle = "cult"
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
|
||||
|
||||
/datum/action/innate/cult/IsAvailable()
|
||||
/datum/action/innate/cult/IsAvailable(silent = FALSE)
|
||||
if(!iscultist(owner))
|
||||
return FALSE
|
||||
return ..()
|
||||
@@ -51,7 +51,7 @@
|
||||
name = "Spiritual Communion"
|
||||
desc = "Conveys a message from the spirit realm that all cultists can hear."
|
||||
|
||||
/datum/action/innate/cult/comm/spirit/IsAvailable()
|
||||
/datum/action/innate/cult/comm/spirit/IsAvailable(silent = FALSE)
|
||||
if(iscultist(owner.mind.current))
|
||||
return TRUE
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
name = "Assert Leadership"
|
||||
button_icon_state = "cultvote"
|
||||
|
||||
/datum/action/innate/cult/mastervote/IsAvailable()
|
||||
/datum/action/innate/cult/mastervote/IsAvailable(silent = FALSE)
|
||||
var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
|
||||
if(!C?.cult_team || C.cult_team.cult_vote_called || !ishuman(owner))
|
||||
return FALSE
|
||||
@@ -140,7 +140,7 @@
|
||||
to_chat(B.current,"<span class='cultlarge'>[Nominee] has won the cult's support and is now their master. Follow [Nominee.p_their()] orders to the best of your ability!</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/cult/master/IsAvailable()
|
||||
/datum/action/innate/cult/master/IsAvailable(silent = FALSE)
|
||||
if(!owner.mind || !owner.mind.has_antag_datum(/datum/antagonist/cult/master) || GLOB.cult_narsie)
|
||||
return 0
|
||||
return ..()
|
||||
@@ -226,9 +226,9 @@
|
||||
CM.attached_action = src
|
||||
..()
|
||||
|
||||
/datum/action/innate/cult/master/cultmark/IsAvailable()
|
||||
/datum/action/innate/cult/master/cultmark/IsAvailable(silent = FALSE)
|
||||
if(cooldown > world.time)
|
||||
if(!CM.active)
|
||||
if(!CM.active && !silent)
|
||||
to_chat(owner, "<span class='cultlarge'><b>You need to wait [DisplayTimeText(cooldown - world.time)] before you can mark another target!</b></span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
@@ -308,7 +308,7 @@
|
||||
name = "Mark a Blood Target for the Cult"
|
||||
desc = "Marks a target for the entire cult to track."
|
||||
|
||||
/datum/action/innate/cult/master/cultmark/ghost/IsAvailable()
|
||||
/datum/action/innate/cult/master/cultmark/ghost/IsAvailable(silent = FALSE)
|
||||
if(istype(owner, /mob/dead/observer) && iscultist(owner.mind.current))
|
||||
return TRUE
|
||||
else
|
||||
@@ -322,7 +322,7 @@
|
||||
var/cooldown = 0
|
||||
var/base_cooldown = 600
|
||||
|
||||
/datum/action/innate/cult/ghostmark/IsAvailable()
|
||||
/datum/action/innate/cult/ghostmark/IsAvailable(silent = FALSE)
|
||||
if(istype(owner, /mob/dead/observer) && iscultist(owner.mind.current))
|
||||
return TRUE
|
||||
else
|
||||
@@ -401,11 +401,11 @@
|
||||
PM.attached_action = src
|
||||
..()
|
||||
|
||||
/datum/action/innate/cult/master/pulse/IsAvailable()
|
||||
/datum/action/innate/cult/master/pulse/IsAvailable(silent = FALSE)
|
||||
if(!owner.mind || !owner.mind.has_antag_datum(/datum/antagonist/cult/master))
|
||||
return FALSE
|
||||
if(cooldown > world.time)
|
||||
if(!PM.active)
|
||||
if(!PM.active && !silent)
|
||||
to_chat(owner, "<span class='cultlarge'><b>You need to wait [DisplayTimeText(cooldown - world.time)] before you can pulse again!</b></span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -222,7 +222,7 @@
|
||||
phasein = /obj/effect/temp_visual/dir_setting/cult/phase
|
||||
phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out
|
||||
|
||||
/datum/action/innate/dash/cult/IsAvailable()
|
||||
/datum/action/innate/dash/cult/IsAvailable(silent = FALSE)
|
||||
if(iscultist(holder) && current_charges)
|
||||
return TRUE
|
||||
else
|
||||
@@ -242,7 +242,7 @@
|
||||
sword = bastard
|
||||
holder = user
|
||||
|
||||
/datum/action/innate/cult/spin2win/IsAvailable()
|
||||
/datum/action/innate/cult/spin2win/IsAvailable(silent = FALSE)
|
||||
if(iscultist(holder) && cooldown <= world.time)
|
||||
return TRUE
|
||||
else
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
var/obj/effect/temp_visual/cult/rune_spawn/rune_center_type
|
||||
var/rune_color
|
||||
|
||||
/datum/action/innate/cult/create_rune/IsAvailable()
|
||||
/datum/action/innate/cult/create_rune/IsAvailable(silent = FALSE)
|
||||
if(!rune_type || cooldown > world.time)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -179,8 +179,8 @@
|
||||
/obj/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
if(resistance_flags & INDESTRUCTIBLE)
|
||||
return FALSE
|
||||
for(var/mob/living/L in contents)
|
||||
if(!issilicon(L) && !isbrain(L))
|
||||
for(var/mob/living/L in GetAllContents())
|
||||
if(!ispAI(L) && !isbrain(L))
|
||||
to_chat(S, "<span class='warning'>An organism has been detected inside this object. Aborting.</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
@@ -416,6 +416,57 @@
|
||||
to_chat(S, "<span class='warning'>Destroying this object would cause a catastrophic chain reaction. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/ore_silo/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>Destroying this object, however tempting it's, will disrupt the research development that may serve for our masters in the future. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/rnd/server/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>Destroying this object, will disrupt the research development that may serve for our masters in the future. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/pool/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) //pool's closed, but not.
|
||||
to_chat(S, "<span class='warning'>The pool must not be closed, it will provide healthy fun for our masters in the future. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/structure/pool/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>The pool must not be closed, it will provide healthy fun for our masters in the future. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/structure/holosign/barrier/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
var/static/list/lazy_typecache = typecacheof(list(/obj/structure/holosign/barrier/engineering, /obj/structure/holosign/barrier/firelock, /obj/structure/holosign/barrier/atmos, /obj/structure/holosign/barrier/combifan))
|
||||
if(lazy_typecache[type])
|
||||
to_chat(S, "<span class='warning'>Destroying this holographic barrier may not benefit us. Aborting.</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/dominator/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>This advanced piece of technology may be of use for our masters in the future. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/computer/bsa_control/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>This advanced piece of technology may be of use for our masters in the future. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/bsa/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>This advanced piece of technology may be of use for our masters in the future. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/dna_vault/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>This advanced piece of technology may be of use for our masters in the future. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/structure/filler/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>This advanced piece of technology may be of use for our masters in the future. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/computer/sat_control/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>Destroying this object will lower the station shielding against space debris. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/satellite/meteor_shield/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>Destroying this object will lower the station shielding against space debris. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
////END CTRL CLICK FOR SWARMERS////
|
||||
|
||||
/mob/living/simple_animal/hostile/swarmer/proc/Fabricate(atom/fabrication_object,fabrication_cost = 0)
|
||||
@@ -429,6 +480,14 @@
|
||||
return new fabrication_object(loc)
|
||||
|
||||
/mob/living/simple_animal/hostile/swarmer/proc/Integrate(atom/movable/target)
|
||||
if(isobj(target))
|
||||
var/obj/O = target
|
||||
if(O.resistance_flags & INDESTRUCTIBLE)
|
||||
return FALSE
|
||||
for(var/mob/living/L in GetAllContents())
|
||||
if(!ispAI(L) && !isbrain(L))
|
||||
to_chat(src, "<span class='warning'>An organism has been detected inside this object. Aborting.</span>")
|
||||
return FALSE
|
||||
var/resource_gain = target.IntegrateAmount()
|
||||
if(resources + resource_gain > max_resources)
|
||||
to_chat(src, "<span class='warning'>We cannot hold more materials!</span>")
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/datum/round_event_control/spawn_swarmer
|
||||
name = "Spawn Swarmer Shell"
|
||||
typepath = /datum/round_event/spawn_swarmer
|
||||
weight = 0
|
||||
max_occurrences = 0
|
||||
weight = 7
|
||||
max_occurrences = 1 //Only once okay fam
|
||||
earliest_start = 30 MINUTES
|
||||
min_players = 15
|
||||
min_players = 35
|
||||
gamemode_blacklist = list("dynamic")
|
||||
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
|
||||
else
|
||||
owner_AI = owner
|
||||
|
||||
/datum/action/innate/ai/IsAvailable()
|
||||
/datum/action/innate/ai/IsAvailable(silent = FALSE)
|
||||
. = ..()
|
||||
if(owner_AI && owner_AI.malf_cooldown > world.time)
|
||||
return FALSE
|
||||
|
||||
@@ -377,3 +377,99 @@
|
||||
name = "black cowboy boots"
|
||||
desc = "A pair of black cowboy boots, pretty easy to scuff up."
|
||||
icon_state = "cowboyboots_black"
|
||||
|
||||
/obj/item/clothing/shoes/wallwalkers
|
||||
name = "wall walking boots"
|
||||
desc = "Contrary to popular belief, these do not allow you to walk on walls. Through bluespace magic stolen from an organisation that hoards technology, they simply allow you to slip through the atoms that make up anything, but only while walking, for safety reasons. As well as this, they unfortunately cause minor breath loss as the majority of atoms in your lungs are sucked out into any solid object you walk through. Make sure not to overuse them."
|
||||
icon_state = "walkboots"
|
||||
var/walkcool = 0
|
||||
var/wallcharges = 4
|
||||
var/newlocobject = null
|
||||
|
||||
/obj/item/clothing/shoes/wallwalkers/equipped(mob/user,slot)
|
||||
. = ..()
|
||||
if(slot == SLOT_SHOES)
|
||||
RegisterSignal(user, COMSIG_MOB_CLIENT_MOVE,.proc/intercept_user_move)
|
||||
|
||||
/obj/item/clothing/shoes/wallwalkers/dropped(mob/user)
|
||||
. = ..()
|
||||
UnregisterSignal(user, COMSIG_MOB_CLIENT_MOVE)
|
||||
|
||||
/obj/item/clothing/shoes/wallwalkers/attackby(obj/item/W, mob/user, params)
|
||||
. = ..()
|
||||
if(!istype(W, /obj/item/bluespacerecharge))
|
||||
return
|
||||
var/obj/item/bluespacerecharge/ER = W
|
||||
if(ER.uses)
|
||||
wallcharges += ER.uses
|
||||
to_chat(user, "<span class='notice'>You charged the bluespace crystal in the [src]. It now has [wallcharges] charges left.</span>")
|
||||
ER.uses = 0
|
||||
ER.icon_state = "[initial(ER.icon_state)]0"
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[ER] has no crystal on it.</span>")
|
||||
|
||||
/obj/item/clothing/shoes/wallwalkers/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='warning'>It has [wallcharges] charges left.</span>"
|
||||
|
||||
/obj/item/clothing/shoes/wallwalkers/proc/intercept_user_move(mob/living/m, client/client, dir, newloc, oldloc)
|
||||
if (walkcool >= world.time || m.m_intent != MOVE_INTENT_WALK || wallcharges <= 0)
|
||||
return
|
||||
walkcool = world.time + m.movement_delay()
|
||||
var/issolid = FALSE
|
||||
var/turf/K = newloc
|
||||
if (istype(K))
|
||||
if (K.density)
|
||||
issolid = TRUE
|
||||
if (!issolid)
|
||||
for (var/atom/T in newloc) //stuff on the new turf
|
||||
if (!T.CanPass(m,newloc) && T != m)
|
||||
issolid = TRUE
|
||||
newlocobject = T
|
||||
break
|
||||
if (!issolid)
|
||||
for (var/atom/T in oldloc) //directional shit on the old turf
|
||||
if (!T.CanPass(m,newloc) && T != m && T != newlocobject)
|
||||
issolid = TRUE
|
||||
break
|
||||
newlocobject = null //stopping structures from using two charges because of how shitty the canpass code is
|
||||
m.forceMove(newloc)
|
||||
if (!issolid)
|
||||
return
|
||||
m.adjustOxyLoss(rand(5,13))
|
||||
if (prob(15))
|
||||
m.adjustBruteLoss(rand(4,7))
|
||||
to_chat(m,"<span class='warning'>You feel as if travelling through the solid object left something behind and it hurts!</span>")
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, oldloc)
|
||||
s.start()
|
||||
flash_lighting_fx(3, 3, LIGHT_COLOR_ORANGE)
|
||||
wallcharges--
|
||||
|
||||
/obj/item/bluespacerecharge
|
||||
name = "bluespace crystal recharging device"
|
||||
desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for replacing the crystals in bluespace devices."
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "bluespace_charge"
|
||||
item_flags = NOBLUDGEON
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/uses = 6
|
||||
|
||||
/obj/item/bluespacerecharge/examine(mob/user)
|
||||
. = ..()
|
||||
if(uses)
|
||||
. += "<span class='notice'>It can add up to [uses] charges to compatible devices.</span>"
|
||||
else
|
||||
. += "<span class='warning'>The crystal is gone.</span>"
|
||||
|
||||
/obj/item/bluespacerecharge/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
if(!istype(I, /obj/item/stack/ore/bluespace_crystal) || uses)
|
||||
return
|
||||
var/obj/item/stack/ore/bluespace_crystal/B = I
|
||||
if (B.amount < 10)
|
||||
return
|
||||
uses += 3
|
||||
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
|
||||
B.use(10)
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
@@ -321,7 +321,7 @@
|
||||
check_flags = AB_CHECK_CONSCIOUS //|AB_CHECK_INSIDE
|
||||
var/obj/item/clothing/suit/space/chronos/chronosuit = null
|
||||
|
||||
/datum/action/innate/chrono_teleport/IsAvailable()
|
||||
/datum/action/innate/chrono_teleport/IsAvailable(silent = FALSE)
|
||||
return (chronosuit && chronosuit.activated && chronosuit.camera && !chronosuit.teleporting)
|
||||
|
||||
/datum/action/innate/chrono_teleport/Activate()
|
||||
|
||||
@@ -30,16 +30,14 @@
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user)
|
||||
on = !on
|
||||
icon_state = "[basestate][on]-[hardsuit_type]"
|
||||
user.update_inv_head() //so our mob-overlays update
|
||||
|
||||
if(on)
|
||||
set_light(brightness_on)
|
||||
else
|
||||
set_light(0)
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/update_icon_state()
|
||||
icon_state = "[basestate][on]-[hardsuit_type]"
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/dropped(mob/user)
|
||||
..()
|
||||
|
||||
@@ -63,23 +63,34 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars_by_type, typecacheof_assoc_list(list(
|
||||
|
||||
var/src_min_x = 99999
|
||||
var/src_min_y = 99999
|
||||
var/src_max_x = 0
|
||||
var/src_max_y = 0
|
||||
var/list/refined_src = new/list()
|
||||
|
||||
for (var/turf/T in turfs_src)
|
||||
src_min_x = min(src_min_x,T.x)
|
||||
src_min_y = min(src_min_y,T.y)
|
||||
src_max_x = max(src_max_x,T.y)
|
||||
src_max_y = max(src_max_y,T.y)
|
||||
for (var/turf/T in turfs_src)
|
||||
refined_src[T] = "[T.x - src_min_x].[T.y - src_min_y]"
|
||||
|
||||
var/trg_min_x = 99999
|
||||
var/trg_min_y = 99999
|
||||
var/trg_max_x = 0
|
||||
var/trg_max_y = 0
|
||||
var/list/refined_trg = new/list()
|
||||
|
||||
for (var/turf/T in turfs_trg)
|
||||
trg_min_x = min(trg_min_x,T.x)
|
||||
trg_min_y = min(trg_min_y,T.y)
|
||||
trg_max_x = max(trg_max_x,T.y)
|
||||
trg_max_y = max(trg_max_y,T.y)
|
||||
|
||||
var/diff_x = round(((src_max_x - src_min_x) - (trg_max_x - trg_min_x))/2)
|
||||
var/diff_y = round(((src_max_y - src_min_y) - (trg_max_y - trg_min_y))/2)
|
||||
for (var/turf/T in turfs_trg)
|
||||
refined_trg["[T.x - trg_min_x].[T.y - trg_min_y]"] = T
|
||||
refined_trg["[T.x - trg_min_x + diff_x].[T.y - trg_min_y + diff_y]"] = T
|
||||
|
||||
var/list/toupdate = new/list()
|
||||
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
Holodeck Update
|
||||
|
||||
The on-station holodeck area is of type [holodeck_type].
|
||||
All subtypes of [program_type] are loaded into the program cache or emag programs list.
|
||||
All types found in GLOB.holodeck_areas_per_comp_type[src.type], generated on make_datum_references_lists(),
|
||||
are loaded into the program cache or emag programs list.
|
||||
Paths with their abstract_type variable equal to themselves will be skipped.
|
||||
|
||||
If init_program is null, a random program will be loaded on startup.
|
||||
If you don't wish this, set it to the offline program or another of your choosing.
|
||||
|
||||
@@ -12,7 +15,6 @@
|
||||
3) Create a new control console that uses those areas
|
||||
|
||||
Non-mapped areas should be skipped but you should probably comment them out anyway.
|
||||
The base of program_type will always be ignored; only subtypes will be loaded.
|
||||
*/
|
||||
|
||||
#define HOLODECK_CD 25
|
||||
@@ -35,7 +37,6 @@
|
||||
// Splitting this up allows two holodecks of the same size
|
||||
// to use the same source patterns. Y'know, if you want to.
|
||||
var/holodeck_type = /area/holodeck/rec_center // locate(this) to get the target holodeck
|
||||
var/program_type = /area/holodeck/rec_center // subtypes of this (but not this itself) are loadable programs
|
||||
|
||||
var/active = FALSE
|
||||
var/damaged = FALSE
|
||||
@@ -181,7 +182,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/generate_program_list()
|
||||
for(var/typekey in subtypesof(program_type))
|
||||
for(var/typekey in GLOB.holodeck_areas_prototypes[type])
|
||||
var/area/holodeck/A = GLOB.areas_by_type[typekey]
|
||||
if(!A || !A.contents.len)
|
||||
continue
|
||||
|
||||
@@ -21,14 +21,13 @@ Doesn't work on other aliens/AI.*/
|
||||
. = ..()
|
||||
action = new(src)
|
||||
|
||||
/obj/effect/proc_holder/alien/Click()
|
||||
if(!iscarbon(usr))
|
||||
return 1
|
||||
var/mob/living/carbon/user = usr
|
||||
if(cost_check(check_turf,user))
|
||||
/obj/effect/proc_holder/alien/Trigger(mob/living/carbon/user, skip_cost_check)
|
||||
if(!istype(user))
|
||||
return TRUE
|
||||
if(!skip_cost_check || cost_check(check_turf,user))
|
||||
if(fire(user) && user) // Second check to prevent runtimes when evolving
|
||||
user.adjustPlasma(-plasma_cost)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/alien/on_gain(mob/living/carbon/user)
|
||||
return
|
||||
|
||||
@@ -469,7 +469,7 @@
|
||||
var/cooldown = 150
|
||||
var/last_teleport = 0
|
||||
|
||||
/datum/action/innate/unstable_teleport/IsAvailable()
|
||||
/datum/action/innate/unstable_teleport/IsAvailable(silent = FALSE)
|
||||
if(..())
|
||||
if(world.time > last_teleport + cooldown)
|
||||
return 1
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
background_icon_state = "bg_alien"
|
||||
required_mobility_flags = NONE
|
||||
|
||||
/datum/action/innate/regenerate_limbs/IsAvailable()
|
||||
/datum/action/innate/regenerate_limbs/IsAvailable(silent = FALSE)
|
||||
if(..())
|
||||
var/mob/living/carbon/human/H = owner
|
||||
var/list/limbs_to_heal = H.get_missing_limbs()
|
||||
@@ -223,7 +223,7 @@
|
||||
icon_icon = 'icons/mob/actions/actions_slime.dmi'
|
||||
background_icon_state = "bg_alien"
|
||||
|
||||
/datum/action/innate/split_body/IsAvailable()
|
||||
/datum/action/innate/split_body/IsAvailable(silent = FALSE)
|
||||
if(..())
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT)
|
||||
@@ -776,7 +776,7 @@
|
||||
..()
|
||||
species = _species
|
||||
|
||||
/datum/action/innate/use_extract/IsAvailable()
|
||||
/datum/action/innate/use_extract/IsAvailable(silent = FALSE)
|
||||
if(..())
|
||||
if(species && species.current_extract && (world.time > species.extract_cooldown))
|
||||
return TRUE
|
||||
|
||||
@@ -321,12 +321,16 @@ There are several things that need to be remembered:
|
||||
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
|
||||
return
|
||||
|
||||
if(client && hud_used && hud_used.inv_slots[SLOT_BACK])
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
|
||||
inv.update_icon()
|
||||
|
||||
update_mutant_bodyparts()
|
||||
if(head)
|
||||
head.screen_loc = ui_head
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += head
|
||||
update_observer_view(head,1)
|
||||
remove_overlay(HEAD_LAYER)
|
||||
var/obj/item/clothing/head/H = head
|
||||
var/alt_icon = H.mob_overlay_icon || 'icons/mob/clothing/head.dmi'
|
||||
@@ -348,6 +352,7 @@ There are several things that need to be remembered:
|
||||
head_overlay.pixel_y += dna.species.offset_features[OFFSET_HEAD][2]
|
||||
overlays_standing[HEAD_LAYER] = head_overlay
|
||||
apply_overlay(HEAD_LAYER)
|
||||
update_mutant_bodyparts()
|
||||
|
||||
/mob/living/carbon/human/update_inv_belt()
|
||||
remove_overlay(BELT_LAYER)
|
||||
@@ -457,11 +462,16 @@ There are several things that need to be remembered:
|
||||
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
|
||||
return
|
||||
|
||||
if(client && hud_used && hud_used.inv_slots[SLOT_WEAR_MASK])
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
|
||||
inv.update_icon()
|
||||
|
||||
if(wear_mask)
|
||||
wear_mask.screen_loc = ui_mask
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += wear_mask
|
||||
update_observer_view(wear_mask,1)
|
||||
var/obj/item/clothing/mask/M = wear_mask
|
||||
remove_overlay(FACEMASK_LAYER)
|
||||
var/alt_icon = M.mob_overlay_icon || 'icons/mob/clothing/mask.dmi'
|
||||
@@ -515,22 +525,6 @@ There are several things that need to be remembered:
|
||||
|
||||
//human HUD updates for items in our inventory
|
||||
|
||||
//update whether our head item appears on our hud.
|
||||
/mob/living/carbon/human/update_hud_head(obj/item/I)
|
||||
I.screen_loc = ui_head
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += I
|
||||
update_observer_view(I,1)
|
||||
|
||||
//update whether our mask item appears on our hud.
|
||||
/mob/living/carbon/human/update_hud_wear_mask(obj/item/I)
|
||||
I.screen_loc = ui_mask
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += I
|
||||
update_observer_view(I,1)
|
||||
|
||||
//update whether our neck item appears on our hud.
|
||||
/mob/living/carbon/human/update_hud_neck(obj/item/I)
|
||||
I.screen_loc = ui_neck
|
||||
@@ -579,13 +573,7 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if
|
||||
/obj/item/proc/build_worn_icon(default_layer = 0, default_icon_file = null, isinhands = FALSE, femaleuniform = NO_FEMALE_UNIFORM, override_state, style_flags = NONE, use_mob_overlay_icon = TRUE)
|
||||
|
||||
var/t_state
|
||||
if(override_state)
|
||||
t_state = override_state
|
||||
else
|
||||
if(isinhands && item_state)
|
||||
t_state = item_state
|
||||
else
|
||||
t_state = icon_state
|
||||
t_state = override_state || item_state || icon_state
|
||||
|
||||
//Find a valid icon file from variables+arguments
|
||||
var/file2use
|
||||
|
||||
@@ -28,10 +28,8 @@
|
||||
if(stat != DEAD)
|
||||
handle_brain_damage()
|
||||
|
||||
/* BUG_PROBABLE_CAUSE
|
||||
if(stat != DEAD)
|
||||
handle_liver()
|
||||
*/
|
||||
|
||||
if(stat == DEAD)
|
||||
stop_sound_channel(CHANNEL_HEARTBEAT)
|
||||
@@ -690,36 +688,17 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
var/obj/item/organ/liver/liver = getorganslot(ORGAN_SLOT_LIVER)
|
||||
if((!dna && !liver) || (NOLIVER in dna.species.species_traits))
|
||||
return
|
||||
if(liver)
|
||||
if(liver.damage < liver.maxHealth)
|
||||
liver.organ_flags |= ORGAN_FAILING
|
||||
liver_failure()
|
||||
else
|
||||
if(!liver || liver.organ_flags & ORGAN_FAILING)
|
||||
liver_failure()
|
||||
|
||||
/mob/living/carbon/proc/undergoing_liver_failure()
|
||||
var/obj/item/organ/liver/liver = getorganslot(ORGAN_SLOT_LIVER)
|
||||
if(liver && liver.failing)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/proc/return_liver_damage()
|
||||
var/obj/item/organ/liver/liver = getorganslot(ORGAN_SLOT_LIVER)
|
||||
if(liver)
|
||||
return liver.damage
|
||||
|
||||
/mob/living/carbon/proc/applyLiverDamage(var/d)
|
||||
var/obj/item/organ/liver/L = getorganslot(ORGAN_SLOT_LIVER)
|
||||
if(L)
|
||||
L.damage += d
|
||||
|
||||
/mob/living/carbon/proc/liver_failure()
|
||||
reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs
|
||||
reagents.metabolize(src, can_overdose=FALSE, liverless = TRUE)
|
||||
if(HAS_TRAIT(src, TRAIT_STABLELIVER))
|
||||
return
|
||||
adjustToxLoss(4, TRUE, TRUE)
|
||||
if(prob(30))
|
||||
to_chat(src, "<span class='warning'>You feel a stabbing pain in your abdomen!</span>")
|
||||
if(prob(15))
|
||||
to_chat(src, "<span class='danger'>You feel a stabbing pain in your abdomen!</span>")
|
||||
|
||||
|
||||
////////////////
|
||||
|
||||
@@ -90,9 +90,9 @@
|
||||
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
|
||||
return
|
||||
|
||||
if(client && hud_used && hud_used.inv_slots[SLOT_WEAR_MASK])
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
|
||||
inv.update_icon()
|
||||
inv?.update_icon()
|
||||
|
||||
if(wear_mask)
|
||||
if(!(head && (head.flags_inv & HIDEMASK)))
|
||||
@@ -110,7 +110,7 @@
|
||||
|
||||
if(wear_neck)
|
||||
if(!(head && (head.flags_inv & HIDENECK)))
|
||||
overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(default_layer = NECK_LAYER, default_icon_file = 'icons/mob/clothing/neck.dmi', override_state = wear_mask.icon_state)
|
||||
overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(default_layer = NECK_LAYER, default_icon_file = 'icons/mob/clothing/neck.dmi', override_state = wear_neck.icon_state)
|
||||
update_hud_neck(wear_neck)
|
||||
|
||||
apply_overlay(NECK_LAYER)
|
||||
@@ -118,9 +118,9 @@
|
||||
/mob/living/carbon/update_inv_back()
|
||||
remove_overlay(BACK_LAYER)
|
||||
|
||||
if(client && hud_used && hud_used.inv_slots[SLOT_BACK])
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_BACK]
|
||||
inv.update_icon()
|
||||
inv?.update_icon()
|
||||
|
||||
if(back)
|
||||
overlays_standing[BACK_LAYER] = back.build_worn_icon(default_layer = BACK_LAYER, default_icon_file = 'icons/mob/clothing/back.dmi', override_state = back.icon_state)
|
||||
@@ -134,9 +134,9 @@
|
||||
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
|
||||
return
|
||||
|
||||
if(client && hud_used && hud_used.inv_slots[SLOT_BACK])
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
|
||||
inv.update_icon()
|
||||
inv?.update_icon()
|
||||
|
||||
if(head)
|
||||
overlays_standing[HEAD_LAYER] = head.build_worn_icon(default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/clothing/head.dmi', override_state = head.icon_state)
|
||||
|
||||
@@ -354,7 +354,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
|
||||
if(cultslurring)
|
||||
message = cultslur(message)
|
||||
|
||||
|
||||
if(clockcultslurring)
|
||||
message = CLOCK_CULT_SLUR(message)
|
||||
|
||||
|
||||
@@ -400,10 +400,9 @@
|
||||
action.button_icon_state = "wrap_[active]"
|
||||
action.UpdateButtonIcon()
|
||||
|
||||
/obj/effect/proc_holder/wrap/Click()
|
||||
if(!istype(usr, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
|
||||
/obj/effect/proc_holder/wrap/Trigger(mob/living/simple_animal/hostile/poison/giant_spider/nurse/user)
|
||||
if(!istype(user))
|
||||
return TRUE
|
||||
var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/user = usr
|
||||
activate(user)
|
||||
return TRUE
|
||||
|
||||
@@ -444,7 +443,7 @@
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
button_icon_state = "lay_eggs"
|
||||
|
||||
/datum/action/innate/spider/lay_eggs/IsAvailable()
|
||||
/datum/action/innate/spider/lay_eggs/IsAvailable(silent = FALSE)
|
||||
if(..())
|
||||
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
|
||||
return 0
|
||||
@@ -508,7 +507,7 @@
|
||||
desc = "Send a command to all living spiders."
|
||||
button_icon_state = "command"
|
||||
|
||||
/datum/action/innate/spider/comm/IsAvailable()
|
||||
/datum/action/innate/spider/comm/IsAvailable(silent = FALSE)
|
||||
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse/midwife))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
background_icon_state = "bg_alien"
|
||||
var/needs_growth = NO_GROWTH_NEEDED
|
||||
|
||||
/datum/action/innate/slime/IsAvailable()
|
||||
/datum/action/innate/slime/IsAvailable(silent = FALSE)
|
||||
if(..())
|
||||
var/mob/living/simple_animal/slime/S = owner
|
||||
if(needs_growth == GROWTH_NEEDED)
|
||||
|
||||
@@ -513,7 +513,7 @@
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "sniper_zoom"
|
||||
|
||||
/datum/action/item_action/toggle_scope_zoom/IsAvailable()
|
||||
/datum/action/item_action/toggle_scope_zoom/IsAvailable(silent = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
var/obj/item/gun/G = target
|
||||
|
||||
@@ -43,8 +43,8 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
booze_power *= 0.7
|
||||
C.drunkenness = max((C.drunkenness + (sqrt(volume) * booze_power * ALCOHOL_RATE)), 0) //Volume, power, and server alcohol rate effect how quickly one gets drunk
|
||||
var/obj/item/organ/liver/L = C.getorganslot(ORGAN_SLOT_LIVER)
|
||||
if (istype(L))
|
||||
C.applyLiverDamage((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * L.alcohol_tolerance, 0))/150)
|
||||
if(L)
|
||||
L.applyOrganDamage((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * L.alcohol_tolerance, 0))/150)
|
||||
return ..()
|
||||
|
||||
/datum/reagent/consumable/ethanol/reaction_obj(obj/O, reac_volume)
|
||||
@@ -1646,7 +1646,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
glass_icon_state = "pina_colada"
|
||||
glass_name = "Pina Colada"
|
||||
glass_desc = "If you like pina coladas, and getting caught in the rain... well, you'll like this drink."
|
||||
|
||||
|
||||
/datum/reagent/consumable/ethanol/grasshopper
|
||||
name = "Grasshopper"
|
||||
description = "A fresh and sweet dessert shooter. Difficult to look manly while drinking this."
|
||||
@@ -2354,7 +2354,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
/datum/reagent/consumable/ethanol/hotlime_miami/on_mob_life(mob/living/carbon/M)
|
||||
M.set_drugginess(50)
|
||||
M.adjustStaminaLoss(-2)
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
/datum/reagent/consumable/ethanol/fruit_wine
|
||||
name = "Fruit Wine"
|
||||
|
||||
@@ -263,9 +263,9 @@
|
||||
/datum/reagent/medicine/silver_sulfadiazine/overdose_start(mob/living/M)
|
||||
metabolization_rate = 15 * REAGENTS_METABOLISM
|
||||
M.adjustBruteLoss(2*REM, 0)
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
C.applyLiverDamage(1)
|
||||
var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
|
||||
if(L)
|
||||
L.applyOrganDamage(1)
|
||||
..()
|
||||
. = 1
|
||||
|
||||
@@ -326,9 +326,9 @@
|
||||
datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
|
||||
metabolization_rate = 15 * REAGENTS_METABOLISM
|
||||
M.adjustBruteLoss(2*REM, 0)
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
C.applyLiverDamage(1)
|
||||
var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
|
||||
if(L)
|
||||
L.applyOrganDamage(1)
|
||||
..()
|
||||
. = 1
|
||||
|
||||
|
||||
@@ -1070,11 +1070,11 @@
|
||||
to_chat(M, "<span class='userdanger'>You start feeling your guts twisting painfully!</span>")
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/overdose, name)
|
||||
|
||||
/datum/reagent/iron/overdose_process(mob/living/carbon/C)
|
||||
/datum/reagent/iron/overdose_process(mob/living/M)
|
||||
if(prob(20))
|
||||
var/obj/item/organ/liver/L = C.getorganslot(ORGAN_SLOT_LIVER)
|
||||
if (istype(L))
|
||||
C.applyLiverDamage(2) //mild until the fabled med rework comes out. the organ damage galore
|
||||
var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
|
||||
if(L)
|
||||
L.applyOrganDamage(2)
|
||||
..()
|
||||
|
||||
/datum/reagent/gold
|
||||
|
||||
@@ -45,6 +45,12 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
|
||||
/obj/effect/proc_holder/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/Click()
|
||||
return Trigger(usr, FALSE)
|
||||
|
||||
/obj/effect/proc_holder/proc/Trigger(mob/user)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/proc/InterceptClickOn(mob/living/caller, params, atom/A)
|
||||
if(caller.ranged_ability != src || ranged_ability_user != caller) //I'm not actually sure how these would trigger, but, uh, safety, I guess?
|
||||
to_chat(caller, "<span class='warning'><b>[caller.ranged_ability.name]</b> has been disabled.</span>")
|
||||
@@ -150,8 +156,8 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
|
||||
if(mobs_blacklist)
|
||||
mobs_blacklist = typecacheof(mobs_blacklist)
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = FALSE, mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell
|
||||
if(!can_cast(user, skipcharge))
|
||||
/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = FALSE, mob/user = usr, skip_can_cast = FALSE) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell
|
||||
if(!skip_can_cast && !can_cast(user, skipcharge))
|
||||
return FALSE
|
||||
|
||||
if(!skipcharge)
|
||||
@@ -181,17 +187,22 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/invocation(mob/user = usr) //spelling the spell out and setting it on recharge/reducing charges amount
|
||||
var/mob/living/L
|
||||
if(isliving(user))
|
||||
L = user
|
||||
switch(invocation_type)
|
||||
if("shout")
|
||||
if(prob(50))//Auto-mute? Fuck that noise
|
||||
user.say(invocation, forced = "spell")
|
||||
else
|
||||
user.say(replacetext(invocation," ","`"), forced = "spell")
|
||||
if(!L || L.can_speak_vocal(invocation))
|
||||
if(prob(50))//Auto-mute? Fuck that noise
|
||||
user.say(invocation, forced = "spell")
|
||||
else
|
||||
user.say(replacetext(invocation," ","`"), forced = "spell")
|
||||
if("whisper")
|
||||
if(prob(50))
|
||||
user.whisper(invocation)
|
||||
else
|
||||
user.whisper(replacetext(invocation," ","`"))
|
||||
if(!L || L.can_speak_vocal(invocation))
|
||||
if(prob(50))
|
||||
user.whisper(invocation)
|
||||
else
|
||||
user.whisper(replacetext(invocation," ","`"))
|
||||
if("emote")
|
||||
user.visible_message(invocation, invocation_emote_self) //same style as in mob/living/emote.dm
|
||||
|
||||
@@ -210,8 +221,8 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
|
||||
qdel(action)
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/Click()
|
||||
if(cast_check())
|
||||
/obj/effect/proc_holder/spell/Trigger(mob/user, skip_can_cast = TRUE)
|
||||
if(cast_check(FALSE, user, skip_can_cast))
|
||||
choose_targets()
|
||||
return 1
|
||||
|
||||
@@ -432,7 +443,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/spell/proc/can_cast(mob/user = usr, skipcharge = FALSE, silent = FALSE)
|
||||
var/magic_flags = SEND_SIGNAL(user, COMSIG_MOB_SPELL_CAST_CHECK, src)
|
||||
var/magic_flags = SEND_SIGNAL(user, COMSIG_MOB_SPELL_CAN_CAST, src)
|
||||
if(magic_flags & SPELL_SKIP_ALL_REQS)
|
||||
return TRUE
|
||||
|
||||
@@ -448,9 +459,8 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
|
||||
to_chat(user, "<span class='notice'>You can't cast this spell here.</span>")
|
||||
return FALSE
|
||||
|
||||
if(!skipcharge)
|
||||
if(!charge_check(user))
|
||||
return FALSE
|
||||
if(!skipcharge && !charge_check(user, silent))
|
||||
return FALSE
|
||||
|
||||
if(user.stat && !stat_allowed && !(magic_flags & SPELL_SKIP_STAT))
|
||||
if(!silent)
|
||||
|
||||
@@ -11,12 +11,11 @@
|
||||
var/current_amount = 0 //How many projectiles left.
|
||||
var/projectiles_per_fire = 1 //Projectiles per fire. Probably not a good thing to use unless you override ready_projectile().
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/Click()
|
||||
var/mob/living/user = usr
|
||||
/obj/effect/proc_holder/spell/aimed/Trigger(mob/user, skip_can_cast = TRUE)
|
||||
if(!istype(user))
|
||||
return
|
||||
var/msg
|
||||
if(!can_cast(user, FALSE, TRUE))
|
||||
if(!skip_can_cast && !can_cast(user, FALSE, TRUE))
|
||||
msg = "<span class='warning'>You can no longer cast [name]!</span>"
|
||||
remove_ranged_ability(msg)
|
||||
return
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
action_icon_state = "lightning"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/tesla/Click()
|
||||
if(!ready && cast_check())
|
||||
StartChargeup()
|
||||
/obj/effect/proc_holder/spell/targeted/tesla/Trigger(mob/user, skip_can_cast = TRUE)
|
||||
if(!ready && cast_check(FALSE, user, skip_can_cast))
|
||||
StartChargeup(user)
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/tesla/proc/StartChargeup(mob/user = usr)
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall/Click()
|
||||
if(usr && usr.mind)
|
||||
if(!usr.mind.miming)
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall/Trigger(mob/user, skip_can_cast = TRUE)
|
||||
if(user.mind)
|
||||
if(!user.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> looks as if a wall is in front of [usr.p_them()]."
|
||||
invocation = "<B>[user.real_name]</B> looks as if a wall is in front of [user.p_them()]."
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
@@ -41,17 +41,12 @@
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mime/speak/Click()
|
||||
if(!usr)
|
||||
return
|
||||
if(!ishuman(usr))
|
||||
return
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if(H.mind.miming)
|
||||
/obj/effect/proc_holder/spell/targeted/mime/speak/Trigger(mob/user, skip_can_cast = TRUE)
|
||||
if(user.mind?.miming)
|
||||
still_recharging_msg = "<span class='warning'>You can't break your vow of silence that fast!</span>"
|
||||
else
|
||||
still_recharging_msg = "<span class='warning'>You'll have to wait before you can give your vow of silence again!</span>"
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/mime/speak/cast(list/targets,mob/user = usr)
|
||||
for(var/mob/living/carbon/human/H in targets)
|
||||
@@ -82,15 +77,15 @@
|
||||
action_icon_state = "mime"
|
||||
action_background_icon_state = "bg_mime"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/forcewall/mime/Click()
|
||||
if(usr && usr.mind)
|
||||
if(!usr.mind.miming)
|
||||
/obj/effect/proc_holder/spell/targeted/forcewall/mime/Trigger(mob/user, skip_can_cast = TRUE)
|
||||
if(user.mind)
|
||||
if(!user.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> looks as if a blockade is in front of [usr.p_them()]."
|
||||
invocation = "<B>[user.real_name]</B> looks as if a blockade is in front of [user.p_them()]."
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/finger_guns
|
||||
name = "Finger Guns"
|
||||
@@ -114,19 +109,18 @@
|
||||
base_icon_state = "mime"
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aimed/finger_guns/Click()
|
||||
var/mob/living/carbon/human/owner = usr
|
||||
if(owner.incapacitated())
|
||||
to_chat(owner, "<span class='warning'>You can't properly point your fingers while incapacitated.</span>")
|
||||
/obj/effect/proc_holder/spell/aimed/finger_guns/Trigger(mob/user, skip_can_cast = TRUE)
|
||||
if(user.incapacitated())
|
||||
to_chat(user, "<span class='warning'>You can't properly point your fingers while incapacitated.</span>")
|
||||
return
|
||||
if(usr && usr.mind)
|
||||
if(!usr.mind.miming)
|
||||
if(user.mind)
|
||||
if(!user.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
invocation = "<B>[usr.real_name]</B> fires [usr.p_their()] finger gun!"
|
||||
invocation = "<B>[user.real_name]</B> fires [user.p_their()] finger gun!"
|
||||
else
|
||||
invocation_type ="none"
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/touch/mimerope
|
||||
name = "Invisible Rope"
|
||||
@@ -144,8 +138,8 @@
|
||||
action_background_icon_state = "bg_mime"
|
||||
hand_path = /obj/item/melee/touch_attack/mimerope
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/touch/mimerope/Click()
|
||||
if(usr && usr.mind)
|
||||
/obj/effect/proc_holder/spell/targeted/touch/mimerope/Trigger(mob/user, skip_can_cast = TRUE)
|
||||
if(user.mind)
|
||||
if(!usr.mind.miming)
|
||||
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
|
||||
return
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#define LIVER_DEFAULT_HEALTH 100 //amount of damage required for liver failure
|
||||
#define LIVER_DEFAULT_TOX_TOLERANCE 3 //amount of toxins the liver can filter out
|
||||
#define LIVER_DEFAULT_TOX_LETHALITY 0.01 //lower values lower how harmful toxins are to the liver
|
||||
#define LIVER_SWELLING_MOVE_MODIFY "pharma"
|
||||
|
||||
/obj/item/organ/liver
|
||||
name = "liver"
|
||||
@@ -15,12 +14,14 @@
|
||||
healing_factor = STANDARD_ORGAN_HEALING
|
||||
decay_factor = STANDARD_ORGAN_DECAY
|
||||
|
||||
high_threshold_passed = "<span class='warning'>You feel a stange ache in your abdomen, almost like a stitch. This pain is encumbering your movements.</span>"
|
||||
high_threshold_cleared = "<span class='notice'>The stitching ache in your abdomen passes away, unencumbering your movements.</span>"
|
||||
now_fixed = "<span class='notice'>The stabbing pain in your abdomen slowly calms down into a more tolerable ache.</span>"
|
||||
|
||||
var/alcohol_tolerance = ALCOHOL_RATE//affects how much damage the liver takes from alcohol
|
||||
var/failing //is this liver failing?
|
||||
var/toxTolerance = LIVER_DEFAULT_TOX_TOLERANCE//maximum amount of toxins the liver can just shrug off
|
||||
var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY//affects how much damage toxins do to the liver
|
||||
var/filterToxins = TRUE //whether to filter toxins
|
||||
var/swelling = 0
|
||||
var/cachedmoveCalc = 1
|
||||
|
||||
/obj/item/organ/liver/on_life()
|
||||
@@ -28,8 +29,6 @@
|
||||
|
||||
if(istype(C))
|
||||
if(!(organ_flags & ORGAN_FAILING))//can't process reagents with a failing liver
|
||||
//slowly heal liver damage
|
||||
damage = max(0, damage - 0.1)
|
||||
|
||||
if(filterToxins && !HAS_TRAIT(owner, TRAIT_TOXINLOVER))
|
||||
//handle liver toxin filtration
|
||||
@@ -46,42 +45,41 @@
|
||||
if(damage > 10 && prob(damage/3))//the higher the damage the higher the probability
|
||||
to_chat(C, "<span class='warning'>You feel a dull pain in your abdomen.</span>")
|
||||
|
||||
if(damage > maxHealth)//cap liver damage
|
||||
damage = maxHealth
|
||||
|
||||
if(swelling >= 10)
|
||||
pharmacokinesis()
|
||||
|
||||
/obj/item/organ/liver/prepare_eat()
|
||||
var/obj/S = ..()
|
||||
S.reagents.add_reagent(/datum/reagent/iron, 5)
|
||||
return S
|
||||
|
||||
//Just in case
|
||||
/obj/item/organ/liver/applyOrganDamage(d, maximum = maxHealth)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(damage >= high_threshold)
|
||||
var/move_calc = 1+((round(damage) - high_threshold)/(high_threshold/3))
|
||||
owner.add_movespeed_modifier(MOVESPEED_ID_CIRRHOSIS, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = move_calc)
|
||||
sizeMoveMod(move_calc, owner)
|
||||
else
|
||||
owner.remove_movespeed_modifier(MOVESPEED_ID_CIRRHOSIS)
|
||||
sizeMoveMod(1, owner)
|
||||
|
||||
/obj/item/organ/liver/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE)
|
||||
. = ..()
|
||||
if(. && damage >= high_threshold)
|
||||
var/move_calc = 1+((round(damage) - high_threshold)/(high_threshold/3))
|
||||
M.add_movespeed_modifier(MOVESPEED_ID_CIRRHOSIS, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = move_calc)
|
||||
sizeMoveMod(move_calc, owner)
|
||||
|
||||
/obj/item/organ/liver/Remove(special = FALSE)
|
||||
if(!QDELETED(owner))
|
||||
owner.remove_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY)
|
||||
owner.ResetBloodVol() //At the moment, this shouldn't allow application twice. You either have this OR a thirsty ferret.
|
||||
owner.remove_movespeed_modifier(MOVESPEED_ID_CIRRHOSIS)
|
||||
sizeMoveMod(1, owner)
|
||||
return ..()
|
||||
|
||||
//Applies some of the effects to the patient.
|
||||
/obj/item/organ/liver/proc/pharmacokinesis()
|
||||
var/moveCalc = 1+((round(swelling) - 9)/3)
|
||||
if(moveCalc == cachedmoveCalc)//reduce calculations
|
||||
return
|
||||
if(prob(5))
|
||||
to_chat(owner, "<span class='notice'>You feel a stange ache in your side, almost like a stitch. This pain is affecting your movements and making you feel lightheaded.</span>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.add_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
|
||||
H.AdjustBloodVol(moveCalc/3)
|
||||
sizeMoveMod(moveCalc, H)
|
||||
|
||||
/obj/item/organ/liver/proc/sizeMoveMod(var/value, mob/living/carbon/human/H)
|
||||
/obj/item/organ/liver/proc/sizeMoveMod(value, mob/living/carbon/C)
|
||||
if(cachedmoveCalc == value)
|
||||
return
|
||||
H.next_move_modifier /= cachedmoveCalc
|
||||
H.next_move_modifier *= value
|
||||
C.next_move_modifier /= cachedmoveCalc
|
||||
C.next_move_modifier *= value
|
||||
cachedmoveCalc = value
|
||||
|
||||
/obj/item/organ/liver/fly
|
||||
|
||||
@@ -143,8 +143,9 @@
|
||||
var/healing_amount = -(maxHealth * healing_factor)
|
||||
///Damage decrements again by a percent of its maxhealth, up to a total of 4 extra times depending on the owner's health
|
||||
healing_amount -= owner.satiety > 0 ? 4 * healing_factor * owner.satiety / MAX_SATIETY : 0
|
||||
applyOrganDamage(healing_amount) //to FERMI_TWEAK
|
||||
//Make it so each threshold is stuck.
|
||||
if(healing_amount)
|
||||
applyOrganDamage(healing_amount) //to FERMI_TWEAK
|
||||
//Make it so each threshold is stuck.
|
||||
|
||||
/obj/item/organ/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -205,14 +206,15 @@
|
||||
///Adjusts an organ's damage by the amount "d", up to a maximum amount, which is by default max damage
|
||||
/obj/item/organ/proc/applyOrganDamage(var/d, var/maximum = maxHealth) //use for damaging effects
|
||||
if(!d) //Micro-optimization.
|
||||
return
|
||||
return FALSE
|
||||
if(maximum < damage)
|
||||
return
|
||||
return FALSE
|
||||
damage = CLAMP(damage + d, 0, maximum)
|
||||
var/mess = check_damage_thresholds(owner)
|
||||
var/mess = check_damage_thresholds()
|
||||
prev_damage = damage
|
||||
if(mess && owner)
|
||||
to_chat(owner, mess)
|
||||
return TRUE
|
||||
|
||||
///SETS an organ's damage to the amount "d", and in doing so clears or sets the failing flag, good for when you have an effect that should fix an organ if broken
|
||||
/obj/item/organ/proc/setOrganDamage(var/d) //use mostly for admin heals
|
||||
@@ -224,7 +226,7 @@
|
||||
* description: By checking our current damage against our previous damage, we can decide whether we've passed an organ threshold.
|
||||
* If we have, send the corresponding threshold message to the owner, if such a message exists.
|
||||
*/
|
||||
/obj/item/organ/proc/check_damage_thresholds(var/M)
|
||||
/obj/item/organ/proc/check_damage_thresholds()
|
||||
if(damage == prev_damage)
|
||||
return
|
||||
var/delta = damage - prev_damage
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
..()
|
||||
cords = target
|
||||
|
||||
/datum/action/item_action/organ_action/colossus/IsAvailable()
|
||||
/datum/action/item_action/organ_action/colossus/IsAvailable(silent = FALSE)
|
||||
if(world.time < cords.next_command)
|
||||
return FALSE
|
||||
if(!owner)
|
||||
@@ -632,7 +632,7 @@
|
||||
..()
|
||||
cords = target
|
||||
|
||||
/datum/action/item_action/organ_action/velvet/IsAvailable()
|
||||
/datum/action/item_action/organ_action/velvet/IsAvailable(silent = FALSE)
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/organ_action/velvet/Trigger()
|
||||
|
||||
@@ -83,4 +83,10 @@
|
||||
name = "Thieving Gloves"
|
||||
desc = "A pair of gloves that are insulated and frictionless, allowing you to steal easily from anyone you see."
|
||||
item = /obj/item/clothing/gloves/thief
|
||||
cost = 4
|
||||
cost = 4
|
||||
|
||||
/datum/uplink_item/suits/wallwalkers
|
||||
name = "Wall Walking Boots"
|
||||
desc = "Through bluespace magic stolen from an organisation that hoards technology, these boots simply allow you to slip through the atoms that make up anything, but only while walking, for safety reasons. As well as this, they unfortunately cause minor breath loss as the majority of atoms in your lungs are sucked out into any solid object you walk through."
|
||||
item = /obj/item/clothing/shoes/wallwalkers
|
||||
cost = 6
|
||||
@@ -20,6 +20,12 @@
|
||||
item = /obj/item/emagrecharge
|
||||
cost = 2
|
||||
|
||||
/datum/uplink_item/device_tools/bluespacerecharge
|
||||
name = "Bluespace Crystal Recharging Device"
|
||||
desc = "A small device intended for recharging Wall Walking boots. Using it will add six charges to them. Use ten bluespace crystals on this recharger to add three more charges to it. "
|
||||
item = /obj/item/bluespacerecharge
|
||||
cost = 2
|
||||
|
||||
/datum/uplink_item/device_tools/phantomthief
|
||||
name = "Syndicate Mask"
|
||||
desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles"
|
||||
|
||||
Reference in New Issue
Block a user