Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit685
This commit is contained in:
@@ -18,8 +18,6 @@
|
||||
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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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]")
|
||||
|
||||
@@ -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
|
||||
. = ..()
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
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>")
|
||||
|
||||
@@ -199,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>")
|
||||
@@ -540,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)
|
||||
@@ -551,6 +557,7 @@
|
||||
guts.throw_at(throw_target, power, 4, src)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/fully_replace_character_name(oldname,newname)
|
||||
..()
|
||||
if(dna)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -1049,15 +1050,19 @@
|
||||
/mob/living/carbon/human/updatehealth()
|
||||
. = ..()
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN))
|
||||
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_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)
|
||||
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(/datum/movespeed_modifier/damage_slowdown)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -24,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
|
||||
@@ -548,8 +545,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 = ""
|
||||
@@ -582,7 +581,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)
|
||||
@@ -597,21 +596,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)
|
||||
@@ -742,95 +737,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]"
|
||||
@@ -840,16 +845,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)
|
||||
@@ -883,9 +879,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
|
||||
@@ -894,14 +890,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]
|
||||
@@ -909,24 +898,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
|
||||
@@ -962,9 +935,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]
|
||||
@@ -973,7 +946,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
|
||||
@@ -1003,9 +976,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]
|
||||
@@ -1014,13 +987,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
|
||||
|
||||
|
||||
/*
|
||||
@@ -1032,21 +1004,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)
|
||||
@@ -1580,9 +1537,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)
|
||||
@@ -1712,9 +1666,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>")
|
||||
@@ -1730,24 +1685,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
|
||||
@@ -1832,7 +1777,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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,7 +31,6 @@ 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.
|
||||
@@ -40,7 +40,6 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
. = ..()
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,6 +84,7 @@
|
||||
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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -74,9 +74,10 @@
|
||||
/mob/living/carbon/monkey/updatehealth()
|
||||
. = ..()
|
||||
var/slow = 0
|
||||
var/health_deficiency = (100 - health)
|
||||
if(health_deficiency >= 45)
|
||||
slow += (health_deficiency / 25)
|
||||
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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
|
||||
@@ -75,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)
|
||||
@@ -84,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)
|
||||
|
||||
@@ -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
|
||||
. = ..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -115,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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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++
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -27,23 +27,51 @@
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1
|
||||
/// Crusher loot dropped when fauna killed with a crusher
|
||||
var/list/crusher_loot
|
||||
var/medal_type
|
||||
/// Score given to players when the fauna is killed
|
||||
var/score_type = BOSS_SCORE
|
||||
/// If the megafauna is actually killed (vs entering another phase)
|
||||
var/elimination = 0
|
||||
/// Modifies attacks when at lower health
|
||||
var/anger_modifier = 0
|
||||
/// Internal tracking GPS inside fauna
|
||||
var/obj/item/gps/internal
|
||||
/// Next time fauna can use a melee attack
|
||||
var/recovery_time = 0
|
||||
|
||||
var/true_spawn = TRUE // if this is a megafauna that should grant achievements, or have a gps signal
|
||||
var/nest_range = 10
|
||||
var/chosen_attack = 1 // chosen attack num
|
||||
var/list/attack_action_types = list()
|
||||
var/small_sprite_type
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/Initialize(mapload)
|
||||
. = ..()
|
||||
apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
|
||||
ADD_TRAIT(src, TRAIT_NO_TELEPORT, MEGAFAUNA_TRAIT)
|
||||
for(var/action_type in attack_action_types)
|
||||
var/datum/action/innate/megafauna_attack/attack_action = new action_type()
|
||||
attack_action.Grant(src)
|
||||
if(small_sprite_type)
|
||||
var/datum/action/small_sprite/small_action = new small_sprite_type()
|
||||
small_action.Grant(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/Destroy()
|
||||
QDEL_NULL(internal)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/Moved()
|
||||
if(nest && nest.parent && get_dist(nest.parent, src) > nest_range)
|
||||
var/turf/closest = get_turf(nest.parent)
|
||||
for(var/i = 1 to nest_range)
|
||||
closest = get_step(closest, get_dir(closest, src))
|
||||
forceMove(closest) // someone teleported out probably and the megafauna kept chasing them
|
||||
target = null
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/death(gibbed)
|
||||
if(health > 0)
|
||||
return
|
||||
@@ -134,3 +162,21 @@
|
||||
SSmedals.SetScore(BOSS_SCORE, C, 1)
|
||||
SSmedals.SetScore(score_type, C, 1)
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/megafauna_attack
|
||||
name = "Megafauna Attack"
|
||||
icon_icon = 'icons/mob/actions/actions_animal.dmi'
|
||||
button_icon_state = ""
|
||||
var/mob/living/simple_animal/hostile/megafauna/M
|
||||
var/chosen_message
|
||||
var/chosen_attack_num = 0
|
||||
|
||||
/datum/action/innate/megafauna_attack/Grant(mob/living/L)
|
||||
if(istype(L, /mob/living/simple_animal/hostile/megafauna))
|
||||
M = L
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
/datum/action/innate/megafauna_attack/Activate()
|
||||
M.chosen_attack = chosen_attack_num
|
||||
to_chat(M, chosen_message)
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
Difficulty: Hard
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo
|
||||
name = "wendigo"
|
||||
desc = "A mythological man-eating legendary creature, you probably aren't going to survive this."
|
||||
health = 2500
|
||||
maxHealth = 2500
|
||||
icon_state = "wendigo"
|
||||
icon_living = "wendigo"
|
||||
icon_dead = "wendigo_dead"
|
||||
icon = 'icons/mob/icemoon/64x64megafauna.dmi'
|
||||
attacktext = "claws"
|
||||
attack_sound = 'sound/magic/demon_attack1.ogg'
|
||||
weather_immunities = list("snow")
|
||||
speak_emote = list("roars")
|
||||
armour_penetration = 40
|
||||
melee_damage_lower = 40
|
||||
melee_damage_upper = 40
|
||||
vision_range = 9
|
||||
aggro_vision_range = 18 // man-eating for a reason
|
||||
speed = 8
|
||||
move_to_delay = 8
|
||||
rapid_melee = 16 // every 1/8 second
|
||||
melee_queue_distance = 20 // as far as possible really, need this because of charging and teleports
|
||||
ranged = TRUE
|
||||
pixel_x = -16
|
||||
loot = list(/obj/item/wendigo_blood)
|
||||
crusher_loot = list(/obj/item/wendigo_blood, /obj/item/crusher_trophy/demon_claws)
|
||||
wander = FALSE
|
||||
del_on_death = TRUE
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
deathmessage = "falls, shaking the ground around it"
|
||||
deathsound = 'sound/effects/gravhit.ogg'
|
||||
attack_action_types = list(/datum/action/innate/megafauna_attack/heavy_stomp,
|
||||
/datum/action/innate/megafauna_attack/teleport,
|
||||
/datum/action/innate/megafauna_attack/disorienting_scream)
|
||||
/// Saves the turf the megafauna was created at (spawns exit portal here)
|
||||
var/turf/starting
|
||||
/// Range for wendigo stomping when it moves
|
||||
var/stomp_range = 1
|
||||
/// Stores directions the mob is moving, then calls that a move has fully ended when these directions are removed in moved
|
||||
var/stored_move_dirs = 0
|
||||
/// If the wendigo is allowed to move
|
||||
var/can_move = TRUE
|
||||
|
||||
/datum/action/innate/megafauna_attack/heavy_stomp
|
||||
name = "Heavy Stomp"
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "sniper_zoom"
|
||||
chosen_message = "<span class='colossus'>You are now stomping the ground around you.</span>"
|
||||
chosen_attack_num = 1
|
||||
|
||||
/datum/action/innate/megafauna_attack/teleport
|
||||
name = "Teleport"
|
||||
icon_icon = 'icons/effects/bubblegum.dmi'
|
||||
button_icon_state = "smack ya one"
|
||||
chosen_message = "<span class='colossus'>You are now teleporting at the target you click on.</span>"
|
||||
chosen_attack_num = 2
|
||||
|
||||
/datum/action/innate/megafauna_attack/disorienting_scream
|
||||
name = "Disorienting Scream"
|
||||
icon_icon = 'icons/turf/walls/wall.dmi'
|
||||
button_icon_state = "wall"
|
||||
chosen_message = "<span class='colossus'>You are now screeching, disorienting targets around you.</span>"
|
||||
chosen_attack_num = 3
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/Initialize()
|
||||
. = ..()
|
||||
starting = get_turf(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/OpenFire()
|
||||
SetRecoveryTime(0, 100)
|
||||
if(health <= maxHealth*0.5)
|
||||
stomp_range = 2
|
||||
speed = 6
|
||||
move_to_delay = 6
|
||||
else
|
||||
stomp_range = initial(stomp_range)
|
||||
speed = initial(speed)
|
||||
move_to_delay = initial(move_to_delay)
|
||||
|
||||
if(client)
|
||||
switch(chosen_attack)
|
||||
if(1)
|
||||
heavy_stomp()
|
||||
if(2)
|
||||
teleport()
|
||||
if(3)
|
||||
disorienting_scream()
|
||||
return
|
||||
|
||||
chosen_attack = rand(1, 3)
|
||||
switch(chosen_attack)
|
||||
if(1)
|
||||
heavy_stomp()
|
||||
if(2)
|
||||
teleport()
|
||||
if(3)
|
||||
disorienting_scream()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/Move(atom/newloc, direct)
|
||||
if(!can_move)
|
||||
return
|
||||
stored_move_dirs |= direct
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/Moved(atom/oldloc, direct)
|
||||
. = ..()
|
||||
stored_move_dirs &= ~direct
|
||||
if(!stored_move_dirs)
|
||||
INVOKE_ASYNC(src, .proc/ground_slam, stomp_range, 1)
|
||||
|
||||
/// Slams the ground around the wendigo throwing back enemies caught nearby
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/proc/ground_slam(range, delay)
|
||||
var/turf/orgin = get_turf(src)
|
||||
var/list/all_turfs = RANGE_TURFS(range, orgin)
|
||||
for(var/i = 0 to range)
|
||||
for(var/turf/T in all_turfs)
|
||||
if(get_dist(orgin, T) > i)
|
||||
continue
|
||||
playsound(T,'sound/effects/bamf.ogg', 600, TRUE, 10)
|
||||
new /obj/effect/temp_visual/small_smoke/halfsecond(T)
|
||||
for(var/mob/living/L in T)
|
||||
if(L == src || L.throwing)
|
||||
continue
|
||||
to_chat(L, "<span class='userdanger'>[src]'s ground slam shockwave sends you flying!</span>")
|
||||
var/turf/thrownat = get_ranged_target_turf_direct(src, L, 8, rand(-10, 10))
|
||||
L.throw_at(thrownat, 8, 2, src, TRUE) //, force = MOVE_FORCE_OVERPOWERING, gentle = TRUE)
|
||||
L.apply_damage(20, BRUTE)
|
||||
shake_camera(L, 2, 1)
|
||||
all_turfs -= T
|
||||
sleep(delay)
|
||||
|
||||
/// Larger but slower ground stomp
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/proc/heavy_stomp()
|
||||
can_move = FALSE
|
||||
ground_slam(5, 2)
|
||||
SetRecoveryTime(0, 0)
|
||||
can_move = TRUE
|
||||
|
||||
/// Teleports to a location 4 turfs away from the enemy in view
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/proc/teleport()
|
||||
var/list/possible_ends = list()
|
||||
for(var/turf/T in view(4, target.loc) - view(3, target.loc))
|
||||
if(isclosedturf(T))
|
||||
continue
|
||||
possible_ends |= T
|
||||
var/turf/end = pick(possible_ends)
|
||||
do_teleport(src, end, 0, channel=TELEPORT_CHANNEL_BLUESPACE, forced = TRUE)
|
||||
SetRecoveryTime(20, 0)
|
||||
|
||||
/// Shakes all nearby enemies screens and animates the wendigo shaking up and down
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/proc/disorienting_scream()
|
||||
can_move = FALSE
|
||||
playsound(src, 'sound/magic/demon_dies.ogg', 600, FALSE, 10)
|
||||
animate(src, pixel_z = rand(5, 15), time = 1, loop = 6)
|
||||
animate(pixel_z = 0, time = 1)
|
||||
for(var/mob/living/L in get_hearers_in_view(7, src) - src)
|
||||
shake_camera(L, 30, 1)
|
||||
to_chat(L, "<span class='danger'>The wendigo screams loudly!</span>")
|
||||
SetRecoveryTime(30, 0)
|
||||
SLEEP_CHECK_DEATH(12)
|
||||
can_move = TRUE
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/death(gibbed, list/force_grant)
|
||||
if(health > 0)
|
||||
return
|
||||
var/obj/effect/portal/permanent/one_way/exit = new /obj/effect/portal/permanent/one_way(starting)
|
||||
exit.id = "wendigo arena exit"
|
||||
exit.add_atom_colour(COLOR_RED_LIGHT, ADMIN_COLOUR_PRIORITY)
|
||||
exit.set_light(20, 1, LIGHT_COLOR_RED)
|
||||
return ..()
|
||||
|
||||
/obj/item/wendigo_blood
|
||||
name = "bottle of wendigo blood"
|
||||
desc = "You're not actually going to drink this, are you?"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "vial"
|
||||
|
||||
/obj/item/wendigo_blood/attack_self(mob/living/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H.mind)
|
||||
return
|
||||
to_chat(H, "<span class='danger'>Power courses through you! You can now shift your form at will.</span>")
|
||||
var/obj/effect/proc_holder/spell/targeted/shapeshift/polar_bear/P = new
|
||||
H.mind.AddSpell(P)
|
||||
playsound(H.loc,'sound/items/drink.ogg', rand(10,50), TRUE)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/shapeshift/polar_bear
|
||||
name = "Polar Bear Form"
|
||||
desc = "Take on the shape of a polar bear."
|
||||
invocation = "RAAAAAAAAWR!"
|
||||
convert_damage = FALSE
|
||||
|
||||
shapeshift_type = /mob/living/simple_animal/hostile/asteroid/polarbear
|
||||
@@ -424,3 +424,29 @@
|
||||
l_pocket = /obj/item/reagent_containers/food/drinks/soda_cans/buzz_fuzz
|
||||
mask = /obj/item/clothing/mask/rat/bee
|
||||
. = ..()
|
||||
|
||||
// Snow Legion
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow
|
||||
name = "snow legion"
|
||||
desc = "You can still see what was once a human under the shifting snowy mass, clearly decorated by a clown."
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
icon_state = "snowlegion"
|
||||
icon_living = "snowlegion"
|
||||
icon_aggro = "snowlegion_alive"
|
||||
icon_dead = "snowlegion"
|
||||
crusher_loot = /obj/item/crusher_trophy/legion_skull
|
||||
loot = list(/obj/item/organ/regenerative_core/legion)
|
||||
brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/tendril
|
||||
fromtendril = TRUE
|
||||
|
||||
// Snow Legion skull
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow
|
||||
name = "snow legion"
|
||||
desc = "One of many."
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
icon_state = "snowlegion_head"
|
||||
icon_living = "snowlegion_head"
|
||||
icon_aggro = "snowlegion_head"
|
||||
icon_dead = "snowlegion_head"
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_demon
|
||||
name = "demonic watcher"
|
||||
desc = "A creature formed entirely out of ice, bluespace energy emanates from inside of it."
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
icon_state = "ice_demon"
|
||||
icon_living = "ice_demon"
|
||||
icon_dead = "ice_demon_dead"
|
||||
icon_gib = "syndicate_gib"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
speak_emote = list("telepathically cries")
|
||||
speed = 1
|
||||
move_to_delay = 2
|
||||
projectiletype = /obj/item/projectile/temp/basilisk/ice
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
ranged = TRUE
|
||||
ranged_message = "manifests ice"
|
||||
ranged_cooldown_time = 30
|
||||
minimum_distance = 3
|
||||
retreat_distance = 3
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
obj_damage = 40
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
attacktext = "slices"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
vision_range = 7
|
||||
aggro_vision_range = 7
|
||||
move_force = MOVE_FORCE_VERY_STRONG
|
||||
move_resist = MOVE_FORCE_VERY_STRONG
|
||||
pull_force = MOVE_FORCE_VERY_STRONG
|
||||
del_on_death = TRUE
|
||||
loot = list(/obj/item/stack/ore/bluespace_crystal = 3)
|
||||
crusher_loot = /obj/item/crusher_trophy/watcher_wing/ice_wing
|
||||
deathmessage = "fades as the energies that tied it to this world dissipate."
|
||||
deathsound = 'sound/magic/demon_dies.ogg'
|
||||
stat_attack = UNCONSCIOUS
|
||||
movement_type = FLYING
|
||||
robust_searching = TRUE
|
||||
/// Distance the demon will teleport from the target
|
||||
var/teleport_distance = 3
|
||||
|
||||
/obj/item/projectile/temp/basilisk/ice
|
||||
name = "ice blast"
|
||||
damage = 5
|
||||
nodamage = FALSE
|
||||
temperature = -75
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_demon/OpenFire()
|
||||
if(teleport_distance <= 0)
|
||||
return ..()
|
||||
var/list/possible_ends = list()
|
||||
for(var/turf/T in view(teleport_distance, target.loc) - view(teleport_distance - 1, target.loc))
|
||||
if(isclosedturf(T))
|
||||
continue
|
||||
possible_ends |= T
|
||||
var/turf/end = pick(possible_ends)
|
||||
do_teleport(src, end, 0, channel=TELEPORT_CHANNEL_BLUESPACE, forced = TRUE)
|
||||
SLEEP_CHECK_DEATH(8)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_demon/Life()
|
||||
. = ..()
|
||||
if(!. || target)
|
||||
return
|
||||
adjustHealth(-maxHealth*0.025)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_demon/death(gibbed)
|
||||
move_force = MOVE_FORCE_DEFAULT
|
||||
move_resist = MOVE_RESIST_DEFAULT
|
||||
pull_force = PULL_FORCE_DEFAULT
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && prob(5))
|
||||
new /obj/item/assembly/signaler/anomaly/bluespace(T)
|
||||
return ..()
|
||||
@@ -0,0 +1,54 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp
|
||||
name = "ice whelp"
|
||||
desc = "The offspring of an ice drake, weak in comparison but still terrifying."
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
icon_state = "ice_whelp"
|
||||
icon_living = "ice_whelp"
|
||||
icon_dead = "ice_whelp_dead"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
friendly = "stares down"
|
||||
speak_emote = list("roars")
|
||||
speed = 30
|
||||
move_to_delay = 30
|
||||
ranged = TRUE
|
||||
ranged_cooldown_time = 40
|
||||
maxHealth = 350
|
||||
health = 350
|
||||
obj_damage = 40
|
||||
armour_penetration = 20
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 20
|
||||
attacktext = "chomps"
|
||||
attack_sound = 'sound/magic/demon_attack1.ogg'
|
||||
vision_range = 9
|
||||
aggro_vision_range = 9
|
||||
move_force = MOVE_FORCE_VERY_STRONG
|
||||
move_resist = MOVE_FORCE_VERY_STRONG
|
||||
pull_force = MOVE_FORCE_VERY_STRONG
|
||||
butcher_results = list(/obj/item/stack/ore/diamond = 3, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 10, /obj/item/stack/sheet/animalhide/ashdrake = 1)
|
||||
loot = list()
|
||||
crusher_loot = /obj/item/crusher_trophy/tail_spike
|
||||
deathmessage = "collapses on it's side."
|
||||
deathsound = 'sound/magic/demon_dies.ogg'
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = TRUE
|
||||
/// How far the whelps fire can go
|
||||
var/fire_range = 4
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp/OpenFire()
|
||||
var/turf/T = get_ranged_target_turf_direct(src, target, fire_range)
|
||||
var/list/burn_turfs = getline(src, T) - get_turf(src)
|
||||
dragon_fire_line(src, burn_turfs)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp/Life()
|
||||
. = ..()
|
||||
if(!. || target)
|
||||
return
|
||||
adjustHealth(-maxHealth*0.025)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp/death(gibbed)
|
||||
move_force = MOVE_FORCE_DEFAULT
|
||||
move_resist = MOVE_RESIST_DEFAULT
|
||||
pull_force = PULL_FORCE_DEFAULT
|
||||
return ..()
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Aggro()
|
||||
..()
|
||||
if(vision_range != aggro_vision_range)
|
||||
if(vision_range == aggro_vision_range && icon_aggro)
|
||||
icon_state = icon_aggro
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/LoseAggro()
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear
|
||||
name = "polar bear"
|
||||
desc = "An aggressive animal that defends it's territory with incredible power. These beasts don't run from their enemies."
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
icon_state = "polarbear"
|
||||
icon_living = "polarbear"
|
||||
icon_dead = "polarbear_dead"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
friendly = "growls at"
|
||||
speak_emote = list("growls")
|
||||
speed = 12
|
||||
move_to_delay = 12
|
||||
maxHealth = 300
|
||||
health = 300
|
||||
obj_damage = 40
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 25
|
||||
attacktext = "claws"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
vision_range = 2 // don't aggro unless you basically antagonize it, though they will kill you worse than a goliath will
|
||||
aggro_vision_range = 9
|
||||
move_force = MOVE_FORCE_VERY_STRONG
|
||||
move_resist = MOVE_FORCE_VERY_STRONG
|
||||
pull_force = MOVE_FORCE_VERY_STRONG
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/bear = 3, /obj/item/stack/sheet/bone = 2)
|
||||
guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/goliath_hide/polar_bear_hide = 1)
|
||||
loot = list()
|
||||
crusher_loot = /obj/item/crusher_trophy/goliath_tentacle
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = TRUE
|
||||
/// Message for when the polar bear starts to attack faster
|
||||
var/aggressive_message_said = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
. = ..()
|
||||
if(health > maxHealth*0.5)
|
||||
rapid_melee = initial(rapid_melee)
|
||||
return
|
||||
if(!aggressive_message_said && target)
|
||||
visible_message("<span class='danger'>The [name] gets an enraged look at [target]!</span>")
|
||||
aggressive_message_said = TRUE
|
||||
rapid_melee = 2
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear/Life()
|
||||
. = ..()
|
||||
if(!. || target)
|
||||
return
|
||||
adjustHealth(-maxHealth*0.025)
|
||||
aggressive_message_said = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear/death(gibbed)
|
||||
move_force = MOVE_FORCE_DEFAULT
|
||||
move_resist = MOVE_RESIST_DEFAULT
|
||||
pull_force = PULL_FORCE_DEFAULT
|
||||
return ..()
|
||||
@@ -0,0 +1,57 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf
|
||||
name = "white wolf"
|
||||
desc = "A beast that survives by feasting on weaker opponents, they're much stronger with numbers."
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
icon_state = "whitewolf"
|
||||
icon_living = "whitewolf"
|
||||
icon_dead = "whitewolf_dead"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
friendly = "howls at"
|
||||
speak_emote = list("howls")
|
||||
speed = 5
|
||||
move_to_delay = 5
|
||||
maxHealth = 130
|
||||
health = 130
|
||||
obj_damage = 15
|
||||
melee_damage_lower = 7.5
|
||||
melee_damage_upper = 7.5
|
||||
rapid_melee = 2 // every second attack
|
||||
dodging = TRUE
|
||||
dodge_prob = 50
|
||||
attacktext = "bites"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
vision_range = 7
|
||||
aggro_vision_range = 7
|
||||
move_force = MOVE_FORCE_WEAK
|
||||
move_resist = MOVE_FORCE_WEAK
|
||||
pull_force = MOVE_FORCE_WEAK
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/stack/sheet/sinew/wolf = 2, /obj/item/stack/sheet/bone = 2)
|
||||
loot = list()
|
||||
crusher_loot = /obj/item/crusher_trophy/watcher_wing
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = TRUE
|
||||
/// Message for when the wolf decides to start running away
|
||||
var/retreat_message_said = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf/Move(atom/newloc)
|
||||
if(newloc && newloc.z == z && (islava(newloc) || ischasm(newloc)))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
. = ..()
|
||||
if(stat == DEAD || health > maxHealth*0.1)
|
||||
retreat_distance = initial(retreat_distance)
|
||||
return
|
||||
if(!retreat_message_said && target)
|
||||
visible_message("<span class='danger'>The [name] tries to flee from [target]!</span>")
|
||||
retreat_message_said = TRUE
|
||||
retreat_distance = 30
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf/Life()
|
||||
. = ..()
|
||||
if(!. || target)
|
||||
return
|
||||
adjustHealth(-maxHealth*0.025)
|
||||
retreat_message_said = FALSE
|
||||
@@ -1,14 +1,13 @@
|
||||
/mob/living/simple_animal/hostile/retaliate/clown
|
||||
name = "Clown"
|
||||
desc = "A denizen of clown planet."
|
||||
icon = 'icons/mob/simple_human.dmi'
|
||||
icon = 'icons/mob/clown_mobs.dmi'
|
||||
icon_state = "clown"
|
||||
icon_living = "clown"
|
||||
icon_dead = "clown_dead"
|
||||
icon_gib = "clown_gib"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
turns_per_move = 5
|
||||
response_help = "pokes"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "robusts"
|
||||
speak = list("HONK", "Honk!", "Welcome to clown planet!")
|
||||
@@ -21,7 +20,6 @@
|
||||
harm_intent_damage = 8
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 10
|
||||
attacktext = "attacks"
|
||||
attack_sound = 'sound/items/bikehorn.ogg'
|
||||
obj_damage = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
@@ -32,15 +30,245 @@
|
||||
minbodytemp = 270
|
||||
maxbodytemp = 370
|
||||
unsuitable_atmos_damage = 10
|
||||
|
||||
do_footstep = TRUE
|
||||
var/banana_time = 0 // If there's no time set it won't spawn.
|
||||
var/banana_type = /obj/item/grown/bananapeel
|
||||
var/attack_reagent
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/handle_temperature_damage()
|
||||
if(bodytemperature < minbodytemp)
|
||||
adjustBruteLoss(10)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 2)
|
||||
else if(bodytemperature > maxbodytemp)
|
||||
adjustBruteLoss(15)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 3)
|
||||
else
|
||||
clear_alert("temp")
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/attack_hand(mob/living/carbon/human/M)
|
||||
..()
|
||||
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)
|
||||
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/Life()
|
||||
. = ..()
|
||||
if(banana_time && banana_time < world.time)
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/adjacent = T.GetAtmosAdjacentTurfs(1)
|
||||
new banana_type(pick(adjacent))
|
||||
banana_time = world.time + rand(30,60)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/AttackingTarget()
|
||||
. = ..()
|
||||
if(attack_reagent && . && isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.reagents)
|
||||
L.reagents.add_reagent(attack_reagent, rand(1,5))
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/lube
|
||||
name = "Living Lube"
|
||||
desc = "A puddle of lube brought to life by the honkmother."
|
||||
icon_state = "lube"
|
||||
icon_living = "lube"
|
||||
turns_per_move = 1
|
||||
response_help = "dips a finger into"
|
||||
response_disarm = "gently scoops and pours aside"
|
||||
emote_see = list("bubbles", "oozes")
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/particle_effect/foam)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/lube/Initialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/snailcrawl)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/banana
|
||||
name = "Clownana"
|
||||
desc = "A fusion of clown and banana DNA birthed from a botany experiment gone wrong."
|
||||
icon_state = "banana tree"
|
||||
icon_living = "banana tree"
|
||||
response_disarm = "peels"
|
||||
response_harm = "peels"
|
||||
turns_per_move = 1
|
||||
speak = list("HONK", "Honk!", "YA-HONK!!!")
|
||||
emote_see = list("honks", "bites into the banana", "plucks a banana off its head", "photosynthesizes")
|
||||
maxHealth = 120
|
||||
health = 120
|
||||
speed = -10
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap, /obj/item/seeds/banana)
|
||||
banana_time = 20
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/honkling
|
||||
name = "Honkling"
|
||||
desc = "A divine being sent by the Honkmother to spread joy. It's not dangerous, but it's a bit of a nuisance."
|
||||
icon_state = "honkling"
|
||||
icon_living = "honkling"
|
||||
turns_per_move = 1
|
||||
speed = -10
|
||||
harm_intent_damage = 1
|
||||
melee_damage_lower = 1
|
||||
melee_damage_upper = 1
|
||||
attacktext = "cheers up"
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap, /obj/item/seeds/banana/bluespace)
|
||||
banana_type = /obj/item/grown/bananapeel
|
||||
attack_reagent = /datum/reagent/consumable/laughter
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/fleshclown
|
||||
name = "Fleshclown"
|
||||
desc = "A being forged out of the pure essence of pranking, cursed into existence by a cruel maker."
|
||||
icon_state = "fleshclown"
|
||||
icon_living = "fleshclown"
|
||||
response_help = "reluctantly pokes"
|
||||
response_disarm = "sinks his hands into the spongy flesh of"
|
||||
response_harm = "cleanses the world of"
|
||||
speak = list("HONK", "Honk!", "I didn't ask for this", "I feel constant and horrible pain", "YA-HONK!!!", "this body is a merciless and unforgiving prison", "I was born out of mirthful pranking but I live in suffering")
|
||||
emote_see = list("honks", "sweats", "jiggles", "contemplates its existence")
|
||||
speak_chance = 5
|
||||
dextrous = TRUE
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
maxHealth = 140
|
||||
health = 140
|
||||
speed = -5
|
||||
melee_damage_upper = 15
|
||||
attacktext = "limply slaps"
|
||||
obj_damage = 5
|
||||
loot = list(/obj/item/clothing/suit/hooded/bloated_human, /obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/longface
|
||||
name = "Longface"
|
||||
desc = "Often found walking into the bar."
|
||||
icon_state = "long face"
|
||||
icon_living = "long face"
|
||||
move_resist = INFINITY
|
||||
turns_per_move = 10
|
||||
response_help = "tries to awkwardly hug"
|
||||
response_disarm = "pushes the unwieldy frame of"
|
||||
response_harm = "tries to shut up"
|
||||
speak = list("YA-HONK!!!")
|
||||
emote_see = list("honks", "squeaks")
|
||||
speak_chance = 60
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
pixel_x = -16
|
||||
speed = 10
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 5
|
||||
attacktext = "YA-HONKs"
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/clownhulk
|
||||
name = "Honk Hulk"
|
||||
desc = "A cruel and fearsome clown. Don't make him angry."
|
||||
icon_state = "honkhulk"
|
||||
icon_living = "honkhulk"
|
||||
move_resist = INFINITY
|
||||
response_help = "tries desperately to appease"
|
||||
response_disarm = "foolishly pushes"
|
||||
response_harm = "angers"
|
||||
speak = list("HONK", "Honk!", "HAUAUANK!!!", "GUUURRRRAAAHHH!!!")
|
||||
emote_see = list("honks", "sweats", "grunts")
|
||||
speak_chance = 5
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
pixel_x = -16
|
||||
speed = 2
|
||||
harm_intent_damage = 15
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 20
|
||||
attacktext = "pummels"
|
||||
obj_damage = 30
|
||||
environment_smash = ENVIRONMENT_SMASH_WALLS
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/clownhulk/chlown
|
||||
name = "Chlown"
|
||||
desc = "A real lunkhead who somehow gets all the girls."
|
||||
icon_state = "chlown"
|
||||
icon_living = "chlown"
|
||||
response_help = "submits to"
|
||||
response_disarm = "tries to assert dominance over"
|
||||
response_harm = "makes a weak beta attack at"
|
||||
speak = list("HONK", "Honk!", "Bruh", "cheeaaaahhh?")
|
||||
emote_see = list("asserts his dominance", "emasculates everyone implicitly")
|
||||
maxHealth = 500
|
||||
health = 500
|
||||
speed = -2
|
||||
armour_penetration = 20
|
||||
attacktext = "steals the girlfriend of"
|
||||
attack_sound = 'sound/items/airhorn2.ogg'
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/effect/particle_effect/foam, /obj/item/soap)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/clownhulk/honcmunculus
|
||||
name = "Honkmunculus"
|
||||
desc = "A slender wiry figure of alchemical origin."
|
||||
icon_state = "honkmunculus"
|
||||
icon_living = "honkmunculus"
|
||||
response_help = "skeptically pokes"
|
||||
response_disarm = "pushes the unwieldy frame of"
|
||||
speak = list("honk")
|
||||
emote_see = list("squirms", "writhes")
|
||||
speak_chance = 1
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
speed = -5
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 10
|
||||
attacktext = "ferociously mauls"
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/xeno/bodypartless, /obj/effect/particle_effect/foam, /obj/item/soap)
|
||||
attack_reagent = /datum/reagent/peaceborg_confuse
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/clownhulk/destroyer
|
||||
name = "The Destroyer"
|
||||
desc = "An ancient being born of arcane honking."
|
||||
icon_state = "destroyer"
|
||||
icon_living = "destroyer"
|
||||
response_disarm = "bounces off of"
|
||||
response_harm = "bounces off of"
|
||||
speak = list("HONK!!!", "The Honkmother is merciful, so I must act out her wrath.", "parce mihi ad beatus honkmother placet mihi ut peccata committere,", "DIE!!!")
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
speed = 5
|
||||
harm_intent_damage = 30
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 40
|
||||
armour_penetration = 30
|
||||
stat_attack = UNCONSCIOUS
|
||||
attacktext = "acts out divine vengeance on"
|
||||
obj_damage = 50
|
||||
environment_smash = ENVIRONMENT_SMASH_RWALLS
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/effect/particle_effect/foam, /obj/item/soap)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/mutant
|
||||
name = "Unknown"
|
||||
desc = "Kill it for its own sake."
|
||||
icon_state = "mutant"
|
||||
icon_living = "mutant"
|
||||
move_resist = INFINITY
|
||||
turns_per_move = 10
|
||||
response_help = "reluctantly sinks a finger into"
|
||||
response_disarm = "squishes into"
|
||||
response_harm = "squishes into"
|
||||
speak = list("aaaaaahhhhuuhhhuhhhaaaaa", "AAAaaauuuaaAAAaauuhhh", "huuuuuh... hhhhuuuooooonnnnkk", "HuaUAAAnKKKK")
|
||||
emote_see = list("squirms", "writhes", "pulsates", "froths", "oozes")
|
||||
speak_chance = 10
|
||||
maxHealth = 130
|
||||
health = 130
|
||||
pixel_x = -16
|
||||
speed = -5
|
||||
harm_intent_damage = 10
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 20
|
||||
attacktext = "awkwardly flails at"
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/xeno/bodypartless, /obj/item/soap, /obj/effect/gibspawner/generic, /obj/effect/gibspawner/generic/animal, /obj/effect/gibspawner/human/bodypartless, /obj/effect/gibspawner/human)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/mutant/blob
|
||||
name = "Something that was once a clown"
|
||||
desc = "A grotesque bulging figure far mutated from it's original state."
|
||||
icon_state = "blob"
|
||||
icon_living = "blob"
|
||||
speak = list("hey, buddy", "HONK!!!", "H-h-h-H-HOOOOONK!!!!", "HONKHONKHONK!!!", "HEY, BUCKO, GET BACK HERE!!!", "HOOOOOOOONK!!!")
|
||||
emote_see = list("jiggles", "wobbles")
|
||||
health = 130
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
speed = 20
|
||||
attacktext = "bounces off of"
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/xeno/bodypartless, /obj/effect/particle_effect/foam, /obj/item/soap, /obj/effect/gibspawner/generic, /obj/effect/gibspawner/generic/animal, /obj/effect/gibspawner/human/bodypartless, /obj/effect/gibspawner/human)
|
||||
attack_reagent = /datum/reagent/toxin/mindbreaker
|
||||
|
||||
@@ -159,12 +159,13 @@
|
||||
/mob/living/simple_animal/slime/updatehealth()
|
||||
. = ..()
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/slime_healthmod)
|
||||
var/health_deficiency = (100 - health)
|
||||
var/mod = 0
|
||||
if(health_deficiency >= 45)
|
||||
mod += (health_deficiency / 25)
|
||||
if(health <= 0)
|
||||
mod += 2
|
||||
if(!HAS_TRAIT(src, TRAIT_IGNOREDAMAGESLOWDOWN))
|
||||
var/health_deficiency = (maxHealth - health)
|
||||
if(health_deficiency >= 45)
|
||||
mod += (health_deficiency / 25)
|
||||
if(health <= 0)
|
||||
mod += 2
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/slime_healthmod, multiplicative_slowdown = mod)
|
||||
|
||||
/mob/living/simple_animal/slime/adjust_bodytemperature()
|
||||
|
||||
@@ -593,7 +593,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
stat("Failsafe Controller:", "ERROR")
|
||||
if(Master)
|
||||
stat(null)
|
||||
for(var/datum/controller/subsystem/SS in Master.subsystems)
|
||||
for(var/datum/controller/subsystem/SS in Master.statworthy_subsystems)
|
||||
SS.stat_entry()
|
||||
GLOB.cameranet.stat_entry()
|
||||
if(statpanel("Tickets"))
|
||||
|
||||
@@ -100,15 +100,16 @@
|
||||
if(mob.throwing)
|
||||
mob.throwing.finalize(FALSE)
|
||||
|
||||
var/atom/movable/P = mob.pulling
|
||||
if(P && !ismob(P) && P.density)
|
||||
mob.setDir(turn(mob.dir, 180))
|
||||
if(L.pulling && !(L.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
L.setDir(turn(L.dir, 180))
|
||||
|
||||
SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_MOVE, src, direction, n, oldloc)
|
||||
|
||||
/// Process_Grab(): checks for grab, attempts to break if so. Return TRUE to prevent movement.
|
||||
/client/proc/Process_Grab()
|
||||
if(mob.pulledby)
|
||||
if((mob.pulledby == mob.pulling) && (mob.pulledby.grab_state == GRAB_PASSIVE)) //Don't autoresist passive grabs if we're grabbing them too.
|
||||
return
|
||||
if(mob.incapacitated(ignore_restraints = 1))
|
||||
move_delay = world.time + 10
|
||||
return TRUE
|
||||
|
||||
@@ -425,6 +425,7 @@
|
||||
mind.transfer_to(new_xeno)
|
||||
else
|
||||
transfer_ckey(new_xeno)
|
||||
update_atom_languages()
|
||||
|
||||
to_chat(new_xeno, "<B>You are now an alien.</B>")
|
||||
. = new_xeno
|
||||
|
||||
Reference in New Issue
Block a user