Merge remote-tracking branch 'citadel/master' into combat_rework_experimental

This commit is contained in:
silicons
2020-10-10 22:23:22 -07:00
215 changed files with 7532 additions and 2391 deletions
+5 -5
View File
@@ -408,7 +408,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(mind.current.key && mind.current.key[1] != "@") //makes sure we don't accidentally kick any clients
to_chat(usr, "<span class='warning'>Another consciousness is in your body...It is resisting you.</span>")
return
client.change_view(CONFIG_GET(string/default_view))
client.view_size.setDefault(getScreenSize(client.prefs.widescreenpref))//Let's reset so people can't become allseeing gods
transfer_ckey(mind.current, FALSE)
SStgui.on_transfer(src, mind.current) // Transfer NanoUIs.
mind.current.client.init_verbs()
@@ -568,15 +568,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set desc = "Change your view range."
var/max_view = client.prefs.unlock_content ? GHOST_MAX_VIEW_RANGE_MEMBER : GHOST_MAX_VIEW_RANGE_DEFAULT
if(client.view == CONFIG_GET(string/default_view))
if(client.view_size.getView() == client.view_size.default)
var/list/views = list()
for(var/i in 7 to max_view)
views |= i
var/new_view = input("Choose your new view", "Modify view range", 7) as null|anything in views
var/new_view = input("Choose your new view", "Modify view range", 0) as null|anything in views
if(new_view)
client.change_view(clamp(new_view, 7, max_view))
client.view_size.setTo(clamp(new_view, 7, max_view) - 7)
else
client.change_view(CONFIG_GET(string/default_view))
client.view_size.resetToDefault()
/mob/dead/observer/verb/add_view_range(input as num)
set name = "Add View Range"
+2 -17
View File
@@ -988,30 +988,15 @@
O.held_index = r_arm_index_next //2, 4, 6, 8...
hand_bodyparts += O
/mob/living/carbon/do_after_coefficent()
. = ..()
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood) //Currently, only carbons or higher use mood, move this once that changes.
if(mood)
switch(mood.sanity) //Alters do_after delay based on how sane you are
if(SANITY_INSANE to SANITY_DISTURBED)
. *= 1.25
if(SANITY_NEUTRAL to SANITY_GREAT)
. *= 0.90
for(var/i in status_effects)
var/datum/status_effect/S = i
. *= S.interact_speed_modifier()
/mob/living/carbon/proc/create_internal_organs()
for(var/X in internal_organs)
var/obj/item/organ/I = X
I.Insert(src)
/mob/living/carbon/proc/update_disabled_bodyparts()
/mob/living/carbon/proc/update_disabled_bodyparts(silent = FALSE)
for(var/B in bodyparts)
var/obj/item/bodypart/BP = B
BP.update_disabled()
BP.update_disabled(silent)
/mob/living/carbon/vv_get_dropdown()
. = ..()
+6 -10
View File
@@ -254,10 +254,10 @@
if(href_list["pockets"])
var/strip_mod = 1
var/strip_silence = FALSE
var/obj/item/clothing/gloves/g = gloves
if (istype(g))
strip_mod = g.strip_mod
strip_silence = g.strip_silence
var/obj/item/clothing/gloves/G = gloves
if(istype(G))
strip_mod = G.strip_mod
strip_silence = G.strip_silence
var/pocket_side = href_list["pockets"]
var/pocket_id = (pocket_side == "right" ? SLOT_R_STORE : SLOT_L_STORE)
var/obj/item/pocket_item = (pocket_id == SLOT_R_STORE ? r_store : l_store)
@@ -1045,7 +1045,8 @@
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
return
if(!HAS_TRAIT(src, TRAIT_IGNOREDAMAGESLOWDOWN)) //if we want to ignore slowdown from damage, but not from equipment
var/health_deficiency = ((maxHealth) - health + (getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss and makes stamina buffer influence it
var/scaling = maxHealth / 100
var/health_deficiency = ((maxHealth / scaling) - (health / scaling) + (getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss and makes stamina buffer influence it
if(health_deficiency >= 40)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, (health_deficiency-39) / 75)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, (health_deficiency-39) / 25)
@@ -1056,11 +1057,6 @@
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
/mob/living/carbon/human/do_after_coefficent()
. = ..()
. *= physiology.do_after_speed
/mob/living/carbon/human/is_bleeding()
if(NOBLOOD in dna.species.species_traits || bleedsuppress)
return FALSE
@@ -100,3 +100,8 @@
if(dna.species.space_move(src))
return TRUE
return ..()
/mob/living/carbon/human/CanPass(atom/movable/mover, turf/target)
if(dna.species.species_pass_check())
return TRUE
return ..()
@@ -23,8 +23,6 @@
var/hunger_mod = 1 //% of hunger rate taken per tick.
var/do_after_speed = 1 //Speed mod for do_after. Lower is better. If temporarily adjusting, please only modify using *= and /=, so you don't interrupt other calculations.
/// footstep type override for both shoeless and not footstep sounds.
var/footstep_type
+28 -13
View File
@@ -64,7 +64,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/stunmod = 1 // multiplier for stun duration
var/punchdamagelow = 1 //lowest possible punch damage. if this is set to 0, punches will always miss
var/punchdamagehigh = 10 //highest possible punch damage
var/punchstunthreshold = 10//damage at which punches from this race will stun //yes it should be to the attacked race but it's not useful that way even if it's logical
var/punchstunthreshold = 10 //damage at which punches from this race will stun //yes it should be to the attacked race but it's not useful that way even if it's logical
var/punchwoundbonus = 0 // additional wound bonus. generally zero.
var/siemens_coeff = 1 //base electrocution coefficient
var/damage_overlay_type = "human" //what kind of damage overlays (if any) appear on our species when wounded?
var/fixed_mut_color = "" //to use MUTCOLOR with a fixed color that's independent of dna.feature["mcolor"]
@@ -106,7 +107,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/whitelisted = 0 //Is this species restricted to certain players?
var/whitelist = list() //List the ckeys that can use this species, if it's whitelisted.: list("John Doe", "poopface666", "SeeALiggerPullTheTrigger") Spaces & capitalization can be included or ignored entirely for each key as it checks for both.
var/icon_limbs //Overrides the icon used for the limbs of this species. Mainly for downstream, and also because hardcoded icons disgust me. Implemented and maintained as a favor in return for a downstream's implementation of synths.
var/species_type
var/species_category
var/tail_type //type of tail i.e. mam_tail
var/wagging_type //type of wagging i.e. waggingtail_lizard
@@ -591,9 +592,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
else
var/left_state = DEFAULT_LEFT_EYE_STATE
var/right_state = DEFAULT_RIGHT_EYE_STATE
message_admins("okay so our eye type is [eye_type] and we can index it to know [GLOB.eye_types[eye_type]]")
if(eye_type in GLOB.eye_types)
message_admins("to know that it's in!")
left_state = eye_type + "_left_eye"
right_state = eye_type + "_right_eye"
var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER)
@@ -1389,6 +1388,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
user.do_attack_animation(target, ATTACK_EFFECT_PUNCH)
var/damage = rand(user.dna.species.punchdamagelow, user.dna.species.punchdamagehigh)
var/punchwoundbonus = user.dna.species.punchwoundbonus
var/puncherstam = user.getStaminaLoss()
var/puncherbrute = user.getBruteLoss()
var/punchedstam = target.getStaminaLoss()
@@ -1404,6 +1404,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
//END OF CITADEL CHANGES
var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected))
if(HAS_TRAIT(user, TRAIT_PUGILIST))
affecting = target.get_bodypart(check_zone(user.zone_selected)) // if you're going the based unarmed route you won't miss
if(!affecting) //Maybe the bodypart is missing? Or things just went wrong..
affecting = target.get_bodypart(BODY_ZONE_CHEST) //target chest instead, as failsafe. Or hugbox? You decide.
@@ -1415,8 +1417,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(user.dna.species.punchdamagelow)
if(atk_verb == ATTACK_EFFECT_KICK) //kicks never miss (provided your species deals more than 0 damage)
miss_chance = 0
else if(HAS_TRAIT(user, TRAIT_PUGILIST)) //pugilists have a flat 10% miss chance
miss_chance = 10
else if(HAS_TRAIT(user, TRAIT_PUGILIST)) //pugilists, being good at Punching People, also never miss
miss_chance = 0
else
miss_chance = min(10 + max(puncherstam * 0.5, puncherbrute * 0.5), 100) //probability of miss has a base of 10, and modified based on half brute total. Capped at max 100 to prevent weirdness in prob()
@@ -1430,12 +1432,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/armor_block = target.run_armor_check(affecting, "melee")
if(HAS_TRAIT(user, TRAIT_MAULER)) // maulers get 15 armorpierce because if you're going to punch someone you might as well do a good job of it
armor_block = target.run_armor_check(affecting, "melee", armour_penetration = 15) // lot of good that sec jumpsuit did you
playsound(target.loc, user.dna.species.attack_sound, 25, 1, -1)
target.visible_message("<span class='danger'>[user] [atk_verb]s [target]!</span>", \
"<span class='userdanger'>[user] [atk_verb]s you!</span>", null, COMBAT_MESSAGE_RANGE, null, \
user, "<span class='danger'>You [atk_verb] [target]!</span>")
target.visible_message("<span class='danger'>[user] [atk_verb]ed [target]!</span>", \
"<span class='userdanger'>[user] [atk_verb]ed you!</span>", null, COMBAT_MESSAGE_RANGE, null, \
user, "<span class='danger'>You [atk_verb]ed [target]!</span>")
target.lastattacker = user.real_name
target.lastattackerckey = user.ckey
@@ -1445,11 +1448,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
target.dismembering_strike(user, affecting.body_zone)
if(atk_verb == ATTACK_EFFECT_KICK)//kicks deal 1.5x raw damage + 0.5x stamina damage
target.apply_damage(damage*1.5, attack_type, affecting, armor_block)
target.apply_damage(damage*1.5, attack_type, affecting, armor_block, wound_bonus = punchwoundbonus)
target.apply_damage(damage*0.5, STAMINA, affecting, armor_block)
log_combat(user, target, "kicked")
else//other attacks deal full raw damage + 2x in stamina damage
target.apply_damage(damage, attack_type, affecting, armor_block)
else if(HAS_TRAIT(user, TRAIT_MAULER)) // mauler punches deal 1.3x raw damage + 1x stam damage, and have some armor pierce
target.apply_damage(damage*1.3, attack_type, affecting, armor_block, wound_bonus = punchwoundbonus)
target.apply_damage(damage, STAMINA, affecting, armor_block)
log_combat(user, target, "punched (mauler)")
else //other attacks deal full raw damage + 2x in stamina damage
target.apply_damage(damage, attack_type, affecting, armor_block, wound_bonus = punchwoundbonus)
target.apply_damage(damage*2, STAMINA, affecting, armor_block)
log_combat(user, target, "punched")
@@ -1956,6 +1963,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(HAS_BONE in species_traits)
. |= BIO_JUST_BONE
//a check for if you should render any overlays or not
/datum/species/proc/should_render(mob/living/carbon/human/H)
return TRUE
//a check for if you want to forcibly make CanPass return TRUE for the mob with this species
/datum/species/proc/species_pass_check()
return FALSE
/////////////
//BREATHING//
/////////////
@@ -1,12 +1,12 @@
/datum/species/abductor
name = "Abductor"
id = "abductor"
id = SPECIES_ABDUCTOR
say_mod = "gibbers"
sexes = FALSE
species_traits = list(NOBLOOD,NOEYES,NOGENITALS,NOAROUSAL,HAS_FLESH,HAS_BONE)
inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_CHUNKYFINGERS,TRAIT_NOHUNGER,TRAIT_NOBREATH)
mutanttongue = /obj/item/organ/tongue/abductor
species_type = "alien"
species_category = SPECIES_CATEGORY_ALIEN
/datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
@@ -1,6 +1,6 @@
/datum/species/android
name = "Android"
id = "android"
id = SPECIES_ANDROID
say_mod = "states"
species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL,ROBOTIC_LIMBS)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_NOFIRE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_LIMBATTACHMENT)
@@ -11,7 +11,7 @@
mutanttongue = /obj/item/organ/tongue/robot
species_language_holder = /datum/language_holder/synthetic
limbs_id = "synth"
species_type = "robotic"
species_category = SPECIES_CATEGORY_ROBOT
/datum/species/android/on_species_gain(mob/living/carbon/C)
. = ..()
@@ -1,6 +1,6 @@
/datum/species/angel
name = "Angel"
id = "angel"
id = SPECIES_ANGEL
default_color = "FFFFFF"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,HAS_FLESH,HAS_BONE)
mutant_bodyparts = list("tail_human" = "None", "ears" = "None", "wings" = "Angel")
@@ -9,7 +9,7 @@
blacklisted = 1
limbs_id = "human"
skinned_type = /obj/item/stack/sheet/animalhide/human
species_type = "human" //they're a kind of human
species_category = SPECIES_CATEGORY_BASIC //they're a kind of human
var/datum/action/innate/flight/fly
@@ -1,6 +1,6 @@
/datum/species/mammal
name = "Anthromorph"
id = "mammal"
id = SPECIES_MAMMAL
default_color = "4B4B4B"
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR,HAS_FLESH,HAS_BONE)
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BEAST
@@ -15,6 +15,6 @@
tail_type = "mam_tail"
wagging_type = "mam_waggingtail"
species_type = "furry"
species_category = SPECIES_CATEGORY_FURRY
allowed_limb_ids = list("mammal","aquatic","avian")
allowed_limb_ids = list("mammal","aquatic","avian")
@@ -1,6 +1,6 @@
/datum/species/insect
name = "Anthromorphic Insect"
id = "insect"
id = SPECIES_INSECT
say_mod = "chitters"
default_color = "00FF00"
species_traits = list(LIPS,EYECOLOR,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR,HAS_FLESH,HAS_BONE)
@@ -18,7 +18,7 @@
tail_type = "mam_tail"
wagging_type = "mam_waggingtail"
species_type = "insect"
species_category = SPECIES_CATEGORY_INSECT
allowed_limb_ids = list("insect","apid","moth","moth_not_greyscale")
@@ -18,4 +18,4 @@
inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOLIMBDISABLE,TRAIT_NOHUNGER)
sexes = 0
gib_types = /obj/effect/gibspawner/robot
species_type = "robotic"
species_category = SPECIES_CATEGORY_ROBOT
@@ -1,6 +1,6 @@
/datum/species/dullahan
name = "Dullahan"
id = "dullahan"
id = SPECIES_DULLAHAN
default_color = "FFFFFF"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,HAS_FLESH,HAS_BONE)
inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
@@ -14,7 +14,7 @@
limbs_id = "human"
skinned_type = /obj/item/stack/sheet/animalhide/human
has_field_of_vision = FALSE //Too much of a trouble, their vision is already bound to their severed head.
species_type = "undead"
species_category = SPECIES_CATEGORY_UNDEAD
var/pumpkin = FALSE
var/obj/item/dullahan_relay/myhead
@@ -4,7 +4,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
/datum/species/dwarf //not to be confused with the genetic manlets
name = "Dwarf"
id = "dwarf" //Also called Homo sapiens pumilionis
id = SPECIES_DWARF //Also called Homo sapiens pumilionis
default_color = "FFFFFF"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,HAS_FLESH,HAS_BONE)
inherent_traits = list(TRAIT_DWARF,TRAIT_SNOB)
@@ -18,7 +18,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
mutant_organs = list(/obj/item/organ/dwarfgland) //Dwarven alcohol gland, literal gland warrior
mutantliver = /obj/item/organ/liver/dwarf //Dwarven super liver (Otherwise they r doomed)
species_language_holder = /datum/language_holder/dwarf
species_type = "human" //a kind of human
species_category = SPECIES_CATEGORY_BASIC //a kind of human
/mob/living/carbon/human/species/dwarf //species admin spawn path
race = /datum/species/dwarf //and the race the path is set to.
@@ -2,7 +2,7 @@
/datum/species/ethereal
name = "Ethereal"
id = "ethereal"
id = SPECIES_ETHEREAL
attack_verb = "burn"
attack_sound = 'sound/weapons/etherealhit.ogg'
miss_sound = 'sound/weapons/etherealmiss.ogg'
@@ -1,7 +1,7 @@
//Subtype of human
/datum/species/human/felinid
name = "Felinid"
id = "felinid"
id = SPECIES_FELINID
limbs_id = "human"
mutant_bodyparts = list("mam_tail" = "Cat", "mam_ears" = "Cat", "deco_wings" = "None")
@@ -11,7 +11,7 @@
tail_type = "mam_tail"
wagging_type = "mam_waggingtail"
species_type = "furry"
species_category = SPECIES_CATEGORY_FURRY
/datum/species/human/felinid/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
if(ishuman(C))
@@ -1,6 +1,6 @@
/datum/species/fly
name = "Anthromorphic Fly"
id = "fly"
id = SPECIES_FLY
say_mod = "buzzes"
species_traits = list(NOEYES,HAS_FLESH,HAS_BONE)
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG
@@ -12,7 +12,7 @@
liked_food = GROSS
exotic_bloodtype = "BUG"
exotic_blood_color = BLOOD_COLOR_BUG
species_type = "insect"
species_category = SPECIES_CATEGORY_INSECT
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(istype(chem, /datum/reagent/toxin/pestkiller))
@@ -1,7 +1,7 @@
/datum/species/golem
// Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck.
name = "Golem"
id = "iron golem"
id = SPECIES_GOLEM
species_traits = list(NOBLOOD,MUTCOLORS,NO_UNDERWEAR,NOGENITALS,NOAROUSAL)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_CHUNKYFINGERS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
inherent_biotypes = MOB_HUMANOID|MOB_MINERAL
@@ -32,7 +32,7 @@
var/special_name_chance = 5
var/owner //dobby is a free golem
species_type = "golem"
species_category = SPECIES_CATEGORY_GOLEM
/datum/species/golem/random_name(gender,unique,lastname)
var/golem_surname = pick(GLOB.golem_names)
@@ -1,6 +1,6 @@
/datum/species/human
name = "Human"
id = "human"
id = SPECIES_HUMAN
default_color = "FFFFFF"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR,HAS_FLESH,HAS_BONE)
@@ -12,7 +12,7 @@
tail_type = "tail_human"
wagging_type = "waggingtail_human"
species_type = "human"
species_category = SPECIES_CATEGORY_BASIC
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
if(H)
@@ -1,6 +1,6 @@
/datum/species/ipc
name = "I.P.C."
id = "ipc"
id = SPECIES_IPC
say_mod = "beeps"
default_color = "00FF00"
blacklisted = 0
@@ -28,7 +28,7 @@
exotic_bloodtype = "HF"
exotic_blood_color = BLOOD_COLOR_OIL
species_type = "robotic"
species_category = SPECIES_CATEGORY_ROBOT
var/datum/action/innate/monitor_change/screen
@@ -1,7 +1,7 @@
/datum/species/jelly
// Entirely alien beings that seem to be made entirely out of gel. They have three eyes and a skeleton visible within them.
name = "Xenobiological Jelly Entity"
id = "jelly"
id = SPECIES_JELLY
default_color = "00FF90"
say_mod = "chirps"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR,HAS_FLESH)
@@ -16,7 +16,8 @@
exotic_blood_color = "BLOOD_COLOR_SLIME"
damage_overlay_type = ""
var/datum/action/innate/regenerate_limbs/regenerate_limbs
var/datum/action/innate/slime_change/slime_change //CIT CHANGE
var/datum/action/innate/slime_change/slime_change
var/datum/action/innate/slime_puddle/slime_puddle
liked_food = TOXIC | MEAT
disliked_food = null
toxic_food = ANTITOXIC
@@ -28,19 +29,22 @@
tail_type = "mam_tail"
wagging_type = "mam_waggingtail"
species_type = "jelly"
species_category = SPECIES_CATEGORY_JELLY
/obj/item/organ/brain/jelly
name = "slime nucleus"
desc = "A slimey membranous mass from a slime person"
icon_state = "brain-slime"
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
if(slime_puddle && slime_puddle.is_puddle)
slime_puddle.Activate()
if(regenerate_limbs)
regenerate_limbs.Remove(C)
if(slime_change) //CIT CHANGE
slime_change.Remove(C) //CIT CHANGE
if(slime_change)
slime_change.Remove(C)
if(slime_puddle)
slime_puddle.Remove(C)
C.faction -= "slime"
..()
C.faction -= "slime"
@@ -50,8 +54,10 @@
if(ishuman(C))
regenerate_limbs = new
regenerate_limbs.Grant(C)
slime_change = new //CIT CHANGE
slime_change.Grant(C) //CIT CHANGE
slime_change = new
slime_change.Grant(C)
slime_puddle = new
slime_puddle.Grant(C)
C.faction |= "slime"
/datum/species/jelly/handle_body(mob/living/carbon/human/H)
@@ -59,6 +65,18 @@
//update blood color to body color
exotic_blood_color = "#" + H.dna.features["mcolor"]
/datum/species/jelly/should_render()
if(slime_puddle && slime_puddle.is_puddle)
return FALSE
else
return ..()
/datum/species/jelly/species_pass_check()
if(slime_puddle && slime_puddle.is_puddle)
return TRUE
else
return ..()
/datum/species/jelly/spec_life(mob/living/carbon/human/H)
if(H.stat == DEAD || HAS_TRAIT(H, TRAIT_NOMARROW)) //can't farm slime jelly from a dead slime/jelly person indefinitely, and no regeneration for blooduskers
return
@@ -140,7 +158,7 @@
/datum/species/jelly/slime
name = "Xenobiological Slime Entity"
id = "slime"
id = SPECIES_SLIME
default_color = "00FFFF"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
say_mod = "says"
@@ -449,7 +467,7 @@
/datum/species/jelly/roundstartslime
name = "Xenobiological Slime Hybrid"
id = "slimeperson"
id = SPECIES_SLIME_HYBRID
limbs_id = "slime"
default_color = "00FFFF"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
@@ -670,6 +688,88 @@
else
return
/datum/action/innate/slime_puddle
name = "Puddle Transformation"
check_flags = AB_CHECK_CONSCIOUS
button_icon_state = "slimepuddle"
icon_icon = 'icons/mob/actions/actions_slime.dmi'
background_icon_state = "bg_alien"
required_mobility_flags = MOBILITY_STAND
var/is_puddle = FALSE
var/in_transformation_duration = 12
var/out_transformation_duration = 7
var/puddle_into_effect = /obj/effect/temp_visual/slime_puddle
var/puddle_from_effect = /obj/effect/temp_visual/slime_puddle/reverse
var/puddle_icon = 'icons/mob/mob.dmi'
var/puddle_state = "puddle"
var/tracked_overlay
var/datum/component/squeak/squeak
var/transforming = FALSE
var/last_use
/datum/action/innate/slime_puddle/IsAvailable()
if(!transforming)
return ..()
else
return FALSE
/datum/action/innate/slime_puddle/Activate()
if(isjellyperson(owner) && IsAvailable())
transforming = TRUE
UpdateButtonIcon()
var/mob/living/carbon/human/H = owner
var/mutcolor = "#" + H.dna.features["mcolor"]
if(!is_puddle)
if(CHECK_MOBILITY(H, MOBILITY_USE))
is_puddle = TRUE
owner.cut_overlays()
var/obj/effect/puddle_effect = new puddle_into_effect(get_turf(owner), owner.dir)
puddle_effect.color = mutcolor
H.Stun(in_transformation_duration, ignore_canstun = TRUE)
ADD_TRAIT(H, TRAIT_PARALYSIS_L_ARM, SLIMEPUDDLE_TRAIT)
ADD_TRAIT(H, TRAIT_PARALYSIS_R_ARM, SLIMEPUDDLE_TRAIT)
ADD_TRAIT(H, TRAIT_MOBILITY_NOPICKUP, SLIMEPUDDLE_TRAIT)
ADD_TRAIT(H, TRAIT_MOBILITY_NOUSE, SLIMEPUDDLE_TRAIT)
ADD_TRAIT(H, TRAIT_SPRINT_LOCKED, SLIMEPUDDLE_TRAIT)
ADD_TRAIT(H, TRAIT_COMBAT_MODE_LOCKED, SLIMEPUDDLE_TRAIT)
ADD_TRAIT(H, TRAIT_MOBILITY_NOREST, SLIMEPUDDLE_TRAIT)
H.add_movespeed_modifier(/datum/movespeed_modifier/slime_puddle)
H.update_disabled_bodyparts(silent = TRUE)
H.layer -= 1 //go one layer down so people go over you
ENABLE_BITFIELD(H.pass_flags, PASSMOB)
squeak = H.AddComponent(/datum/component/squeak, custom_sounds = list('sound/effects/blobattack.ogg'))
sleep(in_transformation_duration)
var/mutable_appearance/puddle_overlay = mutable_appearance(icon = puddle_icon, icon_state = puddle_state)
puddle_overlay.color = mutcolor
tracked_overlay = puddle_overlay
owner.add_overlay(puddle_overlay)
transforming = FALSE
UpdateButtonIcon()
else
owner.cut_overlay(tracked_overlay)
var/obj/effect/puddle_effect = new puddle_from_effect(get_turf(owner), owner.dir)
puddle_effect.color = mutcolor
H.Stun(out_transformation_duration, ignore_canstun = TRUE)
sleep(out_transformation_duration)
REMOVE_TRAIT(H, TRAIT_PARALYSIS_L_ARM, SLIMEPUDDLE_TRAIT)
REMOVE_TRAIT(H, TRAIT_PARALYSIS_R_ARM, SLIMEPUDDLE_TRAIT)
REMOVE_TRAIT(H, TRAIT_MOBILITY_NOPICKUP, SLIMEPUDDLE_TRAIT)
REMOVE_TRAIT(H, TRAIT_MOBILITY_NOUSE, SLIMEPUDDLE_TRAIT)
REMOVE_TRAIT(H, TRAIT_SPRINT_LOCKED, SLIMEPUDDLE_TRAIT)
REMOVE_TRAIT(H, TRAIT_COMBAT_MODE_LOCKED, SLIMEPUDDLE_TRAIT)
REMOVE_TRAIT(H, TRAIT_MOBILITY_NOREST, SLIMEPUDDLE_TRAIT)
H.update_disabled_bodyparts(silent = TRUE)
H.remove_movespeed_modifier(/datum/movespeed_modifier/slime_puddle)
H.layer += 1 //go one layer back above!
DISABLE_BITFIELD(H.pass_flags, PASSMOB)
is_puddle = FALSE
if(squeak)
squeak.RemoveComponent()
owner.regenerate_icons()
transforming = FALSE
UpdateButtonIcon()
else
to_chat(owner, "<span class='warning'>You need to be standing up to do this!") //just assume they're a slime because it's such a weird edgecase to have it and not be one (it shouldn't even be possible)
///////////////////////////////////LUMINESCENTS//////////////////////////////////////////
@@ -677,7 +777,7 @@
/datum/species/jelly/luminescent
name = "Luminescent Slime Entity"
id = "lum"
id = SPECIES_SLIME_LUMI
say_mod = "says"
var/glow_intensity = LUMINESCENT_DEFAULT_GLOW
var/obj/effect/dummy/luminescent_glow/glow
@@ -844,7 +944,7 @@
/datum/species/jelly/stargazer
name = "Stargazer Slime Entity"
id = "stargazer"
id = SPECIES_STARGAZER
var/datum/action/innate/project_thought/project_thought
var/datum/action/innate/link_minds/link_minds
var/list/mob/living/linked_mobs = list()
@@ -1,7 +1,7 @@
/datum/species/lizard
// Reptilian humanoids with scaled skin and tails.
name = "Anthromorphic Lizard"
id = "lizard"
id = SPECIES_LIZARD
say_mod = "hisses"
default_color = "00FF00"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR,HAS_FLESH,HAS_BONE)
@@ -28,7 +28,7 @@
tail_type = "tail_lizard"
wagging_type = "waggingtail_lizard"
species_type = "lizard"
species_category = "lizard"
/datum/species/lizard/random_name(gender,unique,lastname)
if(unique)
@@ -46,7 +46,7 @@
*/
/datum/species/lizard/ashwalker
name = "Ash Walker"
id = "ashlizard"
id = SPECIES_ASHWALKER
limbs_id = "lizard"
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,DIGITIGRADE)
inherent_traits = list(TRAIT_CHUNKYFINGERS)
@@ -1,6 +1,6 @@
/datum/species/mush //mush mush codecuck
name = "Anthromorphic Mushroom"
id = "mush"
id = SPECIES_MUSHROOM
mutant_bodyparts = list("caps" = "Round")
fixed_mut_color = "DBBF92"
@@ -21,7 +21,7 @@
burnmod = 1.25
heatmod = 1.5
species_type = "plant"
species_category = SPECIES_CATEGORY_PLANT
mutanteyes = /obj/item/organ/eyes/night_vision/mushroom
var/datum/martial_art/mushpunch/mush
@@ -1,6 +1,6 @@
/datum/species/plasmaman
name = "Plasmaman"
id = "plasmaman"
id = SPECIES_PLASMAMAN
say_mod = "rattles"
sexes = 0
meat = /obj/item/stack/sheet/mineral/plasma
@@ -22,7 +22,7 @@
liked_food = VEGETABLES
outfit_important_for_life = /datum/outfit/plasmaman
species_type = "skeleton"
species_category = SPECIES_CATEGORY_SKELETON
/datum/species/plasmaman/spec_life(mob/living/carbon/human/H)
var/datum/gas_mixture/environment = H.loc.return_air()
@@ -1,7 +1,7 @@
/datum/species/pod
// A mutation caused by a human being ressurected in a revival pod. These regain health in light, and begin to wither in darkness.
name = "Anthromorphic Plant"
id = "pod"
id = SPECIES_POD
default_color = "59CE00"
species_traits = list(MUTCOLORS,EYECOLOR,CAN_SCAR,HAS_FLESH,HAS_BONE)
attack_verb = "slash"
@@ -19,7 +19,7 @@
var/light_burnheal = -1
var/light_bruteheal = -1
species_type = "plant"
species_category = SPECIES_CATEGORY_PLANT
allowed_limb_ids = list("pod","mush")
@@ -66,7 +66,7 @@
/datum/species/pod/pseudo_weak
name = "Anthromorphic Plant"
id = "podweak"
id = SPECIES_POD_WEAK
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS)
mutant_bodyparts = list("mcolor" = "FFFFFF","mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs")
limbs_id = "pod"
@@ -4,7 +4,7 @@
/datum/species/shadow
// Humans cursed to stay in the darkness, lest their life forces drain. They regain health in shadow and die in light.
name = "???"
id = "shadow"
id = SPECIES_SHADOW
sexes = 0
blacklisted = 1
ignored_by = list(/mob/living/simple_animal/hostile/faithless)
@@ -15,7 +15,7 @@
dangerous_existence = 1
mutanteyes = /obj/item/organ/eyes/night_vision
species_type = "shadow"
species_category = SPECIES_CATEGORY_SHADOW
/datum/species/shadow/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
@@ -32,7 +32,7 @@
/datum/species/shadow/nightmare
name = "Nightmare"
id = "nightmare"
id = SPECIES_NIGHTMARE
limbs_id = "shadow"
burnmod = 1.5
blacklisted = TRUE
@@ -1,6 +1,6 @@
/datum/species/skeleton
name = "Skeleton"
id = "skeleton"
id = SPECIES_SKELETON
say_mod = "rattles"
blacklisted = 0
sexes = 0
@@ -15,7 +15,7 @@
brutemod = 1.25
burnmod = 1.25
species_type = "skeleton" //they have their own category that's disassociated from undead, paired with plasmapeople
species_category = SPECIES_CATEGORY_SKELETON //they have their own category that's disassociated from undead, paired with plasmapeople
/datum/species/skeleton/New()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) //skeletons are stronger during the spooky season!
@@ -31,7 +31,7 @@
/datum/species/skeleton/space
name = "Spooky Spacey Skeleton"
id = "spaceskeleton"
id = SPECIES_SKELETON_SPACE
limbs_id = "skeleton"
blacklisted = 1
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT, TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
@@ -1,6 +1,6 @@
/datum/species/synthliz
name = "Synthetic Lizardperson"
id = "synthliz"
id = SPECIES_SYNTH_LIZARD
say_mod = "beeps"
default_color = "00FF00"
species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR,ROBOTIC_LIMBS,HAS_FLESH,HAS_BONE)
@@ -27,4 +27,4 @@
tail_type = "mam_tail"
wagging_type = "mam_waggingtail"
species_type = "robotic"
species_category = SPECIES_CATEGORY_ROBOT
@@ -1,6 +1,6 @@
/datum/species/synth
name = "Synthetic" //inherited from the real species, for health scanners and things
id = "synth"
id = SPECIES_SYNTH
say_mod = "beep boops" //inherited from a user's real species
sexes = 0
species_traits = list(NOTRANSSTING,NOGENITALS,NOAROUSAL) //all of these + whatever we inherit from the real species
@@ -17,11 +17,11 @@
var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off
var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged
species_language_holder = /datum/language_holder/synthetic
species_type = "robotic"
species_category = SPECIES_CATEGORY_ROBOT
/datum/species/synth/military
name = "Military Synth"
id = "military_synth"
id = SPECIES_SYNTH_MIL
armor = 25
punchdamagelow = 10
punchdamagehigh = 19
@@ -1,6 +1,6 @@
/datum/species/vampire
name = "Vampire"
id = "vampire"
id = SPECIES_VAMPIRE
default_color = "FFFFFF"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,DRINKSBLOOD,HAS_FLESH,HAS_BONE)
inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
@@ -14,7 +14,7 @@
limbs_id = "human"
skinned_type = /obj/item/stack/sheet/animalhide/human
var/info_text = "You are a <span class='danger'>Vampire</span>. You will slowly but constantly lose blood if outside of a coffin. If inside a coffin, you will slowly heal. You may gain more blood by grabbing a live victim and using your drain ability."
species_type = "undead"
species_category = SPECIES_CATEGORY_UNDEAD
/datum/species/vampire/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
@@ -1,7 +1,7 @@
/datum/species/xeno
// A cloning mistake, crossing human and xenomorph DNA
name = "Xenomorph Hybrid"
id = "xeno"
id = SPECIES_XENOHYBRID
say_mod = "hisses"
default_color = "00FF00"
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,CAN_SCAR)
@@ -15,4 +15,4 @@
exotic_bloodtype = "X*"
damage_overlay_type = "xeno"
liked_food = MEAT
species_type = "alien"
species_category = SPECIES_CATEGORY_ALIEN
@@ -15,7 +15,7 @@
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')
disliked_food = NONE
liked_food = GROSS | MEAT | RAW
species_type = "undead"
species_category = SPECIES_CATEGORY_UNDEAD
/datum/species/zombie/notspaceproof
id = "notspaceproofzombie"
@@ -98,7 +98,7 @@
// Your skin falls off
/datum/species/krokodil_addict
name = "Human"
name = SPECIES_HUMAN
id = "goofzombies"
limbs_id = "zombie" //They look like zombies
sexes = 0
@@ -50,19 +50,21 @@ There are several things that need to be remembered:
//HAIR OVERLAY
/mob/living/carbon/human/update_hair()
dna.species.handle_hair(src)
if(dna.species.should_render())
dna.species.handle_hair(src)
//used when putting/removing clothes that hide certain mutant body parts to just update those and not update the whole body.
/mob/living/carbon/human/proc/update_mutant_bodyparts()
dna.species.handle_mutant_bodyparts(src)
if(dna.species.should_render())
dna.species.handle_mutant_bodyparts(src)
/mob/living/carbon/human/update_body(update_genitals = FALSE)
remove_overlay(BODY_LAYER)
dna.species.handle_body(src)
..()
if(update_genitals)
update_genitals()
if(dna.species.should_render())
remove_overlay(BODY_LAYER)
dna.species.handle_body(src)
..()
if(update_genitals)
update_genitals()
/mob/living/carbon/human/update_fire()
..((fire_stacks > 3) ? "Standing" : "Generic_mob_burning")
@@ -71,381 +73,385 @@ There are several things that need to be remembered:
/* --------------------------------------- */
//For legacy support.
/mob/living/carbon/human/regenerate_icons()
if(!..())
icon_render_key = null //invalidate bodyparts cache
update_body(TRUE)
update_hair()
update_inv_w_uniform()
update_inv_wear_id()
update_inv_gloves()
update_inv_glasses()
update_inv_ears()
update_inv_shoes()
update_inv_s_store()
update_inv_wear_mask()
update_inv_head()
update_inv_belt()
update_inv_back()
update_inv_wear_suit()
update_inv_pockets()
update_inv_neck()
update_transform()
//mutations
update_mutations_overlay()
//damage overlays
update_damage_overlays()
if(dna.species.should_render())
if(!..())
icon_render_key = null //invalidate bodyparts cache
update_body(TRUE)
update_hair()
update_inv_w_uniform()
update_inv_wear_id()
update_inv_gloves()
update_inv_glasses()
update_inv_ears()
update_inv_shoes()
update_inv_s_store()
update_inv_wear_mask()
update_inv_head()
update_inv_belt()
update_inv_back()
update_inv_wear_suit()
update_inv_pockets()
update_inv_neck()
update_transform()
//mutations
update_mutations_overlay()
//damage overlays
update_damage_overlays()
/* --------------------------------------- */
//vvvvvv UPDATE_INV PROCS vvvvvv
/mob/living/carbon/human/update_inv_w_uniform()
remove_overlay(UNIFORM_LAYER)
if(dna.species.should_render())
remove_overlay(UNIFORM_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_W_UNIFORM]
inv.update_icon()
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_W_UNIFORM]
inv.update_icon()
if(istype(w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = w_uniform
U.screen_loc = ui_iclothing
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown)
client.screen += w_uniform
update_observer_view(w_uniform,1)
if(istype(w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = w_uniform
U.screen_loc = ui_iclothing
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown)
client.screen += w_uniform
update_observer_view(w_uniform,1)
if(wear_suit && (wear_suit.flags_inv & HIDEJUMPSUIT))
return
if(wear_suit && (wear_suit.flags_inv & HIDEJUMPSUIT))
return
var/target_overlay = U.icon_state
if(U.adjusted == ALT_STYLE)
target_overlay = "[target_overlay]_d"
var/target_overlay = U.icon_state
if(U.adjusted == ALT_STYLE)
target_overlay = "[target_overlay]_d"
var/alt_worn = U.mob_overlay_icon || 'icons/mob/clothing/uniform.dmi'
var/variant_flag = NONE
var/alt_worn = U.mob_overlay_icon || 'icons/mob/clothing/uniform.dmi'
var/variant_flag = NONE
if((DIGITIGRADE in dna.species.species_traits) && U.mutantrace_variation & STYLE_DIGITIGRADE && !(U.mutantrace_variation & STYLE_NO_ANTHRO_ICON))
alt_worn = U.anthro_mob_worn_overlay || 'icons/mob/clothing/uniform_digi.dmi'
variant_flag |= STYLE_DIGITIGRADE
if((DIGITIGRADE in dna.species.species_traits) && U.mutantrace_variation & STYLE_DIGITIGRADE && !(U.mutantrace_variation & STYLE_NO_ANTHRO_ICON))
alt_worn = U.anthro_mob_worn_overlay || 'icons/mob/clothing/uniform_digi.dmi'
variant_flag |= STYLE_DIGITIGRADE
var/mask
if(dna.species.mutant_bodyparts["taur"])
var/datum/sprite_accessory/taur/T = GLOB.taur_list[dna.features["taur"]]
var/clip_flag = U.mutantrace_variation & T?.hide_legs
if(clip_flag)
variant_flag |= clip_flag
mask = T.alpha_mask_state
var/mask
if(dna.species.mutant_bodyparts["taur"])
var/datum/sprite_accessory/taur/T = GLOB.taur_list[dna.features["taur"]]
var/clip_flag = U.mutantrace_variation & T?.hide_legs
if(clip_flag)
variant_flag |= clip_flag
mask = T.alpha_mask_state
var/mutable_appearance/uniform_overlay
var/mutable_appearance/uniform_overlay
var/gendered = (dna?.species.sexes && dna.features["body_model"] == FEMALE) ? U.fitted : NO_FEMALE_UNIFORM
uniform_overlay = U.build_worn_icon( UNIFORM_LAYER, alt_worn, FALSE, gendered, target_overlay, variant_flag, FALSE, mask)
var/gendered = (dna?.species.sexes && dna.features["body_model"] == FEMALE) ? U.fitted : NO_FEMALE_UNIFORM
uniform_overlay = U.build_worn_icon( UNIFORM_LAYER, alt_worn, FALSE, gendered, target_overlay, variant_flag, FALSE, mask)
if(OFFSET_UNIFORM in dna.species.offset_features)
uniform_overlay.pixel_x += dna.species.offset_features[OFFSET_UNIFORM][1]
uniform_overlay.pixel_y += dna.species.offset_features[OFFSET_UNIFORM][2]
overlays_standing[UNIFORM_LAYER] = uniform_overlay
apply_overlay(UNIFORM_LAYER)
update_mutant_bodyparts()
if(OFFSET_UNIFORM in dna.species.offset_features)
uniform_overlay.pixel_x += dna.species.offset_features[OFFSET_UNIFORM][1]
uniform_overlay.pixel_y += dna.species.offset_features[OFFSET_UNIFORM][2]
overlays_standing[UNIFORM_LAYER] = uniform_overlay
apply_overlay(UNIFORM_LAYER)
update_mutant_bodyparts()
/mob/living/carbon/human/update_inv_wear_id()
remove_overlay(ID_LAYER)
if(dna.species.should_render())
remove_overlay(ID_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_ID]
inv.update_icon()
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_ID]
inv.update_icon()
var/mutable_appearance/id_overlay = overlays_standing[ID_LAYER]
var/mutable_appearance/id_overlay = overlays_standing[ID_LAYER]
if(wear_id)
wear_id.screen_loc = ui_id
if(client && hud_used && hud_used.hud_shown)
client.screen += wear_id
update_observer_view(wear_id)
if(wear_id)
wear_id.screen_loc = ui_id
if(client && hud_used && hud_used.hud_shown)
client.screen += wear_id
update_observer_view(wear_id)
//TODO: add an icon file for ID slot stuff, so it's less snowflakey
id_overlay = wear_id.build_worn_icon(default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi', override_state = wear_id.item_state)
if(OFFSET_ID in dna.species.offset_features)
id_overlay.pixel_x += dna.species.offset_features[OFFSET_ID][1]
id_overlay.pixel_y += dna.species.offset_features[OFFSET_ID][2]
overlays_standing[ID_LAYER] = id_overlay
apply_overlay(ID_LAYER)
//TODO: add an icon file for ID slot stuff, so it's less snowflakey
id_overlay = wear_id.build_worn_icon(default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi', override_state = wear_id.item_state)
if(OFFSET_ID in dna.species.offset_features)
id_overlay.pixel_x += dna.species.offset_features[OFFSET_ID][1]
id_overlay.pixel_y += dna.species.offset_features[OFFSET_ID][2]
overlays_standing[ID_LAYER] = id_overlay
apply_overlay(ID_LAYER)
/mob/living/carbon/human/update_inv_gloves()
remove_overlay(GLOVES_LAYER)
if(dna.species.should_render())
remove_overlay(GLOVES_LAYER)
if(client && hud_used && hud_used.inv_slots[SLOT_GLOVES])
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_GLOVES]
inv.update_icon()
if(client && hud_used && hud_used.inv_slots[SLOT_GLOVES])
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_GLOVES]
inv.update_icon()
if(!gloves && bloody_hands)
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color())
if(get_num_arms(FALSE) < 2)
if(has_left_hand(FALSE))
bloody_overlay.icon_state = "bloodyhands_left"
else if(has_right_hand(FALSE))
bloody_overlay.icon_state = "bloodyhands_right"
if(!gloves && bloody_hands)
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color())
if(get_num_arms(FALSE) < 2)
if(has_left_hand(FALSE))
bloody_overlay.icon_state = "bloodyhands_left"
else if(has_right_hand(FALSE))
bloody_overlay.icon_state = "bloodyhands_right"
overlays_standing[GLOVES_LAYER] = bloody_overlay
overlays_standing[GLOVES_LAYER] = bloody_overlay
var/mutable_appearance/gloves_overlay = overlays_standing[GLOVES_LAYER]
if(gloves)
gloves.screen_loc = ui_gloves
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown)
client.screen += gloves
update_observer_view(gloves,1)
overlays_standing[GLOVES_LAYER] = gloves.build_worn_icon(default_layer = GLOVES_LAYER, default_icon_file = 'icons/mob/clothing/hands.dmi')
gloves_overlay = overlays_standing[GLOVES_LAYER]
if(OFFSET_GLOVES in dna.species.offset_features)
gloves_overlay.pixel_x += dna.species.offset_features[OFFSET_GLOVES][1]
gloves_overlay.pixel_y += dna.species.offset_features[OFFSET_GLOVES][2]
overlays_standing[GLOVES_LAYER] = gloves_overlay
apply_overlay(GLOVES_LAYER)
var/mutable_appearance/gloves_overlay = overlays_standing[GLOVES_LAYER]
if(gloves)
gloves.screen_loc = ui_gloves
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown)
client.screen += gloves
update_observer_view(gloves,1)
overlays_standing[GLOVES_LAYER] = gloves.build_worn_icon(default_layer = GLOVES_LAYER, default_icon_file = 'icons/mob/clothing/hands.dmi')
gloves_overlay = overlays_standing[GLOVES_LAYER]
if(OFFSET_GLOVES in dna.species.offset_features)
gloves_overlay.pixel_x += dna.species.offset_features[OFFSET_GLOVES][1]
gloves_overlay.pixel_y += dna.species.offset_features[OFFSET_GLOVES][2]
overlays_standing[GLOVES_LAYER] = gloves_overlay
apply_overlay(GLOVES_LAYER)
/mob/living/carbon/human/update_inv_glasses()
remove_overlay(GLASSES_LAYER)
if(dna.species.should_render())
remove_overlay(GLASSES_LAYER)
if(!get_bodypart(BODY_ZONE_HEAD)) //decapitated
return
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_GLASSES]
inv.update_icon()
if(glasses)
glasses.screen_loc = ui_glasses //...draw the item in the inventory screen
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open ...
client.screen += glasses //Either way, add the item to the HUD
update_observer_view(glasses,1)
if(!(head && (head.flags_inv & HIDEEYES)) && !(wear_mask && (wear_mask.flags_inv & HIDEEYES)))
overlays_standing[GLASSES_LAYER] = glasses.build_worn_icon(default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/clothing/eyes.dmi', override_state = glasses.icon_state)
var/mutable_appearance/glasses_overlay = overlays_standing[GLASSES_LAYER]
if(glasses_overlay)
if(OFFSET_GLASSES in dna.species.offset_features)
glasses_overlay.pixel_x += dna.species.offset_features[OFFSET_GLASSES][1]
glasses_overlay.pixel_y += dna.species.offset_features[OFFSET_GLASSES][2]
overlays_standing[GLASSES_LAYER] = glasses_overlay
apply_overlay(GLASSES_LAYER)
/mob/living/carbon/human/update_inv_ears()
remove_overlay(EARS_LAYER)
if(!get_bodypart(BODY_ZONE_HEAD)) //decapitated
return
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_EARS]
inv.update_icon()
if(ears)
ears.screen_loc = ui_ears //move the item to the appropriate screen loc
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open
client.screen += ears //add it to the client's screen
update_observer_view(ears,1)
overlays_standing[EARS_LAYER] = ears.build_worn_icon(default_layer = EARS_LAYER, default_icon_file = 'icons/mob/ears.dmi')
var/mutable_appearance/ears_overlay = overlays_standing[EARS_LAYER]
if(OFFSET_EARS in dna.species.offset_features)
ears_overlay.pixel_x += dna.species.offset_features[OFFSET_EARS][1]
ears_overlay.pixel_y += dna.species.offset_features[OFFSET_EARS][2]
overlays_standing[EARS_LAYER] = ears_overlay
apply_overlay(EARS_LAYER)
/mob/living/carbon/human/update_inv_shoes()
remove_overlay(SHOES_LAYER)
if(get_num_legs(FALSE) <2)
return
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_SHOES]
inv.update_icon()
if(dna.species.mutant_bodyparts["taur"])
var/datum/sprite_accessory/taur/T = GLOB.taur_list[dna.features["taur"]]
if(T?.hide_legs) //If only they actually made shoes unwearable. Please don't making cosmetics, guys.
if(!get_bodypart(BODY_ZONE_HEAD)) //decapitated
return
if(shoes)
var/obj/item/clothing/shoes/S = shoes
shoes.screen_loc = ui_shoes //move the item to the appropriate screen loc
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open
client.screen += shoes //add it to client's screen
update_observer_view(shoes,1)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_GLASSES]
inv.update_icon()
var/alt_icon = S.mob_overlay_icon || 'icons/mob/clothing/feet.dmi'
var/variation_flag = NONE
if((DIGITIGRADE in dna.species.species_traits) && S.mutantrace_variation & STYLE_DIGITIGRADE && !(S.mutantrace_variation & STYLE_NO_ANTHRO_ICON))
alt_icon = S.anthro_mob_worn_overlay || 'icons/mob/clothing/feet_digi.dmi'
variation_flag |= STYLE_DIGITIGRADE
if(glasses)
glasses.screen_loc = ui_glasses //...draw the item in the inventory screen
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open ...
client.screen += glasses //Either way, add the item to the HUD
update_observer_view(glasses,1)
if(!(head && (head.flags_inv & HIDEEYES)) && !(wear_mask && (wear_mask.flags_inv & HIDEEYES)))
overlays_standing[GLASSES_LAYER] = glasses.build_worn_icon(default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/clothing/eyes.dmi', override_state = glasses.icon_state)
var/mutable_appearance/glasses_overlay = overlays_standing[GLASSES_LAYER]
if(glasses_overlay)
if(OFFSET_GLASSES in dna.species.offset_features)
glasses_overlay.pixel_x += dna.species.offset_features[OFFSET_GLASSES][1]
glasses_overlay.pixel_y += dna.species.offset_features[OFFSET_GLASSES][2]
overlays_standing[GLASSES_LAYER] = glasses_overlay
apply_overlay(GLASSES_LAYER)
overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(SHOES_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, S.icon_state, variation_flag, FALSE)
var/mutable_appearance/shoes_overlay = overlays_standing[SHOES_LAYER]
if(OFFSET_SHOES in dna.species.offset_features)
shoes_overlay.pixel_x += dna.species.offset_features[OFFSET_SHOES][1]
shoes_overlay.pixel_y += dna.species.offset_features[OFFSET_SHOES][2]
overlays_standing[SHOES_LAYER] = shoes_overlay
apply_overlay(SHOES_LAYER)
/mob/living/carbon/human/update_inv_ears()
if(dna.species.should_render())
remove_overlay(EARS_LAYER)
/mob/living/carbon/human/update_inv_s_store()
remove_overlay(SUIT_STORE_LAYER)
if(!get_bodypart(BODY_ZONE_HEAD)) //decapitated
return
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_S_STORE]
inv.update_icon()
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_EARS]
inv.update_icon()
if(s_store)
s_store.screen_loc = ui_sstore1
if(client && hud_used && hud_used.hud_shown)
client.screen += s_store
update_observer_view(s_store)
var/t_state = s_store.item_state
if(!t_state)
t_state = s_store.icon_state
overlays_standing[SUIT_STORE_LAYER] = mutable_appearance(((s_store.mob_overlay_icon) ? s_store.mob_overlay_icon : 'icons/mob/clothing/belt_mirror.dmi'), t_state, -SUIT_STORE_LAYER)
var/mutable_appearance/s_store_overlay = overlays_standing[SUIT_STORE_LAYER]
if(OFFSET_S_STORE in dna.species.offset_features)
s_store_overlay.pixel_x += dna.species.offset_features[OFFSET_S_STORE][1]
s_store_overlay.pixel_y += dna.species.offset_features[OFFSET_S_STORE][2]
overlays_standing[SUIT_STORE_LAYER] = s_store_overlay
apply_overlay(SUIT_STORE_LAYER)
if(ears)
ears.screen_loc = ui_ears //move the item to the appropriate screen loc
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open
client.screen += ears //add it to the client's screen
update_observer_view(ears,1)
overlays_standing[EARS_LAYER] = ears.build_worn_icon(default_layer = EARS_LAYER, default_icon_file = 'icons/mob/ears.dmi')
var/mutable_appearance/ears_overlay = overlays_standing[EARS_LAYER]
if(OFFSET_EARS in dna.species.offset_features)
ears_overlay.pixel_x += dna.species.offset_features[OFFSET_EARS][1]
ears_overlay.pixel_y += dna.species.offset_features[OFFSET_EARS][2]
overlays_standing[EARS_LAYER] = ears_overlay
apply_overlay(EARS_LAYER)
/mob/living/carbon/human/update_inv_head()
remove_overlay(HEAD_LAYER)
/mob/living/carbon/human/update_inv_shoes()
if(dna.species.should_render())
remove_overlay(SHOES_LAYER)
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
return
if(get_num_legs(FALSE) <2)
return
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
inv.update_icon()
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_SHOES]
inv.update_icon()
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'
var/muzzled = FALSE
var/variation_flag = NONE
if(dna.species.mutant_bodyparts["mam_snouts"] && dna.features["mam_snouts"] != "None")
muzzled = TRUE
else if(dna.species.mutant_bodyparts["snout"] && dna.features["snout"] != "None")
muzzled = TRUE
if(muzzled && H.mutantrace_variation & STYLE_MUZZLE && !(H.mutantrace_variation & STYLE_NO_ANTHRO_ICON))
alt_icon = H.anthro_mob_worn_overlay || 'icons/mob/clothing/head_muzzled.dmi'
variation_flag |= STYLE_MUZZLE
overlays_standing[HEAD_LAYER] = H.build_worn_icon(HEAD_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, H.icon_state, variation_flag, FALSE)
var/mutable_appearance/head_overlay = overlays_standing[HEAD_LAYER]
if(OFFSET_HEAD in dna.species.offset_features)
head_overlay.pixel_x += dna.species.offset_features[OFFSET_HEAD][1]
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)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_BELT]
inv.update_icon()
if(belt)
belt.screen_loc = ui_belt
if(client && hud_used && hud_used.hud_shown)
client.screen += belt
update_observer_view(belt)
overlays_standing[BELT_LAYER] = belt.build_worn_icon(default_layer = BELT_LAYER, default_icon_file = 'icons/mob/clothing/belt.dmi')
var/mutable_appearance/belt_overlay = overlays_standing[BELT_LAYER]
if(OFFSET_BELT in dna.species.offset_features)
belt_overlay.pixel_x += dna.species.offset_features[OFFSET_BELT][1]
belt_overlay.pixel_y += dna.species.offset_features[OFFSET_BELT][2]
overlays_standing[BELT_LAYER] = belt_overlay
apply_overlay(BELT_LAYER)
/mob/living/carbon/human/update_inv_wear_suit()
remove_overlay(SUIT_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_SUIT]
inv.update_icon()
if(wear_suit)
var/obj/item/clothing/suit/S = wear_suit
wear_suit.screen_loc = ui_oclothing
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown)
client.screen += wear_suit
update_observer_view(wear_suit,1)
var/worn_icon = wear_suit.mob_overlay_icon || 'icons/mob/clothing/suit.dmi'
var/worn_state = wear_suit.icon_state
var/center = FALSE
var/dimension_x = 32
var/dimension_y = 32
var/variation_flag = NONE
var/datum/sprite_accessory/taur/T
if(dna.species.mutant_bodyparts["taur"])
T = GLOB.taur_list[dna.features["taur"]]
var/datum/sprite_accessory/taur/T = GLOB.taur_list[dna.features["taur"]]
if(T?.hide_legs) //If only they actually made shoes unwearable. Please don't making cosmetics, guys.
return
if(S.mutantrace_variation)
if(shoes)
var/obj/item/clothing/shoes/S = shoes
shoes.screen_loc = ui_shoes //move the item to the appropriate screen loc
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open
client.screen += shoes //add it to client's screen
update_observer_view(shoes,1)
if(T?.taur_mode)
var/init_worn_icon = worn_icon
variation_flag |= S.mutantrace_variation & T.taur_mode || S.mutantrace_variation & T.alt_taur_mode
switch(variation_flag)
if(STYLE_HOOF_TAURIC)
worn_icon = 'icons/mob/clothing/taur_hooved.dmi'
if(STYLE_SNEK_TAURIC)
worn_icon = 'icons/mob/clothing/taur_naga.dmi'
if(STYLE_PAW_TAURIC)
worn_icon = 'icons/mob/clothing/taur_canine.dmi'
if(worn_icon != init_worn_icon) //worn icon sprite was changed, taur offsets will have to be applied.
if(S.taur_mob_worn_overlay) //not going to make several new variables for all taur types. Nope.
var/static/list/icon_to_state = list('icons/mob/clothing/taur_hooved.dmi' = "_hooved", 'icons/mob/clothing/taur_naga.dmi' = "_naga", 'icons/mob/clothing/taur_canine.dmi' = "_paws")
worn_state += icon_to_state[worn_icon]
worn_icon = S.taur_mob_worn_overlay
center = T.center
dimension_x = T.dimension_x
dimension_y = T.dimension_y
else if((DIGITIGRADE in dna.species.species_traits) && S.mutantrace_variation & STYLE_DIGITIGRADE && !(S.mutantrace_variation & STYLE_NO_ANTHRO_ICON)) //not a taur, but digitigrade legs.
worn_icon = S.anthro_mob_worn_overlay || 'icons/mob/clothing/suit_digi.dmi'
var/alt_icon = S.mob_overlay_icon || 'icons/mob/clothing/feet.dmi'
var/variation_flag = NONE
if((DIGITIGRADE in dna.species.species_traits) && S.mutantrace_variation & STYLE_DIGITIGRADE && !(S.mutantrace_variation & STYLE_NO_ANTHRO_ICON))
alt_icon = S.anthro_mob_worn_overlay || 'icons/mob/clothing/feet_digi.dmi'
variation_flag |= STYLE_DIGITIGRADE
overlays_standing[SUIT_LAYER] = S.build_worn_icon(SUIT_LAYER, worn_icon, FALSE, NO_FEMALE_UNIFORM, worn_state, variation_flag, FALSE)
var/mutable_appearance/suit_overlay = overlays_standing[SUIT_LAYER]
if(OFFSET_SUIT in dna.species.offset_features)
suit_overlay.pixel_x += dna.species.offset_features[OFFSET_SUIT][1]
suit_overlay.pixel_y += dna.species.offset_features[OFFSET_SUIT][2]
if(center)
suit_overlay = center_image(suit_overlay, dimension_x, dimension_y)
overlays_standing[SUIT_LAYER] = suit_overlay
update_hair()
update_mutant_bodyparts()
overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(SHOES_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, S.icon_state, variation_flag, FALSE)
var/mutable_appearance/shoes_overlay = overlays_standing[SHOES_LAYER]
if(OFFSET_SHOES in dna.species.offset_features)
shoes_overlay.pixel_x += dna.species.offset_features[OFFSET_SHOES][1]
shoes_overlay.pixel_y += dna.species.offset_features[OFFSET_SHOES][2]
overlays_standing[SHOES_LAYER] = shoes_overlay
apply_overlay(SHOES_LAYER)
apply_overlay(SUIT_LAYER)
/mob/living/carbon/human/update_inv_s_store()
if(dna.species.should_render())
remove_overlay(SUIT_STORE_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_S_STORE]
inv.update_icon()
if(s_store)
s_store.screen_loc = ui_sstore1
if(client && hud_used && hud_used.hud_shown)
client.screen += s_store
update_observer_view(s_store)
var/t_state = s_store.item_state
if(!t_state)
t_state = s_store.icon_state
overlays_standing[SUIT_STORE_LAYER] = mutable_appearance(((s_store.mob_overlay_icon) ? s_store.mob_overlay_icon : 'icons/mob/clothing/belt_mirror.dmi'), t_state, -SUIT_STORE_LAYER)
var/mutable_appearance/s_store_overlay = overlays_standing[SUIT_STORE_LAYER]
if(OFFSET_S_STORE in dna.species.offset_features)
s_store_overlay.pixel_x += dna.species.offset_features[OFFSET_S_STORE][1]
s_store_overlay.pixel_y += dna.species.offset_features[OFFSET_S_STORE][2]
overlays_standing[SUIT_STORE_LAYER] = s_store_overlay
apply_overlay(SUIT_STORE_LAYER)
/mob/living/carbon/human/update_inv_head()
if(dna.species.should_render())
remove_overlay(HEAD_LAYER)
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
return
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
inv.update_icon()
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'
var/muzzled = FALSE
var/variation_flag = NONE
if(dna.species.mutant_bodyparts["mam_snouts"] && dna.features["mam_snouts"] != "None")
muzzled = TRUE
else if(dna.species.mutant_bodyparts["snout"] && dna.features["snout"] != "None")
muzzled = TRUE
if(muzzled && H.mutantrace_variation & STYLE_MUZZLE && !(H.mutantrace_variation & STYLE_NO_ANTHRO_ICON))
alt_icon = H.anthro_mob_worn_overlay || 'icons/mob/clothing/head_muzzled.dmi'
variation_flag |= STYLE_MUZZLE
overlays_standing[HEAD_LAYER] = H.build_worn_icon(HEAD_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, H.icon_state, variation_flag, FALSE)
var/mutable_appearance/head_overlay = overlays_standing[HEAD_LAYER]
if(OFFSET_HEAD in dna.species.offset_features)
head_overlay.pixel_x += dna.species.offset_features[OFFSET_HEAD][1]
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()
if(dna.species.should_render())
remove_overlay(BELT_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_BELT]
inv.update_icon()
if(belt)
belt.screen_loc = ui_belt
if(client && hud_used && hud_used.hud_shown)
client.screen += belt
update_observer_view(belt)
overlays_standing[BELT_LAYER] = belt.build_worn_icon(default_layer = BELT_LAYER, default_icon_file = 'icons/mob/clothing/belt.dmi')
var/mutable_appearance/belt_overlay = overlays_standing[BELT_LAYER]
if(OFFSET_BELT in dna.species.offset_features)
belt_overlay.pixel_x += dna.species.offset_features[OFFSET_BELT][1]
belt_overlay.pixel_y += dna.species.offset_features[OFFSET_BELT][2]
overlays_standing[BELT_LAYER] = belt_overlay
apply_overlay(BELT_LAYER)
/mob/living/carbon/human/update_inv_wear_suit()
if(dna.species.should_render())
remove_overlay(SUIT_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_SUIT]
inv.update_icon()
if(wear_suit)
var/obj/item/clothing/suit/S = wear_suit
wear_suit.screen_loc = ui_oclothing
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown)
client.screen += wear_suit
update_observer_view(wear_suit,1)
var/worn_icon = wear_suit.mob_overlay_icon || 'icons/mob/clothing/suit.dmi'
var/worn_state = wear_suit.icon_state
var/center = FALSE
var/dimension_x = 32
var/dimension_y = 32
var/variation_flag = NONE
var/datum/sprite_accessory/taur/T
if(dna.species.mutant_bodyparts["taur"])
T = GLOB.taur_list[dna.features["taur"]]
if(S.mutantrace_variation)
if(T?.taur_mode)
var/init_worn_icon = worn_icon
variation_flag |= S.mutantrace_variation & T.taur_mode || S.mutantrace_variation & T.alt_taur_mode
switch(variation_flag)
if(STYLE_HOOF_TAURIC)
worn_icon = 'icons/mob/clothing/taur_hooved.dmi'
if(STYLE_SNEK_TAURIC)
worn_icon = 'icons/mob/clothing/taur_naga.dmi'
if(STYLE_PAW_TAURIC)
worn_icon = 'icons/mob/clothing/taur_canine.dmi'
if(worn_icon != init_worn_icon) //worn icon sprite was changed, taur offsets will have to be applied.
if(S.taur_mob_worn_overlay) //not going to make several new variables for all taur types. Nope.
var/static/list/icon_to_state = list('icons/mob/clothing/taur_hooved.dmi' = "_hooved", 'icons/mob/clothing/taur_naga.dmi' = "_naga", 'icons/mob/clothing/taur_canine.dmi' = "_paws")
worn_state += icon_to_state[worn_icon]
worn_icon = S.taur_mob_worn_overlay
center = T.center
dimension_x = T.dimension_x
dimension_y = T.dimension_y
else if((DIGITIGRADE in dna.species.species_traits) && S.mutantrace_variation & STYLE_DIGITIGRADE && !(S.mutantrace_variation & STYLE_NO_ANTHRO_ICON)) //not a taur, but digitigrade legs.
worn_icon = S.anthro_mob_worn_overlay || 'icons/mob/clothing/suit_digi.dmi'
variation_flag |= STYLE_DIGITIGRADE
overlays_standing[SUIT_LAYER] = S.build_worn_icon(SUIT_LAYER, worn_icon, FALSE, NO_FEMALE_UNIFORM, worn_state, variation_flag, FALSE)
var/mutable_appearance/suit_overlay = overlays_standing[SUIT_LAYER]
if(OFFSET_SUIT in dna.species.offset_features)
suit_overlay.pixel_x += dna.species.offset_features[OFFSET_SUIT][1]
suit_overlay.pixel_y += dna.species.offset_features[OFFSET_SUIT][2]
if(center)
suit_overlay = center_image(suit_overlay, dimension_x, dimension_y)
overlays_standing[SUIT_LAYER] = suit_overlay
update_hair()
update_mutant_bodyparts()
apply_overlay(SUIT_LAYER)
/mob/living/carbon/human/update_inv_pockets()
if(client && hud_used)
@@ -471,55 +477,57 @@ There are several things that need to be remembered:
/mob/living/carbon/human/update_inv_wear_mask()
remove_overlay(FACEMASK_LAYER)
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
return
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
if(dna.species.should_render())
remove_overlay(FACEMASK_LAYER)
var/alt_icon = M.mob_overlay_icon || 'icons/mob/clothing/mask.dmi'
var/muzzled = FALSE
var/variation_flag = NONE
if(head && (head.flags_inv & HIDEMASK))
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
return
if(dna.species.mutant_bodyparts["mam_snouts"] && dna.features["mam_snouts"] != "None")
muzzled = TRUE
else if(dna.species.mutant_bodyparts["snout"] && dna.features["snout"] != "None")
muzzled = TRUE
if(muzzled && M.mutantrace_variation & STYLE_MUZZLE && !(M.mutantrace_variation & STYLE_NO_ANTHRO_ICON))
alt_icon = M.anthro_mob_worn_overlay || 'icons/mob/clothing/mask_muzzled.dmi'
variation_flag |= STYLE_MUZZLE
var/mutable_appearance/mask_overlay = M.build_worn_icon(FACEMASK_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, wear_mask.icon_state, variation_flag, FALSE)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
inv.update_icon()
if(OFFSET_FACEMASK in dna.species.offset_features)
mask_overlay.pixel_x += dna.species.offset_features[OFFSET_FACEMASK][1]
mask_overlay.pixel_y += dna.species.offset_features[OFFSET_FACEMASK][2]
overlays_standing[FACEMASK_LAYER] = mask_overlay
apply_overlay(FACEMASK_LAYER)
update_mutant_bodyparts() //e.g. upgate needed because mask now hides lizard snout
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'
var/muzzled = FALSE
var/variation_flag = NONE
if(head && (head.flags_inv & HIDEMASK))
return
if(dna.species.mutant_bodyparts["mam_snouts"] && dna.features["mam_snouts"] != "None")
muzzled = TRUE
else if(dna.species.mutant_bodyparts["snout"] && dna.features["snout"] != "None")
muzzled = TRUE
if(muzzled && M.mutantrace_variation & STYLE_MUZZLE && !(M.mutantrace_variation & STYLE_NO_ANTHRO_ICON))
alt_icon = M.anthro_mob_worn_overlay || 'icons/mob/clothing/mask_muzzled.dmi'
variation_flag |= STYLE_MUZZLE
var/mutable_appearance/mask_overlay = M.build_worn_icon(FACEMASK_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, wear_mask.icon_state, variation_flag, FALSE)
if(OFFSET_FACEMASK in dna.species.offset_features)
mask_overlay.pixel_x += dna.species.offset_features[OFFSET_FACEMASK][1]
mask_overlay.pixel_y += dna.species.offset_features[OFFSET_FACEMASK][2]
overlays_standing[FACEMASK_LAYER] = mask_overlay
apply_overlay(FACEMASK_LAYER)
update_mutant_bodyparts() //e.g. upgate needed because mask now hides lizard snout
/mob/living/carbon/human/update_inv_back()
..()
var/mutable_appearance/back_overlay = overlays_standing[BACK_LAYER]
if(back_overlay)
remove_overlay(BACK_LAYER)
if(OFFSET_BACK in dna.species.offset_features)
back_overlay.pixel_x += dna.species.offset_features[OFFSET_BACK][1]
back_overlay.pixel_y += dna.species.offset_features[OFFSET_BACK][2]
overlays_standing[BACK_LAYER] = back_overlay
apply_overlay(BACK_LAYER)
if(dna.species.should_render())
..()
var/mutable_appearance/back_overlay = overlays_standing[BACK_LAYER]
if(back_overlay)
remove_overlay(BACK_LAYER)
if(OFFSET_BACK in dna.species.offset_features)
back_overlay.pixel_x += dna.species.offset_features[OFFSET_BACK][1]
back_overlay.pixel_y += dna.species.offset_features[OFFSET_BACK][2]
overlays_standing[BACK_LAYER] = back_overlay
apply_overlay(BACK_LAYER)
/proc/wear_alpha_masked_version(state, icon, layer, female, alpha_mask)
var/mask = "-[alpha_mask]"
@@ -710,8 +718,6 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if
..()
update_hair()
/mob/living/carbon/human/proc/update_observer_view(obj/item/I, inventory)
if(observers && observers.len)
for(var/M in observers)
@@ -729,15 +735,17 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if
// Only renders the head of the human
/mob/living/carbon/human/proc/update_body_parts_head_only()
if (!dna)
if(!dna)
return
if (!dna.species)
if(!dna.species)
return
if(dna.species.should_render())
return
var/obj/item/bodypart/HD = get_bodypart("head")
if (!istype(HD))
if(!istype(HD))
return
HD.update_limb()
+5 -5
View File
@@ -844,12 +844,12 @@
return
var/strip_mod = 1
var/strip_silence = FALSE
if (ishuman(src)) //carbon doesn't actually wear gloves
if(ishuman(src)) //carbon doesn't actually wear gloves
var/mob/living/carbon/C = src
var/obj/item/clothing/gloves/g = C.gloves
if (istype(g))
strip_mod = g.strip_mod
strip_silence = g.strip_silence
var/obj/item/clothing/gloves/G = C.gloves
if(istype(G))
strip_mod = G.strip_mod
strip_silence = G.strip_silence
if (!strip_silence)
who.visible_message("<span class='danger'>[src] tries to remove [who]'s [what.name].</span>", \
"<span class='userdanger'>[src] tries to remove your [what.name].</span>", target = src,
@@ -237,6 +237,7 @@
active_block_do_stamina_damage(owner, object, stamina_cost, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
block_return[BLOCK_RETURN_ACTIVE_BLOCK_DAMAGE_MITIGATED] = damage - final_damage
block_return[BLOCK_RETURN_SET_DAMAGE_TO] = final_damage
block_return[BLOCK_RETURN_MITIGATION_PERCENT] = clamp(1 - (final_damage / damage), 0, 1)
. = BLOCK_SHOULD_CHANGE_DAMAGE
if((final_damage <= 0) || (damage <= 0))
. |= BLOCK_SUCCESS //full block
+4 -1
View File
@@ -5,12 +5,15 @@
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOMOVE), .proc/update_mobility)
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOPICKUP), .proc/update_mobility)
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOUSE), .proc/update_mobility)
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOREST), .proc/update_mobility)
//Stuff like mobility flag updates, resting updates, etc.
//Force-set resting variable, without needing to resist/etc.
/mob/living/proc/set_resting(new_resting, silent = FALSE, updating = TRUE)
if(new_resting != resting)
if(resting && HAS_TRAIT(src, TRAIT_MOBILITY_NOREST)) //forcibly block resting from all sources - BE CAREFUL WITH THIS TRAIT
return
resting = new_resting
if(!silent)
to_chat(src, "<span class='notice'>You are now [resting? "resting" : "getting up"].</span>")
@@ -87,7 +90,7 @@
var/canstand_involuntary = conscious && !stat_softcrit && !knockdown && !chokehold && !paralyze && (ignore_legs || has_legs) && !(buckled && buckled.buckle_lying) && !(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
var/canstand = canstand_involuntary && !resting
var/should_be_lying = !canstand
var/should_be_lying = !canstand && !HAS_TRAIT(src, TRAIT_MOBILITY_NOREST)
if(buckled)
if(buckled.buckle_lying != -1)
should_be_lying = buckled.buckle_lying
@@ -52,6 +52,19 @@
var/lose_patience_timer_id //id for a timer to call LoseTarget(), used to stop mobs fixating on a target they can't reach
var/lose_patience_timeout = 300 //30 seconds by default, so there's no major changes to AI behaviour, beyond actually bailing if stuck forever
///When a target is found, will the mob attempt to charge at it's target?
var/charger = FALSE
///Tracks if the target is actively charging.
var/charge_state = FALSE
///In a charge, how many tiles will the charger travel?
var/charge_distance = 3
///How often can the charging mob actually charge? Effects the cooldown between charges.
var/charge_frequency = 6 SECONDS
///If the mob is charging, how long will it stun it's target on success, and itself on failure?
var/knockdown_time = 3 SECONDS
///Declares a cooldown for potential charges right off the bat.
COOLDOWN_DECLARE(charge_cooldown)
/mob/living/simple_animal/hostile/Initialize()
. = ..()
@@ -292,6 +305,9 @@
if(ranged) //We ranged? Shoot at em
if(!target.Adjacent(targets_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown
OpenFire(target)
if(charger && (target_distance > minimum_distance) && (target_distance <= charge_distance))//Attempt to close the distance with a charge.
enter_charge(target)
return TRUE
if(!Process_Spacemove()) //Drifting
walk(src,0)
return 1
@@ -599,3 +615,64 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega
. += M
else if (M.loc.type in hostile_machines)
. += M.loc
/**
* Proc that handles a charge attack windup for a mob.
*/
/mob/living/simple_animal/hostile/proc/enter_charge(var/atom/target)
if((mobility_flags & (MOBILITY_MOVE | MOBILITY_STAND)) != (MOBILITY_MOVE | MOBILITY_STAND) || charge_state)
return FALSE
if(!(COOLDOWN_FINISHED(src, charge_cooldown)) || !has_gravity() || !target.has_gravity())
return FALSE
Shake(15, 15, 1 SECONDS)
addtimer(CALLBACK(src, .proc/handle_charge_target, target), 1.5 SECONDS, TIMER_STOPPABLE)
/**
* Proc that throws the mob at the target after the windup.
*/
/mob/living/simple_animal/hostile/proc/handle_charge_target(var/atom/target)
charge_state = TRUE
throw_at(target, charge_distance, 1, src, FALSE, TRUE, callback = CALLBACK(src, .proc/charge_end))
COOLDOWN_START(src, charge_cooldown, charge_frequency)
return TRUE
/**
* Proc that handles a charge attack after it's concluded.
*/
/mob/living/simple_animal/hostile/proc/charge_end()
charge_state = FALSE
/**
* Proc that handles the charge impact of the charging mob.
*/
/mob/living/simple_animal/hostile/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!charge_state)
return ..()
if(hit_atom)
if(isliving(hit_atom))
var/mob/living/L = hit_atom
var/blocked = FALSE
if(ishuman(hit_atom))
var/mob/living/carbon/human/H = hit_atom
var/list/return_list = list()
if(H.mob_run_block(src, 0, "the [name]", ATTACK_TYPE_TACKLE, 0, src, null, return_list) & BLOCK_SUCCESS)
blocked = TRUE
if(!blocked)
blocked = return_list[BLOCK_RETURN_MITIGATION_PERCENT]
if(!blocked)
L.visible_message("<span class='danger'>[src] charges on [L]!</span>", "<span class='userdanger'>[src] charges into you!</span>")
L.Knockdown(knockdown_time)
else
Stun((knockdown_time * 2), 1, 1)
charge_end()
else if(hit_atom.density && !hit_atom.CanPass(src))
visible_message("<span class='danger'>[src] smashes into [hit_atom]!</span>")
Stun((knockdown_time * 2), 1, 1)
if(charge_state)
charge_state = FALSE
update_icons()
update_mobility()
@@ -0,0 +1,42 @@
/**
* Lobstrosities, the poster boy of charging AI mobs. Drops crab meat and bones.
* Outside of charging, it's intended behavior is that it is generally slow moving, but makes up for that with a knockdown attack to score additional hits.
*/
/mob/living/simple_animal/hostile/asteroid/lobstrosity
name = "arctic lobstrosity"
desc = "A marvel of evolution gone wrong, the frosty ice produces underground lakes where these ill tempered seafood gather. Beware its charge."
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
icon_state = "arctic_lobstrosity"
icon_living = "arctic_lobstrosity"
icon_dead = "arctic_lobstrosity_dead"
mob_biotypes = MOB_ORGANIC|MOB_BEAST
mouse_opacity = MOUSE_OPACITY_ICON
friendly_verb_continuous = "chitters at"
friendly_verb_simple = "chits at"
speak_emote = list("chitters")
speed = 3
move_to_delay = 20
maxHealth = 150
health = 150
obj_damage = 15
melee_damage_lower = 15
melee_damage_upper = 19
attack_verb_continuous = "snips"
attack_verb_simple = "snip"
attack_sound = 'sound/weapons/bite.ogg'
weather_immunities = list("snow")
vision_range = 5
aggro_vision_range = 7
charger = TRUE
charge_distance = 4
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/crab = 2, /obj/item/stack/sheet/bone = 2)
robust_searching = TRUE
footstep_type = FOOTSTEP_MOB_CLAW
gold_core_spawnable = HOSTILE_SPAWN
/mob/living/simple_animal/hostile/asteroid/lobstrosity/lava
name = "tropical lobstrosity"
desc = "A marvel of evolution gone wrong, the sulfur lakes of lavaland have given them a vibrant, red hued shell. Beware its charge."
icon_state = "lobstrosity"
icon_living = "lobstrosity"
icon_dead = "lobstrosity_dead"
@@ -6,6 +6,7 @@
gender = PLURAL //placeholder
///How much blud it has for bloodsucking
blood_volume = 550
rad_flags = RAD_NO_CONTAMINATE
status_flags = CANPUSH
+1 -2
View File
@@ -39,8 +39,7 @@
update_client_colour()
update_mouse_pointer()
if(client)
client.change_view(CONFIG_GET(string/default_view)) // Resets the client.view in case it was changed.
client.view_size?.resetToDefault()
if(client.player_details && istype(client.player_details))
if(client.player_details.player_actions.len)
for(var/datum/action/A in client.player_details.player_actions)
+1
View File
@@ -39,6 +39,7 @@
. = ..()
update_config_movespeed()
update_movespeed(TRUE)
initialize_actionspeed()
hook_vr("mob_new",list(src))
/mob/GenerateTag()
+7
View File
@@ -58,6 +58,13 @@
var/list/movespeed_mod_immunities //Lazy list, see mob_movespeed.dm
/// The calculated mob speed slowdown based on the modifiers list
var/cached_multiplicative_slowdown
/// List of action speed modifiers applying to this mob
var/list/actionspeed_modification //Lazy list, see mob_movespeed.dm
/// List of action speed modifiers ignored by this mob. List -> List (id) -> List (sources)
var/list/actionspeed_mod_immunities //Lazy list, see mob_movespeed.dm
/// The calculated mob action speed slowdown based on the modifiers list
var/cached_multiplicative_actions_slowdown
/////////////////
var/name_archive //For admin things like possession