Merge branch 'master' into upstream-merge-30117
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
/mob/dead/new_player/Login()
|
||||
if(config.use_exp_tracking)
|
||||
client.set_exp_from_db()
|
||||
client.set_db_player_flags()
|
||||
if(!mind)
|
||||
mind = new /datum/mind(key)
|
||||
mind.active = 1
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
diff a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm (rejected hunks)
|
||||
@@ -1,5 +1,6 @@
|
||||
/mob/dead/new_player/Login()
|
||||
- client.update_exp_client(0, 0)
|
||||
+ if(config.use_exp_tracking)
|
||||
+ client.update_exp_client(0, 0)
|
||||
if(!mind)
|
||||
mind = new /datum/mind(key)
|
||||
mind.active = 1
|
||||
@@ -307,6 +307,8 @@
|
||||
return 0
|
||||
if(!job.player_old_enough(src.client))
|
||||
return 0
|
||||
if(job.required_playtime_remaining(client))
|
||||
return 0
|
||||
if(config.enforce_human_authority && !client.prefs.pref_species.qualifies_for_rank(rank, client.prefs.features))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -96,6 +96,20 @@
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/tails/human/kitsune
|
||||
name = "Kitsune"
|
||||
icon_state = "kitsune"
|
||||
extra = 1
|
||||
extra_color_src = MUTCOLORS2
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/tails_animated/human/kitsune
|
||||
name = "Kitsune"
|
||||
icon_state = "kitsune"
|
||||
extra = 1
|
||||
extra_color_src = MUTCOLORS2
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/ears/lab
|
||||
name = "Dog, Floppy"
|
||||
icon_state = "lab"
|
||||
@@ -119,6 +133,33 @@
|
||||
color_src = 0
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/ears/human/otie
|
||||
name = "Otusian"
|
||||
icon_state = "otie"
|
||||
hasinner= 1
|
||||
|
||||
/datum/sprite_accessory/tails/human/otie
|
||||
name = "Otusian"
|
||||
icon_state = "otie"
|
||||
|
||||
/datum/sprite_accessory/tails_animated/human/otie
|
||||
name = "Otusian"
|
||||
icon_state = "otie"
|
||||
|
||||
/datum/sprite_accessory/ears/human/skunk
|
||||
name = "skunk"
|
||||
icon_state = "skunk"
|
||||
|
||||
/datum/sprite_accessory/tails/human/skunk
|
||||
name = "skunk"
|
||||
icon_state = "skunk"
|
||||
color_src = 0
|
||||
|
||||
/datum/sprite_accessory/tails_animated/human/skunk
|
||||
name = "skunk"
|
||||
icon_state = "skunk"
|
||||
color_src = 0
|
||||
|
||||
/datum/sprite_accessory/tails/human/shark
|
||||
name = "Shark"
|
||||
icon_state = "shark"
|
||||
@@ -198,6 +239,16 @@
|
||||
**************** Snouts *******************
|
||||
*******************************************/
|
||||
|
||||
/datum/sprite_accessory/snouts/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/snouts/bird
|
||||
name = "Beak"
|
||||
icon_state = "bird"
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/snouts/lcanid
|
||||
name = "Fox, Long"
|
||||
icon_state = "lcanid"
|
||||
@@ -347,6 +398,31 @@
|
||||
icon_state = "husky"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_ears/kangaroo
|
||||
name = "kangaroo"
|
||||
icon_state = "kangaroo"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_tails/kangaroo
|
||||
name = "kangaroo"
|
||||
icon_state = "kangaroo"
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/kangaroo
|
||||
name = "kangaroo"
|
||||
icon_state = "kangaroo"
|
||||
|
||||
/datum/sprite_accessory/mam_tails/kitsune
|
||||
name = "Kitsune"
|
||||
icon_state = "kitsune"
|
||||
extra = 1
|
||||
extra_color_src = MUTCOLORS2
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/kitsune
|
||||
name = "Kitsune"
|
||||
icon_state = "kitsune"
|
||||
extra = 1
|
||||
extra_color_src = MUTCOLORS2
|
||||
|
||||
/datum/sprite_accessory/mam_ears/lab
|
||||
name = "Dog, Long"
|
||||
icon_state = "lab"
|
||||
@@ -386,6 +462,22 @@
|
||||
name = "Otusian"
|
||||
icon_state = "otie"
|
||||
|
||||
/datum/sprite_accessory/mam_ears/skunk
|
||||
name = "skunk"
|
||||
icon_state = "skunk"
|
||||
|
||||
/datum/sprite_accessory/mam_tails/skunk
|
||||
name = "skunk"
|
||||
icon_state = "skunk"
|
||||
color_src = 0
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/skunk
|
||||
name = "skunk"
|
||||
icon_state = "skunk"
|
||||
color_src = 0
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_tails/shark
|
||||
name = "Shark"
|
||||
icon_state = "shark"
|
||||
@@ -396,17 +488,6 @@
|
||||
icon_state = "shark"
|
||||
color_src = 0
|
||||
|
||||
/datum/sprite_accessory/mam_tails/shark/datashark
|
||||
name = "DataShark"
|
||||
icon_state = "datashark"
|
||||
color_src = 0
|
||||
// ckeys_allowed = list("rubyflamewing")
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/shark/datashark
|
||||
name = "DataShark"
|
||||
icon_state = "datashark"
|
||||
color_src = 0
|
||||
|
||||
/datum/sprite_accessory/mam_tails/shepherd
|
||||
name = "Shepherd"
|
||||
icon_state = "shepherd"
|
||||
@@ -445,31 +526,18 @@
|
||||
name = "Wolf"
|
||||
icon_state = "wolf"
|
||||
|
||||
/datum/sprite_accessory/mam_tails/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_ears/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails/rabbit
|
||||
name = "Rabbit"
|
||||
icon_state = "rabbit"
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/rabbit
|
||||
name = "Rabbit"
|
||||
icon_state = "rabbit"
|
||||
|
||||
/datum/sprite_accessory/mam_ears/rabbit
|
||||
name = "Rabbit"
|
||||
icon_state = "rabbit"
|
||||
hasinner= 1
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/******************************************
|
||||
************ Body Markings ****************
|
||||
@@ -586,21 +654,14 @@
|
||||
color_src = MUTCOLORS2
|
||||
gender_specific = 1
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
extra = 1
|
||||
extra2 = 1
|
||||
icon = 'icons/mob/mam_body_markings.dmi'
|
||||
gender_specific = 1
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/xeno
|
||||
/datum/sprite_accessory/mam_body_markings/xeno
|
||||
name = "Xeno"
|
||||
icon_state = "xeno"
|
||||
color_src = MUTCOLORS2
|
||||
extra_color_src = MUTCOLORS3
|
||||
gender_specific = 1
|
||||
|
||||
|
||||
/******************************************
|
||||
************ Taur Bodies ******************
|
||||
*******************************************/
|
||||
@@ -712,7 +773,6 @@
|
||||
icon = 'icons/mob/xeno_parts_greyscale.dmi'
|
||||
|
||||
//Xeno Caste Heads
|
||||
//unused as of October 3, 2016
|
||||
/datum/sprite_accessory/xeno_head
|
||||
icon = 'icons/mob/xeno_parts_greyscale.dmi'
|
||||
|
||||
@@ -740,17 +800,67 @@
|
||||
icon_state = "warrior"
|
||||
icon = 'icons/mob/xeno_parts_greyscale.dmi'
|
||||
|
||||
// *** Snooooow flaaaaake ***
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
extra_color_src = MUTCOLORS2
|
||||
extra2_color_src = MUTCOLORS3
|
||||
gender_specific = 1
|
||||
|
||||
/datum/sprite_accessory/mam_tails/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_ears/guilmon
|
||||
name = "Guilmon"
|
||||
icon_state = "guilmon"
|
||||
icon = 'icons/mob/mam_bodyparts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails/shark/datashark
|
||||
name = "DataShark"
|
||||
icon_state = "datashark"
|
||||
color_src = 0
|
||||
// ckeys_allowed = list("rubyflamewing")
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/shark/datashark
|
||||
name = "DataShark"
|
||||
icon_state = "datashark"
|
||||
color_src = 0
|
||||
|
||||
/*
|
||||
//Slimecoon Parts
|
||||
/datum/sprite_accessory/slimecoon_ears
|
||||
icon = 'icons/mob/exotic_bodyparts.dmi'
|
||||
name = "Slimecoon Ears"
|
||||
icon_state = "slimecoon"
|
||||
/datum/sprite_accessory/slimecoon_tail
|
||||
icon = 'icons/mob/exotic_bodyparts.dmi'
|
||||
name = "Slimecoon Tail"
|
||||
icon_state = "slimecoon"
|
||||
/datum/sprite_accessory/slimecoon_snout
|
||||
icon = 'icons/mob/exotic_bodyparts.dmi'
|
||||
name = "Hunter"
|
||||
icon_state = "slimecoon" */
|
||||
//Till I get my snowflake only ckey lock, these are locked-locked :D
|
||||
|
||||
/datum/sprite_accessory/mam_ears/sabresune
|
||||
name = "sabresune"
|
||||
icon_state = "sabresune"
|
||||
extra = 1
|
||||
extra_color_src = MUTCOLORS3
|
||||
locked = TRUE
|
||||
|
||||
/datum/sprite_accessory/mam_tails/sabresune
|
||||
name = "sabresune"
|
||||
icon_state = "sabresune"
|
||||
extra = 1
|
||||
locked = TRUE
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/sabresune
|
||||
name = "sabresune"
|
||||
icon_state = "sabresune"
|
||||
extra = 1
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/sabresune
|
||||
name = "Sabresune"
|
||||
icon_state = "sabresune"
|
||||
color_src = MUTCOLORS2
|
||||
extra = 0
|
||||
extra2 = 0
|
||||
locked = TRUE
|
||||
*/
|
||||
|
||||
@@ -309,9 +309,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
if(SSticker.HasRoundStarted())
|
||||
for(var/datum/gang/G in SSticker.mode.gangs)
|
||||
if(G.is_dominating)
|
||||
stat(null, "[G.name] Gang Takeover: [max(G.domination_time_remaining(), 0)]")
|
||||
if(istype(SSticker.mode, /datum/game_mode/blob))
|
||||
var/datum/game_mode/blob/B = SSticker.mode
|
||||
if(B.message_sent)
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
initial_language_holder = /datum/language_holder/alien
|
||||
bubble_icon = "alien"
|
||||
type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
|
||||
var/nightvision = 1
|
||||
|
||||
var/obj/item/card/id/wear_id = null // Fix for station bounced radios -- Skie
|
||||
var/has_fine_manipulation = 0
|
||||
@@ -32,7 +31,7 @@
|
||||
|
||||
var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?")
|
||||
devourable = TRUE
|
||||
|
||||
|
||||
/mob/living/carbon/alien/Initialize()
|
||||
verbs += /mob/living/proc/mob_sleep
|
||||
verbs += /mob/living/proc/lay_down
|
||||
|
||||
@@ -610,50 +610,94 @@
|
||||
if(!client)
|
||||
return
|
||||
|
||||
if(stat == UNCONSCIOUS && health <= HEALTH_THRESHOLD_CRIT)
|
||||
if(health <= HEALTH_THRESHOLD_CRIT)
|
||||
var/severity = 0
|
||||
switch(health)
|
||||
if(-20 to -10) severity = 1
|
||||
if(-30 to -20) severity = 2
|
||||
if(-40 to -30) severity = 3
|
||||
if(-50 to -40) severity = 4
|
||||
if(-60 to -50) severity = 5
|
||||
if(-70 to -60) severity = 6
|
||||
if(-80 to -70) severity = 7
|
||||
if(-90 to -80) severity = 8
|
||||
if(-95 to -90) severity = 9
|
||||
if(-INFINITY to -95) severity = 10
|
||||
if(-20 to -10)
|
||||
severity = 1
|
||||
if(-30 to -20)
|
||||
severity = 2
|
||||
if(-40 to -30)
|
||||
severity = 3
|
||||
if(-50 to -40)
|
||||
severity = 4
|
||||
if(-50 to -40)
|
||||
severity = 5
|
||||
if(-60 to -50)
|
||||
severity = 6
|
||||
if(-70 to -60)
|
||||
severity = 7
|
||||
if(-90 to -70)
|
||||
severity = 8
|
||||
if(-95 to -90)
|
||||
severity = 9
|
||||
if(-INFINITY to -95)
|
||||
severity = 10
|
||||
if(!InFullCritical())
|
||||
var/visionseverity = 4
|
||||
switch(health)
|
||||
if(-8 to -4)
|
||||
visionseverity = 5
|
||||
if(-12 to -8)
|
||||
visionseverity = 6
|
||||
if(-16 to -12)
|
||||
visionseverity = 7
|
||||
if(-20 to -16)
|
||||
visionseverity = 8
|
||||
if(-24 to -20)
|
||||
visionseverity = 9
|
||||
if(-INFINITY to -24)
|
||||
visionseverity = 10
|
||||
overlay_fullscreen("critvision", /obj/screen/fullscreen/crit/vision, visionseverity)
|
||||
else
|
||||
clear_fullscreen("critvision")
|
||||
overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity)
|
||||
else
|
||||
clear_fullscreen("crit")
|
||||
if(oxyloss)
|
||||
var/severity = 0
|
||||
switch(oxyloss)
|
||||
if(10 to 20) severity = 1
|
||||
if(20 to 25) severity = 2
|
||||
if(25 to 30) severity = 3
|
||||
if(30 to 35) severity = 4
|
||||
if(35 to 40) severity = 5
|
||||
if(40 to 45) severity = 6
|
||||
if(45 to INFINITY) severity = 7
|
||||
overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity)
|
||||
else
|
||||
clear_fullscreen("oxy")
|
||||
clear_fullscreen("critvision")
|
||||
|
||||
//Fire and Brute damage overlay (BSSR)
|
||||
var/hurtdamage = getBruteLoss() + getFireLoss() + damageoverlaytemp
|
||||
if(hurtdamage)
|
||||
var/severity = 0
|
||||
switch(hurtdamage)
|
||||
if(5 to 15) severity = 1
|
||||
if(15 to 30) severity = 2
|
||||
if(30 to 45) severity = 3
|
||||
if(45 to 70) severity = 4
|
||||
if(70 to 85) severity = 5
|
||||
if(85 to INFINITY) severity = 6
|
||||
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
|
||||
else
|
||||
clear_fullscreen("brute")
|
||||
//Oxygen damage overlay
|
||||
if(oxyloss)
|
||||
var/severity = 0
|
||||
switch(oxyloss)
|
||||
if(10 to 20)
|
||||
severity = 1
|
||||
if(20 to 25)
|
||||
severity = 2
|
||||
if(25 to 30)
|
||||
severity = 3
|
||||
if(30 to 35)
|
||||
severity = 4
|
||||
if(35 to 40)
|
||||
severity = 5
|
||||
if(40 to 45)
|
||||
severity = 6
|
||||
if(45 to INFINITY)
|
||||
severity = 7
|
||||
overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity)
|
||||
else
|
||||
clear_fullscreen("oxy")
|
||||
|
||||
//Fire and Brute damage overlay (BSSR)
|
||||
var/hurtdamage = getBruteLoss() + getFireLoss() + damageoverlaytemp
|
||||
if(hurtdamage)
|
||||
var/severity = 0
|
||||
switch(hurtdamage)
|
||||
if(5 to 15)
|
||||
severity = 1
|
||||
if(15 to 30)
|
||||
severity = 2
|
||||
if(30 to 45)
|
||||
severity = 3
|
||||
if(45 to 70)
|
||||
severity = 4
|
||||
if(70 to 85)
|
||||
severity = 5
|
||||
if(85 to INFINITY)
|
||||
severity = 6
|
||||
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
|
||||
else
|
||||
clear_fullscreen("brute")
|
||||
|
||||
/mob/living/carbon/update_health_hud(shown_health_amount)
|
||||
if(!client || !hud_used)
|
||||
@@ -688,20 +732,19 @@
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
if(stat != DEAD)
|
||||
if(health<= HEALTH_THRESHOLD_DEAD)
|
||||
if(health <= HEALTH_THRESHOLD_DEAD)
|
||||
death()
|
||||
return
|
||||
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
|
||||
if(stat == CONSCIOUS)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
update_canmove()
|
||||
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_FULLCRIT)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
else
|
||||
if(stat == UNCONSCIOUS)
|
||||
if(health <= HEALTH_THRESHOLD_CRIT)
|
||||
stat = SOFT_CRIT
|
||||
else
|
||||
stat = CONSCIOUS
|
||||
resting = 0
|
||||
adjust_blindness(-1)
|
||||
update_canmove()
|
||||
adjust_blindness(-1)
|
||||
update_canmove()
|
||||
update_damage_hud()
|
||||
update_health_hud()
|
||||
med_hud_set_status()
|
||||
|
||||
@@ -255,6 +255,8 @@
|
||||
else if(check_zone(M.zone_selected) == "head")
|
||||
M.visible_message("<span class='notice'>[M] gives [src] a pat on the head to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You give [src] a pat on the head to make [p_them()] feel better!</span>")
|
||||
if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || (dna.features["tail_human"] != "None") || ("mam_tail" in dna.species.mutant_bodyparts)))
|
||||
emote("wag") //lewd
|
||||
else
|
||||
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/mob/living/carbon/movement_delay()
|
||||
var/FP
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
var/obj/item/device/flightpack/F = C.get_flightpack()
|
||||
if(istype(F) && F.flight)
|
||||
FP = 1
|
||||
var/FP = FALSE
|
||||
var/obj/item/device/flightpack/F = get_flightpack()
|
||||
if(istype(F) && F.flight)
|
||||
FP = TRUE
|
||||
. = ..(FP)
|
||||
if(!FP)
|
||||
. += grab_state * 1 //Flightpacks are too powerful to be slowed too much by the weight of a corpse.
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
if(!appears_dead)
|
||||
if(stat == UNCONSCIOUS)
|
||||
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
|
||||
else if(InCritical())
|
||||
msg += "[t_His] breathing is shallow and labored.\n"
|
||||
|
||||
if(digitalcamo)
|
||||
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner.\n"
|
||||
|
||||
@@ -613,7 +613,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
|
||||
//Check for dresscode violations
|
||||
if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/syndi) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi))
|
||||
threatcount += 3
|
||||
threatcount += 6
|
||||
|
||||
//Check for nonhuman scum
|
||||
if(dna && dna.species.id && !(dna.species.id in list("human" , "lizard", "mammal", "avian", "aquatic", "insect")))
|
||||
@@ -643,6 +643,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
update_hair()
|
||||
|
||||
/mob/living/carbon/human/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_THREE)
|
||||
for(var/obj/item/hand in held_items)
|
||||
if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && dropItemToGround(hand))
|
||||
@@ -651,7 +652,6 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
rad_act(current_size * 3)
|
||||
if(mob_negates_gravity())
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/proc/do_cpr(mob/living/carbon/C)
|
||||
CHECK_DNA_AND_SPECIES(C)
|
||||
|
||||
@@ -105,9 +105,6 @@
|
||||
/mob/living/carbon/human/IsAdvancedToolUser()
|
||||
return 1//Humans can use guns and such
|
||||
|
||||
/mob/living/carbon/human/InCritical()
|
||||
return (health <= HEALTH_THRESHOLD_CRIT && stat == UNCONSCIOUS)
|
||||
|
||||
/mob/living/carbon/human/reagent_check(datum/reagent/R)
|
||||
return dna.species.handle_chemicals(R,src)
|
||||
// if it returns 0, it will run the usual on_mob_life for that reagent. otherwise, it will stop after running handle_chemicals for the species.
|
||||
|
||||
@@ -87,17 +87,23 @@
|
||||
/// SNPC voice handling
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/loadVoice()
|
||||
var/savefile/S = new /savefile("data/npc_saves/snpc.sav")
|
||||
S["knownStrings"] >> knownStrings
|
||||
|
||||
var/json_file = file("data/npc_saves/snpc.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
knownStrings = json["knownStrings"]
|
||||
if(isnull(knownStrings))
|
||||
knownStrings = list()
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/saveVoice()
|
||||
if(voice_saved)
|
||||
return
|
||||
var/savefile/S = new /savefile("data/npc_saves/snpc.sav")
|
||||
WRITE_FILE(S["knownStrings"], knownStrings)
|
||||
var/json_file = file("data/npc_saves/snpc.json")
|
||||
var/list/file_data = list()
|
||||
file_data["knownStrings"] = knownStrings
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
//botPool funcs
|
||||
/mob/living/carbon/human/interactive/proc/takeDelegate(mob/living/carbon/human/interactive/from,doReset=TRUE)
|
||||
@@ -284,7 +290,7 @@
|
||||
//job specific favours
|
||||
switch(myjob.title)
|
||||
if("Assistant")
|
||||
favoured_types = list(/obj/item/clothing, /obj/item/weapon)
|
||||
favoured_types = list(/obj/item/clothing, /obj/item)
|
||||
if("Captain","Head of Personnel")
|
||||
favoured_types = list(/obj/item/clothing, /obj/item/stamp/captain, /obj/item/disk/nuclear)
|
||||
if("Cook")
|
||||
@@ -296,14 +302,14 @@
|
||||
functions += "bartend"
|
||||
restrictedJob = 1
|
||||
if("Station Engineer","Chief Engineer","Atmospheric Technician")
|
||||
favoured_types = list(/obj/item/stack, /obj/item/weapon, /obj/item/clothing)
|
||||
favoured_types = list(/obj/item/stack, /obj/item, /obj/item/clothing)
|
||||
if("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Geneticist")
|
||||
favoured_types = list(/obj/item/reagent_containers/glass/beaker, /obj/item/storage/firstaid, /obj/item/stack/medical, /obj/item/reagent_containers/syringe)
|
||||
functions += "healpeople"
|
||||
if("Research Director","Scientist","Roboticist")
|
||||
favoured_types = list(/obj/item/reagent_containers/glass/beaker, /obj/item/stack, /obj/item/reagent_containers)
|
||||
if("Head of Security","Warden","Security Officer","Detective")
|
||||
favoured_types = list(/obj/item/clothing, /obj/item/weapon, /obj/item/restraints)
|
||||
favoured_types = list(/obj/item/clothing, /obj/item, /obj/item/restraints)
|
||||
if("Janitor")
|
||||
favoured_types = list(/obj/item/mop, /obj/item/reagent_containers/glass/bucket, /obj/item/reagent_containers/spray/cleaner, /obj/effect/decal/cleanable)
|
||||
functions += "dojanitor"
|
||||
@@ -313,7 +319,7 @@
|
||||
if("Mime")
|
||||
functions -= "chatter"
|
||||
if("Botanist")
|
||||
favoured_types = list(/obj/machinery/hydroponics, /obj/item/reagent_containers, /obj/item/weapon)
|
||||
favoured_types = list(/obj/machinery/hydroponics, /obj/item/reagent_containers, /obj/item)
|
||||
functions += "botany"
|
||||
restrictedJob = 1
|
||||
else
|
||||
@@ -633,7 +639,7 @@
|
||||
insert_into_backpack() // dump random item into backpack to make space
|
||||
//---------ITEMS
|
||||
if(isitem(TARGET))
|
||||
if(istype(TARGET, /obj/item/weapon))
|
||||
if(istype(TARGET, /obj/item))
|
||||
var/obj/item/W = TARGET
|
||||
if(W.force >= best_force || prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2))
|
||||
if(!get_item_for_held_index(1) || !get_item_for_held_index(2))
|
||||
@@ -1473,7 +1479,7 @@
|
||||
foundFav = 1
|
||||
return
|
||||
if(!foundFav)
|
||||
if(istype(test, /obj/item/weapon))
|
||||
if(istype(test, /obj/item))
|
||||
var/obj/item/R = test
|
||||
if(R.force > 2) // make sure we don't equip any non-weaponlike items, ie bags and stuff
|
||||
if(!best)
|
||||
@@ -1498,7 +1504,7 @@
|
||||
if(istype(A, /obj/item/gun)) // guns are for shooting, not throwing.
|
||||
continue
|
||||
if(prob(robustness))
|
||||
if(istype(A, /obj/item/weapon))
|
||||
if(istype(A, /obj/item))
|
||||
var/obj/item/W = A
|
||||
if(W.throwforce > 19) // Only throw worthwile stuff, no more lobbing wrenches at wenches
|
||||
npcDrop(W,1)
|
||||
@@ -1612,4 +1618,4 @@
|
||||
TRAITS |= TRAIT_ROBUST
|
||||
TRAITS |= TRAIT_SMART
|
||||
faction += "bot_power"
|
||||
..()
|
||||
..()
|
||||
@@ -147,7 +147,7 @@
|
||||
. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
|
||||
if(!. || !I)
|
||||
return
|
||||
if(index && dna.species.mutanthands)
|
||||
if(index && !QDELETED(src) && dna.species.mutanthands) //hand freed, fill with claws, skip if we're getting deleted.
|
||||
put_in_hand(new dna.species.mutanthands(), index)
|
||||
if(I == wear_suit)
|
||||
if(s_store && invdrop)
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
|
||||
if((wear_suit && (wear_suit.flags_1 & STOPSPRESSUREDMAGE_1)) && (head && (head.flags_1 & STOPSPRESSUREDMAGE_1)))
|
||||
return ONE_ATMOSPHERE
|
||||
if(ismob(loc))
|
||||
return ONE_ATMOSPHERE
|
||||
else
|
||||
return pressure
|
||||
|
||||
@@ -242,6 +244,9 @@
|
||||
|
||||
if(dna && (RESISTCOLD in dna.species.species_traits))
|
||||
return 1
|
||||
|
||||
if(ismob(loc))
|
||||
return 1 //because lazy and being inside somemone insulates you from space
|
||||
|
||||
temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
|
||||
var/thermal_protection_flags = get_cold_protection_flags(temperature)
|
||||
|
||||
@@ -1198,6 +1198,8 @@
|
||||
. += (1.5 - flight)
|
||||
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
. += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR
|
||||
if(H.stat == SOFT_CRIT)
|
||||
. = max(SOFTCRIT_MIN_SLOWDOWN, . + SOFTCRIT_ADD_SLOWDOWN) //regardless of how fast you are, you move at a maximum of SOFTCRIT_MIN_SLOWDOWN while in softcrit
|
||||
return .
|
||||
|
||||
//////////////////
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
liked_food = MEAT | FRIED
|
||||
disliked_food = TOXIC
|
||||
|
||||
/datum/species/mammal/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -24,12 +26,14 @@
|
||||
say_mod = "chirps"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("snout", "wings", "taur", "mam_tail", "mam_body_markings")
|
||||
mutant_bodyparts = list("snout", "wings", "taur", "mam_tail", "mam_body_markings", "taur")
|
||||
default_features = list("snout" = "Sharp", "wings" = "None", "taur" = "None", "mam_body_markings" = "Hawk")
|
||||
attack_verb = "peck"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
liked_food = MEAT | FRUIT
|
||||
disliked_food = TOXIC
|
||||
|
||||
/datum/species/avian/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -44,12 +48,14 @@
|
||||
id = "aquatic"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("mam_tail", "mam_body_markings", "mam_ears")
|
||||
mutant_bodyparts = list("mam_tail", "mam_body_markings", "mam_ears", "taur")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF","mam_tail" = "shark", "mam_body_markings" = "None", "mam_ears" = "None")
|
||||
attack_verb = "bite"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
liked_food = MEAT
|
||||
disliked_food = TOXIC
|
||||
|
||||
/datum/species/aquatic/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -64,12 +70,14 @@
|
||||
id = "insect"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("mam_body_markings", "mam_ears", "mam_tail")
|
||||
mutant_bodyparts = list("mam_body_markings", "mam_ears", "mam_tail", "taur")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_body_markings" = "moth", "mam_tail" = "None", "mam_ears" = "None")
|
||||
attack_verb = "flutter" //wat?
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
liked_food = MEAT | FRUIT
|
||||
disliked_food = TOXIC
|
||||
|
||||
/datum/species/insect/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -98,6 +106,7 @@
|
||||
exotic_bloodtype = "L"
|
||||
damage_overlay_type = "xeno"
|
||||
roundstart = 1
|
||||
liked_food = MEAT
|
||||
|
||||
//Praise the Omnissiah, A challange worthy of my skills - HS
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
damage_overlay_type = ""
|
||||
var/datum/action/innate/regenerate_limbs/regenerate_limbs
|
||||
toxic_food = NONE
|
||||
liked_food = NONE
|
||||
liked_food = MEAT
|
||||
|
||||
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
|
||||
if(regenerate_limbs)
|
||||
|
||||
@@ -95,24 +95,30 @@
|
||||
|
||||
if(I == head)
|
||||
head = null
|
||||
head_update(I)
|
||||
if(!QDELETED(src))
|
||||
head_update(I)
|
||||
else if(I == back)
|
||||
back = null
|
||||
update_inv_back()
|
||||
if(!QDELETED(src))
|
||||
update_inv_back()
|
||||
else if(I == wear_mask)
|
||||
wear_mask = null
|
||||
wear_mask_update(I, toggle_off = 1)
|
||||
if(!QDELETED(src))
|
||||
wear_mask_update(I, toggle_off = 1)
|
||||
if(I == wear_neck)
|
||||
wear_neck = null
|
||||
update_inv_neck(I)
|
||||
if(!QDELETED(src))
|
||||
update_inv_neck(I)
|
||||
else if(I == handcuffed)
|
||||
handcuffed = null
|
||||
if(buckled && buckled.buckle_requires_restraints)
|
||||
buckled.unbuckle_mob(src)
|
||||
update_handcuffed()
|
||||
if(!QDELETED(src))
|
||||
update_handcuffed()
|
||||
else if(I == legcuffed)
|
||||
legcuffed = null
|
||||
update_inv_legcuffed()
|
||||
if(!QDELETED(src))
|
||||
update_inv_legcuffed()
|
||||
|
||||
//handle stuff to update when a mob equips/unequips a mask.
|
||||
/mob/living/proc/wear_mask_update(obj/item/clothing/C, toggle_off = 1)
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
return
|
||||
if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
return
|
||||
if(istype(loc, /obj/item/device/dogborg/sleeper))
|
||||
return
|
||||
if(ismob(loc))
|
||||
return
|
||||
var/datum/gas_mixture/environment
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
..()
|
||||
|
||||
//These have to be after the parent new to ensure that the monkey
|
||||
//bodyparts are actually created before we try to equip things to
|
||||
//bodyparts are actually created before we try to equip things to
|
||||
//those slots
|
||||
if(relic_hat)
|
||||
equip_to_slot_or_del(new relic_hat, slot_head)
|
||||
@@ -42,32 +42,32 @@
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/punpun/proc/Read_Memory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Punpun.sav")
|
||||
S["ancestor_name"] >> ancestor_name
|
||||
S["ancestor_chain"] >> ancestor_chain
|
||||
S["relic_hat"] >> relic_hat
|
||||
S["relic_mask"] >> relic_mask
|
||||
var/json_file = file("data/npc_saves/Punpun.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
ancestor_name = json["ancestor_name"]
|
||||
ancestor_chain = json["ancestor_chain"]
|
||||
relic_hat = json["relic_hat"]
|
||||
relic_mask = json["relic_hat"]
|
||||
|
||||
/mob/living/carbon/monkey/punpun/proc/Write_Memory(dead, gibbed)
|
||||
var/savefile/S = new /savefile("data/npc_saves/Punpun.sav")
|
||||
var/json_file = file("data/npc_saves/Punpun.json")
|
||||
var/list/file_data = list()
|
||||
if(gibbed)
|
||||
WRITE_FILE(S["ancestor_name"], null)
|
||||
WRITE_FILE(S["ancestor_chain"], 1)
|
||||
WRITE_FILE(S["relic_hat"], null)
|
||||
WRITE_FILE(S["relic_mask"], null)
|
||||
return
|
||||
file_data["ancestor_name"] = null
|
||||
file_data["ancestor_chain"] = null
|
||||
file_data["relic_hat"] = null
|
||||
file_data["relic_mask"] = null
|
||||
if(dead)
|
||||
WRITE_FILE(S["ancestor_name"], ancestor_name)
|
||||
WRITE_FILE(S["ancestor_chain"], ancestor_chain + 1)
|
||||
if(!ancestor_name) //new monkey name this round
|
||||
WRITE_FILE(S["ancestor_name"], name)
|
||||
if(head)
|
||||
WRITE_FILE(S["relic_hat"], head.type)
|
||||
else
|
||||
WRITE_FILE(S["relic_hat"], null)
|
||||
if(wear_mask)
|
||||
WRITE_FILE(S["relic_mask"], wear_mask.type)
|
||||
else
|
||||
WRITE_FILE(S["relic_mask"], null)
|
||||
file_data["ancestor_name"] = ancestor_name
|
||||
file_data["ancestor_chain"] = ancestor_chain + 1
|
||||
file_data["relic_hat"] = head ? head.type : null
|
||||
file_data["relic_mask"] = wear_mask ? wear_mask.type : null
|
||||
if(!ancestor_name)
|
||||
file_data["ancestor_name"] = name
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(json_file))
|
||||
if(!dead)
|
||||
memory_saved = 1
|
||||
memory_saved = 1
|
||||
@@ -229,8 +229,8 @@
|
||||
/mob/living/verb/succumb(whispered as null)
|
||||
set hidden = 1
|
||||
if (InCritical())
|
||||
src.log_message("Has [whispered ? "whispered his final words" : "succumbed to death"] with [round(health, 0.1)] points of health!", INDIVIDUAL_ATTACK_LOG)
|
||||
src.adjustOxyLoss(src.health - HEALTH_THRESHOLD_DEAD)
|
||||
log_message("Has [whispered ? "whispered his final words" : "succumbed to death"] while in [InFullCritical() ? "hard":"soft"] critical with [round(health, 0.1)] points of health!", INDIVIDUAL_ATTACK_LOG)
|
||||
adjustOxyLoss(health - HEALTH_THRESHOLD_DEAD)
|
||||
updatehealth()
|
||||
if(!whispered)
|
||||
to_chat(src, "<span class='notice'>You have given up life and succumbed to death.</span>")
|
||||
@@ -241,7 +241,10 @@
|
||||
return 1
|
||||
|
||||
/mob/living/proc/InCritical()
|
||||
return (health < HEALTH_THRESHOLD_CRIT && health > HEALTH_THRESHOLD_DEAD && stat == UNCONSCIOUS)
|
||||
return (health <= HEALTH_THRESHOLD_CRIT && (stat == SOFT_CRIT || stat == UNCONSCIOUS))
|
||||
|
||||
/mob/living/proc/InFullCritical()
|
||||
return (health <= HEALTH_THRESHOLD_FULLCRIT && stat == UNCONSCIOUS)
|
||||
|
||||
//This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually
|
||||
//affects them once clothing is factored in. ~Errorage
|
||||
@@ -471,31 +474,31 @@
|
||||
if(MOVE_INTENT_WALK)
|
||||
. += config.walk_speed
|
||||
|
||||
/mob/living/proc/makeTrail(turf/T)
|
||||
/mob/living/proc/makeTrail(turf/target_turf)
|
||||
if(!has_gravity())
|
||||
return
|
||||
var/blood_exists = 0
|
||||
var/blood_exists = FALSE
|
||||
|
||||
for(var/obj/effect/decal/cleanable/trail_holder/C in src.loc) //checks for blood splatter already on the floor
|
||||
blood_exists = 1
|
||||
if (isturf(src.loc))
|
||||
for(var/obj/effect/decal/cleanable/trail_holder/C in loc) //checks for blood splatter already on the floor
|
||||
blood_exists = TRUE
|
||||
if(isturf(loc))
|
||||
var/trail_type = getTrail()
|
||||
if(trail_type)
|
||||
var/brute_ratio = round(getBruteLoss()/maxHealth, 0.1)
|
||||
var/brute_ratio = round(getBruteLoss() / maxHealth, 0.1)
|
||||
if(blood_volume && blood_volume > max(BLOOD_VOLUME_NORMAL*(1 - brute_ratio * 0.25), 0))//don't leave trail if blood volume below a threshold
|
||||
blood_volume = max(blood_volume - max(1, brute_ratio * 2), 0) //that depends on our brute damage.
|
||||
var/newdir = get_dir(T, src.loc)
|
||||
if(newdir != src.dir)
|
||||
newdir = newdir | src.dir
|
||||
var/newdir = get_dir(target_turf, loc)
|
||||
if(newdir != dir)
|
||||
newdir = newdir | dir
|
||||
if(newdir == 3) //N + S
|
||||
newdir = NORTH
|
||||
else if(newdir == 12) //E + W
|
||||
newdir = EAST
|
||||
if((newdir in GLOB.cardinals) && (prob(50)))
|
||||
newdir = turn(get_dir(T, src.loc), 180)
|
||||
newdir = turn(get_dir(target_turf, loc), 180)
|
||||
if(!blood_exists)
|
||||
new /obj/effect/decal/cleanable/trail_holder(src.loc)
|
||||
for(var/obj/effect/decal/cleanable/trail_holder/TH in src.loc)
|
||||
new /obj/effect/decal/cleanable/trail_holder(loc)
|
||||
for(var/obj/effect/decal/cleanable/trail_holder/TH in loc)
|
||||
if((!(newdir in TH.existing_dirs) || trail_type == "trails_1" || trail_type == "trails_2") && TH.existing_dirs.len <= 16) //maximum amount of overlays is 16 (all light & heavy directions filled)
|
||||
TH.existing_dirs += newdir
|
||||
TH.add_overlay(image('icons/effects/blood.dmi', trail_type, dir = newdir))
|
||||
@@ -560,7 +563,7 @@
|
||||
|
||||
// climbing out of a gut
|
||||
if(attempt_vr(src,"vore_process_resist",args)) return TRUE
|
||||
|
||||
|
||||
//Breaking out of a container (Locker, sleeper, cryo...)
|
||||
else if(isobj(loc))
|
||||
var/obj/C = loc
|
||||
@@ -687,6 +690,7 @@
|
||||
who.equip_to_slot(what, where, TRUE)
|
||||
|
||||
/mob/living/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_SIX)
|
||||
throw_at(S,14,3, spin=1)
|
||||
else
|
||||
@@ -946,13 +950,14 @@
|
||||
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
|
||||
//Robots, animals and brains have their own version so don't worry about them
|
||||
/mob/living/proc/update_canmove()
|
||||
var/ko = IsKnockdown() || IsUnconscious() || stat || (status_flags & FAKEDEATH)
|
||||
var/ko = IsKnockdown() || IsUnconscious() || (stat && (stat != SOFT_CRIT || pulledby)) || (status_flags & FAKEDEATH)
|
||||
var/move_and_fall = stat == SOFT_CRIT && !pulledby
|
||||
var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK
|
||||
var/buckle_lying = !(buckled && !buckled.buckle_lying)
|
||||
var/has_legs = get_num_legs()
|
||||
var/has_arms = get_num_arms()
|
||||
var/ignore_legs = get_leg_ignore()
|
||||
if(ko || resting || has_status_effect(STATUS_EFFECT_STUN) || chokehold)
|
||||
if(ko || resting || move_and_fall || IsStun() || chokehold)
|
||||
drop_all_held_items()
|
||||
unset_machine()
|
||||
if(pulling)
|
||||
@@ -965,7 +970,7 @@
|
||||
else if(!lying)
|
||||
if(resting)
|
||||
fall()
|
||||
else if(ko || (!has_legs && !ignore_legs) || chokehold)
|
||||
else if(ko || move_and_fall || (!has_legs && !ignore_legs) || chokehold)
|
||||
fall(forced = 1)
|
||||
canmove = !(ko || resting || has_status_effect(STATUS_EFFECT_STUN) || has_status_effect(/datum/status_effect/freon) || chokehold || buckled || (!has_legs && !ignore_legs && !has_arms))
|
||||
density = !lying
|
||||
|
||||
@@ -75,3 +75,5 @@
|
||||
var/datum/riding/riding_datum
|
||||
|
||||
var/datum/language/selected_default_language
|
||||
|
||||
var/last_words //used for database logging
|
||||
|
||||
@@ -145,16 +145,18 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
|
||||
var/succumbed = FALSE
|
||||
|
||||
if(message_mode == MODE_WHISPER)
|
||||
var/fullcrit = InFullCritical()
|
||||
if((InCritical() && !fullcrit) || message_mode == MODE_WHISPER)
|
||||
message_range = 1
|
||||
spans |= SPAN_ITALICS
|
||||
message_mode = MODE_WHISPER
|
||||
log_talk(src,"[key_name(src)] : [message]",LOGWHISPER)
|
||||
if(in_critical)
|
||||
if(fullcrit)
|
||||
var/health_diff = round(-HEALTH_THRESHOLD_DEAD + health)
|
||||
// If we cut our message short, abruptly end it with a-..
|
||||
var/message_len = length(message)
|
||||
message = copytext(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]"
|
||||
message = Ellipsis(message, 10, 1)
|
||||
last_words = message
|
||||
message_mode = MODE_WHISPER_CRIT
|
||||
succumbed = TRUE
|
||||
else
|
||||
@@ -164,7 +166,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
if(!message)
|
||||
return
|
||||
|
||||
spans += get_spans()
|
||||
spans |= get_spans()
|
||||
|
||||
if(language)
|
||||
var/datum/language/L = GLOB.language_datum_instances[language]
|
||||
@@ -295,10 +297,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
|
||||
/mob/living/proc/get_message_mode(message)
|
||||
var/key = copytext(message, 1, 2)
|
||||
if(key == ";")
|
||||
return MODE_HEADSET
|
||||
else if(key == "#")
|
||||
if(key == "#")
|
||||
return MODE_WHISPER
|
||||
else if(key == ";")
|
||||
return MODE_HEADSET
|
||||
else if(length(message) > 2 && (key in GLOB.department_radio_prefixes))
|
||||
var/key_symbol = lowertext(copytext(message, 2, 3))
|
||||
return GLOB.department_radio_keys[key_symbol]
|
||||
@@ -384,6 +386,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
|
||||
/mob/living/proc/radio(message, message_mode, list/spans, language)
|
||||
switch(message_mode)
|
||||
if(MODE_WHISPER)
|
||||
return ITALICS
|
||||
if(MODE_R_HAND)
|
||||
for(var/obj/item/r_hand in get_held_items_for_side("r", all = TRUE))
|
||||
if (r_hand)
|
||||
|
||||
@@ -465,7 +465,7 @@
|
||||
set category = "AI Commands"
|
||||
set name = "Access Robot Control"
|
||||
set desc = "Wirelessly control various automatic robots."
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
|
||||
if(control_disabled)
|
||||
@@ -585,7 +585,7 @@
|
||||
cameraFollow = null
|
||||
var/cameralist[0]
|
||||
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
@@ -629,7 +629,7 @@
|
||||
set category = "AI Commands"
|
||||
set name = "AI Status"
|
||||
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
var/list/ai_emotions = list("Very Happy", "Happy", "Neutral", "Unsure", "Confused", "Sad", "BSOD", "Blank", "Problems?", "Awesome", "Facepalm", "Friend Computer", "Dorfy", "Blue Glow", "Red Glow")
|
||||
var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions
|
||||
@@ -652,7 +652,7 @@
|
||||
set desc = "Change the default hologram available to AI to something else."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
var/input
|
||||
switch(alert("Would you like to select a hologram based on a crew member, an animal, or switch to a unique avatar?",,"Crew Member","Unique","Animal"))
|
||||
@@ -774,7 +774,7 @@
|
||||
set desc = "Allows you to change settings of your radio."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
|
||||
to_chat(src, "Accessing Subspace Transceiver control...")
|
||||
@@ -790,7 +790,7 @@
|
||||
set desc = "Modify the default radio setting for your automatic announcements."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(stat == 2)
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
set_autosay()
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
set category = "AI Commands"
|
||||
set name = "Toggle Camera Acceleration"
|
||||
|
||||
if(usr.stat == 2)
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
acceleration = !acceleration
|
||||
to_chat(usr, "Camera acceleration has been toggled [acceleration ? "on" : "off"].")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/mob/living/silicon/ai/proc/show_laws_verb()
|
||||
set category = "AI Commands"
|
||||
set name = "Show Laws"
|
||||
if(usr.stat == 2)
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
src.show_laws()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/silicon/ai/say(message, language)
|
||||
if(parent && istype(parent) && parent.stat != 2) //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
|
||||
if(parent && istype(parent) && parent.stat != DEAD) //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
|
||||
parent.say(message, language)
|
||||
return
|
||||
..(message)
|
||||
@@ -71,7 +71,7 @@
|
||||
set desc = "Display a list of vocal words to announce to the crew."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(usr.stat == 2)
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
|
||||
var/dat = "Here is a list of words you can type into the 'Announcement' button to create sentences to vocally announce to everyone on the same level at you.<BR> \
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
if(temp)
|
||||
left_part = temp
|
||||
else if(src.stat == 2) // Show some flavor text if the pAI is dead
|
||||
else if(src.stat == DEAD) // Show some flavor text if the pAI is dead
|
||||
left_part = "<b><font color=red>�Rr�R �a�� ��Rr����o�</font></b>"
|
||||
right_part = "<pre>Program index hash not found</pre>"
|
||||
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
var/d_hud = DATA_HUD_DIAGNOSTIC //There is only one kind of diag hud
|
||||
|
||||
var/law_change_counter = 0
|
||||
var/obj/machinery/camera/builtInCamera = null
|
||||
var/updating = FALSE //portable camera camerachunk update
|
||||
var/obj/machinery/camera/builtInCamera = null
|
||||
var/updating = FALSE //portable camera camerachunk update
|
||||
|
||||
/mob/living/silicon/Initialize()
|
||||
. = ..()
|
||||
. = ..()
|
||||
GLOB.silicon_mobs += src
|
||||
var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC]
|
||||
diag_hud.add_to_hud(src)
|
||||
@@ -56,7 +56,7 @@
|
||||
/mob/living/silicon/Destroy()
|
||||
radio = null
|
||||
aicamera = null
|
||||
QDEL_NULL(builtInCamera)
|
||||
QDEL_NULL(builtInCamera)
|
||||
GLOB.silicon_mobs -= src
|
||||
return ..()
|
||||
|
||||
@@ -310,7 +310,7 @@
|
||||
else //For department channels, if any, given by the internal radio.
|
||||
for(var/key in GLOB.department_radio_keys)
|
||||
if(GLOB.department_radio_keys[key] == Autochan)
|
||||
radiomod = key
|
||||
radiomod = ":" + key
|
||||
break
|
||||
|
||||
to_chat(src, "<span class='notice'>Automatic announcements [Autochan == "None" ? "will not use the radio." : "set to [Autochan]."]</span>")
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
desc = "A security robot. He looks less than thrilled."
|
||||
icon = 'icons/mob/aibots.dmi'
|
||||
icon_state = "ed2090"
|
||||
density = TRUE
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
anchored = FALSE
|
||||
health = 100
|
||||
maxHealth = 100
|
||||
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
@@ -59,7 +59,7 @@
|
||||
shot_delay = 6//Longer shot delay because JESUS CHRIST
|
||||
check_records = 0//Don't actively target people set to arrest
|
||||
arrest_type = 1//Don't even try to cuff
|
||||
bot_core.req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE)
|
||||
bot_core.req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE)
|
||||
arrest_type = 1
|
||||
if((lasercolor == "b") && (name == "\improper ED-209 Security Robot"))//Picks a name if there isn't already a custome one
|
||||
name = pick("BLUE BALLER","SANIC","BLUE KILLDEATH MURDERBOT")
|
||||
@@ -83,7 +83,7 @@
|
||||
..()
|
||||
target = null
|
||||
oldtarget_name = null
|
||||
anchored = FALSE
|
||||
anchored = FALSE
|
||||
walk_to(src,0)
|
||||
last_found = world.time
|
||||
set_weapon()
|
||||
@@ -153,7 +153,7 @@ Auto Patrol[]"},
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/judgement_criteria()
|
||||
var/final = FALSE
|
||||
var/final = FALSE
|
||||
if(idcheck)
|
||||
final = final|JUDGE_IDCHECK
|
||||
if(check_records)
|
||||
@@ -201,7 +201,7 @@ Auto Patrol[]"},
|
||||
set_weapon()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/bullet_act(obj/item/projectile/Proj)
|
||||
if(istype(Proj , /obj/item/projectile/beam/laser)||istype(Proj, /obj/item/projectile/bullet))
|
||||
if(istype(Proj , /obj/item/projectile/beam/laser)||istype(Proj, /obj/item/projectile/bullet))
|
||||
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
|
||||
if(!Proj.nodamage && Proj.damage < src.health)
|
||||
retaliate(Proj.firer)
|
||||
@@ -254,7 +254,7 @@ Auto Patrol[]"},
|
||||
stun_attack(target)
|
||||
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = TRUE
|
||||
anchored = TRUE
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
|
||||
@@ -288,7 +288,7 @@ Auto Patrol[]"},
|
||||
|
||||
if(BOT_ARREST)
|
||||
if(!target)
|
||||
anchored = FALSE
|
||||
anchored = FALSE
|
||||
mode = BOT_IDLE
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
@@ -303,7 +303,7 @@ Auto Patrol[]"},
|
||||
return
|
||||
else
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = FALSE
|
||||
anchored = FALSE
|
||||
|
||||
if(BOT_START_PATROL)
|
||||
look_for_perp()
|
||||
@@ -317,7 +317,7 @@ Auto Patrol[]"},
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/back_to_idle()
|
||||
anchored = FALSE
|
||||
anchored = FALSE
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
last_found = world.time
|
||||
@@ -325,7 +325,7 @@ Auto Patrol[]"},
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action) //ensure bot quickly responds
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/back_to_hunt()
|
||||
anchored = FALSE
|
||||
anchored = FALSE
|
||||
frustration = 0
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action) //ensure bot quickly responds
|
||||
@@ -335,7 +335,7 @@ Auto Patrol[]"},
|
||||
/mob/living/simple_animal/bot/ed209/proc/look_for_perp()
|
||||
if(disabled)
|
||||
return
|
||||
anchored = FALSE
|
||||
anchored = FALSE
|
||||
threatlevel = 0
|
||||
var/judgement_criteria = judgement_criteria()
|
||||
for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
|
||||
@@ -464,7 +464,7 @@ Auto Patrol[]"},
|
||||
new /obj/effect/temp_visual/emp(loc)
|
||||
var/list/mob/living/carbon/targets = new
|
||||
for(var/mob/living/carbon/C in view(12,src))
|
||||
if(C.stat==2)
|
||||
if(C.stat==DEAD)
|
||||
continue
|
||||
targets += C
|
||||
if(targets.len)
|
||||
@@ -476,7 +476,7 @@ Auto Patrol[]"},
|
||||
emagged = 2
|
||||
set_weapon()
|
||||
shootAt(toshoot)
|
||||
emagged = FALSE
|
||||
emagged = FALSE
|
||||
set_weapon()
|
||||
else
|
||||
shootAt(toshoot)
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
oldpatient = user
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/process_scan(mob/living/carbon/human/H)
|
||||
if(H.stat == 2)
|
||||
if(H.stat == DEAD)
|
||||
return
|
||||
|
||||
if((H == oldpatient) && (world.time < last_found + 200))
|
||||
|
||||
@@ -28,3 +28,6 @@
|
||||
. = ..()
|
||||
var/newcolor = rgb(rand(0, 255), rand(0, 255), rand(0, 255))
|
||||
add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY)
|
||||
|
||||
/mob/living/simple_animal/butterfly/bee_friendly()
|
||||
return TRUE //treaty signed at the Beeneeva convention
|
||||
|
||||
@@ -113,14 +113,17 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Runtime.sav")
|
||||
S["family"] >> family
|
||||
|
||||
var/json_file = file("data/npc_saves/Runtime.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
family = json["family"]
|
||||
if(isnull(family))
|
||||
family = list()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Write_Memory(dead)
|
||||
var/savefile/S = new /savefile("data/npc_saves/Runtime.sav")
|
||||
var/json_file = file("data/npc_saves/Runtime.json")
|
||||
family = list()
|
||||
if(!dead)
|
||||
for(var/mob/living/simple_animal/pet/cat/kitten/C in children)
|
||||
@@ -130,7 +133,8 @@
|
||||
family[C.type] += 1
|
||||
else
|
||||
family[C.type] = 1
|
||||
WRITE_FILE(S["family"], family)
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(family))
|
||||
memory_saved = 1
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Deploy_The_Cats()
|
||||
@@ -271,4 +275,4 @@
|
||||
..()
|
||||
if(L.a_intent == INTENT_HARM && L.reagents && !stat)
|
||||
L.reagents.add_reagent("nutriment", 0.4)
|
||||
L.reagents.add_reagent("vitamin", 0.4)
|
||||
L.reagents.add_reagent("vitamin", 0.4)
|
||||
@@ -328,33 +328,37 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/proc/Read_Memory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Ian.sav")
|
||||
S["age"] >> age
|
||||
S["record_age"] >> record_age
|
||||
S["saved_head"] >> saved_head
|
||||
|
||||
var/json_file = file("data/npc_saves/Ian.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
age = json["age"]
|
||||
record_age = json["record_age"]
|
||||
saved_head = json["saved_head"]
|
||||
if(isnull(age))
|
||||
age = 0
|
||||
if(isnull(record_age))
|
||||
record_age = 1
|
||||
|
||||
if(saved_head)
|
||||
place_on_head(new saved_head)
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/proc/Write_Memory(dead)
|
||||
var/savefile/S = new /savefile("data/npc_saves/Ian.sav")
|
||||
var/json_file = file("data/npc_saves/Ian.json")
|
||||
var/list/file_data = list()
|
||||
if(!dead)
|
||||
WRITE_FILE(S["age"], age + 1)
|
||||
file_data["age"] = age + 1
|
||||
if((age + 1) > record_age)
|
||||
WRITE_FILE(S["record_age"], record_age + 1)
|
||||
file_data["record_age"] = record_age + 1
|
||||
if(inventory_head)
|
||||
WRITE_FILE(S["saved_head"], inventory_head.type)
|
||||
file_data["saved_head"] = inventory_head.type
|
||||
else
|
||||
WRITE_FILE(S["age"], 0)
|
||||
WRITE_FILE(S["saved_head"], null)
|
||||
file_data["age"] = 0
|
||||
file_data["saved_head"] = null
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
memory_saved = 1
|
||||
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/Life()
|
||||
..()
|
||||
|
||||
@@ -565,4 +569,4 @@
|
||||
emote("me", 1, "yaps happily!")
|
||||
else
|
||||
if(M && stat != DEAD) // Same check here, even though emote checks it as well (poor form to check it only in the help case)
|
||||
emote("me", 1, "growls!")
|
||||
emote("me", 1, "growls!")
|
||||
@@ -15,6 +15,10 @@
|
||||
/mob/living/simple_animal/drone/verb/toggle_light()
|
||||
set category = "Drone"
|
||||
set name = "Toggle drone light"
|
||||
|
||||
if(stat == DEAD)
|
||||
to_chat(src, "<span class='warning'>There's no light in your life... by that I mean you're dead.</span>")
|
||||
return
|
||||
if(light_on)
|
||||
set_light(0)
|
||||
else
|
||||
|
||||
@@ -24,11 +24,17 @@
|
||||
butcher_results = list()
|
||||
gold_core_spawnable = 2
|
||||
|
||||
/mob/living/simple_animal/pet/penguin/emperor/shamebrero
|
||||
name = "Shamebrero penguin."
|
||||
desc = "Shameful of all he surveys."
|
||||
icon_state = "penguin_shamebrero"
|
||||
icon_living = "penguin_shamebrero"
|
||||
|
||||
/mob/living/simple_animal/pet/penguin/baby
|
||||
speak = list("gah", "noot noot", "noot!", "noot", "squeee!", "noo!")
|
||||
name = "Penguin chick"
|
||||
real_name = "penguin"
|
||||
desc = "Can't fly and can barely waddles, but the prince of all chicks."
|
||||
desc = "Can't fly and barely waddles, yet the prince of all chicks."
|
||||
icon_state = "penguin_baby"
|
||||
icon_living = "penguin_baby"
|
||||
icon_dead = "penguin_baby_dead"
|
||||
|
||||
@@ -57,7 +57,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/med_hud_set_health()
|
||||
if(summoner)
|
||||
if(!QDELETED(summoner))
|
||||
var/image/holder = hud_list[HEALTH_HUD]
|
||||
holder.icon_state = "hud[RoundHealth(summoner)]"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "A Perfectly Generic Boss Placeholder"
|
||||
desc = ""
|
||||
robust_searching = 1
|
||||
stat_attack = 1
|
||||
stat_attack = UNCONSCIOUS
|
||||
status_flags = 0
|
||||
a_intent = INTENT_HARM
|
||||
gender = NEUTER
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
speed = 0
|
||||
maxHealth = 80
|
||||
health = 80
|
||||
stat_attack = 1
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = 1
|
||||
|
||||
harm_intent_damage = 10
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
faction = list("creature")
|
||||
robust_searching = 1
|
||||
stat_attack = 2
|
||||
stat_attack = DEAD
|
||||
obj_damage = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
speak_emote = list("squeaks")
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
var/ranged_message = "fires" //Fluff text for ranged mobs
|
||||
var/ranged_cooldown = 0 //What the current cooldown on ranged attacks is, generally world.time + ranged_cooldown_time
|
||||
var/ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is
|
||||
var/ranged_telegraph = "prepares to fire at *TARGET*!" //A message shown when the mob prepares to fire; use *TARGET* if you want to show the target's name
|
||||
var/ranged_telegraph_sound //A sound played when the mob prepares to fire
|
||||
var/ranged_telegraph_time = 0 //In deciseconds, how long between the telegraph and ranged shot
|
||||
var/ranged_ignores_vision = FALSE //if it'll fire ranged attacks even if it lacks vision on its target, only works with environment smash
|
||||
var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting
|
||||
var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat.
|
||||
@@ -43,8 +46,8 @@
|
||||
var/search_objects_timer_id //Timer for regaining our old search_objects value after being attacked
|
||||
var/search_objects_regain_time = 30 //the delay between being attacked and gaining our old search_objects value back
|
||||
var/list/wanted_objects = list() //A typecache of objects types that will be checked against to attack, should we have search_objects enabled
|
||||
var/stat_attack = 0 //Mobs with stat_attack to 1 will attempt to attack things that are unconscious, Mobs with stat_attack set to 2 will attempt to attack the dead.
|
||||
var/stat_exclusive = 0 //Mobs with this set to 1 will exclusively attack things defined by stat_attack, stat_attack 2 means they will only attack corpses
|
||||
var/stat_attack = CONSCIOUS //Mobs with stat_attack to UNCONSCIOUS will attempt to attack things that are unconscious, Mobs with stat_attack set to 2 will attempt to attack the dead.
|
||||
var/stat_exclusive = FALSE //Mobs with this set to TRUE will exclusively attack things defined by stat_attack, stat_attack 2 means they will only attack corpses
|
||||
var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction
|
||||
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
|
||||
var/atom/targets_from = null //all range/attack/etc. calculations should be done from this atom, defaults to the mob itself, useful for Vehicles and such
|
||||
@@ -171,7 +174,7 @@
|
||||
var/mob/living/L = the_target
|
||||
var/faction_check = faction_check_mob(L)
|
||||
if(robust_searching)
|
||||
if(L.stat > stat_attack || L.stat != stat_attack && stat_exclusive == 1)
|
||||
if(L.stat > stat_attack || L.stat != stat_attack && stat_exclusive)
|
||||
return 0
|
||||
if(faction_check && !attack_same || !faction_check && attack_same == 2)
|
||||
return 0
|
||||
@@ -232,7 +235,14 @@
|
||||
var/target_distance = get_dist(targets_from,target)
|
||||
if(ranged) //We ranged? Shoot at em
|
||||
if(!target.Adjacent(targets_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown
|
||||
OpenFire(target)
|
||||
if(!ranged_telegraph_time || client)
|
||||
OpenFire(target)
|
||||
else
|
||||
if(ranged_telegraph)
|
||||
visible_message("<span class='danger'>[src] [replacetext(ranged_telegraph, "*TARGET*", "[target]")]</span>")
|
||||
if(ranged_telegraph_sound)
|
||||
playsound(src, ranged_telegraph_sound, 75, FALSE)
|
||||
addtimer(CALLBACK(src, .proc/OpenFire, target), ranged_telegraph_time)
|
||||
if(!Process_Spacemove()) //Drifting
|
||||
walk(src,0)
|
||||
return 1
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
pixel_x = -16
|
||||
layer = LARGE_MOB_LAYER
|
||||
speed = 10
|
||||
stat_attack = 1
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = 1
|
||||
var/hopping = FALSE
|
||||
var/hop_cooldown = 0 //Strictly for player controlled leapers
|
||||
|
||||
@@ -277,19 +277,24 @@ Difficulty: Very Hard
|
||||
WriteMemory()
|
||||
|
||||
/obj/machinery/smartfridge/black_box/proc/WriteMemory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Blackbox.sav")
|
||||
var/json_file = file("data/npc_saves/Blackbox.json")
|
||||
stored_items = list()
|
||||
|
||||
for(var/obj/O in (contents-component_parts))
|
||||
stored_items += O.type
|
||||
|
||||
WRITE_FILE(S["stored_items"], stored_items)
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = stored_items
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
memory_saved = TRUE
|
||||
|
||||
/obj/machinery/smartfridge/black_box/proc/ReadMemory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Blackbox.sav")
|
||||
S["stored_items"] >> stored_items
|
||||
|
||||
var/json_file = file("data/npc_saves/Blackbox.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
stored_items = json["data"]
|
||||
if(isnull(stored_items))
|
||||
stored_items = list()
|
||||
|
||||
@@ -782,4 +787,4 @@ Difficulty: Very Hard
|
||||
#undef ACTIVATE_WEAPON
|
||||
#undef ACTIVATE_MAGIC
|
||||
|
||||
#undef MEDAL_PREFIX
|
||||
#undef MEDAL_PREFIX
|
||||
@@ -16,7 +16,7 @@
|
||||
movement_type = FLYING
|
||||
robust_searching = 1
|
||||
ranged_ignores_vision = TRUE
|
||||
stat_attack = 2
|
||||
stat_attack = DEAD
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
damage_coeff = list(BRUTE = 1, BURN = 0.5, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
|
||||
minbodytemp = 0
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
ranged = 1
|
||||
ranged_message = "stares"
|
||||
ranged_cooldown_time = 30
|
||||
ranged_telegraph = "gathers energy and stares at *TARGET*!"
|
||||
ranged_telegraph_sound = 'sound/magic/magic_missile.ogg'
|
||||
ranged_telegraph_time = 7
|
||||
throw_message = "does nothing against the hard shell of"
|
||||
vision_range = 2
|
||||
speed = 3
|
||||
@@ -70,9 +73,11 @@
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
attacktext = "impales"
|
||||
ranged_telegraph = "fixates on *TARGET* as its eye shines blue!"
|
||||
ranged_telegraph_sound = 'sound/magic/tail_swing.ogg'
|
||||
ranged_telegraph_time = 5
|
||||
a_intent = INTENT_HARM
|
||||
speak_emote = list("telepathically cries")
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
stat_attack = UNCONSCIOUS
|
||||
movement_type = FLYING
|
||||
robust_searching = 1
|
||||
@@ -80,5 +85,35 @@
|
||||
loot = list()
|
||||
butcher_results = list(/obj/item/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/make_shiny()
|
||||
if(prob(75))
|
||||
name = "magmawing watcher"
|
||||
real_name = name
|
||||
desc = "When raised very close to lava, some watchers adapt to the extreme heat and change coloration. Such watchers are known as magmawings and use intense heat as their tool for hunting and defense."
|
||||
icon_state = "watcher_magmawing"
|
||||
icon_living = "watcher_magmawing"
|
||||
icon_aggro = "watcher_magmawing"
|
||||
icon_dead = "watcher_magmawing_dead"
|
||||
maxHealth = 215 //Compensate for the lack of slowdown on projectiles with a bit of extra health
|
||||
health = 215
|
||||
projectiletype = /obj/item/projectile/temp/basilisk/magmawing
|
||||
else
|
||||
name = "icewing watcher"
|
||||
real_name = name
|
||||
desc = "Very rarely, some watchers will eke out an existence far from heat sources. In the absence of warmth, their wings will become papery and turn to an icy blue; these watchers are fragile but much quicker to fire their trademark freezing blasts."
|
||||
icon_state = "watcher_icewing"
|
||||
icon_living = "watcher_icewing"
|
||||
icon_aggro = "watcher_icewing"
|
||||
icon_dead = "watcher_icewing_dead"
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
ranged_cooldown_time = 20
|
||||
butcher_results = list(/obj/item/ore/diamond = 5, /obj/item/stack/sheet/bone = 1) //No sinew; the wings are too fragile to be usable
|
||||
|
||||
/obj/item/projectile/temp/basilisk/magmawing
|
||||
name = "scorching blast"
|
||||
icon_state = "gaussstrong"
|
||||
temperature = 500 //Heats you up!
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril
|
||||
fromtendril = TRUE
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
var/pre_attack = 0
|
||||
var/pre_attack_icon = "Goliath_preattack"
|
||||
loot = list(/obj/item/stack/sheet/animalhide/goliath_hide)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/goliath = 2, /obj/item/stack/sheet/animalhide/goliath_hide = 1, /obj/item/stack/sheet/bone = 2)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/Life()
|
||||
..()
|
||||
@@ -86,14 +87,28 @@
|
||||
throw_message = "does nothing to the tough hide of the"
|
||||
pre_attack_icon = "goliath2"
|
||||
crusher_loot = /obj/item/crusher_trophy/goliath_tentacle
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/goliath = 2, /obj/item/stack/sheet/animalhide/goliath_hide = 1, /obj/item/stack/sheet/bone = 2)
|
||||
loot = list()
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/make_shiny()
|
||||
name = "precursor goliath"
|
||||
real_name = name
|
||||
desc = "Due to their stone hide, goliaths are biologically immortal, although future generations evolved to look much different. This goliath is likely a very early ancestor to many others here, and at least several centuries old."
|
||||
icon_state = "Goliath"
|
||||
icon_living = "Goliath"
|
||||
icon_aggro = "Goliath_alert"
|
||||
icon_dead = "Goliath_dead"
|
||||
pre_attack_icon = "Goliath_preattack"
|
||||
throw_message = "does nothing to the rocky hide of the"
|
||||
loot = list(/obj/item/stack/sheet/animalhide/goliath_hide) //A throwback to the asteroid days
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril
|
||||
fromtendril = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril/make_shiny()
|
||||
return //Precursor goliaths don't come from tendrils!
|
||||
|
||||
//tentacles
|
||||
/obj/effect/goliath_tentacle
|
||||
name = "Goliath tentacle"
|
||||
|
||||
@@ -110,8 +110,21 @@
|
||||
del_on_death = 1
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = 1
|
||||
shiny_chance = 5
|
||||
var/mob/living/carbon/human/stored_mob
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/make_shiny()
|
||||
name = "dwarf legion"
|
||||
real_name = name
|
||||
desc = "On the rare occasion that a human with dwarfism falls to a legion, they can become infested like any other."
|
||||
icon_state = "dwarf_legion"
|
||||
icon_living = "dwarf_legion"
|
||||
icon_aggro = "dwarf_legion"
|
||||
icon_dead = "dwarf_legion"
|
||||
maxHealth = 60
|
||||
health = 60
|
||||
speed = 2 //faster!
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/death(gibbed)
|
||||
visible_message("<span class='warning'>The skulls on [src] wail in anger as they flee from their dying host!</span>")
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -170,11 +183,13 @@
|
||||
H.adjustBruteLoss(1000)
|
||||
L.stored_mob = H
|
||||
H.forceMove(L)
|
||||
if(H.dna.check_mutation(DWARFISM))
|
||||
L.make_shiny() //dwarf legions aren't just fluff!
|
||||
qdel(src)
|
||||
|
||||
//Advanced Legion is slightly tougher to kill and can raise corpses (revive other legions)
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/advanced
|
||||
stat_attack = 2
|
||||
stat_attack = DEAD
|
||||
maxHealth = 120
|
||||
health = 120
|
||||
brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/advanced
|
||||
@@ -184,7 +199,7 @@
|
||||
icon_dead = "dwarf_legion"
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/advanced
|
||||
stat_attack = 2
|
||||
stat_attack = DEAD
|
||||
can_infest_dead = TRUE
|
||||
|
||||
//Legion that spawns Legions
|
||||
|
||||
@@ -15,15 +15,22 @@
|
||||
a_intent = INTENT_HARM
|
||||
var/crusher_loot
|
||||
var/throw_message = "bounces off of"
|
||||
var/icon_aggro = null // for swapping to when we get aggressive
|
||||
var/fromtendril = FALSE
|
||||
see_in_dark = 8
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
var/icon_aggro = null
|
||||
var/shiny = FALSE //If this mob is a much rarer version of its normal self
|
||||
var/shiny_chance = 1 //If this chance passes, the mob will somehow be different from normal ones
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Initialize(mapload)
|
||||
. = ..()
|
||||
apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
|
||||
if(prob(shiny_chance))
|
||||
shiny = TRUE
|
||||
make_shiny()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/proc/make_shiny() //Override this on a per-mob basis
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Aggro()
|
||||
..()
|
||||
@@ -57,7 +64,7 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/death(gibbed)
|
||||
SSblackbox.add_details("mobs_killed_mining","[src.type]")
|
||||
var/datum/status_effect/crusher_damage/C = has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
|
||||
if(C && crusher_loot && prob((C.total_damage/maxHealth)) * 5) //on average, you'll need to kill 20 creatures before getting the item
|
||||
if(C && crusher_loot && prob(((C.total_damage/maxHealth)) * 5) + shiny) //on average, you'll need to kill 20 creatures before getting the item
|
||||
spawn_crusher_loot()
|
||||
..(gibbed)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
faction = list("mushroom")
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
stat_attack = 2
|
||||
stat_attack = DEAD
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
speed = 1
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
response_disarm = "shoves"
|
||||
response_harm = "hits"
|
||||
speed = 0
|
||||
stat_attack = 1
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = 1
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
response_disarm = "shoves"
|
||||
response_harm = "hits"
|
||||
speed = 0
|
||||
stat_attack = 1
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = 1
|
||||
vision_range = 3
|
||||
maxHealth = 100
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
unsuitable_atmos_damage = 10
|
||||
robust_searching = 1
|
||||
stat_attack = 1
|
||||
stat_attack = UNCONSCIOUS
|
||||
gold_core_spawnable = 1
|
||||
faction = list("skeleton")
|
||||
see_in_dark = 8
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
response_disarm = "shoves"
|
||||
response_harm = "hits"
|
||||
speed = 0
|
||||
stat_attack = 1
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = 1
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
maxHealth = 100
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
response_disarm = "shoves"
|
||||
response_harm = "hits"
|
||||
speed = 0
|
||||
stat_attack = 1
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = 1
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
|
||||
@@ -924,22 +924,28 @@
|
||||
..(gibbed)
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/proc/Read_Memory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Poly.sav")
|
||||
S["phrases"] >> speech_buffer
|
||||
S["roundssurvived"] >> rounds_survived
|
||||
S["longestsurvival"] >> longest_survival
|
||||
S["longestdeathstreak"] >> longest_deathstreak
|
||||
|
||||
var/json_file = file("data/npc_saves/Poly.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/list/json = list()
|
||||
json = json_decode(file2text(json_file))
|
||||
speech_buffer = json["phrases"]
|
||||
rounds_survived = json["roundssurvived"]
|
||||
longest_survival = json["longestsurvival"]
|
||||
longest_deathstreak = json["longestdeathstreak"]
|
||||
if(!islist(speech_buffer))
|
||||
speech_buffer = list()
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/proc/Write_Memory()
|
||||
var/savefile/S = new /savefile("data/npc_saves/Poly.sav")
|
||||
var/json_file = file("data/npc_saves/Poly.json")
|
||||
var/list/file_data = list()
|
||||
if(islist(speech_buffer))
|
||||
WRITE_FILE(S["phrases"], speech_buffer)
|
||||
WRITE_FILE(S["roundssurvived"], rounds_survived)
|
||||
WRITE_FILE(S["longestsurvival"], longest_survival)
|
||||
WRITE_FILE(S["longestdeathstreak"], longest_deathstreak)
|
||||
file_data["phrases"] = speech_buffer
|
||||
file_data["roundssurvived"] = rounds_survived
|
||||
file_data["longestsurvival"] = longest_survival
|
||||
file_data["longestdeathstreak"] = longest_deathstreak
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
memory_saved = 1
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/ghost
|
||||
|
||||
@@ -438,7 +438,7 @@
|
||||
|
||||
if (!( GLOB.abandon_allowed ))
|
||||
return
|
||||
if ((stat != 2 || !( SSticker )))
|
||||
if ((stat != DEAD || !( SSticker )))
|
||||
to_chat(usr, "<span class='boldnotice'>You must be dead to use this!</span>")
|
||||
return
|
||||
|
||||
@@ -491,7 +491,7 @@
|
||||
var/t1 = text("window=[href_list["mach_close"]]")
|
||||
unset_machine()
|
||||
src << browse(null, t1)
|
||||
|
||||
|
||||
if(href_list["flavor_more"])
|
||||
usr << browse(text("<HTML><HEAD><TITLE>[]</TITLE></HEAD><BODY><TT>[]</TT></BODY></HTML>", name, replacetext(flavor_text, "\n", "<BR>")), text("window=[];size=500x200", name))
|
||||
onclose(usr, "[name]")
|
||||
@@ -587,7 +587,7 @@
|
||||
var/turf/T = get_turf(client.eye)
|
||||
stat("Location:", COORD(T))
|
||||
stat("CPU:", "[world.cpu]")
|
||||
stat("Instances:", "[world.contents.len]")
|
||||
stat("Instances:", "[num2text(world.contents.len, 10)]")
|
||||
GLOB.stat_entry()
|
||||
config.stat_entry()
|
||||
stat(null)
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
var/old_eye_blind = eye_blind
|
||||
eye_blind = max(eye_blind, amount)
|
||||
if(!old_eye_blind)
|
||||
if(stat == CONSCIOUS)
|
||||
if(stat == CONSCIOUS || stat == SOFT_CRIT)
|
||||
throw_alert("blind", /obj/screen/alert/blind)
|
||||
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
|
||||
|
||||
@@ -155,12 +155,12 @@
|
||||
var/old_eye_blind = eye_blind
|
||||
eye_blind += amount
|
||||
if(!old_eye_blind)
|
||||
if(stat == CONSCIOUS)
|
||||
if(stat == CONSCIOUS || stat == SOFT_CRIT)
|
||||
throw_alert("blind", /obj/screen/alert/blind)
|
||||
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
|
||||
else if(eye_blind)
|
||||
var/blind_minimum = 0
|
||||
if(stat != CONSCIOUS || (disabilities & BLIND))
|
||||
if((stat != CONSCIOUS && stat != SOFT_CRIT) || (disabilities & BLIND))
|
||||
blind_minimum = 1
|
||||
eye_blind = max(eye_blind+amount, blind_minimum)
|
||||
if(!eye_blind)
|
||||
@@ -172,12 +172,12 @@
|
||||
var/old_eye_blind = eye_blind
|
||||
eye_blind = amount
|
||||
if(client && !old_eye_blind)
|
||||
if(stat == CONSCIOUS)
|
||||
if(stat == CONSCIOUS || stat == SOFT_CRIT)
|
||||
throw_alert("blind", /obj/screen/alert/blind)
|
||||
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
|
||||
else if(eye_blind)
|
||||
var/blind_minimum = 0
|
||||
if(stat != CONSCIOUS || (disabilities & BLIND))
|
||||
if((stat != CONSCIOUS && stat != SOFT_CRIT) || (disabilities & BLIND))
|
||||
blind_minimum = 1
|
||||
eye_blind = blind_minimum
|
||||
if(!eye_blind)
|
||||
|
||||
Reference in New Issue
Block a user