Merge conflict fix
This commit is contained in:
@@ -392,6 +392,8 @@
|
||||
|
||||
character.update_parallax_teleport()
|
||||
|
||||
job.standard_assign_skills(character.mind)
|
||||
|
||||
SSticker.minds += character.mind
|
||||
|
||||
var/mob/living/carbon/human/humanc
|
||||
|
||||
@@ -18,16 +18,10 @@
|
||||
hair_color = random_short_color()
|
||||
facial_hair_color = hair_color
|
||||
eye_color = random_eye_color()
|
||||
horn_color = "85615a"
|
||||
wing_color = "fff"
|
||||
if(!pref_species)
|
||||
var/rando_race = pick(GLOB.roundstart_races)
|
||||
pref_species = new rando_race()
|
||||
features = random_features(pref_species?.id)
|
||||
if(gender == MALE || gender != FEMALE)
|
||||
features["body_model"] = gender
|
||||
else if(gender == PLURAL)
|
||||
features["body_model"] = pick(MALE,FEMALE)
|
||||
features = random_features(pref_species?.id, gender)
|
||||
age = rand(AGE_MIN,AGE_MAX)
|
||||
|
||||
/datum/preferences/proc/update_preview_icon(equip_job = TRUE)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
from doing this unless you absolutely know what you are doing, and have defined a
|
||||
conversion in savefile.dm
|
||||
*/
|
||||
|
||||
/proc/init_sprite_accessory_subtypes(prototype, list/L, list/male, list/female, roundstart = FALSE, skip_prototype = TRUE)//Roundstart argument builds a specific list for roundstart parts where some parts may be locked
|
||||
if(!istype(L))
|
||||
L = list()
|
||||
@@ -55,19 +56,19 @@
|
||||
var/gender = NEUTER //Determines if the accessory will be skipped or included in random hair generations
|
||||
var/gender_specific //Something that can be worn by either gender, but looks different on each
|
||||
var/color_src = MUTCOLORS //Currently only used by mutantparts so don't worry about hair and stuff. This is the source that this accessory will get its color from. Default is MUTCOLOR, but can also be HAIR, FACEHAIR, EYECOLOR and 0 if none.
|
||||
var/hasinner //Decides if this sprite has an "inner" part, such as the fleshy parts on ears.
|
||||
var/locked = FALSE //Is this part locked from roundstart selection? Used for parts that apply effects
|
||||
var/dimension_x = 32
|
||||
var/dimension_y = 32
|
||||
var/center = FALSE //Should we center the sprite?
|
||||
var/list/relevant_layers //list of layers that this accessory uses. As of now only used in species.handle_mutant_bodyparts(), but that's where most sprite accessories are anyway.
|
||||
var/mutant_part_string //Also used in species.handle_mutant_bodyparts() to generate the overlay icon state.
|
||||
var/alpha_mask_state
|
||||
|
||||
//Special / holdover traits for Citadel specific sprites.
|
||||
var/extra = FALSE
|
||||
var/extra_color_src = MUTCOLORS2 //The color source for the extra overlay.
|
||||
var/extra_icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
var/extra2 = FALSE
|
||||
var/extra2_color_src = MUTCOLORS3
|
||||
var/extra2_icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
|
||||
//for snowflake/donor specific sprites
|
||||
var/list/ckeys_allowed
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
*******************************************/
|
||||
/datum/sprite_accessory/xeno_dorsal
|
||||
icon = 'modular_citadel/icons/mob/xeno_parts_greyscale.dmi'
|
||||
mutant_part_string = "xenodorsal"
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/xeno_dorsal/standard
|
||||
name = "Standard"
|
||||
@@ -22,9 +24,12 @@
|
||||
*******************************************/
|
||||
/datum/sprite_accessory/xeno_tail
|
||||
icon = 'modular_citadel/icons/mob/xeno_parts_greyscale.dmi'
|
||||
mutant_part_string = "tail"
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/xeno_tail/none
|
||||
name = "None"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/xeno_tail/standard
|
||||
name = "Xenomorph Tail"
|
||||
@@ -35,6 +40,8 @@
|
||||
*******************************************/
|
||||
/datum/sprite_accessory/xeno_head
|
||||
icon = 'modular_citadel/icons/mob/xeno_parts_greyscale.dmi'
|
||||
mutant_part_string = "xhead"
|
||||
relevant_layers = list(BODY_ADJ_LAYER)
|
||||
|
||||
/datum/sprite_accessory/xeno_head/standard
|
||||
name = "Standard"
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
|
||||
/datum/sprite_accessory/body_markings
|
||||
icon = 'icons/mob/mutant_bodyparts.dmi'
|
||||
relevant_layers = list(BODY_ADJ_LAYER)
|
||||
|
||||
/datum/sprite_accessory/body_markings/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/body_markings/dtiger
|
||||
name = "Dark Tiger Body"
|
||||
@@ -45,6 +47,7 @@
|
||||
icon_state = "none"
|
||||
ckeys_allowed = list("yousshouldnteverbeseeingthisyoumeme")
|
||||
icon = 'modular_citadel/icons/mob/markings_notmammals.dmi'
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/plain
|
||||
name = "Plain"
|
||||
@@ -219,10 +222,12 @@
|
||||
/datum/sprite_accessory/insect_fluff
|
||||
icon = 'icons/mob/wings.dmi'
|
||||
color_src = 0
|
||||
relevant_layers = list(BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/plain
|
||||
name = "Plain"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
datum/sprite_accessory/caps
|
||||
icon = 'icons/mob/mutant_bodyparts.dmi'
|
||||
color_src = HAIR
|
||||
relevant_layers = list(BODY_ADJ_LAYER)
|
||||
|
||||
/datum/sprite_accessory/caps/round
|
||||
name = "Round"
|
||||
icon_state = "round"
|
||||
icon_state = "round"
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/datum/sprite_accessory/ears
|
||||
icon = 'icons/mob/mutant_bodyparts.dmi'
|
||||
mutant_part_string = "ears"
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/ears/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/******************************************
|
||||
*************** Human Ears ****************
|
||||
@@ -29,9 +32,10 @@
|
||||
/datum/sprite_accessory/ears/human/bigwolfinner
|
||||
name = "Big Wolf (ALT)"
|
||||
icon_state = "bigwolfinner"
|
||||
hasinner = 1
|
||||
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
|
||||
color_src = MATRIXED
|
||||
extra = TRUE
|
||||
extra_color_src = NONE
|
||||
|
||||
/datum/sprite_accessory/ears/human/bigwolfdark
|
||||
name = "Dark Big Wolf"
|
||||
@@ -42,15 +46,17 @@
|
||||
/datum/sprite_accessory/ears/human/bigwolfinnerdark
|
||||
name = "Dark Big Wolf (ALT)"
|
||||
icon_state = "bigwolfinnerdark"
|
||||
hasinner = 1
|
||||
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
|
||||
color_src = MATRIXED
|
||||
extra = TRUE
|
||||
extra_color_src = NONE
|
||||
|
||||
/datum/sprite_accessory/ears/cat
|
||||
name = "Cat"
|
||||
icon_state = "cat"
|
||||
hasinner = 1
|
||||
color_src = HAIR
|
||||
extra = TRUE
|
||||
extra_color_src = NONE
|
||||
|
||||
/datum/sprite_accessory/ears/human/cow
|
||||
name = "Cow"
|
||||
@@ -172,10 +178,13 @@
|
||||
/datum/sprite_accessory/mam_ears
|
||||
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
|
||||
color_src = MATRIXED
|
||||
mutant_part_string = "ears"
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/mam_ears/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/mam_ears/axolotl
|
||||
name = "Axolotl"
|
||||
@@ -196,7 +205,8 @@
|
||||
/datum/sprite_accessory/mam_ears/bigwolfinner
|
||||
name = "Big Wolf (ALT)"
|
||||
icon_state = "bigwolfinner"
|
||||
hasinner = 1
|
||||
extra = TRUE
|
||||
extra_color_src = NONE
|
||||
|
||||
/datum/sprite_accessory/mam_ears/bigwolfdark
|
||||
name = "Dark Big Wolf"
|
||||
@@ -205,13 +215,16 @@
|
||||
/datum/sprite_accessory/mam_ears/bigwolfinnerdark
|
||||
name = "Dark Big Wolf (ALT)"
|
||||
icon_state = "bigwolfinnerdark"
|
||||
hasinner = 1
|
||||
extra = TRUE
|
||||
extra_color_src = NONE
|
||||
|
||||
/datum/sprite_accessory/mam_ears/cat
|
||||
name = "Cat"
|
||||
icon_state = "cat"
|
||||
hasinner = 1
|
||||
icon = 'icons/mob/mutant_bodyparts.dmi'
|
||||
color_src = HAIR
|
||||
extra = TRUE
|
||||
extra_color_src = NONE
|
||||
|
||||
/datum/sprite_accessory/mam_ears/catbig
|
||||
name = "Cat, Big"
|
||||
@@ -309,4 +322,4 @@
|
||||
|
||||
/datum/sprite_accessory/mam_ears/bunny
|
||||
name = "Bunny"
|
||||
icon_state = "bunny"
|
||||
icon_state = "bunny"
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/datum/sprite_accessory/frills
|
||||
icon = 'icons/mob/mutant_bodyparts.dmi'
|
||||
relevant_layers = list(BODY_ADJ_LAYER)
|
||||
|
||||
/datum/sprite_accessory/frills/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/frills/simple
|
||||
name = "Simple"
|
||||
@@ -15,4 +17,4 @@
|
||||
|
||||
/datum/sprite_accessory/frills/aquatic
|
||||
name = "Aquatic"
|
||||
icon_state = "aqua"
|
||||
icon_state = "aqua"
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
/datum/sprite_accessory/horns
|
||||
icon = 'icons/mob/mutant_bodyparts.dmi'
|
||||
color_src = HORNCOLOR
|
||||
relevant_layers = list(BODY_ADJ_LAYER)
|
||||
|
||||
/datum/sprite_accessory/horns/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/horns/simple
|
||||
name = "Simple"
|
||||
@@ -33,4 +35,4 @@
|
||||
|
||||
/datum/sprite_accessory/horns/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
icon_state = "guilmon"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
/datum/sprite_accessory/screen
|
||||
icon = 'modular_citadel/icons/mob/ipc_screens.dmi'
|
||||
color_src = null
|
||||
relevant_layers = list(BODY_ADJ_LAYER)
|
||||
|
||||
/datum/sprite_accessory/screen/blank
|
||||
name = "Blank"
|
||||
@@ -132,6 +133,7 @@
|
||||
/datum/sprite_accessory/antenna
|
||||
icon = 'modular_citadel/icons/mob/ipc_antennas.dmi'
|
||||
color_src = MUTCOLORS2
|
||||
relevant_layers = list(BODY_ADJ_LAYER)
|
||||
recommended_species = list("ipc")
|
||||
|
||||
/datum/sprite_accessory/antenna/none
|
||||
|
||||
@@ -21,29 +21,42 @@
|
||||
|
||||
/datum/sprite_accessory/taur
|
||||
icon = 'modular_citadel/icons/mob/mam_taur.dmi'
|
||||
extra_icon = 'modular_citadel/icons/mob/mam_taur.dmi'
|
||||
extra = TRUE
|
||||
extra2_icon = 'modular_citadel/icons/mob/mam_taur.dmi'
|
||||
extra2 = TRUE
|
||||
center = TRUE
|
||||
dimension_x = 64
|
||||
var/taur_mode = NONE //Must be a single specific tauric suit variation bitflag. Don't do FLAG_1|FLAG_2
|
||||
var/alt_taur_mode = NONE //Same as above.
|
||||
color_src = MATRIXED
|
||||
recommended_species = list("human", "lizard", "insect", "mammal", "xeno", "jelly", "slimeperson", "podweak")
|
||||
relevant_layers = list(BODY_ADJ_UPPER_LAYER, BODY_FRONT_LAYER)
|
||||
var/taur_mode = NONE //Must be a single specific tauric suit variation bitflag. Don't do FLAG_1|FLAG_2
|
||||
var/alt_taur_mode = NONE //Same as above.
|
||||
var/hide_legs = USE_QUADRUPED_CLIP_MASK
|
||||
|
||||
/datum/sprite_accessory/taur/New()
|
||||
switch(hide_legs)
|
||||
if(USE_QUADRUPED_CLIP_MASK)
|
||||
alpha_mask_state = "taur_mask_def"
|
||||
if(USE_SNEK_CLIP_MASK)
|
||||
alpha_mask_state = "taur_mask_naga"
|
||||
|
||||
/datum/sprite_accessory/taur/none
|
||||
dimension_x = 32
|
||||
center = FALSE
|
||||
name = "None"
|
||||
icon_state = "None"
|
||||
dimension_x = 32
|
||||
center = FALSE
|
||||
recommended_species = null
|
||||
relevant_layers = null
|
||||
hide_legs = FALSE
|
||||
|
||||
/datum/sprite_accessory/taur/cow
|
||||
name = "Cow"
|
||||
icon_state = "cow"
|
||||
taur_mode = STYLE_HOOF_TAURIC
|
||||
alt_taur_mode = STYLE_PAW_TAURIC
|
||||
color_src = MUTCOLORS
|
||||
|
||||
/datum/sprite_accessory/taur/cow/spotted
|
||||
name = "Cow (Spotted)"
|
||||
icon_state = "cow_spotted"
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/taur/deer
|
||||
name = "Deer"
|
||||
@@ -56,27 +69,21 @@
|
||||
name = "Drake"
|
||||
icon_state = "drake"
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
color_src = MUTCOLORS
|
||||
extra = TRUE
|
||||
|
||||
/datum/sprite_accessory/taur/drider
|
||||
name = "Drider"
|
||||
icon_state = "drider"
|
||||
color_src = MUTCOLORS
|
||||
extra = TRUE
|
||||
|
||||
/datum/sprite_accessory/taur/eevee
|
||||
name = "Eevee"
|
||||
icon_state = "eevee"
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
color_src = MUTCOLORS
|
||||
|
||||
/datum/sprite_accessory/taur/fox
|
||||
name = "Fox"
|
||||
icon_state = "fox"
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/husky
|
||||
name = "Husky"
|
||||
icon_state = "husky"
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
extra = TRUE
|
||||
|
||||
/datum/sprite_accessory/taur/horse
|
||||
name = "Horse"
|
||||
@@ -84,15 +91,11 @@
|
||||
taur_mode = STYLE_HOOF_TAURIC
|
||||
alt_taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/lab
|
||||
name = "Lab"
|
||||
icon_state = "lab"
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/naga
|
||||
name = "Naga"
|
||||
icon_state = "naga"
|
||||
taur_mode = STYLE_SNEK_TAURIC
|
||||
hide_legs = USE_SNEK_CLIP_MASK
|
||||
|
||||
/datum/sprite_accessory/taur/otie
|
||||
name = "Otie"
|
||||
@@ -104,29 +107,26 @@
|
||||
icon_state = "pede"
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
color_src = MUTCOLORS
|
||||
|
||||
/datum/sprite_accessory/taur/panther
|
||||
name = "Panther"
|
||||
icon_state = "panther"
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/shepherd
|
||||
name = "Shepherd"
|
||||
icon_state = "shepherd"
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
extra = TRUE
|
||||
extra2 = TRUE
|
||||
|
||||
/datum/sprite_accessory/taur/tentacle
|
||||
name = "Tentacle"
|
||||
icon_state = "tentacle"
|
||||
taur_mode = STYLE_SNEK_TAURIC
|
||||
color_src = MUTCOLORS
|
||||
hide_legs = USE_SNEK_CLIP_MASK
|
||||
|
||||
/datum/sprite_accessory/taur/tiger
|
||||
name = "Tiger"
|
||||
icon_state = "tiger"
|
||||
/datum/sprite_accessory/taur/canine
|
||||
name = "Canine"
|
||||
icon_state = "canine"
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
color_src = MUTCOLORS
|
||||
extra = TRUE
|
||||
|
||||
/datum/sprite_accessory/taur/wolf
|
||||
name = "Wolf"
|
||||
icon_state = "wolf"
|
||||
/datum/sprite_accessory/taur/feline
|
||||
name = "Feline"
|
||||
icon_state = "feline"
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
color_src = MUTCOLORS
|
||||
extra = TRUE
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/datum/sprite_accessory/snouts
|
||||
icon = 'icons/mob/mutant_bodyparts.dmi'
|
||||
mutant_part_string = "snout"
|
||||
relevant_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/snouts/sharp
|
||||
name = "Sharp"
|
||||
@@ -152,11 +154,14 @@
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_snouts.dmi'
|
||||
recommended_species = list("mammal", "slimeperson", "insect", "podweak")
|
||||
mutant_part_string = "snout"
|
||||
relevant_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
recommended_species = null
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/bird
|
||||
name = "Beak"
|
||||
@@ -383,4 +388,4 @@
|
||||
/datum/sprite_accessory/mam_snouts/froundlight
|
||||
name = "Round + Light (Top)"
|
||||
icon_state = "froundlight"
|
||||
color_src = MUTCOLORS
|
||||
color_src = MUTCOLORS
|
||||
|
||||
+4
-1
@@ -1,12 +1,15 @@
|
||||
/datum/sprite_accessory/spines
|
||||
icon = 'icons/mob/mutant_bodyparts.dmi'
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER)
|
||||
|
||||
/datum/sprite_accessory/spines_animated
|
||||
icon = 'icons/mob/mutant_bodyparts.dmi'
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER)
|
||||
|
||||
/datum/sprite_accessory/spines/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/spines_animated/none
|
||||
name = "None"
|
||||
@@ -50,4 +53,4 @@
|
||||
|
||||
/datum/sprite_accessory/spines_animated/aqautic
|
||||
name = "Aquatic"
|
||||
icon_state = "aqua"
|
||||
icon_state = "aqua"
|
||||
@@ -1,8 +1,12 @@
|
||||
/datum/sprite_accessory/tails
|
||||
icon = 'icons/mob/mutant_bodyparts.dmi'
|
||||
mutant_part_string = "tail"
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/tails_animated
|
||||
icon = 'icons/mob/mutant_bodyparts.dmi'
|
||||
mutant_part_string = "tailwag"
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/******************************************
|
||||
************* Lizard Tails ****************
|
||||
@@ -43,10 +47,12 @@
|
||||
/datum/sprite_accessory/tails/lizard/none
|
||||
name = "None"
|
||||
icon_state = "None"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/tails_animated/lizard/none
|
||||
name = "None"
|
||||
icon_state = "None"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/tails/lizard/axolotl
|
||||
name = "Axolotl"
|
||||
@@ -85,10 +91,12 @@
|
||||
/datum/sprite_accessory/tails/human/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/tails_animated/human/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/tails/human/ailurus
|
||||
name = "Red Panda"
|
||||
@@ -502,20 +510,25 @@
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
recommended_species = list("mammal", "slimeperson", "podweak", "felinid", "insect")
|
||||
mutant_part_string = "tail"
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/mam_tails/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
recommended_species = null
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
mutant_part_string = "tailwag"
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
color_src = MATRIXED
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/mam_tails/ailurus
|
||||
name = "Red Panda"
|
||||
@@ -576,7 +589,7 @@
|
||||
/datum/sprite_accessory/mam_tails_animated/catbig
|
||||
name = "Cat, Big"
|
||||
icon_state = "catbig"
|
||||
|
||||
|
||||
/datum/sprite_accessory/mam_tails/twocat
|
||||
name = "Cat, Double"
|
||||
icon_state = "twocat"
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
/datum/sprite_accessory/wings/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/wings_open
|
||||
icon = 'icons/mob/wings.dmi'
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/wings_open/angel
|
||||
name = "Angel"
|
||||
@@ -17,6 +19,7 @@
|
||||
|
||||
/datum/sprite_accessory/wings
|
||||
icon = 'icons/mob/wings.dmi'
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/wings/angel
|
||||
name = "Angel"
|
||||
@@ -32,10 +35,13 @@
|
||||
/datum/sprite_accessory/deco_wings
|
||||
icon = 'icons/mob/wings.dmi'
|
||||
color_src = WINGCOLOR
|
||||
mutant_part_string = "insect_wings"
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/deco_wings/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/deco_wings/angel
|
||||
name = "Angel"
|
||||
@@ -44,6 +50,7 @@
|
||||
dimension_x = 46
|
||||
center = TRUE
|
||||
dimension_y = 34
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/deco_wings/bat
|
||||
name = "Bat"
|
||||
@@ -130,10 +137,12 @@
|
||||
/datum/sprite_accessory/insect_wings
|
||||
icon = 'icons/mob/wings.dmi'
|
||||
color_src = WINGCOLOR
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/insect_wings/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/insect_wings/bat
|
||||
name = "Bat"
|
||||
@@ -231,10 +240,12 @@
|
||||
/datum/sprite_accessory/insect_markings // Extra markings for insects ported from tg.
|
||||
icon = 'icons/mob/insect_markings.dmi'
|
||||
color_src = null
|
||||
relevant_layers = list(BODY_ADJ_LAYER)
|
||||
|
||||
/datum/sprite_accessory/insect_markings/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/insect_markings/reddish
|
||||
name = "Reddish"
|
||||
@@ -290,4 +301,4 @@
|
||||
|
||||
/datum/sprite_accessory/insect_markings/witchwing
|
||||
name = "Witch Wing"
|
||||
icon_state = "witchwing"
|
||||
icon_state = "witchwing"
|
||||
|
||||
@@ -570,7 +570,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
views |= i
|
||||
var/new_view = input("Choose your new view", "Modify view range", 7) as null|anything in views
|
||||
if(new_view)
|
||||
client.change_view(CLAMP(new_view, 7, max_view))
|
||||
client.change_view(clamp(new_view, 7, max_view))
|
||||
else
|
||||
client.change_view(CONFIG_GET(string/default_view))
|
||||
|
||||
@@ -937,3 +937,20 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
spawners_menu = new(src)
|
||||
|
||||
spawners_menu.ui_interact(src)
|
||||
|
||||
/mob/dead/observer/verb/game_info()
|
||||
set name = "Game info"
|
||||
set desc = "Shows various info relating to the game mode, antagonists etc."
|
||||
set category = "Ghost"
|
||||
if(!started_as_observer && can_reenter_corpse)
|
||||
to_chat(src, "You cannot see this info unless you are an observer or you've chosen Do Not Resuscitate!")
|
||||
return
|
||||
var/list/stuff = list("[SSticker.mode.name]")
|
||||
stuff += "Antagonists:\n"
|
||||
for(var/datum/antagonist/A in GLOB.antagonists)
|
||||
if(A.owner)
|
||||
stuff += "[A.owner] the [A.name]"
|
||||
var/ghost_info = SSticker.mode.ghost_info()
|
||||
if(ghost_info)
|
||||
stuff += ghost_info
|
||||
to_chat(src,stuff.Join("\n"))
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
else
|
||||
to_follow = V.source
|
||||
var/link = FOLLOW_LINK(src, to_follow)
|
||||
// Create map text prior to modifying message for goonchat
|
||||
if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker)))
|
||||
create_chat_message(speaker, message_language, raw_message, spans, message_mode)
|
||||
// Recompose the message, because it's scrambled by default
|
||||
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode, FALSE, source)
|
||||
to_chat(src, "[link] [message]")
|
||||
|
||||
@@ -333,7 +333,8 @@
|
||||
I.moveToNullspace()
|
||||
else
|
||||
I.forceMove(newloc)
|
||||
I.dropped(src)
|
||||
if(I.dropped(src) == ITEM_RELOCATED_BY_DROPPED)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//Outdated but still in use apparently. This should at least be a human proc.
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
var/adjusted_amount
|
||||
if(amount >= 0 && maximum)
|
||||
var/brainloss = get_brain_damage()
|
||||
var/new_brainloss = CLAMP(brainloss + amount, 0, maximum)
|
||||
var/new_brainloss = clamp(brainloss + amount, 0, maximum)
|
||||
if(brainloss > new_brainloss) //brainloss is over the cap already
|
||||
return 0
|
||||
adjusted_amount = new_brainloss - brainloss
|
||||
@@ -245,23 +245,17 @@
|
||||
. = adjusted_amount
|
||||
*/
|
||||
|
||||
/obj/item/organ/brain/on_life()
|
||||
if(damage >= BRAIN_DAMAGE_DEATH) //rip
|
||||
to_chat(owner, "<span class='userdanger'>The last spark of life in your brain fizzles out...</span>")
|
||||
owner.death()
|
||||
brain_death = TRUE
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/organ/brain/on_death()
|
||||
if(damage <= BRAIN_DAMAGE_DEATH) //rip
|
||||
brain_death = FALSE
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/organ/brain/applyOrganDamage(var/d, var/maximum = maxHealth)
|
||||
..()
|
||||
|
||||
. = ..()
|
||||
if(!. || !owner)
|
||||
return
|
||||
if(damage >= BRAIN_DAMAGE_DEATH) //rip
|
||||
if(owner.stat != DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>The last spark of life in your brain fizzles out...</span>")
|
||||
owner.death()
|
||||
brain_death = TRUE
|
||||
else
|
||||
brain_death = FALSE
|
||||
|
||||
/obj/item/organ/brain/check_damage_thresholds(mob/M)
|
||||
. = ..()
|
||||
|
||||
@@ -25,10 +25,3 @@
|
||||
/mob/living/brain/treat_message(message)
|
||||
message = capitalize(message)
|
||||
return message
|
||||
|
||||
/mob/living/brain/could_speak_in_language(datum/language/dt)
|
||||
if(istype(container, /obj/item/mmi/posibrain/soul_vessel))
|
||||
// soul vessels can only speak ratvarian.
|
||||
. = ispath(dt, /datum/language/ratvar)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
@@ -12,6 +12,13 @@
|
||||
bubble_icon = "alien"
|
||||
type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
|
||||
|
||||
/// How much brute damage without armor piercing they do against mobs in melee
|
||||
var/meleeSlashHumanPower = 20
|
||||
/// How much power they have for DefaultCombatKnockdown when attacking humans
|
||||
var/meleeKnockdownPower = 100
|
||||
/// How much brute damage they do to simple animals
|
||||
var/meleeSlashSAPower = 35
|
||||
|
||||
var/obj/item/card/id/wear_id = null // Fix for station bounced radios -- Skie
|
||||
var/has_fine_manipulation = 0
|
||||
var/move_delay_add = 0 // movement delay to add
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
maxHealth = 125
|
||||
health = 125
|
||||
icon_state = "aliend"
|
||||
meleeKnockdownPower = 80
|
||||
|
||||
/mob/living/carbon/alien/humanoid/drone/Initialize()
|
||||
AddAbility(new/obj/effect/proc_holder/alien/evolve(null))
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/mob/living/carbon/alien/humanoid/hunter
|
||||
name = "alien hunter"
|
||||
caste = "h"
|
||||
maxHealth = 125
|
||||
health = 125
|
||||
maxHealth = 170
|
||||
health = 170
|
||||
icon_state = "alienh"
|
||||
meleeKnockdownPower = 75
|
||||
meleeSlashHumanPower = 20
|
||||
meleeSlashSAPower = 45
|
||||
var/obj/screen/leap_icon = null
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/create_internal_organs()
|
||||
@@ -63,11 +66,12 @@
|
||||
if(hit_atom)
|
||||
if(isliving(hit_atom))
|
||||
var/mob/living/L = hit_atom
|
||||
if(L.run_block(src, 0, "the [name]", ATTACK_TYPE_TACKLE, 0, src) & BLOCK_SUCCESS)
|
||||
if(L.mob_run_block(src, 0, "the [name]", ATTACK_TYPE_TACKLE, 0, src, null, null) & BLOCK_SUCCESS)
|
||||
DefaultCombatKnockdown(40, 1, 1)
|
||||
else
|
||||
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
|
||||
L.DefaultCombatKnockdown(100)
|
||||
L.Stagger(4 SECONDS)
|
||||
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
|
||||
step_towards(src,L)
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
/mob/living/carbon/alien/humanoid/sentinel
|
||||
name = "alien sentinel"
|
||||
caste = "s"
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
maxHealth = 140
|
||||
health = 140
|
||||
icon_state = "aliens"
|
||||
meleeSlashHumanPower = 15
|
||||
|
||||
/mob/living/carbon/alien/humanoid/sentinel/Initialize()
|
||||
AddAbility(new /obj/effect/proc_holder/alien/sneak)
|
||||
|
||||
@@ -112,7 +112,6 @@
|
||||
return A
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath)
|
||||
if(breath && breath.total_moles() > 0 && !sneaking)
|
||||
playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/mob/living/carbon/alien/humanoid/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src && pulling && grab_state >= GRAB_AGGRESSIVE && !pulling.anchored && iscarbon(pulling))
|
||||
devour_mob(pulling, devour_time = 60)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/proc/adjust_body_temperature(current, loc_temp, boost)
|
||||
var/temperature = current
|
||||
var/difference = abs(current-loc_temp) //get difference
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper.
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 20, /obj/item/stack/sheet/animalhide/xeno = 3)
|
||||
|
||||
meleeKnockdownPower = 125
|
||||
meleeSlashHumanPower = 30
|
||||
meleeSlashSAPower = 60
|
||||
|
||||
var/alt_inhands_file = 'icons/mob/alienqueen.dmi'
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
density = FALSE
|
||||
hud_type = /datum/hud/larva
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
|
||||
maxHealth = 25
|
||||
health = 25
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
alien_powers = list(/obj/effect/proc_holder/alien/transfer)
|
||||
|
||||
/obj/item/organ/alien/plasmavessel/on_life()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
//If there are alien weeds on the ground then heal if needed or give some plasma
|
||||
if(locate(/obj/structure/alien/weeds) in owner.loc)
|
||||
if(owner.health >= owner.maxHealth)
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
/obj/item/organ/body_egg/alien_embryo/on_life()
|
||||
. = ..()
|
||||
if(!owner)
|
||||
return
|
||||
switch(stage)
|
||||
if(2, 3)
|
||||
if(prob(2))
|
||||
|
||||
@@ -20,5 +20,5 @@
|
||||
/mob/living/carbon/alien/AdjustStun(amount, updating = 1, ignore_canstun = 0)
|
||||
. = ..()
|
||||
if(!.)
|
||||
move_delay_add = CLAMP(move_delay_add + round(amount/2), 0, 10)
|
||||
move_delay_add = clamp(move_delay_add + round(amount/2), 0, 10)
|
||||
*/
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
update_body_parts() //to update the carbon's new bodyparts appearance
|
||||
GLOB.carbon_list += src
|
||||
blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio)
|
||||
add_movespeed_modifier(/datum/movespeed_modifier/carbon_crawling)
|
||||
|
||||
/mob/living/carbon/Destroy()
|
||||
//This must be done first, so the mob ghosts correctly before DNA etc is nulled
|
||||
@@ -98,6 +99,8 @@
|
||||
/mob/living/carbon/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
. = ..()
|
||||
var/hurt = TRUE
|
||||
if(GetComponent(/datum/component/tackler))
|
||||
return
|
||||
if(throwingdatum?.thrower && iscyborg(throwingdatum.thrower))
|
||||
var/mob/living/silicon/robot/R = throwingdatum.thrower
|
||||
if(!R.emagged)
|
||||
@@ -196,7 +199,7 @@
|
||||
to_chat(src, "<span class='notice'>You set [I] down gently on the ground.</span>")
|
||||
return
|
||||
|
||||
adjustStaminaLossBuffered(I.getweight()*2)//CIT CHANGE - throwing items shall be more tiring than swinging em. Doubly so.
|
||||
adjustStaminaLossBuffered(I.getweight(src, STAM_COST_THROW_MULT, SKILL_THROW_STAM_COST))
|
||||
|
||||
if(thrown_thing)
|
||||
visible_message("<span class='danger'>[src] has thrown [thrown_thing].</span>")
|
||||
@@ -537,10 +540,16 @@
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/spew_organ(power = 5, amt = 1)
|
||||
var/list/spillable_organs = list()
|
||||
for(var/A in internal_organs)
|
||||
var/obj/item/organ/O = A
|
||||
if(!(O.organ_flags & ORGAN_NO_DISMEMBERMENT))
|
||||
spillable_organs += O
|
||||
for(var/i in 1 to amt)
|
||||
if(!internal_organs.len)
|
||||
if(!spillable_organs.len)
|
||||
break //Guess we're out of organs!
|
||||
var/obj/item/organ/guts = pick(internal_organs)
|
||||
var/obj/item/organ/guts = pick(spillable_organs)
|
||||
spillable_organs -= guts
|
||||
var/turf/T = get_turf(src)
|
||||
guts.Remove()
|
||||
guts.forceMove(T)
|
||||
@@ -548,6 +557,7 @@
|
||||
guts.throw_at(throw_target, power, 4, src)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/fully_replace_character_name(oldname,newname)
|
||||
..()
|
||||
if(dna)
|
||||
@@ -572,9 +582,9 @@
|
||||
become_husk("burn")
|
||||
med_hud_set_health()
|
||||
if(stat == SOFT_CRIT)
|
||||
add_movespeed_modifier(MOVESPEED_ID_CARBON_SOFTCRIT, TRUE, multiplicative_slowdown = SOFTCRIT_ADD_SLOWDOWN)
|
||||
add_movespeed_modifier(/datum/movespeed_modifier/carbon_softcrit)
|
||||
else
|
||||
remove_movespeed_modifier(MOVESPEED_ID_CARBON_SOFTCRIT, TRUE)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/carbon_softcrit)
|
||||
|
||||
/mob/living/carbon/update_stamina()
|
||||
var/stam = getStaminaLoss()
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses)) //glasses
|
||||
var/obj/item/clothing/glasses/GFP = src.glasses
|
||||
number += GFP.flash_protect
|
||||
|
||||
|
||||
if(istype(src.wear_mask, /obj/item/clothing/mask)) //mask
|
||||
var/obj/item/clothing/mask/MFP = src.wear_mask
|
||||
number += MFP.flash_protect
|
||||
@@ -77,24 +77,22 @@
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded)
|
||||
|
||||
/mob/living/carbon/attacked_by(obj/item/I, mob/living/user)
|
||||
//CIT CHANGES START HERE - combatmode and resting checks
|
||||
var/totitemdamage = I.force
|
||||
var/totitemdamage = pre_attacked_by(I, user)
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 0.5
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
totitemdamage *= 0.5
|
||||
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 1.5
|
||||
//CIT CHANGES END HERE
|
||||
var/impacting_zone = (user == src)? check_zone(user.zone_selected) : ran_zone(user.zone_selected)
|
||||
if((user != src) && (run_block(I, totitemdamage, "the [I]", ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone) & BLOCK_SUCCESS))
|
||||
if((user != src) && (mob_run_block(I, totitemdamage, "the [I]", ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone, null) & BLOCK_SUCCESS))
|
||||
return FALSE
|
||||
var/obj/item/bodypart/affecting = get_bodypart(impacting_zone)
|
||||
if(!affecting) //missing limb? we select the first bodypart (you can never have zero, because of chest)
|
||||
affecting = bodyparts[1]
|
||||
SEND_SIGNAL(I, COMSIG_ITEM_ATTACK_ZONE, src, user, affecting)
|
||||
send_item_attack_message(I, user, affecting.name)
|
||||
I.do_stagger_action(src, user)
|
||||
I.do_stagger_action(src, user, totitemdamage)
|
||||
if(I.force)
|
||||
apply_damage(totitemdamage, I.damtype, affecting) //CIT CHANGE - replaces I.force with totitemdamage
|
||||
if(I.damtype == BRUTE && affecting.status == BODYPART_ORGANIC)
|
||||
@@ -275,7 +273,7 @@
|
||||
|
||||
if(health >= 0 && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
|
||||
var/friendly_check = FALSE
|
||||
if(run_block(M, 0, M.name, ATTACK_TYPE_UNARMED))
|
||||
if(mob_run_block(M, 0, M.name, ATTACK_TYPE_UNARMED, 0, null, null, null))
|
||||
return
|
||||
if(lying)
|
||||
if(buckled)
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
var/damageoverlaytemp = 0
|
||||
|
||||
var/drunkenness = 0 //Overall drunkenness - check handle_alcohol() in life.dm for effects
|
||||
var/tackling = FALSE //Whether or not we are tackling, this will prevent the knock into effects for carbons
|
||||
|
||||
/// Protection (insulation) from the heat, Value 0-1 corresponding to the percentage of protection
|
||||
var/heat_protection = 0 // No heat protection
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
adjustCloneLoss(damage_amount, forced = forced)
|
||||
if(STAMINA)
|
||||
if(BP)
|
||||
if(damage > 0 ? BP.receive_damage(0, 0, damage_amount) : BP.heal_damage(0, 0, abs(damage_amount)))
|
||||
if(damage > 0 ? BP.receive_damage(0, 0, damage_amount) : BP.heal_damage(0, 0, abs(damage_amount), FALSE, FALSE))
|
||||
update_damage_overlays()
|
||||
else
|
||||
adjustStaminaLoss(damage_amount, forced = forced)
|
||||
|
||||
@@ -41,18 +41,14 @@
|
||||
if(no_brain && istype(O, /obj/item/organ/brain))
|
||||
qdel(O) //so the brain isn't transfered to the head when the head drops.
|
||||
continue
|
||||
var/org_zone = check_zone(O.zone) //both groin and chest organs.
|
||||
if(org_zone == BODY_ZONE_CHEST)
|
||||
if(!(O.organ_flags & ORGAN_NO_DISMEMBERMENT) && check_zone(O.zone) == BODY_ZONE_CHEST)
|
||||
O.Remove()
|
||||
O.forceMove(Tsec)
|
||||
O.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
|
||||
else
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/I = X
|
||||
if(no_brain && istype(I, /obj/item/organ/brain))
|
||||
qdel(I)
|
||||
continue
|
||||
if(no_organs && !istype(I, /obj/item/organ/brain))
|
||||
if(I.organ_flags & ORGAN_NO_DISMEMBERMENT || (no_brain && istype(I, /obj/item/organ/brain)) || (no_organs && !istype(I, /obj/item/organ/brain)))
|
||||
qdel(I)
|
||||
continue
|
||||
I.Remove()
|
||||
|
||||
@@ -43,5 +43,6 @@ GLOBAL_LIST_EMPTY(dummy_mob_list)
|
||||
return
|
||||
var/mob/living/carbon/human/dummy/D = GLOB.human_dummy_list[slotnumber]
|
||||
if(istype(D))
|
||||
D.set_species(/datum/species/human,icon_update = TRUE, pref_load = TRUE) //for some fucking reason, if you don't change the species every time, some species will dafault certain things when it's their own species on the mannequin two times in a row, like lizards losing spines and tails setting to smooth. If you can find a fix for this that isn't this, good on you
|
||||
D.wipe_state()
|
||||
D.in_use = FALSE
|
||||
|
||||
@@ -38,8 +38,9 @@
|
||||
. = ..()
|
||||
if(!CONFIG_GET(flag/disable_human_mood))
|
||||
AddComponent(/datum/component/mood)
|
||||
AddElement(/datum/element/flavor_text/carbon)
|
||||
AddElement(/datum/element/flavor_text/carbon, _name = "Flavor Text", _save_key = "flavor_text")
|
||||
AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!")
|
||||
AddElement(/datum/element/flavor_text, _name = "OOC Notes", _addendum = "Put information on ERP/vore/lewd-related preferences here. THIS SHOULD NOT CONTAIN REGULAR FLAVORTEXT!!", _always_show = TRUE, _save_key = "ooc_notes", _examine_no_preview = TRUE)
|
||||
|
||||
/mob/living/carbon/human/Destroy()
|
||||
QDEL_NULL(physiology)
|
||||
@@ -768,7 +769,7 @@
|
||||
return
|
||||
else
|
||||
if(hud_used.healths)
|
||||
var/health_amount = min(health, maxHealth - CLAMP(getStaminaLoss()-50, 0, 80))//CIT CHANGE - makes staminaloss have less of an impact on the health hud
|
||||
var/health_amount = min(health, maxHealth - clamp(getStaminaLoss()-50, 0, 80))//CIT CHANGE - makes staminaloss have less of an impact on the health hud
|
||||
if(..(health_amount)) //not dead
|
||||
switch(hal_screwyhud)
|
||||
if(SCREWYHUD_CRIT)
|
||||
@@ -1041,7 +1042,7 @@
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/proc/clear_shove_slowdown()
|
||||
remove_movespeed_modifier(MOVESPEED_ID_SHOVE)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/shove)
|
||||
var/active_item = get_active_held_item()
|
||||
if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
|
||||
visible_message("<span class='warning'>[src.name] regains their grip on \the [active_item]!</span>", "<span class='warning'>You regain your grip on \the [active_item]</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
@@ -1049,18 +1050,22 @@
|
||||
/mob/living/carbon/human/updatehealth()
|
||||
. = ..()
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN))
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN)
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING)
|
||||
if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN)) //if we want to ignore slowdown from damage and equipment
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
|
||||
return
|
||||
var/stambufferinfluence = (bufferedstam*(100/stambuffer))*0.2 //CIT CHANGE - makes stamina buffer influence movedelay
|
||||
var/health_deficiency = ((100 + stambufferinfluence) - health + (getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss and makes stamina buffer influence it
|
||||
if(health_deficiency >= 40)
|
||||
add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 75), blacklisted_movetypes = FLOATING|FLYING)
|
||||
add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 25), movetypes = FLYING, blacklisted_movetypes = FLOATING)
|
||||
if(!HAS_TRAIT(src, TRAIT_IGNOREDAMAGESLOWDOWN)) //if we want to ignore slowdown from damage, but not from equipment
|
||||
var/health_deficiency = ((maxHealth + stambufferinfluence) - health + (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)
|
||||
else
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
|
||||
else
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN)
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
|
||||
|
||||
/mob/living/carbon/human/do_after_coefficent()
|
||||
. = ..()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/mob/living/carbon/human/get_blocking_items()
|
||||
. = ..()
|
||||
if(wear_suit)
|
||||
. += wear_suit
|
||||
. |= wear_suit
|
||||
if(w_uniform)
|
||||
. += w_uniform
|
||||
. |= w_uniform
|
||||
if(wear_neck)
|
||||
. += wear_neck
|
||||
. |= wear_neck
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
if(M.a_intent == INTENT_HARM)
|
||||
if (w_uniform)
|
||||
w_uniform.add_fingerprint(M)
|
||||
var/damage = prob(90) ? 20 : 0
|
||||
var/damage = prob(90) ? M.meleeSlashHumanPower : 0
|
||||
if(!damage)
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
|
||||
@@ -182,10 +182,7 @@
|
||||
"<span class='userdanger'>[M] disarmed [src]!</span>")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
if(!lying) //CITADEL EDIT
|
||||
DefaultCombatKnockdown(100, TRUE, FALSE, 30, 25)
|
||||
else
|
||||
DefaultCombatKnockdown(100)
|
||||
DefaultCombatKnockdown(M.meleeKnockdownPower)
|
||||
log_combat(M, src, "tackled")
|
||||
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [src]!</span>")
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH|CANSTAGGER
|
||||
|
||||
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
|
||||
|
||||
|
||||
//Hair colour and style
|
||||
var/hair_color = "000"
|
||||
var/hair_style = "Bald"
|
||||
@@ -23,10 +23,6 @@
|
||||
//Eye colour
|
||||
var/eye_color = "000"
|
||||
|
||||
var/horn_color = "85615a" //specific horn colors, because why not?
|
||||
|
||||
var/wing_color = "fff" //wings too
|
||||
|
||||
var/skin_tone = "caucasian1" //Skin tone
|
||||
|
||||
var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
/mob/living/carbon/human/get_movespeed_modifiers()
|
||||
var/list/considering = ..()
|
||||
. = considering
|
||||
if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN))
|
||||
for(var/id in .)
|
||||
var/list/data = .[id]
|
||||
if(data[MOVESPEED_DATA_INDEX_FLAGS] & IGNORE_NOSLOW)
|
||||
.[id] = data
|
||||
. = list()
|
||||
for(var/id in considering)
|
||||
var/datum/movespeed_modifier/M = considering[id]
|
||||
if(M.flags & IGNORE_NOSLOW || M.multiplicative_slowdown < 0)
|
||||
.[id] = M
|
||||
return
|
||||
return considering
|
||||
|
||||
/mob/living/carbon/human/movement_delay()
|
||||
. = ..()
|
||||
@@ -22,13 +24,18 @@
|
||||
/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube)
|
||||
if(HAS_TRAIT(src, TRAIT_NOSLIPALL))
|
||||
return 0
|
||||
if (!(lube&GALOSHES_DONT_HELP))
|
||||
if (!(lube & GALOSHES_DONT_HELP))
|
||||
if(HAS_TRAIT(src, TRAIT_NOSLIPWATER))
|
||||
return 0
|
||||
if(shoes && istype(shoes, /obj/item/clothing))
|
||||
var/obj/item/clothing/CS = shoes
|
||||
if (CS.clothing_flags & NOSLIP)
|
||||
return 0
|
||||
if (lube & SLIDE_ICE)
|
||||
if(shoes && istype(shoes, /obj/item/clothing))
|
||||
var/obj/item/clothing/CS = shoes
|
||||
if (CS.clothing_flags & NOSLIP_ICE)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/experience_pressure_difference()
|
||||
|
||||
@@ -35,10 +35,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
var/hair_color // this allows races to have specific hair colors... if null, it uses the H's hair/facial hair colors. if "mutcolor", it uses the H's mutant_color
|
||||
var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent.
|
||||
|
||||
var/horn_color //specific horn colors, because why not?
|
||||
var/wing_color
|
||||
|
||||
var/use_skintones = NO_SKINTONES // does it use skintones or not? (spoiler alert this is only used by humans)
|
||||
var/exotic_blood = "" // If your race wants to bleed something other than bog standard blood, change this to reagent id.
|
||||
var/exotic_bloodtype = "" //If your race uses a non standard bloodtype (A+, O-, AB-, etc)
|
||||
@@ -53,6 +49,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/blacklisted = 0 //Flag to exclude from green slime core species.
|
||||
var/dangerous_existence //A flag for transformation spells that tells them "hey if you turn a person into one of these without preperation, they'll probably die!"
|
||||
var/say_mod = "says" // affects the speech message
|
||||
var/species_language_holder = /datum/language_holder
|
||||
var/list/mutant_bodyparts = list() // Visible CURRENT bodyparts that are unique to a species. Changes to this list for non-species specific bodyparts (ie cat ears and tails) should be assigned at organ level if possible. Layer hiding is handled by handle_mutant_bodyparts() below.
|
||||
var/list/mutant_organs = list() //Internal organs that are unique to this race.
|
||||
var/speedmod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster
|
||||
@@ -331,7 +328,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(mutant_bodyparts["meat_type"]) //I can't believe it's come to the meat
|
||||
H.type_of_meat = GLOB.meat_types[H.dna.features["meat_type"]]
|
||||
|
||||
C.add_movespeed_modifier(MOVESPEED_ID_SPECIES, TRUE, 100, override=TRUE, multiplicative_slowdown=speedmod, movetypes=(~FLYING))
|
||||
C.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/species, TRUE, multiplicative_slowdown = speedmod)
|
||||
|
||||
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
|
||||
|
||||
@@ -349,7 +346,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
for(var/X in inherent_traits)
|
||||
REMOVE_TRAIT(C, X, SPECIES_TRAIT)
|
||||
|
||||
C.remove_movespeed_modifier(MOVESPEED_ID_SPECIES)
|
||||
C.remove_movespeed_modifier(/datum/movespeed_modifier/species)
|
||||
|
||||
if(mutant_bodyparts["meat_type"])
|
||||
C.type_of_meat = GLOB.meat_types[C.dna.features["meat_type"]]
|
||||
@@ -550,8 +547,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
//Underwear, Undershirts & Socks
|
||||
if(!(NO_UNDERWEAR in species_traits))
|
||||
|
||||
if(H.socks && !H.hidden_socks && H.get_num_legs(FALSE) >= 2)
|
||||
var/datum/sprite_accessory/taur/TA
|
||||
if(mutant_bodyparts["taur"] && H.dna.features["taur"])
|
||||
TA = GLOB.taur_list[H.dna.features["taur"]]
|
||||
if(!(TA?.hide_legs) && H.socks && !H.hidden_socks && H.get_num_legs(FALSE) >= 2)
|
||||
if(H.saved_socks)
|
||||
H.socks = H.saved_socks
|
||||
H.saved_socks = ""
|
||||
@@ -584,7 +583,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/state = "[T.icon_state][((DIGITIGRADE in species_traits) && T.has_digitigrade) ? "_d" : ""]"
|
||||
var/mutable_appearance/MA
|
||||
if(H.dna.species.sexes && H.dna.features["body_model"] == FEMALE)
|
||||
MA = wear_female_version(state, T.icon, BODY_LAYER)
|
||||
MA = wear_alpha_masked_version(state, T.icon, BODY_LAYER, FEMALE_UNIFORM_TOP)
|
||||
else
|
||||
MA = mutable_appearance(T.icon, state, -BODY_LAYER)
|
||||
if(T.has_color)
|
||||
@@ -599,21 +598,17 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour)
|
||||
var/list/bodyparts_to_add = mutant_bodyparts.Copy()
|
||||
var/list/relevent_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER, BODY_TAUR_LAYER)
|
||||
var/list/standing = list()
|
||||
|
||||
H.remove_overlay(BODY_BEHIND_LAYER)
|
||||
H.remove_overlay(BODY_ADJ_LAYER)
|
||||
H.remove_overlay(BODY_ADJ_UPPER_LAYER)
|
||||
H.remove_overlay(BODY_FRONT_LAYER)
|
||||
//CITADEL EDIT - Do not forget to add this to relevent_layers list just above too!
|
||||
H.remove_overlay(BODY_TAUR_LAYER)
|
||||
//END EDIT
|
||||
|
||||
if(!mutant_bodyparts)
|
||||
return
|
||||
|
||||
var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD)
|
||||
var/tauric = H.dna.features["taur"] && H.dna.features["taur"] != "None"
|
||||
var/tauric = mutant_bodyparts["taur"] && H.dna.features["taur"] && H.dna.features["taur"] != "None"
|
||||
|
||||
if(mutant_bodyparts["tail_lizard"])
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
@@ -744,95 +739,105 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(!bodyparts_to_add)
|
||||
return
|
||||
|
||||
var/list/relevant_layers = list()
|
||||
var/list/dna_feature_as_text_string = list()
|
||||
|
||||
for(var/bodypart in bodyparts_to_add)
|
||||
var/datum/sprite_accessory/S
|
||||
switch(bodypart)
|
||||
if("tail_lizard")
|
||||
S = GLOB.tails_list_lizard[H.dna.features["tail_lizard"]]
|
||||
if("waggingtail_lizard")
|
||||
S = GLOB.animated_tails_list_lizard[H.dna.features["tail_lizard"]]
|
||||
if("tail_human")
|
||||
S = GLOB.tails_list_human[H.dna.features["tail_human"]]
|
||||
if("waggingtail_human")
|
||||
S = GLOB.animated_tails_list_human[H.dna.features["tail_human"]]
|
||||
if("spines")
|
||||
S = GLOB.spines_list[H.dna.features["spines"]]
|
||||
if("waggingspines")
|
||||
S = GLOB.animated_spines_list[H.dna.features["spines"]]
|
||||
if("snout")
|
||||
S = GLOB.snouts_list[H.dna.features["snout"]]
|
||||
if("frills")
|
||||
S = GLOB.frills_list[H.dna.features["frills"]]
|
||||
if("horns")
|
||||
S = GLOB.horns_list[H.dna.features["horns"]]
|
||||
if("ears")
|
||||
S = GLOB.ears_list[H.dna.features["ears"]]
|
||||
if("body_markings")
|
||||
S = GLOB.body_markings_list[H.dna.features["body_markings"]]
|
||||
if("wings")
|
||||
S = GLOB.wings_list[H.dna.features["wings"]]
|
||||
if("wingsopen")
|
||||
S = GLOB.wings_open_list[H.dna.features["wings"]]
|
||||
if("deco_wings")
|
||||
S = GLOB.deco_wings_list[H.dna.features["deco_wings"]]
|
||||
if("legs")
|
||||
S = GLOB.legs_list[H.dna.features["legs"]]
|
||||
if("insect_wings")
|
||||
S = GLOB.insect_wings_list[H.dna.features["insect_wings"]]
|
||||
if("insect_fluff")
|
||||
S = GLOB.insect_fluffs_list[H.dna.features["insect_fluff"]]
|
||||
if("insect_markings")
|
||||
S = GLOB.insect_markings_list[H.dna.features["insect_markings"]]
|
||||
if("caps")
|
||||
S = GLOB.caps_list[H.dna.features["caps"]]
|
||||
if("ipc_screen")
|
||||
S = GLOB.ipc_screens_list[H.dna.features["ipc_screen"]]
|
||||
if("ipc_antenna")
|
||||
S = GLOB.ipc_antennas_list[H.dna.features["ipc_antenna"]]
|
||||
if("mam_tail")
|
||||
S = GLOB.mam_tails_list[H.dna.features["mam_tail"]]
|
||||
if("mam_waggingtail")
|
||||
S = GLOB.mam_tails_animated_list[H.dna.features["mam_tail"]]
|
||||
if("mam_body_markings")
|
||||
S = GLOB.mam_body_markings_list[H.dna.features["mam_body_markings"]]
|
||||
if("mam_ears")
|
||||
S = GLOB.mam_ears_list[H.dna.features["mam_ears"]]
|
||||
if("mam_snouts")
|
||||
S = GLOB.mam_snouts_list[H.dna.features["mam_snouts"]]
|
||||
if("taur")
|
||||
S = GLOB.taur_list[H.dna.features["taur"]]
|
||||
if("xenodorsal")
|
||||
S = GLOB.xeno_dorsal_list[H.dna.features["xenodorsal"]]
|
||||
if("xenohead")
|
||||
S = GLOB.xeno_head_list[H.dna.features["xenohead"]]
|
||||
if("xenotail")
|
||||
S = GLOB.xeno_tail_list[H.dna.features["xenotail"]]
|
||||
|
||||
if(!S || S.icon_state == "none")
|
||||
continue
|
||||
|
||||
for(var/L in S.relevant_layers)
|
||||
LAZYADD(relevant_layers["[L]"], S)
|
||||
if(!S.mutant_part_string)
|
||||
dna_feature_as_text_string[S] = bodypart
|
||||
|
||||
var/static/list/layer_text = list("[BODY_BEHIND_LAYER]" = "BEHIND", "[BODY_ADJ_LAYER]" = "ADJ", \
|
||||
"[BODY_ADJ_UPPER_LAYER]" = "ADJUP", "[BODY_FRONT_LAYER]" = "FRONT")
|
||||
|
||||
var/g = (H.dna.features["body_model"] == FEMALE) ? "f" : "m"
|
||||
var/list/colorlist = list()
|
||||
var/husk = HAS_TRAIT(H, TRAIT_HUSK)
|
||||
colorlist += husk ? ReadRGB("#a3a3a3") :ReadRGB("[H.dna.features["mcolor"]]0")
|
||||
colorlist += husk ? ReadRGB("#a3a3a3") :ReadRGB("[H.dna.features["mcolor2"]]0")
|
||||
colorlist += husk ? ReadRGB("#a3a3a3") : ReadRGB("[H.dna.features["mcolor3"]]0")
|
||||
colorlist += list(0,0,0, hair_alpha)
|
||||
for(var/index in 1 to colorlist.len)
|
||||
colorlist[index] /= 255
|
||||
|
||||
for(var/layer in relevent_layers)
|
||||
var/layertext = mutant_bodyparts_layertext(layer)
|
||||
|
||||
for(var/bodypart in bodyparts_to_add)
|
||||
var/datum/sprite_accessory/S
|
||||
switch(bodypart)
|
||||
if("tail_lizard")
|
||||
S = GLOB.tails_list_lizard[H.dna.features["tail_lizard"]]
|
||||
if("waggingtail_lizard")
|
||||
S = GLOB.animated_tails_list_lizard[H.dna.features["tail_lizard"]]
|
||||
if("tail_human")
|
||||
S = GLOB.tails_list_human[H.dna.features["tail_human"]]
|
||||
if("waggingtail_human")
|
||||
S = GLOB.animated_tails_list_human[H.dna.features["tail_human"]]
|
||||
if("spines")
|
||||
S = GLOB.spines_list[H.dna.features["spines"]]
|
||||
if("waggingspines")
|
||||
S = GLOB.animated_spines_list[H.dna.features["spines"]]
|
||||
if("snout")
|
||||
S = GLOB.snouts_list[H.dna.features["snout"]]
|
||||
if("frills")
|
||||
S = GLOB.frills_list[H.dna.features["frills"]]
|
||||
if("horns")
|
||||
S = GLOB.horns_list[H.dna.features["horns"]]
|
||||
if("ears")
|
||||
S = GLOB.ears_list[H.dna.features["ears"]]
|
||||
if("body_markings")
|
||||
S = GLOB.body_markings_list[H.dna.features["body_markings"]]
|
||||
if("wings")
|
||||
S = GLOB.wings_list[H.dna.features["wings"]]
|
||||
if("wingsopen")
|
||||
S = GLOB.wings_open_list[H.dna.features["wings"]]
|
||||
if("deco_wings")
|
||||
S = GLOB.deco_wings_list[H.dna.features["deco_wings"]]
|
||||
if("legs")
|
||||
S = GLOB.legs_list[H.dna.features["legs"]]
|
||||
if("insect_wings")
|
||||
S = GLOB.insect_wings_list[H.dna.features["insect_wings"]]
|
||||
if("insect_fluff")
|
||||
S = GLOB.insect_fluffs_list[H.dna.features["insect_fluff"]]
|
||||
if("insect_markings")
|
||||
S = GLOB.insect_markings_list[H.dna.features["insect_markings"]]
|
||||
if("caps")
|
||||
S = GLOB.caps_list[H.dna.features["caps"]]
|
||||
if("ipc_screen")
|
||||
S = GLOB.ipc_screens_list[H.dna.features["ipc_screen"]]
|
||||
if("ipc_antenna")
|
||||
S = GLOB.ipc_antennas_list[H.dna.features["ipc_antenna"]]
|
||||
if("mam_tail")
|
||||
S = GLOB.mam_tails_list[H.dna.features["mam_tail"]]
|
||||
if("mam_waggingtail")
|
||||
S = GLOB.mam_tails_animated_list[H.dna.features["mam_tail"]]
|
||||
if("mam_body_markings")
|
||||
S = GLOB.mam_body_markings_list[H.dna.features["mam_body_markings"]]
|
||||
if("mam_ears")
|
||||
S = GLOB.mam_ears_list[H.dna.features["mam_ears"]]
|
||||
if("mam_snouts")
|
||||
S = GLOB.mam_snouts_list[H.dna.features["mam_snouts"]]
|
||||
if("taur")
|
||||
S = GLOB.taur_list[H.dna.features["taur"]]
|
||||
if("xenodorsal")
|
||||
S = GLOB.xeno_dorsal_list[H.dna.features["xenodorsal"]]
|
||||
if("xenohead")
|
||||
S = GLOB.xeno_head_list[H.dna.features["xenohead"]]
|
||||
if("xenotail")
|
||||
S = GLOB.xeno_tail_list[H.dna.features["xenotail"]]
|
||||
|
||||
if(!S || S.icon_state == "none")
|
||||
continue
|
||||
|
||||
var/mutable_appearance/accessory_overlay = mutable_appearance(S.icon, layer = -layer)
|
||||
|
||||
accessory_overlay.color = null //just because. reee.
|
||||
|
||||
//A little rename so we don't have to use tail_lizard or tail_human when naming the sprites.
|
||||
if(bodypart == "tail_lizard" || bodypart == "tail_human" || bodypart == "mam_tail" || bodypart == "xenotail")
|
||||
bodypart = "tail"
|
||||
if(bodypart == "mam_waggingtail" || bodypart == "waggingtail_human" || bodypart == "waggingtail_lizard")
|
||||
bodypart = "tailwag"
|
||||
if(bodypart == "mam_ears" || bodypart == "ears")
|
||||
bodypart = "ears"
|
||||
if(bodypart == "mam_snouts" || bodypart == "snout")
|
||||
bodypart = "snout"
|
||||
if(bodypart == "xenohead")
|
||||
bodypart = "xhead"
|
||||
if(bodypart == "insect_wings" || bodypart == "deco_wings")
|
||||
bodypart = "insect_wings"
|
||||
for(var/layer in relevant_layers)
|
||||
var/list/standing = list()
|
||||
var/layertext = layer_text[layer]
|
||||
if(!layertext) //shouldn't happen
|
||||
stack_trace("invalid layer '[layer]' found in the list of relevant layers on species.handle_mutant_bodyparts().")
|
||||
continue
|
||||
var/layernum = text2num(layer)
|
||||
for(var/bodypart in relevant_layers[layer])
|
||||
var/datum/sprite_accessory/S = bodypart
|
||||
var/mutable_appearance/accessory_overlay = mutable_appearance(S.icon, layer = -layernum)
|
||||
bodypart = S.mutant_part_string || dna_feature_as_text_string[S]
|
||||
|
||||
if(S.gender_specific)
|
||||
accessory_overlay.icon_state = "[g]_[bodypart]_[S.icon_state]_[layertext]"
|
||||
@@ -842,16 +847,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(S.center)
|
||||
accessory_overlay = center_image(accessory_overlay, S.dimension_x, S.dimension_y)
|
||||
|
||||
var/list/colorlist = list()
|
||||
colorlist.Cut()
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor"]]0")
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor2"]]0")
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor3"]]0")
|
||||
colorlist += list(0,0,0, hair_alpha)
|
||||
for(var/index=1, index<=colorlist.len, index++)
|
||||
colorlist[index] = colorlist[index]/255
|
||||
|
||||
if(!HAS_TRAIT(H, TRAIT_HUSK))
|
||||
if(!husk)
|
||||
if(!forced_colour)
|
||||
switch(S.color_src)
|
||||
if(SKINTONE)
|
||||
@@ -885,9 +881,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(EYECOLOR)
|
||||
accessory_overlay.color = "#[H.eye_color]"
|
||||
if(HORNCOLOR)
|
||||
accessory_overlay.color = "#[H.horn_color]"
|
||||
accessory_overlay.color = "#[H.dna.features["horns_color"]]"
|
||||
if(WINGCOLOR)
|
||||
accessory_overlay.color = "#[H.wing_color]"
|
||||
accessory_overlay.color = "#[H.dna.features["wings_color"]]"
|
||||
else
|
||||
accessory_overlay.color = forced_colour
|
||||
else
|
||||
@@ -896,14 +892,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(bodypart == "tail")
|
||||
accessory_overlay.icon_state = "m_tail_husk_[layertext]"
|
||||
if(S.color_src == MATRIXED)
|
||||
var/list/husklist = list()
|
||||
husklist += ReadRGB("#a3a3a3")
|
||||
husklist += ReadRGB("#a3a3a3")
|
||||
husklist += ReadRGB("#a3a3a3")
|
||||
husklist += list(0,0,0, hair_alpha)
|
||||
for(var/index=1, index<=husklist.len, index++)
|
||||
husklist[index] = husklist[index]/255
|
||||
accessory_overlay.color = husklist
|
||||
accessory_overlay.color = colorlist
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
@@ -911,24 +900,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
standing += accessory_overlay
|
||||
|
||||
if(S.hasinner)
|
||||
var/mutable_appearance/inner_accessory_overlay = mutable_appearance(S.icon, layer = -layer)
|
||||
if(S.gender_specific)
|
||||
inner_accessory_overlay.icon_state = "[g]_[bodypart]inner_[S.icon_state]_[layertext]"
|
||||
else
|
||||
inner_accessory_overlay.icon_state = "m_[bodypart]inner_[S.icon_state]_[layertext]"
|
||||
|
||||
if(S.center)
|
||||
inner_accessory_overlay = center_image(inner_accessory_overlay, S.dimension_x, S.dimension_y)
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
inner_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
inner_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
|
||||
|
||||
standing += inner_accessory_overlay
|
||||
|
||||
if(S.extra) //apply the extra overlay, if there is one
|
||||
var/mutable_appearance/extra_accessory_overlay = mutable_appearance(S.icon, layer = -layer)
|
||||
var/mutable_appearance/extra_accessory_overlay = mutable_appearance(S.icon, layer = -layernum)
|
||||
if(S.gender_specific)
|
||||
extra_accessory_overlay.icon_state = "[g]_[bodypart]_extra_[S.icon_state]_[layertext]"
|
||||
else
|
||||
@@ -964,9 +937,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
extra_accessory_overlay.color = "#[H.eye_color]"
|
||||
|
||||
if(HORNCOLOR)
|
||||
extra_accessory_overlay.color = "#[H.horn_color]"
|
||||
extra_accessory_overlay.color = "#[H.dna.features["horns_color"]]"
|
||||
if(WINGCOLOR)
|
||||
extra_accessory_overlay.color = "#[H.wing_color]"
|
||||
extra_accessory_overlay.color = "#[H.dna.features["wings_color"]]"
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
extra_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
@@ -975,7 +948,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
standing += extra_accessory_overlay
|
||||
|
||||
if(S.extra2) //apply the extra overlay, if there is one
|
||||
var/mutable_appearance/extra2_accessory_overlay = mutable_appearance(S.icon, layer = -layer)
|
||||
var/mutable_appearance/extra2_accessory_overlay = mutable_appearance(S.icon, layer = -layernum)
|
||||
if(S.gender_specific)
|
||||
extra2_accessory_overlay.icon_state = "[g]_[bodypart]_extra2_[S.icon_state]_[layertext]"
|
||||
else
|
||||
@@ -1005,9 +978,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
else
|
||||
extra2_accessory_overlay.color = "#[H.hair_color]"
|
||||
if(HORNCOLOR)
|
||||
extra2_accessory_overlay.color = "#[H.horn_color]"
|
||||
extra2_accessory_overlay.color = "#[H.dna.features["horns_color"]]"
|
||||
if(WINGCOLOR)
|
||||
extra2_accessory_overlay.color = "#[H.wing_color]"
|
||||
extra2_accessory_overlay.color = "#[H.dna.features["wings_color"]]"
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
extra2_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
@@ -1016,13 +989,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
standing += extra2_accessory_overlay
|
||||
|
||||
|
||||
H.overlays_standing[layer] = standing.Copy()
|
||||
standing = list()
|
||||
H.overlays_standing[layernum] = standing
|
||||
|
||||
H.apply_overlay(BODY_BEHIND_LAYER)
|
||||
H.apply_overlay(BODY_ADJ_LAYER)
|
||||
H.apply_overlay(BODY_ADJ_UPPER_LAYER)
|
||||
H.apply_overlay(BODY_FRONT_LAYER)
|
||||
H.apply_overlay(BODY_TAUR_LAYER) // CITADEL EDIT
|
||||
|
||||
|
||||
/*
|
||||
@@ -1034,21 +1006,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
outfit_important_for_life= new()
|
||||
outfit_important_for_life.equip(human_to_equip)
|
||||
|
||||
//This exists so sprite accessories can still be per-layer without having to include that layer's
|
||||
//number in their sprite name, which causes issues when those numbers change.
|
||||
/datum/species/proc/mutant_bodyparts_layertext(layer)
|
||||
switch(layer)
|
||||
if(BODY_BEHIND_LAYER)
|
||||
return "BEHIND"
|
||||
if(BODY_ADJ_LAYER)
|
||||
return "ADJ"
|
||||
if(BODY_FRONT_LAYER)
|
||||
return "FRONT"
|
||||
//CITADEL EDIT
|
||||
if(BODY_TAUR_LAYER)
|
||||
return "TAUR"
|
||||
//END EDIT
|
||||
|
||||
/* TODO: Snowflake trail marks
|
||||
// Impliments different trails for species depending on if they're wearing shoes.
|
||||
/datum/species/proc/get_move_trail(var/mob/living/carbon/human/H)
|
||||
@@ -1301,14 +1258,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(H.overeatduration < 100)
|
||||
to_chat(H, "<span class='notice'>You feel fit again!</span>")
|
||||
REMOVE_TRAIT(H, TRAIT_FAT, OBESITY)
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_FAT)
|
||||
H.remove_movespeed_modifier(/datum/movespeed_modifier/obesity)
|
||||
H.update_inv_w_uniform()
|
||||
H.update_inv_wear_suit()
|
||||
else
|
||||
if(H.overeatduration >= 100)
|
||||
to_chat(H, "<span class='danger'>You suddenly feel blubbery!</span>")
|
||||
ADD_TRAIT(H, TRAIT_FAT, OBESITY)
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_FAT, multiplicative_slowdown = 1.5)
|
||||
H.add_movespeed_modifier(/datum/movespeed_modifier/obesity)
|
||||
H.update_inv_w_uniform()
|
||||
H.update_inv_wear_suit()
|
||||
|
||||
@@ -1364,9 +1321,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(!HAS_TRAIT(H, TRAIT_NOHUNGER))
|
||||
var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80
|
||||
if(hungry >= 70)
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_HUNGRY, override = TRUE, multiplicative_slowdown = (hungry / 50))
|
||||
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/hunger, multiplicative_slowdown = (hungry / 50))
|
||||
else
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_HUNGRY)
|
||||
H.remove_movespeed_modifier(/datum/movespeed_modifier/hunger)
|
||||
|
||||
switch(H.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
@@ -1582,9 +1539,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(IS_STAMCRIT(user))
|
||||
to_chat(user, "<span class='warning'>You're too exhausted!</span>")
|
||||
return FALSE
|
||||
else if(target.check_block())
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>")
|
||||
return FALSE
|
||||
|
||||
else if(aim_for_mouth && ( target_on_help || target_restrained || target_aiming_for_mouth))
|
||||
playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
|
||||
@@ -1617,7 +1571,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
"You hear a slap."
|
||||
)
|
||||
return FALSE
|
||||
|
||||
|
||||
else
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
|
||||
|
||||
@@ -1625,10 +1579,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
user.adjustStaminaLossBuffered(1)
|
||||
else
|
||||
user.adjustStaminaLossBuffered(3)
|
||||
|
||||
|
||||
if(attacker_style && attacker_style.disarm_act(user,target))
|
||||
return TRUE
|
||||
|
||||
|
||||
if(target.w_uniform)
|
||||
target.w_uniform.add_fingerprint(user)
|
||||
//var/randomized_zone = ran_zone(user.zone_selected) CIT CHANGE - comments out to prevent compiling errors
|
||||
@@ -1661,7 +1615,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
randn -= 25 //if you are a pugilist, you're slapping that item from them pretty reliably
|
||||
if(HAS_TRAIT(target, TRAIT_PUGILIST))
|
||||
randn += 25 //meanwhile, pugilists are less likely to get disarmed
|
||||
|
||||
|
||||
if(randn <= 35)//CIT CHANGE - changes this back to a 35% chance to accomodate for the above being commented out in favor of right-click pushing
|
||||
var/obj/item/I = null
|
||||
if(target.pulling)
|
||||
@@ -1714,9 +1668,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
disarm(M, H, attacker_style)
|
||||
|
||||
/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
|
||||
var/totitemdamage = H.pre_attacked_by(I, user)
|
||||
// Allows you to put in item-specific reactions based on species
|
||||
if(user != H)
|
||||
if(H.run_block(I, I.force, "the [I.name]", ATTACK_TYPE_MELEE, I.armour_penetration, user, affecting.body_zone) & BLOCK_SUCCESS)
|
||||
if(H.mob_run_block(I, totitemdamage, "the [I.name]", ATTACK_TYPE_MELEE, I.armour_penetration, user, affecting.body_zone, null) & BLOCK_SUCCESS)
|
||||
return 0
|
||||
if(H.check_martial_melee_block())
|
||||
H.visible_message("<span class='warning'>[H] blocks [I]!</span>")
|
||||
@@ -1732,24 +1687,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/armor_block = H.run_armor_check(affecting, "melee", "<span class='notice'>Your armor has protected your [hit_area].</span>", "<span class='notice'>Your armor has softened a hit to your [hit_area].</span>",I.armour_penetration)
|
||||
armor_block = min(90,armor_block) //cap damage reduction at 90%
|
||||
var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)
|
||||
//CIT CHANGES START HERE - combatmode and resting checks
|
||||
var/totitemdamage = I.force
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 0.5
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
totitemdamage *= 0.5
|
||||
if(istype(H))
|
||||
if(!(H.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 1.5
|
||||
//CIT CHANGES END HERE
|
||||
var/weakness = H.check_weakness(I, user)
|
||||
apply_damage(totitemdamage * weakness, I.damtype, def_zone, armor_block, H) //CIT CHANGE - replaces I.force with totitemdamage
|
||||
|
||||
H.send_item_attack_message(I, user, hit_area)
|
||||
|
||||
I.do_stagger_action(H, user)
|
||||
I.do_stagger_action(H, user, totitemdamage)
|
||||
|
||||
if(!I.force)
|
||||
if(!totitemdamage)
|
||||
return 0 //item force is zero
|
||||
|
||||
//dismemberment
|
||||
@@ -1834,7 +1779,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
return TRUE
|
||||
if(M.mind)
|
||||
attacker_style = M.mind.martial_art
|
||||
if((M != H) && M.a_intent != INTENT_HELP && (H.run_block(M, 0, "[M]", ATTACK_TYPE_UNARMED, 0, M, M.zone_selected) & BLOCK_SUCCESS))
|
||||
if((M != H) && M.a_intent != INTENT_HELP && (H.mob_run_block(M, 0, "[M]", ATTACK_TYPE_UNARMED, 0, M, M.zone_selected, null) & BLOCK_SUCCESS))
|
||||
log_combat(M, H, "attempted to touch")
|
||||
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
|
||||
return TRUE
|
||||
@@ -1934,8 +1879,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/obj/item/target_held_item = target.get_active_held_item()
|
||||
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
|
||||
target_held_item = null
|
||||
if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE))
|
||||
target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
|
||||
if(!target.has_movespeed_modifier(/datum/movespeed_modifier/shove))
|
||||
target.add_movespeed_modifier(/datum/movespeed_modifier/shove)
|
||||
if(target_held_item)
|
||||
if(!HAS_TRAIT(target_held_item, TRAIT_NODROP))
|
||||
target.visible_message("<span class='danger'>[target.name]'s grip on \the [target_held_item] loosens!</span>",
|
||||
@@ -2086,7 +2031,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "hot", /datum/mood_event/hot)
|
||||
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_COLD)
|
||||
H.remove_movespeed_modifier(/datum/movespeed_modifier/cold)
|
||||
|
||||
var/burn_damage
|
||||
var/firemodifier = H.fire_stacks / 50
|
||||
@@ -2103,8 +2048,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold)
|
||||
//Sorry for the nasty oneline but I don't want to assign a variable on something run pretty frequently
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_COLD, override = TRUE, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR), blacklisted_movetypes = FLOATING)
|
||||
//Apply cold slowdown
|
||||
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR))
|
||||
switch(H.bodytemperature)
|
||||
if(200 to BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
H.apply_damage(COLD_DAMAGE_LEVEL_1*coldmod*H.physiology.cold_mod, BURN)
|
||||
@@ -2114,7 +2059,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod*H.physiology.cold_mod, BURN)
|
||||
|
||||
else
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_COLD)
|
||||
H.remove_movespeed_modifier(/datum/movespeed_modifier/cold)
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
gib_types = /obj/effect/gibspawner/robot
|
||||
damage_overlay_type = "synth"
|
||||
mutanttongue = /obj/item/organ/tongue/robot
|
||||
species_language_holder = /datum/language_holder/synthetic
|
||||
limbs_id = "synth"
|
||||
|
||||
/datum/species/android/on_species_gain(mob/living/carbon/C)
|
||||
|
||||
@@ -6,7 +6,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
name = "Dwarf"
|
||||
id = "dwarf" //Also called Homo sapiens pumilionis
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,NO_UNDERWEAR)
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,NO_UNDERWEAR,TRAIT_DWARF)
|
||||
inherent_traits = list()
|
||||
limbs_id = "human"
|
||||
use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM
|
||||
@@ -17,6 +17,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
disliked_food = JUNKFOOD | FRIED //Dwarves hate foods that have no nutrition other than alcohol.
|
||||
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
|
||||
|
||||
/mob/living/carbon/human/species/dwarf //species admin spawn path
|
||||
race = /datum/species/dwarf //and the race the path is set to.
|
||||
@@ -30,18 +31,15 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
. = ..()
|
||||
var/dwarf_hair = pick("Beard (Dwarf)", "Beard (Very Long)", "Beard (Long)") //beard roullette
|
||||
var/mob/living/carbon/human/H = C
|
||||
H.grant_language(/datum/language/dwarf)
|
||||
H.facial_hair_style = dwarf_hair
|
||||
H.update_hair()
|
||||
H.transform = H.transform.Scale(1, 0.8) //We use scale, and yeah. Dwarves can become gnomes with DWARFISM.
|
||||
RegisterSignal(C, COMSIG_MOB_SAY, .proc/handle_speech) //We register handle_speech is being used.
|
||||
|
||||
|
||||
/datum/species/dwarf/on_species_loss(mob/living/carbon/H, datum/species/new_species)
|
||||
. = ..()
|
||||
H.transform = H.transform.Scale(1, 1.25) //And we undo it.
|
||||
UnregisterSignal(H, COMSIG_MOB_SAY) //We register handle_speech is not being used.
|
||||
H.remove_language(/datum/language/dwarf)
|
||||
|
||||
//Dwarf Name stuff
|
||||
/proc/dwarf_name() //hello caller: my name is urist mcuristurister
|
||||
@@ -102,12 +100,11 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
|
||||
/obj/item/organ/dwarfgland/on_life() //Primary loop to hook into to start delayed loops for other loops..
|
||||
. = ..()
|
||||
dwarf_cycle_ticker()
|
||||
if(owner && owner.stat != DEAD)
|
||||
dwarf_cycle_ticker()
|
||||
|
||||
//Handles the delayed tick cycle by just adding on increments per each on_life() tick
|
||||
/obj/item/organ/dwarfgland/proc/dwarf_cycle_ticker()
|
||||
if(owner.stat == DEAD)
|
||||
return //We make sure they are not dead, so they don't increment any tickers.
|
||||
dwarf_eth_ticker++
|
||||
dwarf_filth_ticker++
|
||||
|
||||
@@ -170,7 +167,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
for(var/datum/reagent/R in owner.reagents.reagent_list)
|
||||
if(istype(R, /datum/reagent/consumable/ethanol))
|
||||
var/datum/reagent/consumable/ethanol/E = R
|
||||
stored_alcohol = CLAMP(stored_alcohol + E.boozepwr / 50, 0, max_alcohol)
|
||||
stored_alcohol = clamp(stored_alcohol + E.boozepwr / 50, 0, max_alcohol)
|
||||
var/heal_amt = heal_rate
|
||||
stored_alcohol -= alcohol_rate //Subtracts alcohol_Rate from stored alcohol so EX: 250 - 0.25 per each loop that occurs.
|
||||
if(stored_alcohol > 400) //If they are over 400 they start regenerating
|
||||
|
||||
@@ -397,7 +397,7 @@
|
||||
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
|
||||
var/turf/target = get_turf(P.starting)
|
||||
// redirect the projectile
|
||||
P.preparePixelProjectile(locate(CLAMP(target.x + new_x, 1, world.maxx), CLAMP(target.y + new_y, 1, world.maxy), H.z), H)
|
||||
P.preparePixelProjectile(locate(clamp(target.x + new_x, 1, world.maxx), clamp(target.y + new_y, 1, world.maxy), H.z), H)
|
||||
return BULLET_ACT_FORCE_PIERCE
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -21,20 +21,19 @@
|
||||
coldmod = 6 // = 3x cold damage
|
||||
heatmod = 0.5 // = 1/4x heat damage
|
||||
burnmod = 0.5 // = 1/2x generic burn damage
|
||||
species_language_holder = /datum/language_holder/jelly
|
||||
|
||||
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
|
||||
if(regenerate_limbs)
|
||||
regenerate_limbs.Remove(C)
|
||||
if(slime_change) //CIT CHANGE
|
||||
slime_change.Remove(C) //CIT CHANGE
|
||||
C.remove_language(/datum/language/slime)
|
||||
C.faction -= "slime"
|
||||
..()
|
||||
C.faction -= "slime"
|
||||
|
||||
/datum/species/jelly/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
..()
|
||||
C.grant_language(/datum/language/slime)
|
||||
if(ishuman(C))
|
||||
regenerate_limbs = new
|
||||
regenerate_limbs.Grant(C)
|
||||
@@ -606,7 +605,7 @@
|
||||
var/max_D = CONFIG_GET(number/penis_max_inches_prefs)
|
||||
var/new_length = input(owner, "Penis length in inches:\n([min_D]-[max_D])", "Genital Alteration") as num|null
|
||||
if(new_length)
|
||||
H.dna.features["cock_length"] = CLAMP(round(new_length), min_D, max_D)
|
||||
H.dna.features["cock_length"] = clamp(round(new_length), min_D, max_D)
|
||||
H.update_genitals()
|
||||
H.apply_overlay()
|
||||
H.give_genital(/obj/item/organ/genital/testicles)
|
||||
|
||||
@@ -24,9 +24,7 @@
|
||||
disliked_food = GRAIN | DAIRY
|
||||
liked_food = GROSS | MEAT
|
||||
inert_mutation = FIREBREATH
|
||||
|
||||
/datum/species/lizard/after_equip_job(datum/job/J, mob/living/carbon/human/H)
|
||||
H.grant_language(/datum/language/draconic)
|
||||
species_language_holder = /datum/language_holder/lizard
|
||||
|
||||
/datum/species/lizard/random_name(gender,unique,lastname)
|
||||
if(unique)
|
||||
@@ -86,9 +84,15 @@
|
||||
mutantlungs = /obj/item/organ/lungs/ashwalker
|
||||
burnmod = 0.9
|
||||
brutemod = 0.9
|
||||
species_language_holder = /datum/language_holder/lizard/ash
|
||||
|
||||
/datum/species/lizard/ashwalker/on_species_gain(mob/living/carbon/human/C, datum/species/old_species)
|
||||
if((C.dna.features["spines"] != "None" ) && (C.dna.features["tail_lizard"] == "None")) //tbh, it's kinda ugly for them not to have a tail yet have floating spines
|
||||
C.dna.features["tail_lizard"] = "Smooth"
|
||||
C.update_body()
|
||||
if(C.dna.features["legs"] != "digitigrade")
|
||||
C.dna.features["legs"] = "digitigrade"
|
||||
for(var/obj/item/bodypart/leggie in C.bodyparts)
|
||||
if(leggie.body_zone == BODY_ZONE_L_LEG || leggie.body_zone == BODY_ZONE_R_LEG)
|
||||
leggie.update_limb(FALSE, C)
|
||||
return ..()
|
||||
|
||||
@@ -23,9 +23,7 @@
|
||||
|
||||
mutanteyes = /obj/item/organ/eyes/night_vision/mushroom
|
||||
var/datum/martial_art/mushpunch/mush
|
||||
|
||||
/datum/species/mush/after_equip_job(datum/job/J, mob/living/carbon/human/H)
|
||||
H.grant_language(/datum/language/mushroom) //pomf pomf
|
||||
species_language_holder = /datum/language_holder/mushroom
|
||||
|
||||
/datum/species/mush/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/plant
|
||||
disliked_food = MEAT | DAIRY
|
||||
liked_food = VEGETABLES | FRUIT | GRAIN
|
||||
species_language_holder = /datum/language_holder/sylvan
|
||||
var/light_nutrition_gain_factor = 10
|
||||
var/light_toxheal = 1
|
||||
var/light_oxyheal = 1
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
var/list/initial_inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOLIMBDISABLE,TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
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
|
||||
|
||||
/datum/species/synth/military
|
||||
name = "Military Synth"
|
||||
|
||||
@@ -106,8 +106,8 @@
|
||||
to_chat(victim, "<span class='danger'>[H] is draining your blood!</span>")
|
||||
to_chat(H, "<span class='notice'>You drain some blood!</span>")
|
||||
playsound(H, 'sound/items/drink.ogg', 30, 1, -2)
|
||||
victim.blood_volume = CLAMP(victim.blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM)
|
||||
H.blood_volume = CLAMP(H.blood_volume + drained_blood, 0, BLOOD_VOLUME_MAXIMUM)
|
||||
victim.blood_volume = clamp(victim.blood_volume - drained_blood, 0, BLOOD_VOLUME_MAXIMUM)
|
||||
H.blood_volume = clamp(H.blood_volume + drained_blood, 0, BLOOD_VOLUME_MAXIMUM)
|
||||
if(!victim.blood_volume)
|
||||
to_chat(H, "<span class='warning'>You finish off [victim]'s blood supply!</span>")
|
||||
|
||||
|
||||
@@ -34,12 +34,11 @@
|
||||
/mob/living/carbon/human/set_drugginess(amount)
|
||||
..()
|
||||
if(!amount)
|
||||
remove_language(/datum/language/beachbum)
|
||||
remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH)
|
||||
|
||||
/mob/living/carbon/human/adjust_drugginess(amount)
|
||||
..()
|
||||
if(!dna.check_mutation(STONER))
|
||||
if(druggy)
|
||||
grant_language(/datum/language/beachbum)
|
||||
else
|
||||
remove_language(/datum/language/beachbum)
|
||||
if(druggy)
|
||||
grant_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH)
|
||||
else
|
||||
remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH)
|
||||
|
||||
@@ -129,16 +129,18 @@ There are several things that need to be remembered:
|
||||
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/mutable_appearance/uniform_overlay
|
||||
|
||||
if(dna && dna.species.sexes)
|
||||
var/G = (dna.features["body_model"] == FEMALE) ? "f" : "m"
|
||||
if(G == "f" && U.fitted != NO_FEMALE_UNIFORM)
|
||||
uniform_overlay = U.build_worn_icon(UNIFORM_LAYER, alt_worn, FALSE, U.fitted, target_overlay, variant_flag, FALSE)
|
||||
|
||||
if(!uniform_overlay)
|
||||
uniform_overlay = U.build_worn_icon( UNIFORM_LAYER, alt_worn, FALSE, NO_FEMALE_UNIFORM, target_overlay, variant_flag, FALSE)
|
||||
|
||||
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]
|
||||
@@ -269,6 +271,11 @@ There are several things that need to be remembered:
|
||||
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.
|
||||
return
|
||||
|
||||
if(shoes)
|
||||
var/obj/item/clothing/shoes/S = shoes
|
||||
shoes.screen_loc = ui_shoes //move the item to the appropriate screen loc
|
||||
@@ -514,12 +521,17 @@ There are several things that need to be remembered:
|
||||
overlays_standing[BACK_LAYER] = back_overlay
|
||||
apply_overlay(BACK_LAYER)
|
||||
|
||||
/proc/wear_female_version(t_color, icon, layer, type)
|
||||
var/index = "[t_color]-[icon]"
|
||||
var/icon/female_clothing_icon = GLOB.female_clothing_icons[index]
|
||||
if(!female_clothing_icon) //Create standing/laying icons if they don't exist
|
||||
generate_female_clothing(index,t_color,icon,type)
|
||||
return mutable_appearance(GLOB.female_clothing_icons[index], layer = -layer)
|
||||
/proc/wear_alpha_masked_version(state, icon, layer, female, alpha_mask)
|
||||
var/mask = "-[alpha_mask]"
|
||||
if(islist(alpha_mask))
|
||||
mask = "-"
|
||||
for(var/t in alpha_mask)
|
||||
mask += t
|
||||
var/index = "[state]-[icon]-[female][mask]"
|
||||
. = GLOB.alpha_masked_worn_icons[index]
|
||||
if(!.) //Create standing/laying icons if they don't exist
|
||||
. = generate_alpha_masked_clothing(index,state,icon,female,alpha_mask)
|
||||
return mutable_appearance(., layer = -layer)
|
||||
|
||||
/mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers)
|
||||
var/list/out = new
|
||||
@@ -574,10 +586,12 @@ generate/load female uniform sprites matching all previously decided variables
|
||||
|
||||
style_flags: mutant race appearance flags, mostly used for worn_overlays()
|
||||
|
||||
alpha_mask: a text string or list of text, the actual icons are stored in a global list and associated with said text string(s).
|
||||
|
||||
use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if mob_overlay_icon is present.
|
||||
|
||||
*/
|
||||
/obj/item/proc/build_worn_icon(default_layer = 0, default_icon_file = null, isinhands = FALSE, femaleuniform = NO_FEMALE_UNIFORM, override_state, style_flags = NONE, use_mob_overlay_icon = TRUE)
|
||||
/obj/item/proc/build_worn_icon(default_layer = 0, default_icon_file = null, isinhands = FALSE, femaleuniform = NO_FEMALE_UNIFORM, override_state, style_flags = NONE, use_mob_overlay_icon = TRUE, alpha_mask)
|
||||
|
||||
var/t_state
|
||||
t_state = override_state || item_state || icon_state
|
||||
@@ -597,8 +611,8 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if
|
||||
layer2use = default_layer
|
||||
|
||||
var/mutable_appearance/standing
|
||||
if(femaleuniform)
|
||||
standing = wear_female_version(t_state,file2use,layer2use,femaleuniform)
|
||||
if(femaleuniform || alpha_mask)
|
||||
standing = wear_alpha_masked_version(t_state, file2use, layer2use, femaleuniform, alpha_mask)
|
||||
if(!standing)
|
||||
standing = mutable_appearance(file2use, t_state, -layer2use)
|
||||
|
||||
@@ -661,19 +675,17 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if
|
||||
|
||||
. += "-[dna.features["body_model"]]"
|
||||
|
||||
|
||||
var/is_taur = FALSE
|
||||
if(dna.species.mutant_bodyparts["taur"] && dna.features["taur"] != "None")
|
||||
is_taur = TRUE
|
||||
|
||||
if(dna.species.mutant_bodyparts["taur"])
|
||||
var/datum/sprite_accessory/taur/T = GLOB.taur_list[dna.features["taur"]]
|
||||
if(T?.hide_legs)
|
||||
is_taur = TRUE
|
||||
|
||||
var/static/list/leg_day = typecacheof(list(/obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg))
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
|
||||
if(istype(BP, /obj/item/bodypart/r_leg) || istype(BP, /obj/item/bodypart/l_leg))
|
||||
if(is_taur)
|
||||
continue
|
||||
|
||||
if(is_taur && leg_day[BP.type])
|
||||
continue
|
||||
|
||||
. += "-[BP.body_zone]"
|
||||
if(BP.status == BODYPART_ORGANIC)
|
||||
|
||||
@@ -235,7 +235,7 @@
|
||||
//TOXINS/PLASMA
|
||||
if(Toxins_partialpressure > safe_tox_max)
|
||||
var/ratio = (breath_gases[/datum/gas/plasma]/safe_tox_max) * 10
|
||||
adjustToxLoss(CLAMP(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
|
||||
adjustToxLoss(clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
|
||||
throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
|
||||
else
|
||||
clear_alert("too_much_tox")
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
if(pickupTarget)
|
||||
if(restrained() || blacklistItems[pickupTarget] || HAS_TRAIT(pickupTarget, TRAIT_NODROP))
|
||||
pickupTarget = null
|
||||
else
|
||||
else if(!isobj(loc) || istype(loc, /obj/item/clothing/head/mob_holder))
|
||||
pickupTimer++
|
||||
if(pickupTimer >= 4)
|
||||
blacklistItems[pickupTarget] ++
|
||||
@@ -126,10 +126,8 @@
|
||||
pickupTarget = null
|
||||
pickupTimer = 0
|
||||
else if(ismob(pickupTarget.loc)) // in someones hand
|
||||
if(istype(pickupTarget, /obj/item/clothing/head/mob_holder/))
|
||||
var/obj/item/clothing/head/mob_holder/h = pickupTarget
|
||||
if(h && h.held_mob==src)
|
||||
return//dont let them pickpocket themselves
|
||||
if(istype(pickupTarget, /obj/item/clothing/head/mob_holder))
|
||||
return//dont let them pickpocket themselves or hold other monkys.
|
||||
var/mob/M = pickupTarget.loc
|
||||
if(!pickpocketing)
|
||||
pickpocketing = TRUE
|
||||
|
||||
@@ -65,20 +65,20 @@
|
||||
|
||||
/mob/living/carbon/monkey/on_reagent_change()
|
||||
. = ..()
|
||||
remove_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE)
|
||||
var/amount
|
||||
if(reagents.has_reagent(/datum/reagent/medicine/morphine))
|
||||
amount = -1
|
||||
if(amount)
|
||||
add_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_reagent_speedmod, TRUE, amount)
|
||||
|
||||
/mob/living/carbon/monkey/updatehealth()
|
||||
. = ..()
|
||||
var/slow = 0
|
||||
var/health_deficiency = (100 - health)
|
||||
if(health_deficiency >= 45)
|
||||
slow += (health_deficiency / 25)
|
||||
add_movespeed_modifier(MOVESPEED_ID_MONKEY_HEALTH_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = slow)
|
||||
if(!HAS_TRAIT(src, TRAIT_IGNOREDAMAGESLOWDOWN))
|
||||
var/health_deficiency = (maxHealth - health)
|
||||
if(health_deficiency >= 45)
|
||||
slow += (health_deficiency / 25)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_health_speedmod, TRUE, slow)
|
||||
|
||||
/mob/living/carbon/monkey/adjust_bodytemperature(amount)
|
||||
. = ..()
|
||||
@@ -87,7 +87,7 @@
|
||||
slow += (283.222 - bodytemperature) / 10 * 1.75
|
||||
if(slow <= 0)
|
||||
return
|
||||
add_movespeed_modifier(MOVESPEED_ID_MONKEY_TEMPERATURE_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_temperature_speedmod, TRUE, slow)
|
||||
|
||||
/mob/living/carbon/monkey/Stat()
|
||||
..()
|
||||
@@ -99,7 +99,6 @@
|
||||
if(changeling)
|
||||
stat("Chemical Storage", "[changeling.chem_charges]/[changeling.chem_storage]")
|
||||
stat("Absorbed DNA", changeling.absorbedcount)
|
||||
return
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/verb/removeinternal()
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/could_speak_in_language(datum/language/dt)
|
||||
/mob/living/carbon/could_speak_language(datum/language/language)
|
||||
var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
|
||||
if(T)
|
||||
. = T.could_speak_in_language(dt)
|
||||
return T.could_speak_language(language)
|
||||
else
|
||||
. = initial(dt.flags) & TONGUELESS_SPEECH
|
||||
return initial(language.flags) & TONGUELESS_SPEECH
|
||||
@@ -23,10 +23,10 @@
|
||||
clear_alert("high")
|
||||
|
||||
/mob/living/carbon/adjust_disgust(amount)
|
||||
disgust = CLAMP(disgust+amount, 0, DISGUST_LEVEL_MAXEDOUT)
|
||||
disgust = clamp(disgust+amount, 0, DISGUST_LEVEL_MAXEDOUT)
|
||||
|
||||
/mob/living/carbon/set_disgust(amount)
|
||||
disgust = CLAMP(amount, 0, DISGUST_LEVEL_MAXEDOUT)
|
||||
disgust = clamp(amount, 0, DISGUST_LEVEL_MAXEDOUT)
|
||||
|
||||
|
||||
////////////////////////////////////////TRAUMAS/////////////////////////////////////////
|
||||
|
||||
@@ -203,6 +203,12 @@
|
||||
|
||||
remove_overlay(BODYPARTS_LAYER)
|
||||
|
||||
var/is_taur = FALSE
|
||||
if(dna?.species.mutant_bodyparts["taur"])
|
||||
var/datum/sprite_accessory/taur/T = GLOB.taur_list[dna.features["taur"]]
|
||||
if(T?.hide_legs)
|
||||
is_taur = TRUE
|
||||
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
BP.update_limb()
|
||||
@@ -213,9 +219,12 @@
|
||||
return
|
||||
|
||||
//GENERATE NEW LIMBS
|
||||
var/static/list/leg_day = typecacheof(list(/obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg))
|
||||
var/list/new_limbs = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(is_taur && leg_day[BP.type])
|
||||
continue
|
||||
new_limbs += BP.get_limb_icon()
|
||||
if(new_limbs.len)
|
||||
overlays_standing[BODYPARTS_LAYER] = new_limbs
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
if(EFFECT_STUN)
|
||||
Stun(effect * hit_percent)
|
||||
if(EFFECT_KNOCKDOWN)
|
||||
DefaultCombatKnockdown(effect * hit_percent, override_stamdmg = knockdown_stammax ? CLAMP(knockdown_stamoverride, 0, knockdown_stammax-getStaminaLoss()) : knockdown_stamoverride)
|
||||
DefaultCombatKnockdown(effect * hit_percent, override_stamdmg = knockdown_stammax ? clamp(knockdown_stamoverride, 0, knockdown_stammax-getStaminaLoss()) : knockdown_stamoverride)
|
||||
if(EFFECT_UNCONSCIOUS)
|
||||
Unconscious(effect * hit_percent)
|
||||
if(EFFECT_IRRADIATE)
|
||||
@@ -140,7 +140,7 @@
|
||||
/mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
bruteloss = CLAMP((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
bruteloss = clamp((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
@@ -151,7 +151,7 @@
|
||||
/mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
oxyloss = CLAMP((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
oxyloss = clamp((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
@@ -170,7 +170,7 @@
|
||||
/mob/living/proc/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
toxloss = CLAMP((toxloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
toxloss = clamp((toxloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
@@ -189,7 +189,7 @@
|
||||
/mob/living/proc/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
fireloss = CLAMP((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
fireloss = clamp((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
@@ -200,7 +200,7 @@
|
||||
/mob/living/proc/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
cloneloss = CLAMP((cloneloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
cloneloss = clamp((cloneloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
var/obj/O = A
|
||||
if(ObjBump(O))
|
||||
return
|
||||
if(ismovableatom(A))
|
||||
if(ismovable(A))
|
||||
var/atom/movable/AM = A
|
||||
if(PushAM(AM, move_force))
|
||||
return
|
||||
@@ -316,6 +316,45 @@
|
||||
|
||||
update_pull_movespeed()
|
||||
|
||||
set_pull_offsets(M, state)
|
||||
|
||||
/mob/living/proc/set_pull_offsets(mob/living/M, grab_state = GRAB_PASSIVE)
|
||||
if(M.buckled || M.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
return //don't make them change direction or offset them if they're buckled into something or in combat mode.
|
||||
var/offset = 0
|
||||
switch(grab_state)
|
||||
if(GRAB_PASSIVE)
|
||||
offset = GRAB_PIXEL_SHIFT_PASSIVE
|
||||
if(GRAB_AGGRESSIVE)
|
||||
offset = GRAB_PIXEL_SHIFT_AGGRESSIVE
|
||||
if(GRAB_NECK)
|
||||
offset = GRAB_PIXEL_SHIFT_NECK
|
||||
if(GRAB_KILL)
|
||||
offset = GRAB_PIXEL_SHIFT_NECK
|
||||
M.setDir(get_dir(M, src))
|
||||
switch(M.dir)
|
||||
if(NORTH)
|
||||
animate(M, pixel_x = 0, pixel_y = offset, 3)
|
||||
if(SOUTH)
|
||||
animate(M, pixel_x = 0, pixel_y = -offset, 3)
|
||||
if(EAST)
|
||||
if(M.lying == 270) //update the dragged dude's direction if we've turned
|
||||
M.lying = 90
|
||||
M.update_transform() //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so
|
||||
M.lying_prev = M.lying
|
||||
animate(M, pixel_x = offset, pixel_y = 0, 3)
|
||||
if(WEST)
|
||||
if(M.lying == 90)
|
||||
M.lying = 270
|
||||
M.update_transform()
|
||||
M.lying_prev = M.lying
|
||||
animate(M, pixel_x = -offset, pixel_y = 0, 3)
|
||||
|
||||
/mob/living/proc/reset_pull_offsets(mob/living/M, override)
|
||||
if(!override && M.buckled)
|
||||
return
|
||||
animate(M, pixel_x = 0, pixel_y = 0, 1)
|
||||
|
||||
//mob verbs are a lot faster than object verbs
|
||||
//for more info on why this is not atom/pull, see examinate() in mob.dm
|
||||
/mob/living/verb/pulled(atom/movable/AM as mob|obj in oview(1))
|
||||
@@ -328,6 +367,8 @@
|
||||
stop_pulling()
|
||||
|
||||
/mob/living/stop_pulling()
|
||||
if(ismob(pulling))
|
||||
reset_pull_offsets(pulling)
|
||||
..()
|
||||
update_pull_movespeed()
|
||||
update_pull_hud_icon()
|
||||
@@ -502,8 +543,16 @@
|
||||
var/obj/effect/proc_holder/spell/spell = S
|
||||
spell.updateButtonIcon()
|
||||
|
||||
//proc used to remove all immobilisation effects + reset stamina
|
||||
/mob/living/proc/remove_CC(should_update_mobility = TRUE)
|
||||
SetAllImmobility(0, FALSE)
|
||||
setStaminaLoss(0)
|
||||
SetUnconscious(0, FALSE)
|
||||
if(should_update_mobility)
|
||||
update_mobility()
|
||||
|
||||
//proc used to completely heal a mob.
|
||||
/mob/living/proc/fully_heal(admin_revive = 0)
|
||||
/mob/living/proc/fully_heal(admin_revive = FALSE)
|
||||
restore_blood()
|
||||
setToxLoss(0, 0) //zero as second argument not automatically call updatehealth().
|
||||
setOxyLoss(0, 0)
|
||||
@@ -645,7 +694,7 @@
|
||||
attempt_resist_grab(FALSE)
|
||||
// Return as we should only resist one thing at a time. Give clickdelay if the grab wasn't passive.
|
||||
return old_gs? TRUE : FALSE
|
||||
|
||||
|
||||
// unbuckling yourself. stops the chain if you try it.
|
||||
if(buckled && last_special <= world.time)
|
||||
log_combat(src, buckled, "resisted buckle")
|
||||
@@ -1030,7 +1079,7 @@
|
||||
update_fire()
|
||||
|
||||
/mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person
|
||||
fire_stacks = CLAMP(fire_stacks + add_fire_stacks, -20, 20)
|
||||
fire_stacks = clamp(fire_stacks + add_fire_stacks, -20, 20)
|
||||
if(on_fire && fire_stacks <= 0)
|
||||
ExtinguishMob()
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
// This file has a weird name, but it's for anything related to the checks for shields, blocking, dodging, and similar "stop this attack before it actually impacts the target" as opposed to "defend once it has hit".
|
||||
// This file has a weird name, but it's for anything related to the checks for shields, blocking, dodging,
|
||||
// and similar "stop this attack before it actually impacts the target" as opposed to "defend once it has hit".
|
||||
|
||||
/*
|
||||
/// Bitflags for check_block() and handle_block(). Meant to be combined. You can be hit and still reflect, for example, if you do not use BLOCK_SUCCESS.
|
||||
/// You can find the mob_check_block() and mob_run_block() macros in __DEFINES/combat.dm
|
||||
|
||||
/// Bitflags for check_block() and run_block(). Meant to be combined. You can be hit and still reflect, for example, if you do not use BLOCK_SUCCESS.
|
||||
/// Attack was not blocked
|
||||
#define BLOCK_NONE NONE
|
||||
/// Attack was blocked, do not do damage. THIS FLAG MUST BE THERE FOR DAMAGE/EFFECT PREVENTION!
|
||||
@@ -23,14 +26,6 @@
|
||||
#define BLOCK_TARGET_DODGED (1<<7)
|
||||
*/
|
||||
|
||||
///Check whether or not we can block, without "triggering" a block. Basically run checks without effects like depleting shields. Wrapper for do_run_block(). The arguments on that means the same as for this.
|
||||
/mob/living/proc/check_block(atom/object, damage, attack_text = "the attack", attack_type, armour_penetration, mob/attacker, def_zone, list/return_list)
|
||||
return do_run_block(FALSE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list)
|
||||
|
||||
/// Runs a block "sequence", effectively checking and then doing effects if necessary. Wrapper for do_run_block(). The arguments on that means the same as for this.
|
||||
/mob/living/proc/run_block(atom/object, damage, attack_text = "the attack", attack_type, armour_penetration, mob/attacker, def_zone, list/return_list)
|
||||
return do_run_block(TRUE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list)
|
||||
|
||||
/** The actual proc for block checks. DO NOT USE THIS DIRECTLY UNLESS YOU HAVE VERY GOOD REASON TO. To reduce copypaste for differences between handling for real attacks and virtual checks.
|
||||
* Automatically checks all held items for /obj/item/proc/run_block() with the same parameters.
|
||||
* @params
|
||||
@@ -57,7 +52,7 @@
|
||||
if(real_attack)
|
||||
for(var/obj/item/I in tocheck)
|
||||
// i don't like this too
|
||||
var/final_block_chance = I.block_chance - (CLAMP((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
|
||||
var/final_block_chance = I.block_chance - (clamp((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
|
||||
var/results = I.run_block(src, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, return_list)
|
||||
. |= results
|
||||
if((results & BLOCK_SUCCESS) && !(results & BLOCK_CONTINUE_CHAIN))
|
||||
@@ -65,12 +60,13 @@
|
||||
else
|
||||
for(var/obj/item/I in tocheck)
|
||||
// i don't like this too
|
||||
var/final_block_chance = I.block_chance - (CLAMP((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
|
||||
var/final_block_chance = I.block_chance - (clamp((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
|
||||
I.check_block(src, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, return_list)
|
||||
|
||||
/// Gets an unsortedlist of objects to run block checks on.
|
||||
/mob/living/proc/get_blocking_items()
|
||||
. = list()
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_GET_BLOCKING_ITEMS, .)
|
||||
for(var/obj/item/I in held_items)
|
||||
// this is a bad check but i am not removing it until a better catchall is made
|
||||
if(istype(I, /obj/item/clothing))
|
||||
@@ -85,11 +81,13 @@
|
||||
|
||||
/// Runs block and returns flag for do_run_block to process.
|
||||
/obj/item/proc/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_RUN_BLOCK, owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
. = SEND_SIGNAL(src, COMSIG_ITEM_RUN_BLOCK, owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
if(. & BLOCK_SUCCESS)
|
||||
return
|
||||
if(prob(final_block_chance))
|
||||
owner.visible_message("<span class='danger'>[owner] blocks [attack_text] with [src]!</span>")
|
||||
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
|
||||
return BLOCK_NONE
|
||||
return . | BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
|
||||
return . | BLOCK_NONE
|
||||
|
||||
/// Returns block information using list/block_return. Used for check_block() on mobs.
|
||||
/obj/item/proc/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
update_combat_mode_icon()
|
||||
|
||||
/mob/living/proc/disable_combat_mode(silent = TRUE, was_forced = FALSE, visible = FALSE, update_icon = TRUE)
|
||||
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) || (combat_flags & COMBAT_FLAG_COMBAT_FORCED))
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_COMBAT_DISABLED, was_forced)
|
||||
@@ -60,6 +60,8 @@
|
||||
/mob/living/proc/disable_intentional_combat_mode(silent = TRUE, visible = FALSE)
|
||||
if(!(combat_flags & COMBAT_FLAG_COMBAT_TOGGLED) && !(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
return
|
||||
if(combat_flags & COMBAT_FLAG_COMBAT_FORCED)
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_TOGGLED)
|
||||
if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
disable_combat_mode(silent, FALSE, visible, FALSE)
|
||||
@@ -71,6 +73,9 @@
|
||||
/mob/living/proc/user_toggle_intentional_combat_mode(visible = TRUE)
|
||||
var/old = (combat_flags & COMBAT_FLAG_COMBAT_TOGGLED)
|
||||
if(old)
|
||||
if(combat_flags & COMBAT_FLAG_COMBAT_FORCED)
|
||||
to_chat(src, "<span class='warning'>You are unable to relax your muscles.</span>")
|
||||
return
|
||||
disable_intentional_combat_mode()
|
||||
playsound_local(src, 'sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the above!
|
||||
else if(CAN_TOGGLE_COMBAT_MODE(src))
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
/mob/living/bullet_act(obj/item/projectile/P, def_zone)
|
||||
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
|
||||
var/list/returnlist = list()
|
||||
var/returned = run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
|
||||
var/returned = mob_run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
|
||||
if(returned & BLOCK_SHOULD_REDIRECT)
|
||||
handle_projectile_attack_redirection(P, returnlist[BLOCK_RETURN_REDIRECT_METHOD])
|
||||
if(returned & BLOCK_REDIRECTED)
|
||||
@@ -88,9 +88,9 @@
|
||||
|
||||
/obj/item/proc/get_volume_by_throwforce_and_or_w_class()
|
||||
if(throwforce && w_class)
|
||||
return CLAMP((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
|
||||
return clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
|
||||
else if(w_class)
|
||||
return CLAMP(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
|
||||
return clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
I = AM
|
||||
throwpower = I.throwforce
|
||||
var/impacting_zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest
|
||||
if(run_block(AM, throwpower, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, impacting_zone) & BLOCK_SUCCESS)
|
||||
if(mob_run_block(AM, throwpower, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, impacting_zone, null) & BLOCK_SUCCESS)
|
||||
hitpush = FALSE
|
||||
skipcatch = TRUE
|
||||
blocked = TRUE
|
||||
@@ -264,12 +264,13 @@
|
||||
update_mobility() //we fall down
|
||||
if(!buckled && !density)
|
||||
Move(user.loc)
|
||||
user.set_pull_offsets(src, grab_state)
|
||||
return 1
|
||||
|
||||
/mob/living/attack_hand(mob/user)
|
||||
..() //Ignoring parent return value here.
|
||||
SEND_SIGNAL(src, COMSIG_MOB_ATTACK_HAND, user)
|
||||
if((user != src) && user.a_intent != INTENT_HELP && (run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS))
|
||||
if((user != src) && user.a_intent != INTENT_HELP && (mob_run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS))
|
||||
log_combat(user, src, "attempted to touch")
|
||||
visible_message("<span class='warning'>[user] attempted to touch [src]!</span>")
|
||||
return TRUE
|
||||
@@ -280,7 +281,7 @@
|
||||
to_chat(user, "<span class='notice'>You don't want to hurt [src]!</span>")
|
||||
return TRUE
|
||||
var/hulk_verb = pick("smash","pummel")
|
||||
if(user != src && (run_block(user, 15, "the [hulk_verb]ing", ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS))
|
||||
if(user != src && (mob_run_block(user, 15, "the [hulk_verb]ing", ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS))
|
||||
return TRUE
|
||||
..()
|
||||
return FALSE
|
||||
@@ -302,7 +303,7 @@
|
||||
var/damage = rand(5, 35)
|
||||
if(M.is_adult)
|
||||
damage = rand(20, 40)
|
||||
if(run_block(M, damage, "the [M.name]", ATTACK_TYPE_MELEE, null, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS)
|
||||
if(mob_run_block(M, damage, "the [M.name]", ATTACK_TYPE_MELEE, null, M, check_zone(M.zone_selected), null) & BLOCK_SUCCESS)
|
||||
return FALSE
|
||||
|
||||
if (stat != DEAD)
|
||||
@@ -321,7 +322,7 @@
|
||||
if(HAS_TRAIT(M, TRAIT_PACIFISM))
|
||||
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
|
||||
return FALSE
|
||||
if(run_block(M, rand(M.melee_damage_lower, M.melee_damage_upper), "the [M.name]", ATTACK_TYPE_MELEE, M.armour_penetration, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS)
|
||||
if(mob_run_block(M, rand(M.melee_damage_lower, M.melee_damage_upper), "the [M.name]", ATTACK_TYPE_MELEE, M.armour_penetration, M, check_zone(M.zone_selected), null) & BLOCK_SUCCESS)
|
||||
return FALSE
|
||||
if(M.attack_sound)
|
||||
playsound(loc, M.attack_sound, 50, 1, 1)
|
||||
@@ -339,7 +340,7 @@
|
||||
if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
|
||||
to_chat(M, "<span class='warning'>You can't bite with your mouth covered!</span>")
|
||||
return FALSE
|
||||
if(run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS)
|
||||
if(mob_run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, 0, M, check_zone(M.zone_selected), null) & BLOCK_SUCCESS)
|
||||
return FALSE
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
|
||||
if (prob(75))
|
||||
@@ -363,7 +364,7 @@
|
||||
if(HAS_TRAIT(L, TRAIT_PACIFISM))
|
||||
to_chat(L, "<span class='notice'>You don't want to hurt anyone!</span>")
|
||||
return FALSE
|
||||
if(L != src && (run_block(L, rand(1, 3), "the [L.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, L, check_zone(L.zone_selected)) & BLOCK_SUCCESS))
|
||||
if(L != src && (mob_run_block(L, rand(1, 3), "the [L.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, 0, L, check_zone(L.zone_selected), null) & BLOCK_SUCCESS))
|
||||
return FALSE
|
||||
L.do_attack_animation(src)
|
||||
if(prob(90))
|
||||
@@ -377,7 +378,7 @@
|
||||
"<span class='userdanger'>[L.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if((M != src) && M.a_intent != INTENT_HELP && (run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS))
|
||||
if((M != src) && M.a_intent != INTENT_HELP && (mob_run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, 0, M, check_zone(M.zone_selected), null) & BLOCK_SUCCESS))
|
||||
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
|
||||
return FALSE
|
||||
switch(M.a_intent)
|
||||
|
||||
@@ -98,8 +98,6 @@
|
||||
|
||||
var/datum/riding/riding_datum
|
||||
|
||||
var/datum/language/selected_default_language
|
||||
|
||||
var/last_words //used for database logging
|
||||
|
||||
var/list/obj/effect/proc_holder/abilities = list()
|
||||
|
||||
@@ -94,11 +94,13 @@
|
||||
|
||||
if(should_be_lying)
|
||||
mobility_flags &= ~MOBILITY_STAND
|
||||
setMovetype(movement_type | CRAWLING)
|
||||
if(!lying) //force them on the ground
|
||||
lying = pick(90, 270)
|
||||
if(has_gravity() && !buckled)
|
||||
playsound(src, "bodyfall", 20, 1)
|
||||
else
|
||||
setMovetype(movement_type & ~CRAWLING)
|
||||
mobility_flags |= MOBILITY_STAND
|
||||
lying = 0
|
||||
|
||||
@@ -161,8 +163,8 @@
|
||||
if(!has_legs && has_arms < 2)
|
||||
limbless_slowdown += 6 - (has_arms * 3)
|
||||
if(limbless_slowdown)
|
||||
add_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=limbless_slowdown, blacklisted_movetypes = FLYING|FLOATING)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/limbless, multiplicative_slowdown = limbless_slowdown)
|
||||
else
|
||||
remove_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/limbless)
|
||||
|
||||
return mobility_flags
|
||||
|
||||
@@ -36,38 +36,26 @@
|
||||
sprint_stamina_cost = CONFIG_GET(number/movedelay/sprint_stamina_cost)
|
||||
return ..()
|
||||
|
||||
/mob/living/movement_delay(ignorewalk = 0)
|
||||
. = ..()
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
. += 6
|
||||
|
||||
/// whether or not we can slide under another living mob. defaults to if we're not dense. CanPass should check "overriding circumstances" like buckled mobs/having PASSMOB flag, etc.
|
||||
/mob/living/proc/can_move_under_living(mob/living/other)
|
||||
return !density
|
||||
|
||||
/mob/living/proc/update_move_intent_slowdown()
|
||||
var/mod = 0
|
||||
if(m_intent == MOVE_INTENT_WALK)
|
||||
mod = CONFIG_GET(number/movedelay/walk_delay)
|
||||
else
|
||||
mod = CONFIG_GET(number/movedelay/run_delay)
|
||||
if(!isnum(mod))
|
||||
mod = 1
|
||||
add_movespeed_modifier(MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED, TRUE, 100, override = TRUE, multiplicative_slowdown = mod)
|
||||
add_movespeed_modifier((m_intent == MOVE_INTENT_WALK)? /datum/movespeed_modifier/config_walk_run/walk : /datum/movespeed_modifier/config_walk_run/run)
|
||||
|
||||
/mob/living/proc/update_turf_movespeed(turf/open/T)
|
||||
if(isopenturf(T) && !is_flying())
|
||||
add_movespeed_modifier(MOVESPEED_ID_LIVING_TURF_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = T.slowdown)
|
||||
if(isopenturf(T))
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/turf_slowdown, multiplicative_slowdown = T.slowdown)
|
||||
else
|
||||
remove_movespeed_modifier(MOVESPEED_ID_LIVING_TURF_SPEEDMOD)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/turf_slowdown)
|
||||
|
||||
/mob/living/proc/update_pull_movespeed()
|
||||
if(pulling && isliving(pulling))
|
||||
var/mob/living/L = pulling
|
||||
if(drag_slowdown && L.lying && !L.buckled && grab_state < GRAB_AGGRESSIVE)
|
||||
add_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING, multiplicative_slowdown = PULL_PRONE_SLOWDOWN)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/bulky_drag, multiplicative_slowdown = PULL_PRONE_SLOWDOWN)
|
||||
return
|
||||
remove_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/bulky_drag)
|
||||
|
||||
/mob/living/canZMove(dir, turf/target)
|
||||
return can_zTravel(target, dir) && (movement_type & FLYING)
|
||||
@@ -87,8 +75,12 @@
|
||||
|
||||
. = ..()
|
||||
|
||||
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move.
|
||||
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1 && (pulledby != moving_from_pull))//separated from our puller and not in the middle of a diagonal move.
|
||||
pulledby.stop_pulling()
|
||||
else
|
||||
if(isliving(pulledby))
|
||||
var/mob/living/L = pulledby
|
||||
L.set_pull_offsets(src, pulledby.grab_state)
|
||||
|
||||
if(active_storage && !(CanReach(active_storage.parent,view_only = TRUE)))
|
||||
active_storage.close(src)
|
||||
@@ -96,6 +88,14 @@
|
||||
if(lying && !buckled && prob(getBruteLoss()*200/maxHealth))
|
||||
makeTrail(newloc, T, old_direction)
|
||||
|
||||
|
||||
/mob/living/Move_Pulled(atom/A)
|
||||
. = ..()
|
||||
if(!. || !isliving(A))
|
||||
return
|
||||
var/mob/living/L = A
|
||||
set_pull_offsets(L, grab_state)
|
||||
|
||||
/mob/living/forceMove(atom/destination)
|
||||
stop_pulling()
|
||||
if(buckled)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
update_sprint_icon()
|
||||
|
||||
/mob/living/proc/disable_sprint_mode(update_icon = TRUE)
|
||||
if(!(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
if(!(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) || (combat_flags & COMBAT_FLAG_SPRINT_FORCED))
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
if(update_icon)
|
||||
@@ -51,6 +51,8 @@
|
||||
/mob/living/proc/disable_intentional_sprint_mode()
|
||||
if(!(combat_flags & COMBAT_FLAG_SPRINT_TOGGLED) && !(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
return
|
||||
if(combat_flags & COMBAT_FLAG_SPRINT_FORCED)
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_TOGGLED)
|
||||
if(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
disable_sprint_mode(FALSE)
|
||||
@@ -59,6 +61,9 @@
|
||||
/mob/living/proc/user_toggle_intentional_sprint_mode()
|
||||
var/old = (combat_flags & COMBAT_FLAG_SPRINT_TOGGLED)
|
||||
if(old)
|
||||
if(combat_flags & COMBAT_FLAG_SPRINT_FORCED)
|
||||
to_chat(src, "<span class='warning'>You are unable to stop sprinting!</span>")
|
||||
return
|
||||
disable_intentional_sprint_mode()
|
||||
if((m_intent == MOVE_INTENT_RUN) && CHECK_ALL_MOBILITY(src, MOBILITY_STAND|MOBILITY_MOVE))
|
||||
playsound_local(src, 'sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
|
||||
@@ -133,7 +133,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
var/datum/language/message_language = get_message_language(message)
|
||||
if(message_language)
|
||||
// No, you cannot speak in xenocommon just because you know the key
|
||||
if(can_speak_in_language(message_language))
|
||||
if(can_speak_language(message_language))
|
||||
language = message_language
|
||||
message = copytext_char(message, 3)
|
||||
|
||||
@@ -141,7 +141,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
message = trim_left(message)
|
||||
|
||||
if(!language)
|
||||
language = get_default_language()
|
||||
language = get_selected_language()
|
||||
|
||||
// Detection of language needs to be before inherent channels, because
|
||||
// AIs use inherent channels for the holopad. Most inherent channels
|
||||
@@ -237,6 +237,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
deaf_message = "<span class='notice'>You can't hear yourself!</span>"
|
||||
deaf_type = 2 // Since you should be able to hear yourself without looking
|
||||
|
||||
// Create map text prior to modifying message for goonchat
|
||||
if (client?.prefs.chat_on_map && stat != UNCONSCIOUS && (client.prefs.see_chat_non_mob || ismob(speaker)) && can_hear())
|
||||
create_chat_message(speaker, message_language, raw_message, spans, message_mode)
|
||||
|
||||
// Recompose message for AI hrefs, language incomprehension.
|
||||
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode, FALSE, source)
|
||||
|
||||
@@ -289,7 +293,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
//speech bubble
|
||||
var/list/speech_bubble_recipients = list()
|
||||
for(var/mob/M in listening)
|
||||
if(M.client)
|
||||
if(M.client && !M.client.prefs.chat_on_map)
|
||||
speech_bubble_recipients.Add(M.client)
|
||||
var/image/I = image('icons/mob/talk.dmi', src, "[bubble_type][say_test(message)]", FLY_LAYER)
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
@@ -411,11 +415,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
/mob/living/whisper(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
|
||||
say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced)
|
||||
|
||||
/mob/living/get_language_holder(shadow=TRUE)
|
||||
if(mind && shadow)
|
||||
// Mind language holders shadow mob holders.
|
||||
. = mind.get_language_holder()
|
||||
if(.)
|
||||
return .
|
||||
|
||||
/mob/living/get_language_holder(get_minds = TRUE)
|
||||
if(get_minds && mind)
|
||||
return mind.get_language_holder()
|
||||
. = ..()
|
||||
|
||||
@@ -822,21 +822,21 @@
|
||||
return get_dist(src, A) <= max(viewscale[1]*0.5,viewscale[2]*0.5)
|
||||
|
||||
/mob/living/silicon/ai/proc/relay_speech(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
raw_message = lang_treat(speaker, message_language, raw_message, spans, message_mode)
|
||||
var/treated_message = lang_treat(speaker, message_language, raw_message, spans, message_mode)
|
||||
var/start = "Relayed Speech: "
|
||||
var/namepart = "[speaker.GetVoice()][speaker.get_alt_name()]"
|
||||
var/hrefpart = "<a href='?src=[REF(src)];track=[html_encode(namepart)]'>"
|
||||
var/jobpart
|
||||
var/jobpart = "Unknown"
|
||||
|
||||
if (iscarbon(speaker))
|
||||
var/mob/living/carbon/S = speaker
|
||||
if(S.job)
|
||||
jobpart = "[S.job]"
|
||||
else
|
||||
jobpart = "Unknown"
|
||||
|
||||
var/rendered = "<i><span class='game say'>[start]<span class='name'>[hrefpart][namepart] ([jobpart])</a> </span><span class='message'>[raw_message]</span></span></i>"
|
||||
var/rendered = "<i><span class='game say'>[start]<span class='name'>[hrefpart][namepart] ([jobpart])</a> </span><span class='message'>[treated_message]</span></span></i>"
|
||||
|
||||
if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker)))
|
||||
create_chat_message(speaker, message_language, raw_message, spans, message_mode)
|
||||
show_message(rendered, MSG_AUDIBLE)
|
||||
|
||||
/mob/living/silicon/ai/fully_replace_character_name(oldname,newname)
|
||||
@@ -869,7 +869,7 @@
|
||||
if(istype(A, /obj/machinery/camera))
|
||||
current = A
|
||||
if(client)
|
||||
if(ismovableatom(A))
|
||||
if(ismovable(A))
|
||||
if(A != GLOB.ai_camera_room_landmark)
|
||||
end_multicam()
|
||||
client.perspective = EYE_PERSPECTIVE
|
||||
@@ -1016,7 +1016,7 @@
|
||||
if("Yes.")
|
||||
src.ghostize(FALSE, penalize = TRUE)
|
||||
var/announce_rank = "Artificial Intelligence,"
|
||||
if(GLOB.announcement_systems.len)
|
||||
if(GLOB.announcement_systems.len)
|
||||
// Sends an announcement the AI has cryoed.
|
||||
var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems)
|
||||
announcer.announce("CRYOSTORAGE", src.real_name, announce_rank, list())
|
||||
|
||||
@@ -171,10 +171,3 @@
|
||||
|
||||
#undef VOX_DELAY
|
||||
#endif
|
||||
|
||||
/mob/living/silicon/ai/could_speak_in_language(datum/language/dt)
|
||||
if(is_servant_of_ratvar(src))
|
||||
// Ratvarian AIs can only speak Ratvarian
|
||||
. = ispath(dt, /datum/language/ratvar)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
/mob/living/silicon/pai/proc/process_hack()
|
||||
|
||||
if(cable && cable.machine && istype(cable.machine, /obj/machinery/door) && cable.machine == hackdoor && get_dist(src, hackdoor) <= 1)
|
||||
hackprogress = CLAMP(hackprogress + 4, 0, 100)
|
||||
hackprogress = clamp(hackprogress + 4, 0, 100)
|
||||
else
|
||||
temp = "Door Jack: Connection to airlock has been lost. Hack aborted."
|
||||
hackprogress = 0
|
||||
@@ -273,9 +273,9 @@
|
||||
/mob/living/silicon/pai/Process_Spacemove(movement_dir = 0)
|
||||
. = ..()
|
||||
if(!.)
|
||||
add_movespeed_modifier(MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD, TRUE, 100, multiplicative_slowdown = 2)
|
||||
add_movespeed_modifier(/datum/movespeed_modifier/pai_spacewalk)
|
||||
return TRUE
|
||||
remove_movespeed_modifier(MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD, TRUE)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/pai_spacewalk)
|
||||
return TRUE
|
||||
|
||||
/mob/living/silicon/pai/examine(mob/user)
|
||||
@@ -301,7 +301,7 @@
|
||||
update_stat()
|
||||
|
||||
/mob/living/silicon/pai/process()
|
||||
emitterhealth = CLAMP((emitterhealth + emitterregen), -50, emittermaxhealth)
|
||||
emitterhealth = clamp((emitterhealth + emitterregen), -50, emittermaxhealth)
|
||||
|
||||
/obj/item/paicard/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
return FALSE //No we're not flammable
|
||||
|
||||
/mob/living/silicon/pai/proc/take_holo_damage(amount)
|
||||
emitterhealth = CLAMP((emitterhealth - amount), -50, emittermaxhealth)
|
||||
emitterhealth = clamp((emitterhealth - amount), -50, emittermaxhealth)
|
||||
if(emitterhealth < 0)
|
||||
fold_in(force = TRUE)
|
||||
if(amount > 0)
|
||||
|
||||
@@ -267,9 +267,8 @@
|
||||
if(href_list["toggle"])
|
||||
encryptmod = TRUE
|
||||
if("translator")
|
||||
if(href_list["toggle"])
|
||||
grant_all_languages(TRUE)
|
||||
// this is PERMAMENT.
|
||||
if(href_list["toggle"]) //This is permanent.
|
||||
grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE)
|
||||
if("doorjack")
|
||||
if(href_list["jack"])
|
||||
if(cable && cable.machine)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
if(cell && cell.charge)
|
||||
if(cell.charge <= 100)
|
||||
uneq_all()
|
||||
var/amt = CLAMP((lamp_intensity - 2) * 2,1,cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell.
|
||||
var/amt = clamp((lamp_intensity - 2) * 2,1,cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell.
|
||||
cell.use(amt) //Usage table: 1/tick if off/lowest setting, 4 = 4/tick, 6 = 8/tick, 8 = 12/tick, 10 = 16/tick
|
||||
else
|
||||
uneq_all()
|
||||
|
||||
@@ -237,7 +237,7 @@
|
||||
return
|
||||
|
||||
if(!CONFIG_GET(flag/disable_secborg) && GLOB.security_level < CONFIG_GET(number/minimum_secborg_alert))
|
||||
to_chat(src, "<span class='notice'>NOTICE: Due to local station regulations, the security cyborg module and its variants are only available during [num2seclevel(CONFIG_GET(number/minimum_secborg_alert))] alert and greater.</span>")
|
||||
to_chat(src, "<span class='notice'>NOTICE: Due to local station regulations, the security cyborg module and its variants are only available during [NUM2SECLEVEL(CONFIG_GET(number/minimum_secborg_alert))] alert and greater.</span>")
|
||||
|
||||
var/list/modulelist = list("Standard" = /obj/item/robot_module/standard, \
|
||||
"Engineering" = /obj/item/robot_module/engineering, \
|
||||
@@ -427,24 +427,23 @@
|
||||
|
||||
else if(istype(W, /obj/item/stack/cable_coil) && wiresexposed)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
var/obj/item/stack/cable_coil/coil = W
|
||||
if (getFireLoss() > 0 || getToxLoss() > 0)
|
||||
if(src == user && coil.use(1))
|
||||
if(src == user)
|
||||
to_chat(user, "<span class='notice'>You start fixing yourself...</span>")
|
||||
if(!do_after(user, 50, target = src))
|
||||
if(!W.use_tool(src, user, 50, 1, max_level = JOB_SKILL_TRAINED))
|
||||
to_chat(user, "<span class='warning'>You need more cable to repair [src]!</span>")
|
||||
return
|
||||
adjustFireLoss(-10)
|
||||
adjustToxLoss(-10)
|
||||
if (coil.use(1))
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You start fixing [src]...</span>")
|
||||
if(!do_after(user, 30, target = src))
|
||||
if(!W.use_tool(src, user, 30, 1))
|
||||
to_chat(user, "<span class='warning'>You need more cable to repair [src]!</span>")
|
||||
return
|
||||
adjustFireLoss(-30)
|
||||
adjustToxLoss(-30)
|
||||
updatehealth()
|
||||
user.visible_message("[user] has fixed some of the burnt wires on [src].", "<span class='notice'>You fix some of the burnt wires on [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need more cable to repair [src]!</span>")
|
||||
else
|
||||
to_chat(user, "The wires seem fine, there's no need to fix them.")
|
||||
|
||||
|
||||
@@ -276,6 +276,19 @@
|
||||
R.hud_used.update_robot_modules_display()
|
||||
SSblackbox.record_feedback("tally", "cyborg_modules", 1, R.module)
|
||||
|
||||
/**
|
||||
* check_menu: Checks if we are allowed to interact with a radial menu
|
||||
*
|
||||
* Arguments:
|
||||
* * user The mob interacting with a menu
|
||||
*/
|
||||
/obj/item/robot_module/proc/check_menu(mob/user)
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(user.incapacitated() || !user.Adjacent(src))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/robot_module/standard
|
||||
name = "Standard"
|
||||
basic_modules = list(
|
||||
@@ -337,13 +350,28 @@
|
||||
|
||||
/obj/item/robot_module/medical/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/medmodels = list("Default", "Heavy", "Sleek", "Marina", "Droid", "Eyebot", "Medihound", "Medihound Dark", "Vale")
|
||||
if(R.client && (R.client.ckey in list("nezuli")))
|
||||
medmodels += "Alina"
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in medmodels
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
var/static/list/med_icons
|
||||
if(!med_icons)
|
||||
med_icons = list(
|
||||
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "medical"),
|
||||
"Droid" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "medical"),
|
||||
"Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekmed"),
|
||||
"Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinamed"),
|
||||
"Eyebot" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "eyebotmed"),
|
||||
"Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavymed")
|
||||
)
|
||||
var/list/L = list("Medihound" = "medihound", "Medihound Dark" = "medihounddark", "Vale" = "valemed")
|
||||
for(var/a in L)
|
||||
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
|
||||
wide.pixel_x = -16
|
||||
med_icons[a] = wide
|
||||
if(R.client && R.client.ckey == "nezuli")
|
||||
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-med")
|
||||
bad_snowflake.pixel_x = -16
|
||||
med_icons["Alina"] = bad_snowflake
|
||||
med_icons = sortList(med_icons)
|
||||
var/med_borg_icon = show_radial_menu(R, R , med_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
|
||||
switch(med_borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "medical"
|
||||
if("Droid")
|
||||
@@ -391,6 +419,8 @@
|
||||
moduleselect_icon = "medihound"
|
||||
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
|
||||
dogborg = TRUE
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/engineering
|
||||
@@ -434,13 +464,31 @@
|
||||
|
||||
/obj/item/robot_module/engineering/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "Vale")
|
||||
if(R.client && (R.client.ckey in list("nezuli")))
|
||||
engymodels += "Alina"
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in engymodels
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
var/static/list/engi_icons
|
||||
if(!engi_icons)
|
||||
engi_icons = list(
|
||||
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "engineer"),
|
||||
"Default - Treads" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "engi-tread"),
|
||||
"Loader" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "loaderborg"),
|
||||
"Handy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "handyeng"),
|
||||
"Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekeng"),
|
||||
"Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "caneng"),
|
||||
"Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinaeng"),
|
||||
"Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "spidereng"),
|
||||
"Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyeng")
|
||||
)
|
||||
var/list/L = list("Pup Dozer" = "pupdozer", "Vale" = "valeeng")
|
||||
for(var/a in L)
|
||||
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
|
||||
wide.pixel_x = -16
|
||||
engi_icons[a] = wide
|
||||
if(R.client && R.client.ckey == "nezuli")
|
||||
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-eng")
|
||||
bad_snowflake.pixel_x = -16
|
||||
engi_icons["Alina"] = bad_snowflake
|
||||
engi_icons = sortList(engi_icons)
|
||||
var/engi_borg_icon = show_radial_menu(R, R , engi_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
|
||||
switch(engi_borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "engineer"
|
||||
if("Default - Treads")
|
||||
@@ -485,6 +533,8 @@
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
sleeper_overlay = "alinasleeper"
|
||||
dogborg = TRUE
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/security
|
||||
@@ -512,13 +562,29 @@
|
||||
|
||||
/obj/item/robot_module/security/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/list/secmodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Can", "Marina", "Spider", "K9", "K9 Dark", "Vale")
|
||||
if(R.client && (R.client.ckey in list("nezuli")))
|
||||
secmodels += "Alina"
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in secmodels
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
var/static/list/sec_icons
|
||||
if(!sec_icons)
|
||||
sec_icons = list(
|
||||
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "sec"),
|
||||
"Default - Treads" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sec-tread"),
|
||||
"Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleeksec"),
|
||||
"Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "cansec"),
|
||||
"Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinasec"),
|
||||
"Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "spidersec"),
|
||||
"Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavysec")
|
||||
)
|
||||
var/list/L = list("K9" = "k9", "Vale" = "valesec", "K9 Dark" = "k9dark")
|
||||
for(var/a in L)
|
||||
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
|
||||
wide.pixel_x = -16
|
||||
sec_icons[a] = wide
|
||||
if(R.client && R.client.ckey == "nezuli")
|
||||
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-sec")
|
||||
bad_snowflake.pixel_x = -16
|
||||
sec_icons["Alina"] = bad_snowflake
|
||||
sec_icons = sortList(sec_icons)
|
||||
var/sec_borg_icon = show_radial_menu(R, R , sec_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
|
||||
switch(sec_borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "sec"
|
||||
if("Default - Treads")
|
||||
@@ -561,6 +627,8 @@
|
||||
sleeper_overlay = "valesecsleeper"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
dogborg = TRUE
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/security/Initialize()
|
||||
@@ -599,10 +667,13 @@
|
||||
|
||||
/obj/item/robot_module/peacekeeper/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Spider", "Borgi")
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
var/static/list/peace_icons = sortList(list(
|
||||
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "peace"),
|
||||
"Borgi" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "borgi"),
|
||||
"Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "whitespider")
|
||||
))
|
||||
var/peace_borg_icon = show_radial_menu(R, R , peace_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
|
||||
switch(peace_borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "peace"
|
||||
if("Spider")
|
||||
@@ -615,6 +686,8 @@
|
||||
hat_offset = INFINITY
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
//Janitor module combined with Service module
|
||||
@@ -738,10 +811,35 @@
|
||||
|
||||
/obj/item/robot_module/butler/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("(Service) Waitress", "(Service) Heavy", "(Service) Sleek", "(Service) Butler", "(Service) Tophat", "(Service) Can", "(Service) Bro", "(Service) DarkK9", "(Service) Vale", "(Service) ValeDark", "(Janitor) Default", "(Janitor) Sleek", "(Janitor) Marina", "(Janitor) Can", "(Janitor) Heavy", "(Janitor) Scrubpuppy")
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
var/static/list/service_icons
|
||||
if(!service_icons)
|
||||
service_icons = list(
|
||||
"(Service) Waitress" = image(icon = 'icons/mob/robots.dmi', icon_state = "service_f"),
|
||||
"(Service) Butler" = image(icon = 'icons/mob/robots.dmi', icon_state = "service_m"),
|
||||
"(Service) Bro" = image(icon = 'icons/mob/robots.dmi', icon_state = "brobot"),
|
||||
"(Service) Can" = image(icon = 'icons/mob/robots.dmi', icon_state = "kent"),
|
||||
"(Service) Tophat" = image(icon = 'icons/mob/robots.dmi', icon_state = "tophat"),
|
||||
"(Service) Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekserv"),
|
||||
"(Service) Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyserv"),
|
||||
"(Janitor) Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "janitor"),
|
||||
"(Janitor) Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinajan"),
|
||||
"(Janitor) Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekjan"),
|
||||
"(Janitor) Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "canjan"),
|
||||
"(Janitor) Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyjan"),
|
||||
)
|
||||
var/list/L = list("(Service) DarkK9" = "k50", "(Service) Vale" = "valeserv", "(Service) ValeDark" = "valeservdark",
|
||||
"(Janitor) Scrubpuppy" = "scrubpup")
|
||||
for(var/a in L)
|
||||
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
|
||||
wide.pixel_x = -16
|
||||
service_icons[a] = wide
|
||||
if(R.client && R.client.ckey == "nezuli")
|
||||
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-sec")
|
||||
bad_snowflake.pixel_x = -16
|
||||
service_icons["Alina"] = bad_snowflake
|
||||
service_icons = sortList(service_icons)
|
||||
var/service_robot_icon = show_radial_menu(R, R , service_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
|
||||
switch(service_robot_icon)
|
||||
if("(Service) Waitress")
|
||||
cyborg_base_icon = "service_f"
|
||||
special_light_key = "service"
|
||||
@@ -799,6 +897,8 @@
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
sleeper_overlay = "jsleeper"
|
||||
dogborg = TRUE
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/miner
|
||||
@@ -833,10 +933,25 @@
|
||||
|
||||
/obj/item/robot_module/miner/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Heavy", "Sleek", "Marina", "Can", "Spider", "Asteroid", "Droid", "Blade", "Vale")
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
var/static/list/mining_icons
|
||||
if(!mining_icons)
|
||||
mining_icons = list(
|
||||
"Lavaland" = image(icon = 'icons/mob/robots.dmi', icon_state = "miner"),
|
||||
"Asteroid" = image(icon = 'icons/mob/robots.dmi', icon_state = "minerOLD"),
|
||||
"Droid" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "miner"),
|
||||
"Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekmin"),
|
||||
"Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinamin"),
|
||||
"Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "canmin"),
|
||||
"Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavymin"),
|
||||
)
|
||||
var/list/L = list("Blade" = "blade", "Vale" = "valemine")
|
||||
for(var/a in L)
|
||||
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
|
||||
wide.pixel_x = -16
|
||||
mining_icons[a] = wide
|
||||
mining_icons = sortList(mining_icons)
|
||||
var/mining_borg_icon = show_radial_menu(R, R , mining_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
|
||||
switch(mining_borg_icon)
|
||||
if("Lavaland")
|
||||
cyborg_base_icon = "miner"
|
||||
if("Asteroid")
|
||||
@@ -871,6 +986,8 @@
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
sleeper_overlay = "valeminesleeper"
|
||||
dogborg = TRUE
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/syndicate
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/mob/living/silicon/KnockToFloor(disarm_items = FALSE, silent = TRUE, updating = TRUE)
|
||||
return
|
||||
|
||||
/mob/living/silicon/grippedby(mob/living/user, instant = FALSE)
|
||||
return //can't upgrade a simple pull into a more aggressive grab.
|
||||
@@ -113,7 +115,7 @@
|
||||
/mob/living/silicon/bullet_act(obj/item/projectile/P, def_zone)
|
||||
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
|
||||
var/list/returnlist = list()
|
||||
var/returned = run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
|
||||
var/returned = mob_run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
|
||||
if(returned & BLOCK_SHOULD_REDIRECT)
|
||||
handle_projectile_attack_redirection(P, returnlist[BLOCK_RETURN_REDIRECT_METHOD])
|
||||
if(returned & BLOCK_REDIRECTED)
|
||||
|
||||
@@ -61,11 +61,10 @@
|
||||
"<span class='userdanger'>[M] [response_disarm] [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
log_combat(M, src, "disarmed")
|
||||
else
|
||||
var/damage = rand(15, 30)
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed at [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
attack_threshold_check(damage)
|
||||
attack_threshold_check(M.meleeSlashSAPower)
|
||||
log_combat(M, src, "attacked")
|
||||
|
||||
/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
|
||||
@@ -911,7 +911,6 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
bot_name = name
|
||||
name = paicard.pai.name
|
||||
faction = user.faction.Copy()
|
||||
language_holder = paicard.pai.language_holder.copy(src)
|
||||
log_combat(user, paicard.pai, "uploaded to [bot_name],")
|
||||
return TRUE
|
||||
else
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
path_image_color = "#993299"
|
||||
weather_immunities = list("lava","ash")
|
||||
|
||||
var/clean_time = 50 //How long do we take to clean?
|
||||
var/broom = FALSE //Do we have an speed buff from a broom?
|
||||
var/adv_mop = FALSE //Do we have a cleaning buff from a better mop?
|
||||
|
||||
|
||||
var/blood = 1
|
||||
var/trash = 0
|
||||
var/pests = 0
|
||||
@@ -75,6 +80,26 @@
|
||||
to_chat(user, "<span class='warning'>Please close the access panel before locking it.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\The [src] doesn't seem to respect your authority.</span>")
|
||||
|
||||
if(istype(W, /obj/item/mop/advanced))
|
||||
if(bot_core.allowed(user) && open && adv_mop == TRUE)
|
||||
to_chat(user, "<span class='notice'>You replace \the [src] old mop with a new better one!</span>")
|
||||
adv_mop = TRUE
|
||||
clean_time = 20 //2.5 the speed!
|
||||
window_name = "Automatic Station Cleaner v2.1 BETA" //New!
|
||||
qdel(W)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\the [src] already has this mop!</span>")
|
||||
|
||||
if(istype(W, /obj/item/twohanded/broom))
|
||||
if(bot_core.allowed(user) && open && broom == TRUE)
|
||||
to_chat(user, "<span class='notice'>You add to \the [src] a broom speeding it up!</span>")
|
||||
broom = TRUE
|
||||
base_speed = 1 //2x faster!
|
||||
qdel(W)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\the [src] already has a broom!</span>")
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -221,7 +246,7 @@
|
||||
icon_state = "cleanbot-c"
|
||||
visible_message("<span class='notice'>[src] begins to clean up [A].</span>")
|
||||
mode = BOT_CLEANING
|
||||
spawn(50)
|
||||
spawn(clean_time)
|
||||
if(mode == BOT_CLEANING)
|
||||
if(A && isturf(A.loc))
|
||||
var/atom/movable/AM = A
|
||||
|
||||
@@ -147,9 +147,8 @@
|
||||
to_chat(user, "<span class='warning'>You need one length of cable to wire the ED-209!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start to wire [src]...</span>")
|
||||
if(do_after(user, 40, target = src))
|
||||
if(coil.get_amount() >= 1 && build_step == 6)
|
||||
coil.use(1)
|
||||
if(coil.use_tool(src, user, 40, 1))
|
||||
if(build_step == 6)
|
||||
to_chat(user, "<span class='notice'>You wire [src].</span>")
|
||||
name = "wired ED-209 assembly"
|
||||
build_step++
|
||||
|
||||
@@ -264,6 +264,9 @@
|
||||
if((last_newpatient_speak + 300) < world.time) //Don't spam these messages!
|
||||
var/list/messagevoice = list("Hey, [H.name]! Hold on, I'm coming." = 'sound/voice/medbot/coming.ogg',"Wait [H.name]! I want to help!" = 'sound/voice/medbot/help.ogg',"[H.name], you appear to be injured!" = 'sound/voice/medbot/injured.ogg')
|
||||
var/message = pick(messagevoice)
|
||||
if(prob(1) && ISINRANGE_EX(H.getFireLoss(), 0, 20))
|
||||
message = "Notices your minor burns*OwO what's this?"
|
||||
messagevoice[message] = 'sound/voice/medbot/owo.ogg'
|
||||
speak(message)
|
||||
playsound(loc, messagevoice[message], 50, 0)
|
||||
last_newpatient_speak = world.time
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
uniform = /obj/item/clothing/under/syndicate
|
||||
suit = /obj/item/clothing/suit/armor/vest
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
gloves = /obj/item/clothing/gloves/tackler/combat/insulated
|
||||
ears = /obj/item/radio/headset
|
||||
mask = /obj/item/clothing/mask/gas
|
||||
head = /obj/item/clothing/head/helmet/swat
|
||||
@@ -39,7 +39,7 @@
|
||||
uniform = /obj/item/clothing/under/syndicate
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
gloves = /obj/item/clothing/gloves/tackler/combat/insulated
|
||||
ears = /obj/item/radio/headset
|
||||
mask = /obj/item/clothing/mask/gas/syndicate
|
||||
back = /obj/item/tank/jetpack/oxygen
|
||||
@@ -59,7 +59,7 @@
|
||||
uniform = /obj/item/clothing/under/syndicate
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/syndi/elite
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
gloves = /obj/item/clothing/gloves/tackler/combat
|
||||
ears = /obj/item/radio/headset
|
||||
mask = /obj/item/clothing/mask/gas/syndicate
|
||||
back = /obj/item/tank/jetpack/oxygen/harness
|
||||
@@ -130,7 +130,7 @@
|
||||
uniform = /obj/item/clothing/under/syndicate/camo
|
||||
suit = /obj/item/clothing/suit/armor/bulletproof
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
gloves = /obj/item/clothing/gloves/tackler/combat
|
||||
ears = /obj/item/radio/headset
|
||||
head = /obj/item/clothing/head/helmet/alt
|
||||
mask = /obj/item/clothing/mask/balaclava
|
||||
@@ -177,7 +177,7 @@
|
||||
uniform = /obj/item/clothing/under/rank/security/officer
|
||||
suit = /obj/item/clothing/suit/armor/vest
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
gloves = /obj/item/clothing/gloves/tackler/combat
|
||||
ears = /obj/item/radio/headset
|
||||
mask = /obj/item/clothing/mask/gas/sechailer/swat
|
||||
head = /obj/item/clothing/head/helmet/swat/nanotrasen
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/mob/living/simple_animal/proc/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
bruteloss = round(CLAMP(bruteloss + amount, 0, maxHealth),DAMAGE_PRECISION)
|
||||
bruteloss = round(clamp(bruteloss + amount, 0, maxHealth),DAMAGE_PRECISION)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
|
||||
@@ -87,7 +87,6 @@
|
||||
pass_flags = PASSMOB
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
collar_type = "kitten"
|
||||
held_icon = "cat"
|
||||
|
||||
//RUNTIME IS ALIVE! SQUEEEEEEEE~
|
||||
/mob/living/simple_animal/pet/cat/Runtime
|
||||
@@ -99,6 +98,7 @@
|
||||
gender = FEMALE
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
unique_pet = TRUE
|
||||
held_icon = "cat"
|
||||
var/list/family = list()//var restored from savefile, has count of each child type
|
||||
var/list/children = list()//Actual mob instances of children
|
||||
var/cats_deployed = 0
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
blood_volume = 350
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/rawcrab = 1)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/rawcrab = 4)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "stomps"
|
||||
|
||||
@@ -97,6 +97,8 @@
|
||||
body_color = "brown"
|
||||
icon_state = "mouse_brown"
|
||||
|
||||
GLOBAL_VAR(tom_existed)
|
||||
|
||||
//TOM IS ALIVE! SQUEEEEEEEE~K :)
|
||||
/mob/living/simple_animal/mouse/brown/Tom
|
||||
name = "Tom"
|
||||
@@ -106,6 +108,10 @@
|
||||
response_harm = "splats"
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
|
||||
/mob/living/simple_animal/mouse/brown/Tom/Initialize()
|
||||
. = ..()
|
||||
GLOB.tom_existed = TRUE
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/deadmouse
|
||||
name = "dead mouse"
|
||||
desc = "It looks like somebody dropped the bass on it. A lizard's favorite meal."
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
var/blocked = FALSE
|
||||
if(hasmatchingsummoner(hit_atom)) //if the summoner matches don't hurt them
|
||||
blocked = TRUE
|
||||
if(L.run_block(src, 90, "[name]", ATTACK_TYPE_TACKLE, 0, src) & BLOCK_SUCCESS)
|
||||
if(L.mob_run_block(src, 90, "[name]", ATTACK_TYPE_TACKLE, 0, src, null, null) & BLOCK_SUCCESS)
|
||||
blocked = TRUE
|
||||
if(!blocked)
|
||||
L.drop_all_held_items()
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
AddElement(/datum/element/cleaning)
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/maid/AttackingTarget()
|
||||
if(ismovableatom(target))
|
||||
if(ismovable(target))
|
||||
if(istype(target, /obj/effect/decal/cleanable))
|
||||
visible_message("[src] cleans up \the [target].")
|
||||
qdel(target)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
icon_living = "carp"
|
||||
icon_dead = "carp_dead"
|
||||
icon_gib = "carp_gib"
|
||||
threat = 0.2
|
||||
threat = 0.1
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
speak_chance = 0
|
||||
turns_per_move = 5
|
||||
|
||||
@@ -186,10 +186,10 @@
|
||||
. = ..()
|
||||
if(slowed_by_webs)
|
||||
if(!(locate(/obj/structure/spider/stickyweb) in loc))
|
||||
remove_movespeed_modifier(MOVESPEED_ID_TARANTULA_WEB)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/tarantula_web)
|
||||
slowed_by_webs = FALSE
|
||||
else if(locate(/obj/structure/spider/stickyweb) in loc)
|
||||
add_movespeed_modifier(MOVESPEED_ID_TARANTULA_WEB, priority=100, multiplicative_slowdown=3)
|
||||
add_movespeed_modifier(/datum/movespeed_modifier/tarantula_web)
|
||||
slowed_by_webs = TRUE
|
||||
|
||||
//midwives are the queen of the spiders, can send messages to all them and web faster. That rare round where you get a queen spider and turn your 'for honor' players into 'r6siege' players will be a fun one.
|
||||
|
||||
@@ -265,4 +265,12 @@ Difficulty: Medium
|
||||
desc = "The sweet blood, oh, it sings to me."
|
||||
invisibility = 100
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/doom
|
||||
name = "hostile-environment miner"
|
||||
desc = "A miner destined to hop across dimensions for all eternity, hunting anomalous creatures."
|
||||
speed = 8
|
||||
move_to_delay = 8
|
||||
ranged_cooldown_time = 8
|
||||
dash_cooldown = 8
|
||||
|
||||
#undef MINER_DASH_RANGE
|
||||
|
||||
@@ -65,10 +65,10 @@ Difficulty: Hard
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/Life()
|
||||
..()
|
||||
move_to_delay = CLAMP(round((health/maxHealth) * 10), 3, 10)
|
||||
move_to_delay = clamp(round((health/maxHealth) * 10), 3, 10)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire()
|
||||
anger_modifier = CLAMP(((maxHealth - health)/50),0,20)
|
||||
anger_modifier = clamp(((maxHealth - health)/50),0,20)
|
||||
if(charging)
|
||||
return
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
|
||||
@@ -56,7 +56,7 @@ Difficulty: Very Hard
|
||||
L.dust()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/colossus/OpenFire()
|
||||
anger_modifier = CLAMP(((maxHealth - health)/50),0,20)
|
||||
anger_modifier = clamp(((maxHealth - health)/50),0,20)
|
||||
ranged_cooldown = world.time + 120
|
||||
|
||||
if(enrage(target))
|
||||
|
||||
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
Difficulty: Extremely Hard
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner
|
||||
name = "demonic-frost miner"
|
||||
desc = "An extremely geared miner, driven crazy or possessed by the demonic forces here, either way a terrifying enemy."
|
||||
health = 1500
|
||||
maxHealth = 1500
|
||||
icon_state = "demonic_miner"
|
||||
icon_living = "demonic_miner"
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
attacktext = "pummels"
|
||||
attack_sound = 'sound/weapons/sonic_jackhammer.ogg'
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
light_color = "#E4C7C5"
|
||||
movement_type = GROUND
|
||||
weather_immunities = list("snow")
|
||||
speak_emote = list("roars")
|
||||
armour_penetration = 100
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 10
|
||||
aggro_vision_range = 18 // large vision range so combat doesn't abruptly end when someone runs a bit away
|
||||
rapid_melee = 4
|
||||
speed = 20
|
||||
move_to_delay = 20
|
||||
ranged = TRUE
|
||||
crusher_loot = list(/obj/effect/decal/remains/plasma, /obj/item/crusher_trophy/ice_block_talisman)
|
||||
loot = list(/obj/effect/decal/remains/plasma)
|
||||
wander = FALSE
|
||||
del_on_death = TRUE
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
deathmessage = "falls to the ground, decaying into plasma particles."
|
||||
deathsound = "bodyfall"
|
||||
attack_action_types = list(/datum/action/innate/megafauna_attack/frost_orbs,
|
||||
/datum/action/innate/megafauna_attack/snowball_machine_gun,
|
||||
/datum/action/innate/megafauna_attack/ice_shotgun)
|
||||
/// Modifies the speed of the projectiles the demonic frost miner shoots out
|
||||
var/projectile_speed_multiplier = 1
|
||||
/// If the demonic frost miner is in its enraged state
|
||||
var/enraged = FALSE
|
||||
/// If the demonic frost miner is currently transforming to its enraged state
|
||||
var/enraging = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/knockback, 7, FALSE, TRUE)
|
||||
AddComponent(/datum/component/lifesteal, 50)
|
||||
|
||||
/datum/action/innate/megafauna_attack/frost_orbs
|
||||
name = "Fire Frost Orbs"
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "sniper_zoom"
|
||||
chosen_message = "<span class='colossus'>You are now sending out frost orbs to track in on a target.</span>"
|
||||
chosen_attack_num = 1
|
||||
|
||||
/datum/action/innate/megafauna_attack/snowball_machine_gun
|
||||
name = "Fire Snowball Machine Gun"
|
||||
icon_icon = 'icons/obj/guns/energy.dmi'
|
||||
button_icon_state = "kineticgun"
|
||||
chosen_message = "<span class='colossus'>You are now firing a snowball machine gun at a target.</span>"
|
||||
chosen_attack_num = 2
|
||||
|
||||
/datum/action/innate/megafauna_attack/ice_shotgun
|
||||
name = "Fire Ice Shotgun"
|
||||
icon_icon = 'icons/obj/guns/projectile.dmi'
|
||||
button_icon_state = "shotgun"
|
||||
chosen_message = "<span class='colossus'>You are now firing shotgun ice blasts.</span>"
|
||||
chosen_attack_num = 3
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/OpenFire()
|
||||
check_enraged()
|
||||
projectile_speed_multiplier = 1 - enraged * 0.25
|
||||
SetRecoveryTime(100, 100)
|
||||
|
||||
if(client)
|
||||
switch(chosen_attack)
|
||||
if(1)
|
||||
frost_orbs()
|
||||
if(2)
|
||||
snowball_machine_gun()
|
||||
if(3)
|
||||
ice_shotgun()
|
||||
return
|
||||
|
||||
var/easy_attack = prob(80 - enraged * 40)
|
||||
chosen_attack = rand(1, 3)
|
||||
switch(chosen_attack)
|
||||
if(1)
|
||||
if(easy_attack)
|
||||
frost_orbs(10, 8)
|
||||
else
|
||||
frost_orbs(5, 16)
|
||||
if(2)
|
||||
if(easy_attack)
|
||||
snowball_machine_gun()
|
||||
else
|
||||
INVOKE_ASYNC(src, .proc/ice_shotgun, 5, list(list(-180, -140, -100, -60, -20, 20, 60, 100, 140), list(-160, -120, -80, -40, 0, 40, 80, 120, 160)))
|
||||
snowball_machine_gun(5 * 8, 5)
|
||||
if(3)
|
||||
if(easy_attack)
|
||||
ice_shotgun()
|
||||
else
|
||||
ice_shotgun(5, list(list(0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330), list(-30, -15, 0, 15, 30)))
|
||||
|
||||
/obj/item/projectile/frost_orb
|
||||
name = "frost orb"
|
||||
icon_state = "ice_1"
|
||||
damage = 20
|
||||
armour_penetration = 100
|
||||
speed = 10
|
||||
homing_turn_speed = 30
|
||||
damage_type = BURN
|
||||
|
||||
/obj/item/projectile/frost_orb/on_hit(atom/target, blocked = FALSE)
|
||||
. = ..()
|
||||
if(isturf(target) || isobj(target))
|
||||
target.ex_act(EXPLODE_HEAVY)
|
||||
|
||||
/obj/item/projectile/snowball
|
||||
name = "machine-gun snowball"
|
||||
icon_state = "nuclear_particle"
|
||||
damage = 5
|
||||
armour_penetration = 100
|
||||
speed = 4
|
||||
damage_type = BRUTE
|
||||
|
||||
/obj/item/projectile/ice_blast
|
||||
name = "ice blast"
|
||||
icon_state = "ice_2"
|
||||
damage = 15
|
||||
armour_penetration = 100
|
||||
speed = 4
|
||||
damage_type = BRUTE
|
||||
|
||||
/obj/item/projectile/ice_blast/on_hit(atom/target, blocked = FALSE)
|
||||
. = ..()
|
||||
if(isturf(target) || isobj(target))
|
||||
target.ex_act(EXPLODE_HEAVY)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/ex_act(severity, target)
|
||||
adjustBruteLoss(30 * severity - 120)
|
||||
visible_message("<span class='danger'>[src] absorbs the explosion!</span>", "<span class='userdanger'>You absorb the explosion!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/Goto(target, delay, minimum_distance)
|
||||
if(enraging)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/MoveToTarget(list/possible_targets)
|
||||
if(enraging)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/Move()
|
||||
if(enraging)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/// Shoots out homing frost orbs that explode into ice blast projectiles after a couple seconds
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/proc/frost_orbs(added_delay = 10, shoot_times = 8)
|
||||
for(var/i in 1 to shoot_times)
|
||||
var/turf/startloc = get_turf(src)
|
||||
var/turf/endloc = get_turf(target)
|
||||
if(!endloc)
|
||||
break
|
||||
var/obj/item/projectile/frost_orb/P = new(startloc)
|
||||
P.preparePixelProjectile(endloc, startloc)
|
||||
P.firer = src
|
||||
if(target)
|
||||
P.original = target
|
||||
P.set_homing_target(target)
|
||||
P.fire(rand(0, 360))
|
||||
addtimer(CALLBACK(P, /obj/item/projectile/frost_orb/proc/orb_explosion, projectile_speed_multiplier), 20) // make the orbs home in after a second
|
||||
SLEEP_CHECK_DEATH(added_delay)
|
||||
SetRecoveryTime(40, 60)
|
||||
|
||||
/// Called when the orb is exploding, shoots out projectiles
|
||||
/obj/item/projectile/frost_orb/proc/orb_explosion(projectile_speed_multiplier)
|
||||
for(var/i in 0 to 5)
|
||||
var/angle = i * 60
|
||||
var/turf/startloc = get_turf(src)
|
||||
var/turf/endloc = get_turf(original)
|
||||
if(!startloc || !endloc)
|
||||
break
|
||||
var/obj/item/projectile/ice_blast/P = new(startloc)
|
||||
P.speed *= projectile_speed_multiplier
|
||||
P.preparePixelProjectile(endloc, startloc, null, angle + rand(-10, 10))
|
||||
P.firer = firer
|
||||
if(original)
|
||||
P.original = original
|
||||
P.fire()
|
||||
qdel(src)
|
||||
|
||||
/// Shoots out snowballs with a random spread
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/proc/snowball_machine_gun(shots = 60, spread = 45)
|
||||
for(var/i in 1 to shots)
|
||||
var/turf/startloc = get_turf(src)
|
||||
var/turf/endloc = get_turf(target)
|
||||
if(!endloc)
|
||||
break
|
||||
var/obj/item/projectile/P = new /obj/item/projectile/snowball(startloc)
|
||||
P.speed *= projectile_speed_multiplier
|
||||
P.preparePixelProjectile(endloc, startloc, null, rand(-spread, spread))
|
||||
P.firer = src
|
||||
if(target)
|
||||
P.original = target
|
||||
P.fire()
|
||||
SLEEP_CHECK_DEATH(1)
|
||||
SetRecoveryTime(15, 15)
|
||||
|
||||
/// Shoots out ice blasts in a shotgun like pattern
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/proc/ice_shotgun(shots = 5, list/patterns = list(list(-40, -20, 0, 20, 40), list(-30, -10, 10, 30)))
|
||||
for(var/i in 1 to shots)
|
||||
var/list/pattern = patterns[i % length(patterns) + 1] // alternating patterns
|
||||
for(var/spread in pattern)
|
||||
var/turf/startloc = get_turf(src)
|
||||
var/turf/endloc = get_turf(target)
|
||||
if(!endloc)
|
||||
break
|
||||
var/obj/item/projectile/P = new /obj/item/projectile/ice_blast(startloc)
|
||||
P.speed *= projectile_speed_multiplier
|
||||
P.preparePixelProjectile(endloc, startloc, null, spread)
|
||||
P.firer = src
|
||||
if(target)
|
||||
P.original = target
|
||||
P.fire()
|
||||
SLEEP_CHECK_DEATH(8)
|
||||
SetRecoveryTime(15, 20)
|
||||
|
||||
/// Checks if the demonic frost miner is ready to be enraged
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/proc/check_enraged()
|
||||
if(enraged)
|
||||
return
|
||||
if(health > maxHealth*0.25)
|
||||
return
|
||||
SetRecoveryTime(80, 80)
|
||||
adjustHealth(-maxHealth)
|
||||
enraged = TRUE
|
||||
enraging = TRUE
|
||||
animate(src, pixel_y = pixel_y + 96, time = 100, easing = ELASTIC_EASING)
|
||||
spin(100, 10)
|
||||
SLEEP_CHECK_DEATH(60)
|
||||
playsound(src, 'sound/effects/explosion3.ogg', 100, TRUE)
|
||||
icon_state = "demonic_miner_phase2"
|
||||
animate(src, pixel_y = pixel_y - 96, time = 8, flags = ANIMATION_END_NOW)
|
||||
spin(8, 2)
|
||||
SLEEP_CHECK_DEATH(8)
|
||||
for(var/mob/living/L in viewers(src))
|
||||
shake_camera(L, 3, 2)
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE)
|
||||
setMovetype(movement_type | FLYING)
|
||||
enraging = FALSE
|
||||
adjustHealth(-maxHealth)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/death(gibbed, list/force_grant)
|
||||
if(health > 0)
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
var/loot = rand(1, 3)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/resurrection_crystal(T)
|
||||
if(2)
|
||||
new /obj/item/clothing/shoes/winterboots/ice_boots/speedy(T)
|
||||
if(3)
|
||||
new /obj/item/pickaxe/drill/jackhammer/demonic(T)
|
||||
return ..()
|
||||
|
||||
/obj/item/resurrection_crystal
|
||||
name = "resurrection crystal"
|
||||
desc = "When used by anything holding it, this crystal gives them a second chance at life if they die."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "demonic_crystal"
|
||||
|
||||
/obj/item/resurrection_crystal/attack_self(mob/living/user)
|
||||
if(!iscarbon(user))
|
||||
to_chat(user, "<span class='notice'>A dark presence stops you from absorbing the crystal.</span>")
|
||||
return
|
||||
forceMove(user)
|
||||
to_chat(user, "<span class='notice'>You feel a bit safer... but a demonic presence lurks in the back of your head...</span>")
|
||||
RegisterSignal(user, COMSIG_MOB_DEATH, .proc/resurrect)
|
||||
|
||||
/// Resurrects the target when they die by cloning them into a new duplicate body and transferring their mind to the clone on a safe station turf
|
||||
/obj/item/resurrection_crystal/proc/resurrect(mob/living/carbon/user, gibbed)
|
||||
user.visible_message("<span class='notice'>You see [user]'s soul dragged out of their body!</span>", "<span class='notice'>You feel your soul dragged away to a fresh body!</span>")
|
||||
var/typepath = user.type
|
||||
var/turf/T = find_safe_turf()
|
||||
var/mob/living/carbon/clone = new typepath(T)
|
||||
clone.real_name = user.real_name
|
||||
user.dna.transfer_identity(clone)
|
||||
clone.updateappearance(mutcolor_update=1)
|
||||
user.mind.transfer_to(clone) // second life
|
||||
to_chat(clone, "<span class='notice'>You blink and find yourself in [get_area_name(T)].</span>")
|
||||
user.gib()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/shoes/winterboots/ice_boots/speedy
|
||||
name = "cursed ice hiking boots"
|
||||
desc = "A pair of winter boots contractually made by a devil, they cannot be taken off once put on."
|
||||
slowdown = SHOES_SPEED_SLIGHT
|
||||
|
||||
/obj/item/clothing/shoes/winterboots/ice_boots/speedy/Initialize()
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CURSED_ITEM_TRAIT)
|
||||
|
||||
/obj/item/pickaxe/drill/jackhammer/demonic
|
||||
name = "demonic jackhammer"
|
||||
desc = "Cracks rocks at an inhuman speed, as well as being enhanced for combat purposes."
|
||||
toolspeed = 0
|
||||
|
||||
/obj/item/pickaxe/drill/jackhammer/demonic/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/knockback, 4, FALSE, TRUE)
|
||||
AddComponent(/datum/component/lifesteal, 5)
|
||||
|
||||
/obj/item/crusher_trophy/ice_block_talisman
|
||||
name = "ice block talisman"
|
||||
desc = "A glowing trinket that a demonic miner had on him, it seems he couldn't utilize it for whatever reason."
|
||||
icon_state = "ice_trap_talisman"
|
||||
denied_type = /obj/item/crusher_trophy/ice_block_talisman
|
||||
|
||||
/obj/item/crusher_trophy/ice_block_talisman/effect_desc()
|
||||
return "mark detonation to freeze a creature in a block of ice for a period, preventing them from moving"
|
||||
|
||||
/obj/item/crusher_trophy/ice_block_talisman/on_mark_detonation(mob/living/target, mob/living/user)
|
||||
target.apply_status_effect(/datum/status_effect/ice_block_talisman)
|
||||
|
||||
/datum/status_effect/ice_block_talisman
|
||||
id = "ice_block_talisman"
|
||||
duration = 25
|
||||
status_type = STATUS_EFFECT_REFRESH
|
||||
alert_type = /obj/screen/alert/status_effect/ice_block_talisman
|
||||
/// Stored icon overlay for the hit mob, removed when effect is removed
|
||||
var/icon/cube
|
||||
|
||||
/obj/screen/alert/status_effect/ice_block_talisman
|
||||
name = "Frozen Solid"
|
||||
desc = "You're frozen inside an ice cube, and cannot move!"
|
||||
icon_state = "frozen"
|
||||
|
||||
/datum/status_effect/ice_block_talisman/on_apply()
|
||||
RegisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE, .proc/owner_moved)
|
||||
if(!owner.stat)
|
||||
to_chat(owner, "<span class='userdanger'>You become frozen in a cube!</span>")
|
||||
cube = icon('icons/effects/freeze.dmi', "ice_cube")
|
||||
var/icon/size_check = icon(owner.icon, owner.icon_state)
|
||||
cube.Scale(size_check.Width(), size_check.Height())
|
||||
owner.add_overlay(cube)
|
||||
return ..()
|
||||
|
||||
/// Blocks movement from the status effect owner
|
||||
/datum/status_effect/ice_block_talisman/proc/owner_moved()
|
||||
return COMPONENT_MOVABLE_BLOCK_PRE_MOVE
|
||||
|
||||
/datum/status_effect/ice_block_talisman/on_remove()
|
||||
. = ..()
|
||||
if(!owner.stat)
|
||||
to_chat(owner, "<span class='notice'>The cube melts!</span>")
|
||||
owner.cut_overlay(cube)
|
||||
UnregisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE)
|
||||
@@ -105,7 +105,7 @@ Difficulty: Medium
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/OpenFire()
|
||||
if(swooping)
|
||||
return
|
||||
anger_modifier = CLAMP(((maxHealth - health)/50),0,20)
|
||||
anger_modifier = clamp(((maxHealth - health)/50),0,20)
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
|
||||
if(prob(15 + anger_modifier) && !client)
|
||||
@@ -394,3 +394,26 @@ Difficulty: Medium
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/lesser/grant_achievement(medaltype,scoretype)
|
||||
return
|
||||
|
||||
//fire line keeps going even if dragon is deleted
|
||||
/proc/dragon_fire_line(source, list/turfs)
|
||||
var/list/hit_list = list()
|
||||
for(var/turf/T in turfs)
|
||||
if(istype(T, /turf/closed))
|
||||
break
|
||||
new /obj/effect/hotspot(T)
|
||||
T.hotspot_expose(700,50,1)
|
||||
for(var/mob/living/L in T.contents)
|
||||
if(L in hit_list || L == source)
|
||||
continue
|
||||
hit_list += L
|
||||
L.adjustFireLoss(20)
|
||||
to_chat(L, "<span class='userdanger'>You're hit by [source]'s fire breath!</span>")
|
||||
|
||||
// deals damage to mechs
|
||||
for(var/obj/mecha/M in T.contents)
|
||||
if(M in hit_list)
|
||||
continue
|
||||
hit_list += M
|
||||
M.take_damage(45, BRUTE, "melee", 1)
|
||||
sleep(1.5)
|
||||
|
||||
@@ -191,7 +191,7 @@ Difficulty: Normal
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/calculate_rage() //how angry we are overall
|
||||
did_reset = FALSE //oh hey we're doing SOMETHING, clearly we might need to heal if we recall
|
||||
anger_modifier = CLAMP(((maxHealth - health) / 42),0,50)
|
||||
anger_modifier = clamp(((maxHealth - health) / 42),0,50)
|
||||
burst_range = initial(burst_range) + round(anger_modifier * 0.08)
|
||||
beam_range = initial(beam_range) + round(anger_modifier * 0.12)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user