diff --git a/code/game/antagonist/antagonist_build.dm b/code/game/antagonist/antagonist_build.dm
index f0f92c62b7..34631d36fb 100644
--- a/code/game/antagonist/antagonist_build.dm
+++ b/code/game/antagonist/antagonist_build.dm
@@ -28,7 +28,9 @@
// This could use work.
if(flags & ANTAG_CLEAR_EQUIPMENT)
for(var/obj/item/thing in player.contents)
- del(thing)
+ player.drop_from_inventory(thing)
+ if(thing.loc != player)
+ del(thing)
return 1
if(flags & ANTAG_SET_APPEARANCE)
@@ -80,6 +82,7 @@
/datum/antagonist/proc/create_id(var/assignment, var/mob/living/carbon/human/player)
var/obj/item/weapon/card/id/W = new id_type(player)
+ if(!W) return
W.name = "[player.real_name]'s ID Card"
W.access |= default_access
W.assignment = "[assignment]"
diff --git a/code/game/antagonist/outsider/deathsquad.dm b/code/game/antagonist/outsider/deathsquad.dm
index 05fb6d1ec9..73c2c7fd78 100644
--- a/code/game/antagonist/outsider/deathsquad.dm
+++ b/code/game/antagonist/outsider/deathsquad.dm
@@ -44,8 +44,9 @@ var/datum/antagonist/deathsquad/deathsquad
player.implant_loyalty(player)
var/obj/item/weapon/card/id/id = create_id("Asset Protection", player)
- id.access |= get_all_accesses()
- id.icon_state = "centcom"
+ if(id)
+ id.access |= get_all_accesses()
+ id.icon_state = "centcom"
create_radio(DTH_FREQ, player)
/datum/antagonist/deathsquad/apply(var/datum/mind/player)
diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm
index 9bfdf9f0b6..e1fda4965c 100644
--- a/code/game/dna/dna2_helpers.dm
+++ b/code/game/dna/dna2_helpers.dm
@@ -165,7 +165,7 @@
if((0 < beard) && (beard <= facial_hair_styles_list.len))
H.f_style = facial_hair_styles_list[beard]
- H.update_body(0)
+ H.force_update_limbs()
H.update_hair()
return 1
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index 544776d144..8ad65194d1 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -98,8 +98,8 @@ var/global/datum/controller/gameticker/ticker
src.mode = config.pick_mode(master_mode)
if(!mode_started && !src.mode.can_start())
world << "Unable to start [mode.name]. Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby."
- del(mode)
current_state = GAME_STATE_PREGAME
+ mode = null
job_master.ResetOccupations()
return 0
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index ea56c749b8..829ee6e86d 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -151,7 +151,7 @@ var/list/slot_equipment_priority = list( \
remove_from_mob(W)
if(!W) return 1 // self destroying objects (tk, grabs)
-
+
W.forceMove(Target)
update_icons()
return 1
@@ -173,11 +173,11 @@ var/list/slot_equipment_priority = list( \
/*
Removes the object from any slots the mob might have, calling the appropriate icon update proc.
Does nothing else.
-
+
DO NOT CALL THIS PROC DIRECTLY. It is meant to be called only by other inventory procs.
It's probably okay to use it if you are transferring the item between slots on the same mob,
but chances are you're safer calling remove_from_mob() or drop_from_inventory() anyways.
-
+
As far as I can tell the proc exists so that mobs with different inventory slots can override
the search through all the slots, without having to duplicate the rest of the item dropping.
*/
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index d2aa61e635..05ceed7916 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -2,6 +2,9 @@
name = "brain"
health = 400 //They need to live awhile longer than other organs.
desc = "A piece of juicy meat found in a person's head."
+ organ_tag = "brain"
+ parent_organ = "head"
+ vital = 1
icon_state = "brain2"
force = 1.0
w_class = 2.0
@@ -46,7 +49,7 @@
/obj/item/organ/brain/removed(var/mob/living/user)
- ..()
+ name = "[owner.real_name]'s brain"
var/mob/living/simple_animal/borer/borer = owner.has_brain_worms()
@@ -57,6 +60,8 @@
if(istype(B) && istype(owner))
B.transfer_identity(owner)
+ ..()
+
/obj/item/organ/brain/replaced(var/mob/living/target)
if(target.key)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 63eba6e781..da10a9ea00 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -31,10 +31,9 @@
var/d = rand(round(I.force / 4), I.force)
if(istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
- var/organ = H.get_organ("chest")
- if (istype(organ, /obj/item/organ/external))
- var/obj/item/organ/external/temp = organ
- if(temp.take_damage(d, 0))
+ var/obj/item/organ/external/organ = H.get_organ("chest")
+ if (istype(organ))
+ if(organ.take_damage(d, 0))
H.UpdateDamageIcon()
H.updatehealth()
else
@@ -328,7 +327,7 @@
if(!item) return //Grab processing has a chance of returning null
-
+
src.remove_from_mob(item)
item.loc = src.loc
diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm
index 311942ca02..e2ef586f05 100644
--- a/code/modules/mob/living/carbon/human/appearance.dm
+++ b/code/modules/mob/living/carbon/human/appearance.dm
@@ -117,7 +117,7 @@
g_skin = green
b_skin = blue
- update_body()
+ force_update_limbs()
return 1
/mob/living/carbon/human/proc/change_skin_tone(var/tone)
@@ -126,7 +126,7 @@
s_tone = tone
- update_body()
+ force_update_limbs()
return 1
/mob/living/carbon/human/proc/update_dna()
@@ -186,3 +186,8 @@
/proc/q()
var/mob/living/carbon/human/H = usr
H.change_appearance(APPEARANCE_ALL)
+
+/mob/living/carbon/human/proc/force_update_limbs()
+ for(var/obj/item/organ/external/O in organs)
+ O.sync_colour_to_human(src)
+ update_body(0)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 9c3057c52d..1e693fd63f 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -20,6 +20,9 @@
else
set_species()
+ if(species)
+ name = species.get_random_name(gender)
+
var/datum/reagents/R = new/datum/reagents(1000)
reagents = R
R.my_atom = src
@@ -326,8 +329,8 @@
//Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when polyacided or when updating a human's name variable
/mob/living/carbon/human/proc/get_face_name()
- var/obj/item/organ/external/head/head = get_organ("head")
- if( !head || head.disfigured || (head.status & ORGAN_DESTROYED) || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible
+ var/obj/item/organ/external/head = get_organ("head")
+ if(!head || head.disfigured || (head.status & ORGAN_DESTROYED) || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible
return "Unknown"
return real_name
@@ -1119,8 +1122,6 @@
species = all_species[new_species]
- species.create_organs(src)
-
if(species.language)
add_language(species.language)
@@ -1137,6 +1138,8 @@
g_skin = 0
b_skin = 0
+ species.create_organs(src)
+
species.handle_post_spawn(src)
maxHealth = species.total_health
@@ -1361,3 +1364,8 @@
U << "You pop [S]'s [current_limb.joint] back in!"
S << "[U] pops your [current_limb.joint] back in!"
current_limb.undislocate()
+
+/mob/living/carbon/human/drop_from_inventory(var/obj/item/W, var/atom/Target = null)
+ if(W in organs)
+ return
+ ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox.dm b/code/modules/mob/living/carbon/human/species/outsider/vox.dm
index 853fb4e8d4..c037d81fb7 100644
--- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm
+++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm
@@ -45,7 +45,7 @@
"heart" = /obj/item/organ/heart,
"lungs" = /obj/item/organ/lungs,
"liver" = /obj/item/organ/liver,
- "kidneys" = /obj/item/organ/kidney,
+ "kidneys" = /obj/item/organ/kidneys,
"brain" = /obj/item/organ/brain,
"eyes" = /obj/item/organ/eyes,
"stack" = /obj/item/organ/stack/vox
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 09f3360d45..b97e8ceed6 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -110,7 +110,7 @@
"heart" = /obj/item/organ/heart,
"lungs" = /obj/item/organ/lungs,
"liver" = /obj/item/organ/liver,
- "kidneys" = /obj/item/organ/kidney,
+ "kidneys" = /obj/item/organ/kidneys,
"brain" = /obj/item/organ/brain,
"appendix" = /obj/item/organ/appendix,
"eyes" = /obj/item/organ/eyes
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 00802c5da9..0bf4978297 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -967,6 +967,11 @@ default behaviour is:
/mob/living/proc/slip(var/slipped_on,stun_duration=8)
return 0
+/mob/living/carbon/drop_from_inventory(var/obj/item/W, var/atom/Target = null)
+ if(W in internal_organs)
+ return
+ ..()
+
/mob/living/carbon/proc/spin(spintime, speed)
spawn()
var/D = dir
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index e4405c5767..482ec2e3a1 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -729,7 +729,7 @@ note dizziness decrements automatically in the mob's Life() proc.
stat(null,"Location:\t([x], [y], [z])")
stat(null,"CPU:\t[world.cpu]")
stat(null,"Instances:\t[world.contents.len]")
- if(statpanel("Status") && processScheduler.getIsRunning())
+ if(statpanel("Status") && processScheduler && processScheduler.getIsRunning())
var/datum/controller/process/process
process = processScheduler.getProcess("ticker")
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 90e201b382..1d67b712f5 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -473,6 +473,7 @@
//new_character.dna.UpdateSE()
// Do the initial caching of the player's body icons.
+ new_character.force_update_limbs()
new_character.regenerate_icons()
new_character.key = key //Manually transfer the key to log them in
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 5d307fffcf..f97df89080 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -235,12 +235,14 @@ var/list/organ_cache = list()
owner.internal_organs_by_name[organ_tag] = null
owner.internal_organs_by_name -= organ_tag
+ owner.internal_organs_by_name -= null
owner.internal_organs -= src
var/obj/item/organ/external/affected = owner.get_organ(parent_organ)
if(affected) affected.internal_organs -= src
loc = owner.loc
+ processing_objects |= src
rejecting = null
var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list
if(!organ_blood || !organ_blood.data["blood_DNA"])
@@ -269,6 +271,7 @@ var/list/organ_cache = list()
transplant_data["blood_DNA"] = transplant_blood.data["blood_DNA"]
owner = target
+ processing_objects -= src
target.internal_organs |= src
affected.internal_organs |= src
target.internal_organs_by_name[organ_tag] = src
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index b6f14b64bc..d8ba25d750 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -3,13 +3,16 @@
****************************************************/
/obj/item/organ/external
name = "external"
+ min_broken_damage = 30
+ max_damage = 0
+ dir = SOUTH
+ organ_tag = "limb"
+
var/icon_name = null
var/body_part = null
var/icon_position = 0
-
var/model
var/force_icon
-
var/damage_state = "00"
var/brute_dam = 0
var/burn_dam = 0
@@ -18,7 +21,7 @@
var/icon/mob_icon
var/gendered_icon = 0
var/limb_name
- var/disfigured = 1
+ var/disfigured = 0
var/cannot_amputate
var/cannot_break
var/s_tone
@@ -26,38 +29,25 @@
var/list/wounds = list()
var/number_wounds = 0 // cache the number of wounds, which is NOT wounds.len!
var/perma_injury = 0
-
var/obj/item/organ/external/parent
var/list/obj/item/organ/external/children
-
- // Internal organs of this body part
- var/list/internal_organs = list()
-
+ var/list/internal_organs = list() // Internal organs of this body part
var/damage_msg = "\red You feel an intense pain"
var/broken_description
-
var/open = 0
var/stage = 0
var/cavity = 0
var/sabotaged = 0 // If a prosthetic limb is emagged, it will detonate when it fails.
var/encased // Needs to be opened with a saw to access the organs.
-
var/obj/item/hidden = null
var/list/implants = list()
-
- // how often wounds should be updated, a higher number means less often
- var/wound_update_accuracy = 1
-
+ var/wound_update_accuracy = 1 // how often wounds should be updated, a higher number means less often
var/joint = "joint" // Descriptive string used in dislocation.
var/amputation_point // Descriptive string used in amputation.
var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ.
var/can_grasp
var/can_stand
- min_broken_damage = 30
- max_damage = 0
- dir = SOUTH
-
/obj/item/organ/external/attackby(obj/item/weapon/W as obj, mob/user as mob)
switch(stage)
if(0)
@@ -650,8 +640,8 @@ Note that amputating the affected organ does in fact remove the infection from t
wounds.Cut()
if(parent)
var/datum/wound/W
- if(max_damage < 50)
- W = new/datum/wound/lost_limb/small(max_damage)
+ if(clean || max_damage < 50)
+ W = new/datum/wound/lost_limb/small(max_damage/2)
else
W = new/datum/wound/lost_limb(max_damage)
parent.children -= src
@@ -940,6 +930,7 @@ Note that amputating the affected organ does in fact remove the infection from t
gendered_icon = 1
cannot_amputate = 1
parent_organ = null
+ encased = "ribcage"
/obj/item/organ/external/groin
name = "lower body"
@@ -1061,9 +1052,11 @@ Note that amputating the affected organ does in fact remove the infection from t
joint = "jaw"
amputation_point = "neck"
gendered_icon = 1
+ encased = "skull"
/obj/item/organ/external/head/removed()
if(owner)
+ name = "[owner.real_name]'s head"
owner.u_equip(owner.glasses)
owner.u_equip(owner.head)
owner.u_equip(owner.l_ear)
diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm
index d5b6bf2a4e..b0e23df3d2 100644
--- a/code/modules/organs/organ_icon.dm
+++ b/code/modules/organs/organ_icon.dm
@@ -16,7 +16,9 @@ var/global/list/limb_icon_cache = list()
/obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human)
s_tone = null
s_col = null
- if(human.s_tone && (human.species.flags & HAS_SKIN_TONE))
+ if(status & ORGAN_ROBOT)
+ return
+ if(!isnull(human.s_tone) && (human.species.flags & HAS_SKIN_TONE))
s_tone = human.s_tone
if(human.species.flags & HAS_SKIN_COLOR)
s_col = list(human.r_skin, human.g_skin, human.b_skin)
diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm
index c552631abf..46e22e1e5f 100644
--- a/code/modules/organs/organ_internal.dm
+++ b/code/modules/organs/organ_internal.dm
@@ -44,7 +44,7 @@
organ_tag = "kidneys"
parent_organ = "groin"
-/obj/item/organ/kidney/process()
+/obj/item/organ/kidneys/process()
..()
@@ -61,7 +61,6 @@
else if(is_broken())
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
-
/obj/item/organ/eyes
name = "eyeballs"
icon_state = "eyes"
@@ -113,7 +112,7 @@
name = "liver"
icon_state = "liver"
organ_tag = "liver"
- parent_organ = "chest"
+ parent_organ = "groin"
/obj/item/organ/liver/process()
@@ -175,6 +174,7 @@
name = "appendix"
icon_state = "appendix"
parent_organ = "groin"
+ organ_tag = "appendix"
/obj/item/organ/appendix/removed()
diff --git a/code/modules/projectiles/targeting.dm b/code/modules/projectiles/targeting.dm
index 388b53a256..4e49a785e7 100644
--- a/code/modules/projectiles/targeting.dm
+++ b/code/modules/projectiles/targeting.dm
@@ -23,7 +23,7 @@
//Removing the lock and the buttons.
/obj/item/weapon/gun/dropped(mob/user as mob)
stop_aim()
- if (user.client)
+ if(user && user.client)
user.client.remove_gun_icons()
return ..()
@@ -47,7 +47,7 @@
/obj/item/weapon/gun/proc/PreFire(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, params)
//Lets not spam it.
if(lock_time > world.time - 2) return
-
+
user.set_dir(get_cardinal_dir(src, A))
if(isliving(A) && !(A in aim_targets))
Aim(A) //Clicked a mob, aim at them
@@ -58,7 +58,7 @@
if(isliving(M) && (M in view(user)) && !(M in aim_targets))
Aim(M) //Aha! Aim at them!
return 1
-
+
return 0
//Aiming at the target mob.
@@ -83,12 +83,12 @@
if(src != M.get_active_hand())
stop_aim()
return
-
+
//reflex firing is disabled when help intent is set
if (M.a_intent == I_HELP)
M << "\red You refrain from firing your [src] as your intent is set to help."
return
-
+
M.last_move_intent = world.time
var/firing_check = can_hit(T,usr) //0 if it cannot hit them, 1 if it is capable of hitting, and 2 if a special check is preventing it from firing.
if(firing_check > 0)
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index bb0a6314c8..8f5d7155dd 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -343,9 +343,11 @@
var/o_a = (O.gender == PLURAL) ? "" : "a "
var/o_do = (O.gender == PLURAL) ? "don't" : "doesn't"
- if(target.species.has_organ[O.organ_tag])
+ if(O.organ_tag == "limb")
+ return 0
+ else if(target.species.has_organ[O.organ_tag])
- if(!O.health)
+ if(O.is_damaged())
user << "\red \The [O.organ_tag] [o_is] in no state to be transplanted."
return 2
@@ -355,7 +357,7 @@
user << "\red \The [target] already has [o_a][O.organ_tag]."
return 2
- if(O && affected.name == O.parent_organ)
+ if(O && affected.limb_name == O.parent_organ)
organ_compatible = 1
else
user << "\red \The [O.organ_tag] [o_do] normally go in \the [affected.name]."
diff --git a/code/modules/surgery/robolimbs.dm b/code/modules/surgery/robolimbs.dm
index 5b524288f9..e845d8bb7b 100644
--- a/code/modules/surgery/robolimbs.dm
+++ b/code/modules/surgery/robolimbs.dm
@@ -39,8 +39,11 @@
if(L.part)
for(var/part_name in L.part)
- if(!isnull(target.get_organ(part_name))) continue
+ if(!isnull(target.get_organ(part_name)))
+ continue
var/list/organ_data = target.species.has_limbs["[target_zone]"]
+ if(!organ_data)
+ continue
var/new_limb_type = organ_data["path"]
var/obj/item/organ/external/new_limb = new new_limb_type(target)
new_limb.robotize(L.model_info)