diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm
index 0ba005455c6..f3419b074af 100644
--- a/code/_onclick/telekinesis.dm
+++ b/code/_onclick/telekinesis.dm
@@ -74,135 +74,104 @@ var/const/tk_maxrange = 15
var/atom/movable/focus = null
var/mob/living/host = null
+/obj/item/tk_grab/dropped(mob/user as mob)
+ if(focus && user && loc != user && loc != user.loc) // drop_item() gets called when you tk-attack a table/closet with an item
+ if(focus.Adjacent(loc))
+ focus.loc = loc
+ loc = null
+ spawn(1)
+ qdel(src)
+ return
- dropped(mob/user as mob)
- if(focus && user && loc != user && loc != user.loc) // drop_item() gets called when you tk-attack a table/closet with an item
- if(focus.Adjacent(loc))
- focus.loc = loc
+//stops TK grabs being equipped anywhere but into hands
+/obj/item/tk_grab/equipped(var/mob/user, var/slot)
+ if( (slot == slot_l_hand) || (slot== slot_r_hand) ) return
+ qdel(src)
+ return
+/obj/item/tk_grab/attack_self(mob/user as mob)
+ if(focus)
+ focus.attack_self_tk(user)
+
+/obj/item/tk_grab/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity)//TODO: go over this
+ if(!target || !user) return
+ if(last_throw+3 > world.time) return
+ if(!host || host != user)
qdel(src)
return
-
-
- //stops TK grabs being equipped anywhere but into hands
- equipped(var/mob/user, var/slot)
- if( (slot == slot_l_hand) || (slot== slot_r_hand) ) return
+ if(!(TK in host.mutations))
qdel(src)
return
+ if(isobj(target) && !isturf(target.loc))
+ return
-
- attack_self(mob/user as mob)
- if(focus)
- focus.attack_self_tk(user)
-
- afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity)//TODO: go over this
- if(!target || !user) return
- if(last_throw+3 > world.time) return
- if(!host || host != user)
- qdel(src)
- return
- if(!(TK in host.mutations))
- qdel(src)
- return
- if(isobj(target) && !isturf(target.loc))
- return
-
- var/d = get_dist(user, target)
- if(focus) d = max(d,get_dist(user,focus)) // whichever is further
- switch(d)
- if(0)
- ;
- if(1 to 5) // not adjacent may mean blocked by window
- if(!proximity)
- user.next_move += 2
- if(5 to 7)
- user.next_move += 5
- if(8 to tk_maxrange)
- user.next_move += 10
- else
- user << "Your mind won't reach that far."
- return
-
- if(!focus)
- focus_object(target, user)
- return
-
- if(target == focus)
- target.attack_self_tk(user)
- return // todo: something like attack_self not laden with assumptions inherent to attack_self
-
-
- if(!istype(target, /turf) && istype(focus,/obj/item) && target.Adjacent(focus))
- var/obj/item/I = focus
- var/resolved = target.attackby(I, user, user:get_organ_target())
- if(!resolved && target && I)
- I.afterattack(target,user,1) // for splashing with beakers
-
-
+ var/d = get_dist(user, target)
+ if(focus) d = max(d,get_dist(user,focus)) // whichever is further
+ switch(d)
+ if(0)
+ ;
+ if(1 to 5) // not adjacent may mean blocked by window
+ if(!proximity)
+ user.next_move += 2
+ if(5 to 7)
+ user.next_move += 5
+ if(8 to tk_maxrange)
+ user.next_move += 10
else
- apply_focus_overlay()
- focus.throw_at(target, 10, 1, user)
- last_throw = world.time
- return
-
- attack(mob/living/M as mob, mob/living/user as mob, def_zone)
- return
-
-
- proc/focus_object(var/obj/target, var/mob/living/user)
- if(!istype(target,/obj)) return//Cant throw non objects atm might let it do mobs later
- if(target.anchored || !isturf(target.loc))
- qdel(src)
+ user << "Your mind won't reach that far."
return
- focus = target
- update_icon()
+
+ if(!focus)
+ focus_object(target, user)
+ return
+
+ if(target == focus)
+ target.attack_self_tk(user)
+ return // todo: something like attack_self not laden with assumptions inherent to attack_self
+
+
+ if(!istype(target, /turf) && istype(focus,/obj/item) && target.Adjacent(focus))
+ var/obj/item/I = focus
+ var/resolved = target.attackby(I, user, user:get_organ_target())
+ if(!resolved && target && I)
+ I.afterattack(target,user,1) // for splashing with beakers
+ else
apply_focus_overlay()
+ focus.throw_at(target, 10, 1, user)
+ last_throw = world.time
+ return
+
+/obj/item/tk_grab/attack(mob/living/M as mob, mob/living/user as mob, def_zone)
+ return
+
+
+/obj/item/tk_grab/proc/focus_object(var/obj/target, var/mob/living/user)
+ if(!istype(target,/obj)) return//Cant throw non objects atm might let it do mobs later
+ if(target.anchored || !isturf(target.loc))
+ qdel(src)
return
-
-
- proc/apply_focus_overlay()
- if(!focus) return
- var/obj/effect/overlay/O = PoolOrNew(/obj/effect/overlay, locate(focus.x,focus.y,focus.z))
- O.name = "sparkles"
- O.anchored = 1
- O.density = 0
- O.layer = FLY_LAYER
- O.set_dir(pick(cardinal))
- O.icon = 'icons/effects/effects.dmi'
- O.icon_state = "nothing"
- flick("empdisable",O)
- spawn(5)
- qdel(O)
- return
-
-
+ focus = target
update_icon()
- overlays.Cut()
- if(focus && focus.icon && focus.icon_state)
- overlays += icon(focus.icon,focus.icon_state)
- return
+ apply_focus_overlay()
+ return
-/*Not quite done likely needs to use something thats not get_step_to
- proc/check_path()
- var/turf/ref = get_turf(src.loc)
- var/turf/target = get_turf(focus.loc)
- if(!ref || !target) return 0
- var/distance = get_dist(ref, target)
- if(distance >= 10) return 0
- for(var/i = 1 to distance)
- ref = get_step_to(ref, target, 0)
- if(ref != target) return 0
- return 1
-*/
-
-//equip_to_slot_or_del(obj/item/W, slot, del_on_fail = 1)
-/*
- if(istype(user, /mob/living/carbon))
- if(user:mutations & TK && get_dist(source, user) <= 7)
- if(user:get_active_hand()) return 0
- var/X = source:x
- var/Y = source:y
- var/Z = source:z
-
-*/
+/obj/item/tk_grab/proc/apply_focus_overlay()
+ if(!focus) return
+ var/obj/effect/overlay/O = PoolOrNew(/obj/effect/overlay, locate(focus.x,focus.y,focus.z))
+ O.name = "sparkles"
+ O.anchored = 1
+ O.density = 0
+ O.layer = FLY_LAYER
+ O.set_dir(pick(cardinal))
+ O.icon = 'icons/effects/effects.dmi'
+ O.icon_state = "nothing"
+ flick("empdisable",O)
+ spawn(5)
+ qdel(O)
+ return
+/obj/item/tk_grab/update_icon()
+ overlays.Cut()
+ if(focus && focus.icon && focus.icon_state)
+ overlays += icon(focus.icon,focus.icon_state)
+ return
diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm
index 54a9fc8092b..c697f1a4c11 100644
--- a/code/game/objects/structures/crates_lockers/largecrate.dm
+++ b/code/game/objects/structures/crates_lockers/largecrate.dm
@@ -13,8 +13,8 @@
if(istype(W, /obj/item/weapon/crowbar))
new /obj/item/stack/material/wood(src)
var/turf/T = get_turf(src)
- for(var/obj/O in contents)
- O.loc = T
+ for(var/atom/movable/AM in contents)
+ if(AM.simulated) AM.loc = T
user.visible_message("[user] pries \the [src] open.", \
"You pry open \the [src].", \
"You hear splitting wood.")
@@ -73,4 +73,4 @@
/obj/structure/largecrate/animal/chick
name = "chicken crate"
held_count = 5
- held_type = /mob/living/simple_animal/chick
\ No newline at end of file
+ held_type = /mob/living/simple_animal/chick
diff --git a/code/modules/materials/material_sheets.dm b/code/modules/materials/material_sheets.dm
index 82d55960df2..cfe4e1ed474 100644
--- a/code/modules/materials/material_sheets.dm
+++ b/code/modules/materials/material_sheets.dm
@@ -29,7 +29,8 @@
desc = "A stack of sheets of [material.display_name]."
recipes = material.get_recipes()
stacktype = material.stack_type
- origin_tech = material.stack_origin_tech.Copy()
+ if(islist(material.stack_origin_tech))
+ origin_tech = material.stack_origin_tech.Copy()
perunit = SHEET_MATERIAL_AMOUNT
if(apply_colour)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 65a05fdcea0..1faf2f7e7ab 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -440,19 +440,19 @@ emp_act
var/penetrated_dam = max(0,(damage - SS.breach_threshold))
if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam)
-/mob/living/human/reagent_permeability()
+/mob/living/carbon/human/reagent_permeability()
var/perm = 0
-
+
var/list/perm_by_part = list(
- "head" = THERMAL_PROTECTION_HEAD,
- "upper_torso" = THERMAL_PROTECTION_UPPER_TORSO,
- "lower_torso" = THERMAL_PROTECTION_LOWER_TORSO,
- "legs" = THERMAL_PROTECTION_LEG_LEFT + THERMAL_PROTECTION_LEG_RIGHT,
- "feet" = THERMAL_PROTECTION_FOOT_LEFT + THERMAL_PROTECTION_FOOT_RIGHT,
- "arms" = THERMAL_PROTECTION_ARM_LEFT + THERMAL_PROTECTION_ARM_RIGHT,
+ "head" = THERMAL_PROTECTION_HEAD,
+ "upper_torso" = THERMAL_PROTECTION_UPPER_TORSO,
+ "lower_torso" = THERMAL_PROTECTION_LOWER_TORSO,
+ "legs" = THERMAL_PROTECTION_LEG_LEFT + THERMAL_PROTECTION_LEG_RIGHT,
+ "feet" = THERMAL_PROTECTION_FOOT_LEFT + THERMAL_PROTECTION_FOOT_RIGHT,
+ "arms" = THERMAL_PROTECTION_ARM_LEFT + THERMAL_PROTECTION_ARM_RIGHT,
"hands" = THERMAL_PROTECTION_HAND_LEFT + THERMAL_PROTECTION_HAND_RIGHT
)
-
+
for(var/obj/item/clothing/C in src.get_equipped_items())
if(C.permeability_coefficient == 1 || !C.body_parts_covered)
continue
@@ -470,9 +470,9 @@ emp_act
perm_by_part["arms"] *= C.permeability_coefficient
if(C.body_parts_covered & HANDS)
perm_by_part["hands"] *= C.permeability_coefficient
-
+
for(var/part in perm_by_part)
perm += perm_by_part[part]
-
+
return perm
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index a4ab3322217..4b6a03a7e24 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -838,13 +838,13 @@ Note that amputating the affected organ does in fact remove the infection from t
if((status & ORGAN_BROKEN) || cannot_break)
return
- owner.visible_message(\
- "\red You hear a loud cracking sound coming from \the [owner].",\
- "\red Something feels like it shattered in your [name]!",\
- "You hear a sickening crack.")
-
- if(owner.species && !(owner.species.flags & NO_PAIN))
- owner.emote("scream")
+ if(owner)
+ owner.visible_message(\
+ "\red You hear a loud cracking sound coming from \the [owner].",\
+ "\red Something feels like it shattered in your [name]!",\
+ "You hear a sickening crack.")
+ if(owner.species && !(owner.species.flags & NO_PAIN))
+ owner.emote("scream")
status |= ORGAN_BROKEN
broken_description = pick("broken","fracture","hairline fracture")
@@ -857,7 +857,7 @@ Note that amputating the affected organ does in fact remove the infection from t
// This is mostly for the ninja suit to stop ninja being so crippled by breaks.
// TODO: consider moving this to a suit proc or process() or something during
// hardsuit rewrite.
- if(!(status & ORGAN_SPLINTED) && istype(owner,/mob/living/carbon/human))
+ if(owner && !(status & ORGAN_SPLINTED) && istype(owner,/mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
@@ -905,11 +905,11 @@ Note that amputating the affected organ does in fact remove the infection from t
if(src.status & ORGAN_ROBOT)
return
src.status |= ORGAN_MUTATED
- owner.update_body()
+ if(owner) owner.update_body()
/obj/item/organ/external/proc/unmutate()
src.status &= ~ORGAN_MUTATED
- owner.update_body()
+ if(owner) owner.update_body()
/obj/item/organ/external/proc/get_damage() //returns total damage
return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use max_damage?
@@ -929,7 +929,7 @@ Note that amputating the affected organ does in fact remove the infection from t
return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam))
/obj/item/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0)
- if(loc != owner)
+ if(!owner || loc != owner)
return
if(!silent)
owner.visible_message("\The [W] sticks in the wound!")
@@ -1013,7 +1013,7 @@ Note that amputating the affected organ does in fact remove the infection from t
/obj/item/organ/external/proc/get_wounds_desc()
. = ""
if(status & ORGAN_DESTROYED && !is_stump())
- . += "tear at [amputation_point] so bad it barely hangs on few tendons"
+ . += "tear at [amputation_point] so severe that it hangs by a scrap of flesh"
if(status & ORGAN_ROBOT)
if(brute_dam)