Merge remote-tracking branch 'citadel/master' into mobility_flags
This commit is contained in:
@@ -16,7 +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,var/roundstart = FALSE)//Roundstart argument builds a specific list for roundstart parts where some parts may be locked
|
||||
/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()
|
||||
if(!istype(male))
|
||||
@@ -25,7 +25,7 @@
|
||||
female = list()
|
||||
|
||||
for(var/path in typesof(prototype))
|
||||
if(path == prototype)
|
||||
if(path == prototype && skip_prototype)
|
||||
continue
|
||||
if(roundstart)
|
||||
var/datum/sprite_accessory/P = path
|
||||
|
||||
@@ -159,6 +159,11 @@
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
|
||||
|
||||
/datum/sprite_accessory/ears/bunny
|
||||
name = "Bunny"
|
||||
icon_state = "bunny"
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
|
||||
|
||||
/******************************************
|
||||
*************** Furry Ears ****************
|
||||
@@ -301,3 +306,7 @@
|
||||
/datum/sprite_accessory/mam_ears/wolf
|
||||
name = "Wolf"
|
||||
icon_state = "wolf"
|
||||
|
||||
/datum/sprite_accessory/mam_ears/bunny
|
||||
name = "Bunny"
|
||||
icon_state = "bunny"
|
||||
@@ -479,32 +479,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
pixel_y = 0
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1)
|
||||
|
||||
/mob/dead/observer/verb/observe()
|
||||
set name = "Observe"
|
||||
set category = "Ghost"
|
||||
|
||||
var/list/creatures = getpois()
|
||||
|
||||
reset_perspective(null)
|
||||
|
||||
var/eye_name = null
|
||||
|
||||
eye_name = input("Please, select a player!", "Observe", null, null) as null|anything in creatures
|
||||
|
||||
if (!eye_name)
|
||||
return
|
||||
|
||||
var/mob/mob_eye = creatures[eye_name]
|
||||
//Istype so we filter out points of interest that are not mobs
|
||||
if(client && mob_eye && istype(mob_eye))
|
||||
client.eye = mob_eye
|
||||
if(mob_eye.hud_used)
|
||||
client.screen = list()
|
||||
LAZYINITLIST(mob_eye.observers)
|
||||
mob_eye.observers |= src
|
||||
mob_eye.hud_used.show_hud(mob_eye.hud_used.hud_version, src)
|
||||
observetarget = mob_eye
|
||||
|
||||
/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
|
||||
set category = "Ghost"
|
||||
set name = "Jump to Mob"
|
||||
@@ -796,7 +770,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
update_icon()
|
||||
|
||||
/mob/dead/observer/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
|
||||
return IsAdminGhost(usr)
|
||||
return IsAdminGhost(usr) || (M.ghost_flags & INTERACT_GHOST_READ)
|
||||
|
||||
/mob/dead/observer/is_literate()
|
||||
return 1
|
||||
@@ -831,6 +805,32 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
client.screen = list()
|
||||
hud_used.show_hud(hud_used.hud_version)
|
||||
|
||||
/mob/dead/observer/verb/observe()
|
||||
set name = "Observe"
|
||||
set category = "OOC"
|
||||
|
||||
var/list/creatures = getpois()
|
||||
|
||||
reset_perspective(null)
|
||||
|
||||
var/eye_name = null
|
||||
|
||||
eye_name = input("Please, select a player!", "Observe", null, null) as null|anything in creatures
|
||||
|
||||
if (!eye_name)
|
||||
return
|
||||
|
||||
var/mob/mob_eye = creatures[eye_name]
|
||||
//Istype so we filter out points of interest that are not mobs
|
||||
if(client && mob_eye && istype(mob_eye))
|
||||
client.eye = mob_eye
|
||||
if(mob_eye.hud_used)
|
||||
client.screen = list()
|
||||
LAZYINITLIST(mob_eye.observers)
|
||||
mob_eye.observers |= src
|
||||
mob_eye.hud_used.show_hud(mob_eye.hud_used.hud_version, src)
|
||||
observetarget = mob_eye
|
||||
|
||||
/mob/dead/observer/verb/register_pai_candidate()
|
||||
set category = "Ghost"
|
||||
set name = "pAI Setup"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
. = say_dead(message)
|
||||
|
||||
/mob/dead/observer/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source)
|
||||
. = ..()
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args) //parent calls can't overwrite the current proc args.
|
||||
var/atom/movable/to_follow = speaker
|
||||
if(radio_freq)
|
||||
var/atom/movable/virtualspeaker/V = speaker
|
||||
@@ -36,4 +36,3 @@
|
||||
// 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]")
|
||||
|
||||
|
||||
@@ -252,7 +252,9 @@
|
||||
return 0
|
||||
if(M.getorgan(/obj/item/organ/alien/hivenode))
|
||||
return 0
|
||||
|
||||
if(isvamp(M))
|
||||
return 0
|
||||
|
||||
if(ismonkey(M))
|
||||
return 1
|
||||
|
||||
|
||||
@@ -559,7 +559,7 @@
|
||||
health = round(maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute, DAMAGE_PRECISION)
|
||||
staminaloss = round(total_stamina, DAMAGE_PRECISION)
|
||||
update_stat()
|
||||
if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD) && stat == DEAD )
|
||||
if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD*2) && stat == DEAD )
|
||||
become_husk("burn")
|
||||
med_hud_set_health()
|
||||
if(stat == SOFT_CRIT)
|
||||
@@ -986,4 +986,4 @@
|
||||
if(H.clothing_flags & SCAN_REAGENTS)
|
||||
return TRUE
|
||||
if(isclothing(wear_mask) && (wear_mask.clothing_flags & SCAN_REAGENTS))
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -274,7 +274,7 @@
|
||||
return
|
||||
|
||||
if(health >= 0 && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
|
||||
|
||||
var/friendly_check = FALSE
|
||||
if(lying)
|
||||
if(buckled)
|
||||
to_chat(M, "<span class='warning'>You need to unbuckle [src] first to do that!")
|
||||
@@ -289,39 +289,35 @@
|
||||
playsound(src, 'sound/items/Nose_boop.ogg', 50, 0)
|
||||
|
||||
else if(check_zone(M.zone_selected) == "head")
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/datum/species/pref_species = H.dna.species
|
||||
var/datum/species/S
|
||||
if(ishuman(src))
|
||||
S = dna.species
|
||||
|
||||
M.visible_message("<span class='notice'>[M] gives [H] a pat on the head to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You give [H] a pat on the head to make [p_them()] feel better!</span>")
|
||||
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>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat)
|
||||
if(HAS_TRAIT(M, TRAIT_FRIENDLY))
|
||||
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
|
||||
if (mood.sanity >= SANITY_GREAT)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M)
|
||||
else if (mood.sanity >= SANITY_DISTURBED)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/betterhug, M)
|
||||
if(H.dna.species.can_wag_tail(H))
|
||||
if("tail_human" in pref_species.default_features)
|
||||
if(H.dna.features["tail_human"] == "None")
|
||||
friendly_check = TRUE
|
||||
if(S?.can_wag_tail(src))
|
||||
if("tail_human" in S.default_features)
|
||||
if(dna.features["tail_human"] == "None")
|
||||
return
|
||||
else
|
||||
if(!H.dna.species.is_wagging_tail())
|
||||
H.emote("wag")
|
||||
if(!dna.species.is_wagging_tail())
|
||||
emote("wag")
|
||||
|
||||
if("tail_lizard" in pref_species.default_features)
|
||||
if(H.dna.features["tail_lizard"] == "None")
|
||||
if("tail_lizard" in S.default_features)
|
||||
if(dna.features["tail_lizard"] == "None")
|
||||
return
|
||||
else
|
||||
if(!H.dna.species.is_wagging_tail())
|
||||
H.emote("wag")
|
||||
if(!dna.species.is_wagging_tail())
|
||||
emote("wag")
|
||||
|
||||
if("mam_tail" in pref_species.default_features)
|
||||
if(H.dna.features["mam_tail"] == "None")
|
||||
if("mam_tail" in S.default_features)
|
||||
if(dna.features["mam_tail"] == "None")
|
||||
return
|
||||
else
|
||||
if(!H.dna.species.is_wagging_tail())
|
||||
H.emote("wag")
|
||||
if(!dna.species.is_wagging_tail())
|
||||
emote("wag")
|
||||
|
||||
else
|
||||
return
|
||||
@@ -335,8 +331,11 @@
|
||||
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>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug)
|
||||
if(HAS_TRAIT(M, TRAIT_FRIENDLY))
|
||||
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
|
||||
friendly_check = TRUE
|
||||
|
||||
if(friendly_check && HAS_TRAIT(M, TRAIT_FRIENDLY))
|
||||
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
|
||||
if(mood)
|
||||
if (mood.sanity >= SANITY_GREAT)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M)
|
||||
else if (mood.sanity >= SANITY_DISTURBED)
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
. += "[t_He] [t_is] wearing [wear_mask.get_examine_string(user)] on [t_his] face."
|
||||
if (wear_neck)
|
||||
. += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck.\n"
|
||||
if(can_be_held)
|
||||
. += "[t_He] looks small enough to be picked up with <b>Alt+Click</b>!\n"
|
||||
|
||||
|
||||
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.item_flags & ABSTRACT))
|
||||
@@ -116,4 +112,5 @@
|
||||
. += "[t_He] look[p_s()] very happy."
|
||||
if(MOOD_LEVEL_HAPPY4 to INFINITY)
|
||||
. += "[t_He] look[p_s()] ecstatic."
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
|
||||
. += "*---------*</span>"
|
||||
|
||||
@@ -7,13 +7,14 @@
|
||||
/mob/living/carbon/human/spawn_gibs(with_bodyparts, atom/loc_override)
|
||||
var/location = loc_override ? loc_override.drop_location() : drop_location()
|
||||
if(dna?.species?.gib_types)
|
||||
var/blood_dna = get_blood_dna_list()
|
||||
var/datum/species/S = dna.species
|
||||
var/length = length(S.gib_types)
|
||||
if(length)
|
||||
var/path = (with_bodyparts && length > 1) ? S.gib_types[2] : S.gib_types[1]
|
||||
new path(location, src, get_static_viruses())
|
||||
else
|
||||
new S.gib_types(location, src, get_static_viruses())
|
||||
new S.gib_types(location, src, get_static_viruses(), blood_dna)
|
||||
else
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/human(location, src, get_static_viruses())
|
||||
@@ -67,4 +68,4 @@
|
||||
/mob/living/carbon/proc/makeUncloneable()
|
||||
ADD_TRAIT(src, TRAIT_NOCLONE, MADE_UNCLONEABLE)
|
||||
blood_volume = 0
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -99,6 +99,10 @@
|
||||
. += "[t_He] [t_has] [glasses.get_examine_string(user)] covering [t_his] eyes."
|
||||
else if(eye_color == BLOODCULT_EYE && iscultist(src) && HAS_TRAIT(src, TRAIT_CULT_EYES))
|
||||
. += "<span class='warning'><B>[t_His] eyes are glowing an unnatural red!</B></span>"
|
||||
else if(HAS_TRAIT(src, TRAIT_HIJACKER))
|
||||
var/obj/item/implant/hijack/H = user.getImplant(/obj/item/implant/hijack)
|
||||
if (H && !H.stealthmode && H.toggled)
|
||||
. += "<b><font color=orange>[t_His] eyes are flickering a bright yellow!</font></b>"
|
||||
|
||||
//ears
|
||||
if(ears && !(SLOT_EARS in obscured))
|
||||
@@ -396,6 +400,7 @@
|
||||
var/temp_flavor = print_flavor_text_2()
|
||||
if(temp_flavor)
|
||||
. += temp_flavor
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
|
||||
. += "*---------*</span>"
|
||||
|
||||
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/mob/living/carbon/human/proc/examine_nutrition()
|
||||
var/message = ""
|
||||
var/nutrition_examine = round(nutrition)
|
||||
var/t_He = "It" //capitalised for use at the start of each line.
|
||||
var/t_His = "Its"
|
||||
var/t_his = "its"
|
||||
var/t_is = "is"
|
||||
var/t_has = "has"
|
||||
switch(gender)
|
||||
if(MALE)
|
||||
t_He = "He"
|
||||
t_his = "his"
|
||||
t_His = "His"
|
||||
if(FEMALE)
|
||||
t_He = "She"
|
||||
t_his = "her"
|
||||
t_His = "Her"
|
||||
if(PLURAL)
|
||||
t_He = "They"
|
||||
t_his = "their"
|
||||
t_His = "Their"
|
||||
t_is = "are"
|
||||
t_has = "have"
|
||||
if(NEUTER)
|
||||
t_He = "It"
|
||||
t_his = "its"
|
||||
t_His = "Its"
|
||||
switch(nutrition_examine)
|
||||
if(0 to 49)
|
||||
message = "<span class='warning'>[t_He] [t_is] starving! You can hear [t_his] stomach snarling from across the room!</span>\n"
|
||||
if(50 to 99)
|
||||
message = "<span class='warning'>[t_He] [t_is] extremely hungry. A deep growl occasionally rumbles from [t_his] empty stomach.</span>\n"
|
||||
if(100 to 499)
|
||||
return message //Well that's pretty normal, really.
|
||||
if(500 to 864) // Fat.
|
||||
message = "[t_He] [t_has] a stuffed belly, bloated fat and round from eating too much.\n"
|
||||
if(1200 to 1934) // One person fully digested.
|
||||
message = "<span class='warning'>[t_He] [t_is] sporting a large, round, sagging stomach. It's contains at least their body weight worth of glorping slush.</span>\n"
|
||||
if(1935 to 3004) // Two people.
|
||||
message = "<span class='warning'>[t_He] [t_is] engorged with a huge stomach that sags and wobbles as they move. [t_He] must have consumed at least twice their body weight. It looks incredibly soft.</span>\n"
|
||||
if(3005 to 4074) // Three people.
|
||||
message = "<span class='warning'>[t_His] stomach is firmly packed with digesting slop. [t_He] must have eaten at least a few times worth their body weight! It looks hard for them to stand, and [t_his] gut jiggles when they move.</span>\n"
|
||||
if(4075 to 10000) // Four or more people.
|
||||
message = "<span class='warning'>[t_He] [t_is] so absolutely stuffed that you aren't sure how it's possible to move. [t_He] can't seem to swell any bigger. The surface of [t_his] belly looks sorely strained!</span>\n"
|
||||
return message
|
||||
@@ -91,7 +91,7 @@
|
||||
var/say_starter = "Say \"" //"
|
||||
if(findtextEx(temp, say_starter, 1, length(say_starter) + 1) && length(temp) > length(say_starter)) //case sensitive means
|
||||
|
||||
temp = trim_left(copytext(temp, length(say_starter + 1)))
|
||||
temp = trim_left(copytext(temp, length(say_starter) + 1))
|
||||
temp = replacetext(temp, ";", "", 1, 2) //general radio
|
||||
while(trim_left(temp)[1] == ":") //dept radio again (necessary)
|
||||
temp = copytext_char(trim_left(temp), 3)
|
||||
|
||||
@@ -1585,7 +1585,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if (!HAS_TRAIT(target, TRAIT_PERMABONER))
|
||||
stop_wagging_tail(target)
|
||||
return FALSE
|
||||
else if(aim_for_groin && (target == user || target.lying || same_dir) && (target_on_help || target_restrained || target_aiming_for_groin))
|
||||
else if(!(user.client?.prefs.cit_toggles & NO_ASS_SLAP) && aim_for_groin && (target == user || target.lying || same_dir) && (target_on_help || target_restrained || target_aiming_for_groin))
|
||||
if(target.client?.prefs.cit_toggles & NO_ASS_SLAP)
|
||||
to_chat(user,"A force stays your hand, preventing you from slapping \the [target]'s ass!")
|
||||
return FALSE
|
||||
@@ -1886,6 +1886,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(get_turf(target) == target_oldturf)
|
||||
shove_blocked = TRUE
|
||||
|
||||
var/append_message = ""
|
||||
if(shove_blocked && !target.buckled)
|
||||
var/directional_blocked = !target.Adjacent(target_shove_turf)
|
||||
var/targetatrest = !CHECK_MOBILITY(target, MOBILITY_STAND)
|
||||
@@ -1899,33 +1900,30 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
target_collateral_human.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_COLLATERAL)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name] into [target_collateral_human.name]!</span>",
|
||||
"<span class='danger'>You shove [target.name] into [target_collateral_human.name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
log_combat(user, target, "shoved", "into [target_collateral_human.name]")
|
||||
append_message += ", into [target_collateral_human.name]"
|
||||
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name]!</span>",
|
||||
"<span class='danger'>You shove [target.name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
var/target_held_item = target.get_active_held_item()
|
||||
var/knocked_item = FALSE
|
||||
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
|
||||
target_held_item = null
|
||||
if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE))
|
||||
target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
|
||||
if(target_held_item)
|
||||
var/obj/item/target_held_item = target.get_active_held_item()
|
||||
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
|
||||
target_held_item = null
|
||||
if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE))
|
||||
target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
|
||||
if(target_held_item)
|
||||
if(!HAS_TRAIT(target_held_item, TRAIT_NODROP))
|
||||
target.visible_message("<span class='danger'>[target.name]'s grip on \the [target_held_item] loosens!</span>",
|
||||
"<span class='danger'>Your grip on \the [target_held_item] loosens!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
|
||||
else if(target_held_item)
|
||||
target.dropItemToGround(target_held_item)
|
||||
knocked_item = TRUE
|
||||
append_message += ", loosening their grip on [target_held_item]"
|
||||
else
|
||||
append_message += ", but couldn't loose their grip on [target_held_item]"
|
||||
addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
|
||||
else if(target_held_item)
|
||||
if(target.dropItemToGround(target_held_item))
|
||||
target.visible_message("<span class='danger'>[target.name] drops \the [target_held_item]!!</span>",
|
||||
"<span class='danger'>You drop \the [target_held_item]!!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
var/append_message = ""
|
||||
if(target_held_item)
|
||||
if(knocked_item)
|
||||
append_message = "causing them to drop [target_held_item]"
|
||||
else
|
||||
append_message = "loosening their grip on [target_held_item]"
|
||||
log_combat(user, target, "shoved", append_message)
|
||||
append_message += ", causing them to drop [target_held_item]"
|
||||
log_combat(user, target, "shoved", append_message)
|
||||
|
||||
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
|
||||
var/hit_percent = (100-(blocked+armor))/100
|
||||
|
||||
@@ -132,14 +132,14 @@
|
||||
return INITIALIZE_HINT_QDEL
|
||||
owner = new_owner
|
||||
START_PROCESSING(SSobj, src)
|
||||
RegisterSignal(owner, COMSIG_MOB_EXAMINATE, .proc/examinate_check)
|
||||
RegisterSignal(owner, COMSIG_CLICK_SHIFT, .proc/examinate_check)
|
||||
RegisterSignal(src, COMSIG_ATOM_HEARER_IN_VIEW, .proc/include_owner)
|
||||
RegisterSignal(owner, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head)
|
||||
RegisterSignal(owner, COMSIG_LIVING_FULLY_HEAL, .proc/retrieve_head)
|
||||
|
||||
/obj/item/dullahan_relay/proc/examinate_check(mob/source, atom/A)
|
||||
if(source.client.eye == src && ((A in view(source.client.view, src)) || (isturf(A) && source.sight & SEE_TURFS) || (ismob(A) && source.sight & SEE_MOBS) || (isobj(A) && source.sight & SEE_OBJS)))
|
||||
return COMPONENT_ALLOW_EXAMINE
|
||||
/obj/item/dullahan_relay/proc/examinate_check(atom/source, mob/user)
|
||||
if(user.client.eye == src)
|
||||
return COMPONENT_ALLOW_EXAMINATE
|
||||
|
||||
/obj/item/dullahan_relay/proc/include_owner(datum/source, list/processing_list, list/hearers)
|
||||
if(!QDELETED(owner))
|
||||
|
||||
@@ -31,6 +31,7 @@ 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.
|
||||
@@ -41,6 +42,7 @@ 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
|
||||
@@ -52,21 +54,20 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
//Dwarf Speech handling - Basically a filter/forces them to say things. The IC helper
|
||||
/datum/species/dwarf/proc/handle_speech(datum/source, list/speech_args)
|
||||
var/message = speech_args[SPEECH_MESSAGE]
|
||||
if(message[1] != "*")
|
||||
message = " [message]" //Credits to goonstation for the strings list.
|
||||
var/list/dwarf_words = strings("dwarf_replacement.json", "dwarf") //thanks to regex too.
|
||||
if(speech_args[SPEECH_LANGUAGE] != /datum/language/dwarf) // No accent if they speak their language
|
||||
if(message[1] != "*")
|
||||
message = " [message]" //Credits to goonstation for the strings list.
|
||||
var/list/dwarf_words = strings("dwarf_replacement.json", "dwarf") //thanks to regex too.
|
||||
for(var/key in dwarf_words) //Theres like 1459 words or something man.
|
||||
var/value = dwarf_words[key] //Thus they will always be in character.
|
||||
if(islist(value)) //Whether they like it or not.
|
||||
value = pick(value) //This could be drastically reduced if needed though.
|
||||
message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]")
|
||||
message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]")
|
||||
message = replacetextEx(message, " [key]", " [value]") //Also its scottish.
|
||||
|
||||
for(var/key in dwarf_words) //Theres like 1459 words or something man.
|
||||
var/value = dwarf_words[key] //Thus they will always be in character.
|
||||
if(islist(value)) //Whether they like it or not.
|
||||
value = pick(value) //This could be drastically reduced if needed though.
|
||||
|
||||
message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]")
|
||||
message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]")
|
||||
message = replacetextEx(message, " [key]", " [value]") //Also its scottish.
|
||||
|
||||
if(prob(3))
|
||||
message += pick(" By Armok!")
|
||||
if(prob(3))
|
||||
message += " By Armok!"
|
||||
speech_args[SPEECH_MESSAGE] = trim(message)
|
||||
|
||||
//This mostly exists because my testdwarf's liver died while trying to also not die due to no alcohol.
|
||||
|
||||
@@ -182,10 +182,10 @@ There are several things that need to be remembered:
|
||||
|
||||
if(!gloves && bloody_hands)
|
||||
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color())
|
||||
if(get_num_arms() < 2)
|
||||
if(has_left_hand())
|
||||
if(get_num_arms(FALSE) < 2)
|
||||
if(has_left_hand(FALSE))
|
||||
bloody_overlay.icon_state = "bloodyhands_left"
|
||||
else if(has_right_hand())
|
||||
else if(has_right_hand(FALSE))
|
||||
bloody_overlay.icon_state = "bloodyhands_right"
|
||||
|
||||
overlays_standing[GLOVES_LAYER] = bloody_overlay
|
||||
@@ -265,7 +265,7 @@ There are several things that need to be remembered:
|
||||
/mob/living/carbon/human/update_inv_shoes()
|
||||
remove_overlay(SHOES_LAYER)
|
||||
|
||||
if(get_num_legs() <2)
|
||||
if(get_num_legs(FALSE) <2)
|
||||
return
|
||||
|
||||
if(client && hud_used)
|
||||
|
||||
@@ -358,7 +358,7 @@
|
||||
return
|
||||
|
||||
// No decay if formaldehyde in corpse or when the corpse is charred
|
||||
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 15) || HAS_TRAIT(src, TRAIT_HUSK))
|
||||
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || HAS_TRAIT(src, TRAIT_HUSK))
|
||||
return
|
||||
|
||||
// Also no decay if corpse chilled or not organic/undead
|
||||
@@ -397,6 +397,8 @@
|
||||
if(O)
|
||||
O.on_life()
|
||||
else
|
||||
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1)) // No organ decay if the body contains formaldehyde.
|
||||
return
|
||||
for(var/V in internal_organs)
|
||||
var/obj/item/organ/O = V
|
||||
if(O)
|
||||
@@ -579,6 +581,9 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
if(cultslurring)
|
||||
cultslurring = max(cultslurring-1, 0)
|
||||
|
||||
if(clockcultslurring)
|
||||
clockcultslurring = max(clockcultslurring-1, 0)
|
||||
|
||||
if(silent)
|
||||
silent = max(silent-1, 0)
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
bodyparts = list(/obj/item/bodypart/chest/monkey, /obj/item/bodypart/head/monkey, /obj/item/bodypart/l_arm/monkey,
|
||||
/obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey)
|
||||
hud_type = /datum/hud/monkey
|
||||
can_be_held = "monkey"
|
||||
|
||||
/mob/living/carbon/monkey/Initialize(mapload, cubespawned=FALSE, mob/spawner)
|
||||
verbs += /mob/living/proc/mob_sleep
|
||||
@@ -42,14 +41,15 @@
|
||||
create_dna(src)
|
||||
dna.initialize_dna(random_blood_type())
|
||||
|
||||
/mob/living/carbon/monkey/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/mob_holder, "monkey", null, null, null, SLOT_HEAD)
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/Destroy()
|
||||
SSmobs.cubemonkeys -= src
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/monkey/generate_mob_holder()
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, "monkey", 'icons/mob/animals_held.dmi', 'icons/mob/animals_held_lh.dmi', 'icons/mob/animals_held_rh.dmi', TRUE)
|
||||
return holder
|
||||
|
||||
/mob/living/carbon/monkey/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/appendix
|
||||
internal_organs += new /obj/item/organ/lungs
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
//Generic system for picking up mobs.
|
||||
//Currently works for head and hands.
|
||||
/obj/item/clothing/head/mob_holder
|
||||
name = "bugged mob"
|
||||
desc = "Yell at coderbrush."
|
||||
icon = null
|
||||
icon_state = ""
|
||||
var/mob/living/held_mob
|
||||
var/can_head = FALSE
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/clothing/head/mob_holder/Initialize(mapload, mob/living/M, _worn_state, alt_worn, lh_icon, rh_icon, _can_head_override = FALSE)
|
||||
. = ..()
|
||||
|
||||
if(M)
|
||||
M.setDir(SOUTH)
|
||||
held_mob = M
|
||||
M.forceMove(src)
|
||||
appearance = M.appearance
|
||||
name = M.name
|
||||
desc = M.desc
|
||||
|
||||
if(_can_head_override)
|
||||
can_head = _can_head_override
|
||||
if(alt_worn)
|
||||
alternate_worn_icon = alt_worn
|
||||
if(_worn_state)
|
||||
item_state = _worn_state
|
||||
icon_state = _worn_state
|
||||
if(lh_icon)
|
||||
lefthand_file = lh_icon
|
||||
if(rh_icon)
|
||||
righthand_file = rh_icon
|
||||
if(!can_head)
|
||||
slot_flags = NONE
|
||||
|
||||
/obj/item/clothing/head/mob_holder/Destroy()
|
||||
if(held_mob)
|
||||
release()
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/head/mob_holder/dropped()
|
||||
..()
|
||||
if(isturf(loc))//don't release on soft-drops
|
||||
release()
|
||||
|
||||
/obj/item/clothing/head/mob_holder/proc/release()
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
L.dropItemToGround(src)
|
||||
if(held_mob)
|
||||
var/mob/living/m = held_mob
|
||||
m.forceMove(get_turf(m))
|
||||
m.reset_perspective()
|
||||
m.setDir(SOUTH)
|
||||
held_mob = null
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/head/mob_holder/relaymove(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/clothing/head/mob_holder/container_resist()
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
visible_message("<span class='warning'>[src] escapes [L]!</span>")
|
||||
release()
|
||||
|
||||
/mob/living/proc/mob_pickup(mob/living/L)
|
||||
var/obj/item/clothing/head/mob_holder/holder = generate_mob_holder()
|
||||
if(!holder)
|
||||
return
|
||||
drop_all_held_items()
|
||||
L.put_in_hands(holder)
|
||||
return
|
||||
|
||||
/mob/living/proc/mob_try_pickup(mob/living/user)
|
||||
if(!ishuman(user) || !src.Adjacent(user) || user.incapacitated() || !can_be_held)
|
||||
return FALSE
|
||||
if(user.get_active_held_item())
|
||||
to_chat(user, "<span class='warning'>Your hands are full!</span>")
|
||||
return FALSE
|
||||
if(buckled)
|
||||
to_chat(user, "<span class='warning'>[src] is buckled to something!</span>")
|
||||
return FALSE
|
||||
if(src == user)
|
||||
to_chat(user, "<span class='warning'>You can't pick yourself up.</span>")
|
||||
return FALSE
|
||||
visible_message("<span class='warning'>[user] starts picking up [src].</span>", \
|
||||
"<span class='userdanger'>[user] starts picking you up!</span>")
|
||||
if(!do_after(user, 20, target = src))
|
||||
return FALSE
|
||||
|
||||
if(user.get_active_held_item()||buckled)
|
||||
return FALSE
|
||||
|
||||
visible_message("<span class='warning'>[user] picks up [src]!</span>", \
|
||||
"<span class='userdanger'>[user] picks you up!</span>")
|
||||
to_chat(user, "<span class='notice'>You pick [src] up.</span>")
|
||||
mob_pickup(user)
|
||||
return TRUE
|
||||
|
||||
/mob/living/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(mob_try_pickup(user))
|
||||
return TRUE
|
||||
|
||||
|
||||
// I didn't define these for mobs, because you shouldn't be able to breathe out of mobs and using their loc isn't always the logical thing to do.
|
||||
|
||||
/obj/item/clothing/head/mob_holder/assume_air(datum/gas_mixture/env)
|
||||
var/atom/location = loc
|
||||
if(!loc)
|
||||
return //null
|
||||
var/turf/T = get_turf(loc)
|
||||
while(location != T)
|
||||
location = location.loc
|
||||
if(ismob(location))
|
||||
return location.loc.assume_air(env)
|
||||
return loc.assume_air(env)
|
||||
|
||||
/obj/item/clothing/head/mob_holder/remove_air(amount)
|
||||
var/atom/location = loc
|
||||
if(!loc)
|
||||
return //null
|
||||
var/turf/T = get_turf(loc)
|
||||
while(location != T)
|
||||
location = location.loc
|
||||
if(ismob(location))
|
||||
return location.loc.remove_air(amount)
|
||||
return loc.remove_air(amount)
|
||||
@@ -40,11 +40,6 @@
|
||||
QDEL_LIST(diseases)
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/proc/generate_mob_holder()
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, (istext(can_be_held) ? can_be_held : ""), 'icons/mob/animals_held.dmi', 'icons/mob/animals_held_lh.dmi', 'icons/mob/animals_held_rh.dmi')
|
||||
return holder
|
||||
|
||||
/mob/living/onZImpact(turf/T, levels)
|
||||
if(!isgroundlessturf(T))
|
||||
ZImpactDamage(T, levels)
|
||||
@@ -761,10 +756,22 @@
|
||||
if(HAS_TRAIT(what, TRAIT_NODROP))
|
||||
to_chat(src, "<span class='warning'>You can't remove \the [what.name], it appears to be stuck!</span>")
|
||||
return
|
||||
who.visible_message("<span class='danger'>[src] tries to remove [who]'s [what.name].</span>", \
|
||||
var/strip_mod = 1
|
||||
var/strip_silence = FALSE
|
||||
if (ishuman(src)) //carbon doesn't actually wear gloves
|
||||
var/mob/living/carbon/C = src
|
||||
var/obj/item/clothing/gloves/g = C.gloves
|
||||
if (istype(g))
|
||||
strip_mod = g.strip_mod
|
||||
strip_silence = g.strip_silence
|
||||
if (!strip_silence)
|
||||
who.visible_message("<span class='danger'>[src] tries to remove [who]'s [what.name].</span>", \
|
||||
"<span class='userdanger'>[src] tries to remove [who]'s [what.name].</span>")
|
||||
what.add_fingerprint(src)
|
||||
if(do_mob(src, who, what.strip_delay, ignorehelditem = TRUE))
|
||||
what.add_fingerprint(src)
|
||||
else
|
||||
to_chat(src,"<span class='notice'>You try to remove [who]'s [what.name].</span>")
|
||||
what.add_fingerprint(src)
|
||||
if(do_mob(src, who, round(what.strip_delay / strip_mod), ignorehelditem = TRUE))
|
||||
if(what && Adjacent(who))
|
||||
if(islist(where))
|
||||
var/list/L = where
|
||||
@@ -1119,8 +1126,6 @@
|
||||
return
|
||||
if(!over.Adjacent(src) || (user != src) || !canUseTopic(over))
|
||||
return
|
||||
if(can_be_held)
|
||||
mob_try_pickup(over)
|
||||
|
||||
/mob/living/proc/get_static_viruses() //used when creating blood and other infective objects
|
||||
if(!LAZYLEN(diseases))
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
var/stuttering = 0
|
||||
var/slurring = 0
|
||||
var/cultslurring = 0
|
||||
var/clockcultslurring = 0
|
||||
var/derpspeech = 0
|
||||
|
||||
var/list/implants = null
|
||||
@@ -103,8 +104,6 @@
|
||||
|
||||
var/list/obj/effect/proc_holder/abilities = list()
|
||||
|
||||
var/can_be_held = FALSE //whether this can be picked up and held.
|
||||
|
||||
var/radiation = 0 //If the mob is irradiated.
|
||||
var/ventcrawl_layer = PIPING_LAYER_DEFAULT
|
||||
var/losebreath = 0
|
||||
|
||||
@@ -103,7 +103,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
else if(message_mode || saymode)
|
||||
message = copytext_char(message, 3)
|
||||
message = trim_left(message)
|
||||
|
||||
if(!message)
|
||||
return
|
||||
if(message_mode == MODE_ADMIN)
|
||||
if(client)
|
||||
client.cmd_admin_say(message)
|
||||
@@ -223,7 +224,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
. = "<span class='small'>[.]</span>"
|
||||
|
||||
/mob/living/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source)
|
||||
. = ..()
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args) //parent calls can't overwrite the current proc args.
|
||||
if(!client)
|
||||
return
|
||||
var/deaf_message
|
||||
@@ -353,6 +354,9 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
|
||||
if(cultslurring)
|
||||
message = cultslur(message)
|
||||
|
||||
if(clockcultslurring)
|
||||
message = CLOCK_CULT_SLUR(message)
|
||||
|
||||
message = capitalize(message)
|
||||
|
||||
|
||||
@@ -315,10 +315,10 @@
|
||||
var/is_anchored = FALSE
|
||||
if(move_resist == MOVE_FORCE_OVERPOWERING)
|
||||
move_resist = MOVE_FORCE_NORMAL
|
||||
REMOVE_TRAIT(src, TRAIT_NO_TELEPORT, src)
|
||||
else
|
||||
is_anchored = TRUE
|
||||
move_resist = MOVE_FORCE_OVERPOWERING
|
||||
REMOVE_TRAIT(src, TRAIT_NO_TELEPORT, src)
|
||||
ADD_TRAIT(src, TRAIT_NO_TELEPORT, src)
|
||||
|
||||
to_chat(src, "<b>You are now [is_anchored ? "" : "un"]anchored.</b>")
|
||||
|
||||
@@ -7,4 +7,7 @@
|
||||
var/datum/antagonist/bloodsucker/V = mind.has_antag_datum(/datum/antagonist/bloodsucker)
|
||||
if(V)
|
||||
mind.remove_antag_datum(V)
|
||||
var/datum/antagonist/gang/G = mind.has_antag_datum(/datum/antagonist/gang)
|
||||
if(G)
|
||||
mind.remove_antag_datum(G)
|
||||
..()
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
health = 500
|
||||
maxHealth = 500
|
||||
layer = BELOW_MOB_LAYER
|
||||
can_be_held = TRUE
|
||||
var/datum/element/mob_holder/current_mob_holder //because only a few of their chassis can be actually held.
|
||||
|
||||
var/network = "ss13"
|
||||
var/obj/machinery/camera/current = null
|
||||
@@ -64,9 +64,6 @@
|
||||
var/list/possible_chassis //initialized in initialize.
|
||||
var/list/dynamic_chassis_icons //ditto.
|
||||
var/list/chassis_pixel_offsets_x //stupid dogborgs
|
||||
var/static/item_head_icon = 'icons/mob/pai_item_head.dmi'
|
||||
var/static/item_lh_icon = 'icons/mob/pai_item_lh.dmi'
|
||||
var/static/item_rh_icon = 'icons/mob/pai_item_rh.dmi'
|
||||
|
||||
var/emitterhealth = 20
|
||||
var/emittermaxhealth = 20
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#define PAI_EMP_SILENCE_DURATION 3 MINUTES
|
||||
|
||||
/mob/living/silicon/pai/blob_act(obj/structure/blob/B)
|
||||
return FALSE
|
||||
@@ -8,7 +9,7 @@
|
||||
return
|
||||
take_holo_damage(50/severity)
|
||||
DefaultCombatKnockdown(400/severity)
|
||||
silent = max((3 MINUTES)/severity, silent)
|
||||
silent = max(silent, (PAI_EMP_SILENCE_DURATION) / SSmobs.wait / severity)
|
||||
if(holoform)
|
||||
fold_in(force = TRUE)
|
||||
emitter_next_use = world.time + emitter_emp_cd
|
||||
|
||||
@@ -95,6 +95,12 @@
|
||||
dynamic_chassis = choice
|
||||
resist_a_rest(FALSE, TRUE)
|
||||
update_icon()
|
||||
if(possible_chassis[chassis])
|
||||
current_mob_holder = AddElement(/datum/element/mob_holder, chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', SLOT_HEAD)
|
||||
else
|
||||
current_mob_holder?.Detach(src)
|
||||
current_mob_holder = null
|
||||
return
|
||||
to_chat(src, "<span class='boldnotice'>You switch your holochassis projection composite to [chassis]</span>")
|
||||
|
||||
/mob/living/silicon/pai/lay_down()
|
||||
@@ -116,19 +122,6 @@
|
||||
set_light(0)
|
||||
to_chat(src, "<span class='notice'>You disable your integrated light.</span>")
|
||||
|
||||
/mob/living/silicon/pai/mob_pickup(mob/living/L)
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, chassis, item_head_icon, item_lh_icon, item_rh_icon)
|
||||
if(!L.put_in_hands(holder))
|
||||
qdel(holder)
|
||||
else
|
||||
L.visible_message("<span class='warning'>[L] scoops up [src]!</span>")
|
||||
|
||||
/mob/living/silicon/pai/mob_try_pickup(mob/living/user)
|
||||
if(!possible_chassis[chassis])
|
||||
to_chat(user, "<span class='warning'>[src]'s current form isn't able to be carried!</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/pai/verb/toggle_chassis_sit()
|
||||
set name = "Toggle Chassis Sit"
|
||||
set category = "IC"
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
else if(istype(I, /obj/item/gun/energy))
|
||||
var/obj/item/gun/energy/EG = I
|
||||
if(EG.cell?.charge < EG.cell.maxcharge)
|
||||
var/obj/item/ammo_casing/energy/S = EG.ammo_type[EG.select]
|
||||
var/obj/item/ammo_casing/energy/S = EG.ammo_type[EG.current_firemode_index]
|
||||
EG.cell.give(S.e_cost * coeff)
|
||||
if(!EG.chambered)
|
||||
EG.recharge_newshot(TRUE)
|
||||
|
||||
@@ -182,8 +182,9 @@
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/bot/death(gibbed)
|
||||
explode()
|
||||
..()
|
||||
. = ..()
|
||||
if(!gibbed)
|
||||
explode()
|
||||
|
||||
/mob/living/simple_animal/bot/proc/explode()
|
||||
qdel(src)
|
||||
@@ -809,14 +810,14 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
|
||||
switch(href_list["operation"])
|
||||
if("patrol")
|
||||
if(!issilicon(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
auto_patrol = !auto_patrol
|
||||
bot_reset()
|
||||
if("remote")
|
||||
remote_disabled = !remote_disabled
|
||||
if("hack")
|
||||
if(!issilicon(usr) && !IsAdminGhost(usr))
|
||||
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr))
|
||||
var/msg = "[key_name(usr)] attempted to hack a bot with a href that shouldn't be available!"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
@@ -835,7 +836,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
to_chat(usr, "<span class='notice'>[text_dehack]</span>")
|
||||
bot_reset()
|
||||
if("ejectpai")
|
||||
if(paicard && (!locked || issilicon(usr) || IsAdminGhost(usr)))
|
||||
if(paicard && (!locked || hasSiliconAccessInArea(usr) || IsAdminGhost(usr)))
|
||||
to_chat(usr, "<span class='notice'>You eject [paicard] from [bot_name]</span>")
|
||||
ejectpai(usr)
|
||||
update_controls()
|
||||
@@ -862,13 +863,13 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
if(emagged == 2) //An emagged bot cannot be controlled by humans, silicons can if one hacked it.
|
||||
if(!hacked) //Manually emagged by a human - access denied to all.
|
||||
return TRUE
|
||||
else if(!issilicon(user) && !IsAdminGhost(user)) //Bot is hacked, so only silicons and admins are allowed access.
|
||||
else if(!hasSiliconAccessInArea(user) && !IsAdminGhost(user)) //Bot is hacked, so only silicons and admins are allowed access.
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/proc/hack(mob/user)
|
||||
var/hack
|
||||
if(issilicon(user) || IsAdminGhost(user)) //Allows silicons or admins to toggle the emag status of a bot.
|
||||
if(hasSiliconAccessInArea(user) || IsAdminGhost(user)) //Allows silicons or admins to toggle the emag status of a bot.
|
||||
hack += "[emagged == 2 ? "Software compromised! Unit may exhibit dangerous or erratic behavior." : "Unit operating normally. Release safety lock?"]<BR>"
|
||||
hack += "Harm Prevention Safety System: <A href='?src=[REF(src)];operation=hack'>[emagged ? "<span class='bad'>DANGER</span>" : "Engaged"]</A><BR>"
|
||||
else if(!locked) //Humans with access can use this option to hide a bot from the AI's remote control panel and PDA control.
|
||||
@@ -877,7 +878,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
|
||||
/mob/living/simple_animal/bot/proc/showpai(mob/user)
|
||||
var/eject = ""
|
||||
if((!locked || issilicon(usr) || IsAdminGhost(usr)))
|
||||
if((!locked || hasSiliconAccessInArea(usr) || IsAdminGhost(usr)))
|
||||
if(paicard || allow_pai)
|
||||
eject += "Personality card status: "
|
||||
if(paicard)
|
||||
|
||||
@@ -298,7 +298,7 @@
|
||||
Status: <A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A><BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"})
|
||||
if(!locked || issilicon(user)|| IsAdminGhost(user))
|
||||
if(!locked || hasSiliconAccessInArea(user)|| IsAdminGhost(user))
|
||||
dat += "<BR>Clean Blood: <A href='?src=[REF(src)];operation=blood'>[blood ? "Yes" : "No"]</A>"
|
||||
dat += "<BR>Clean Trash: <A href='?src=[REF(src)];operation=trash'>[trash ? "Yes" : "No"]</A>"
|
||||
dat += "<BR>Exterminate Pests: <A href='?src=[REF(src)];operation=pests'>[pests ? "Yes" : "No"]</A>"
|
||||
|
||||
@@ -110,7 +110,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]<BR>"},
|
||||
|
||||
"<A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A>" )
|
||||
|
||||
if(!locked || issilicon(user)|| IsAdminGhost(user))
|
||||
if(!locked || hasSiliconAccessInArea(user)|| IsAdminGhost(user))
|
||||
if(!lasercolor)
|
||||
dat += text({"<BR>
|
||||
Arrest Unidentifiable Persons: []<BR>
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
|
||||
|
||||
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
if(!locked || issilicon(user) || IsAdminGhost(user))
|
||||
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
|
||||
dat += "Extinguish Fires: <A href='?src=[REF(src)];operation=extinguish_fires'>[extinguish_fires ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Extinguish People: <A href='?src=[REF(src)];operation=extinguish_people'>[extinguish_people ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Patrol Station: <A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A><BR>"
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
dat += "None Loaded<BR>"
|
||||
|
||||
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
if(!locked || issilicon(user) || IsAdminGhost(user))
|
||||
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
|
||||
dat += "Add tiles to new hull plating: <A href='?src=[REF(src)];operation=autotile'>[autotile ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Place floor tiles: <A href='?src=[REF(src)];operation=place'>[placetiles ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Replace existing floor tiles with custom tiles: <A href='?src=[REF(src)];operation=replace'>[replacetiles ? "Yes" : "No"]</A><BR>"
|
||||
|
||||
@@ -90,7 +90,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
|
||||
"<A href='?src=[REF(src)];power=[TRUE]'>[on ? "On" : "Off"]</A>" )
|
||||
|
||||
if(!locked || issilicon(user) || IsAdminGhost(user))
|
||||
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
|
||||
dat += text({"<BR> Auto Patrol: []"},
|
||||
|
||||
"<A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
else
|
||||
dat += "None Loaded"
|
||||
dat += "<br>Behaviour controls are [locked ? "locked" : "unlocked"]<hr>"
|
||||
if(!locked || issilicon(user) || IsAdminGhost(user))
|
||||
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
|
||||
dat += "<TT>Healing Threshold: "
|
||||
dat += "<a href='?src=[REF(src)];adj_threshold=-10'>--</a> "
|
||||
dat += "<a href='?src=[REF(src)];adj_threshold=-5'>-</a> "
|
||||
|
||||
@@ -279,7 +279,7 @@
|
||||
|
||||
// TODO: remove this; PDAs currently depend on it
|
||||
/mob/living/simple_animal/bot/mulebot/get_controls(mob/user)
|
||||
var/ai = issilicon(user)
|
||||
var/ai = hasSiliconAccessInArea(user)
|
||||
var/dat
|
||||
dat += "<h3>Multiple Utility Load Effector Mk. V</h3>"
|
||||
dat += "<b>ID:</b> [id]<BR>"
|
||||
|
||||
@@ -110,7 +110,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
|
||||
"<A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A>" )
|
||||
|
||||
if(!locked || issilicon(user) || IsAdminGhost(user))
|
||||
if(!locked || hasSiliconAccessInArea(user) || IsAdminGhost(user))
|
||||
dat += text({"<BR>
|
||||
Arrest Unidentifiable Persons: []<BR>
|
||||
Arrest for Unauthorized Weapons: []<BR>
|
||||
@@ -131,7 +131,7 @@ Auto Patrol: []"},
|
||||
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(!issilicon(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
switch(href_list["operation"])
|
||||
if("idcheck")
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
/datum/outfit/russiancorpse/officer
|
||||
name = "Russian Officer Corpse"
|
||||
uniform = /obj/item/clothing/under/rank/security/navyblue/russian
|
||||
suit = /obj/item/clothing/suit/security/officer/russian
|
||||
suit = /obj/item/clothing/suit/armor/navyblue/russian
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
ears = /obj/item/radio/headset
|
||||
head = /obj/item/clothing/head/ushanka
|
||||
@@ -207,7 +207,7 @@
|
||||
/obj/effect/mob_spawn/human/corpse/bee_terrorist
|
||||
name = "BLF Operative"
|
||||
outfit = /datum/outfit/bee_terrorist
|
||||
|
||||
|
||||
/datum/outfit/bee_terrorist
|
||||
name = "BLF Operative"
|
||||
uniform = /obj/item/clothing/under/color/yellow
|
||||
|
||||
@@ -1,309 +1,312 @@
|
||||
//Cat
|
||||
/mob/living/simple_animal/pet/cat
|
||||
name = "cat"
|
||||
desc = "Kitty!!"
|
||||
icon = 'icons/mob/pets.dmi'
|
||||
icon_state = "cat2"
|
||||
icon_living = "cat2"
|
||||
icon_dead = "cat2_dead"
|
||||
gender = MALE
|
||||
speak = list("Meow!", "Esp!", "Purr!", "HSSSSS")
|
||||
speak_emote = list("purrs", "meows")
|
||||
emote_hear = list("meows.", "mews.")
|
||||
emote_see = list("shakes its head.", "shivers.")
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
pass_flags = PASSTABLE
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
|
||||
minbodytemp = 200
|
||||
maxbodytemp = 400
|
||||
unsuitable_atmos_damage = 1
|
||||
animal_species = /mob/living/simple_animal/pet/cat
|
||||
childtype = list(/mob/living/simple_animal/pet/cat/kitten)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/organ/ears/cat = 1, /obj/item/organ/tail/cat = 1)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
var/turns_since_scan = 0
|
||||
var/mob/living/simple_animal/mouse/movement_target
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
collar_type = "cat"
|
||||
can_be_held = "cat2"
|
||||
do_footstep = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Initialize()
|
||||
. = ..()
|
||||
verbs += /mob/living/proc/lay_down
|
||||
|
||||
/mob/living/simple_animal/pet/cat/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/wuv, "purrs!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "hisses!", EMOTE_AUDIBLE)
|
||||
|
||||
/mob/living/simple_animal/pet/cat/update_mobility()
|
||||
. = ..()
|
||||
if(client && stat != DEAD)
|
||||
if(!CHECK_BITFIELD(mobility_flags, MOBILITY_STAND))
|
||||
icon_state = "[icon_living]_rest"
|
||||
collar_type = "[initial(collar_type)]_rest"
|
||||
else
|
||||
icon_state = "[icon_living]"
|
||||
collar_type = "[initial(collar_type)]"
|
||||
regenerate_icons()
|
||||
|
||||
|
||||
/mob/living/simple_animal/pet/cat/space
|
||||
name = "space cat"
|
||||
desc = "It's a cat... in space!"
|
||||
icon_state = "spacecat"
|
||||
icon_living = "spacecat"
|
||||
icon_dead = "spacecat_dead"
|
||||
unsuitable_atmos_damage = 0
|
||||
minbodytemp = TCMB
|
||||
maxbodytemp = T0C + 40
|
||||
|
||||
/mob/living/simple_animal/pet/cat/original
|
||||
name = "Batsy"
|
||||
desc = "The product of alien DNA and bored geneticists."
|
||||
gender = FEMALE
|
||||
icon_state = "original"
|
||||
icon_living = "original"
|
||||
icon_dead = "original_dead"
|
||||
collar_type = null
|
||||
unique_pet = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/cat/kitten
|
||||
name = "kitten"
|
||||
desc = "D'aaawwww."
|
||||
icon_state = "kitten"
|
||||
icon_living = "kitten"
|
||||
icon_dead = "kitten_dead"
|
||||
density = FALSE
|
||||
pass_flags = PASSMOB
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
collar_type = "kitten"
|
||||
can_be_held = "cat"
|
||||
|
||||
//RUNTIME IS ALIVE! SQUEEEEEEEE~
|
||||
/mob/living/simple_animal/pet/cat/Runtime
|
||||
name = "Runtime"
|
||||
desc = "GCAT"
|
||||
icon_state = "cat"
|
||||
icon_living = "cat"
|
||||
icon_dead = "cat_dead"
|
||||
gender = FEMALE
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
unique_pet = TRUE
|
||||
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
|
||||
var/memory_saved = FALSE
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/Initialize()
|
||||
if(prob(5))
|
||||
icon_state = "original"
|
||||
icon_living = "original"
|
||||
icon_dead = "original_dead"
|
||||
Read_Memory()
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/Life()
|
||||
if(!cats_deployed && SSticker.current_state >= GAME_STATE_SETTING_UP)
|
||||
Deploy_The_Cats()
|
||||
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
Write_Memory()
|
||||
memory_saved = TRUE
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/make_babies()
|
||||
var/mob/baby = ..()
|
||||
if(baby)
|
||||
children += baby
|
||||
return baby
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/death()
|
||||
if(!memory_saved)
|
||||
Write_Memory(TRUE)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory()
|
||||
if(fexists("data/npc_saves/Runtime.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Runtime.sav")
|
||||
S["family"] >> family
|
||||
fdel("data/npc_saves/Runtime.sav")
|
||||
else
|
||||
var/json_file = file("data/npc_saves/Runtime.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/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/json_file = file("data/npc_saves/Runtime.json")
|
||||
var/list/file_data = list()
|
||||
family = list()
|
||||
if(!dead)
|
||||
for(var/mob/living/simple_animal/pet/cat/kitten/C in children)
|
||||
if(istype(C,type) || C.stat || !C.z || !C.butcher_results) //That last one is a work around for hologram cats
|
||||
continue
|
||||
if(C.type in family)
|
||||
family[C.type] += 1
|
||||
else
|
||||
family[C.type] = 1
|
||||
file_data["family"] = family
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Deploy_The_Cats()
|
||||
cats_deployed = 1
|
||||
for(var/cat_type in family)
|
||||
if(family[cat_type] > 0)
|
||||
for(var/i in 1 to min(family[cat_type],100)) //Limits to about 500 cats, you wouldn't think this would be needed (BUT IT IS)
|
||||
new cat_type(loc)
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Proc
|
||||
name = "Proc"
|
||||
gender = MALE
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
unique_pet = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Life()
|
||||
if(!stat && !buckled && !client)
|
||||
if(prob(1))
|
||||
emote("me", EMOTE_VISIBLE, pick("stretches out for a belly rub.", "wags its tail.", "lies down."))
|
||||
icon_state = "[icon_living]_rest"
|
||||
collar_type = "[initial(collar_type)]_rest"
|
||||
set_resting(TRUE)
|
||||
else if (prob(1))
|
||||
emote("me", EMOTE_VISIBLE, pick("sits down.", "crouches on its hind legs.", "looks alert."))
|
||||
icon_state = "[icon_living]_sit"
|
||||
collar_type = "[initial(collar_type)]_sit"
|
||||
set_resting(TRUE)
|
||||
else if (prob(1))
|
||||
if (resting)
|
||||
emote("me", EMOTE_VISIBLE, pick("gets up and meows.", "walks around.", "stops resting."))
|
||||
icon_state = "[icon_living]"
|
||||
collar_type = "[initial(collar_type)]"
|
||||
set_resting(FALSE)
|
||||
else
|
||||
emote("me", EMOTE_VISIBLE, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat."))
|
||||
|
||||
//MICE!
|
||||
if((src.loc) && isturf(src.loc))
|
||||
if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled)
|
||||
for(var/mob/living/simple_animal/mouse/M in view(1,src))
|
||||
if(!M.stat && Adjacent(M))
|
||||
emote("me", EMOTE_VISIBLE, "splats \the [M]!")
|
||||
M.splat()
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
break
|
||||
for(var/obj/item/toy/cattoy/T in view(1,src))
|
||||
if (T.cooldown < (world.time - 400))
|
||||
emote("me", EMOTE_VISIBLE, "bats \the [T] around with its paw!")
|
||||
T.cooldown = world.time
|
||||
|
||||
..()
|
||||
|
||||
make_babies()
|
||||
|
||||
if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled)
|
||||
turns_since_scan++
|
||||
if(turns_since_scan > 5)
|
||||
walk_to(src,0)
|
||||
turns_since_scan = 0
|
||||
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
if( !movement_target || !(movement_target.loc in oview(src, 3)) )
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
for(var/mob/living/simple_animal/mouse/snack in oview(src,3))
|
||||
if(isturf(snack.loc) && !snack.stat)
|
||||
movement_target = snack
|
||||
break
|
||||
if(movement_target)
|
||||
stop_automated_movement = 1
|
||||
walk_to(src,movement_target,0,3)
|
||||
|
||||
/mob/living/simple_animal/pet/cat/cak //I told you I'd do it, Remie
|
||||
name = "Keeki"
|
||||
desc = "It's a cat made out of cake."
|
||||
icon_state = "cak"
|
||||
icon_living = "cak"
|
||||
icon_dead = "cak_dead"
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
gender = FEMALE
|
||||
harm_intent_damage = 10
|
||||
butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/reagent_containers/food/snacks/cakeslice/birthday = 3, \
|
||||
/obj/item/reagent_containers/food/snacks/meat/slab = 2)
|
||||
response_harm = "takes a bite out of"
|
||||
attacked_sound = 'sound/items/eatfood.ogg'
|
||||
deathmessage = "loses its false life and collapses!"
|
||||
death_sound = "bodyfall"
|
||||
can_be_held = "cak"
|
||||
|
||||
/mob/living/simple_animal/pet/cat/cak/CheckParts(list/parts)
|
||||
..()
|
||||
var/obj/item/organ/brain/B = locate(/obj/item/organ/brain) in contents
|
||||
if(!B || !B.brainmob || !B.brainmob.mind)
|
||||
return
|
||||
B.brainmob.mind.transfer_to(src)
|
||||
to_chat(src, "<span class='big bold'>You are a cak!</span><b> You're a harmless cat/cake hybrid that everyone loves. People can take bites out of you if they're hungry, but you regenerate health \
|
||||
so quickly that it generally doesn't matter. You're remarkably resilient to any damage besides this and it's hard for you to really die at all. You should go around and bring happiness and \
|
||||
free cake to the station!</b>")
|
||||
var/new_name = stripped_input(src, "Enter your name, or press \"Cancel\" to stick with Keeki.", "Name Change")
|
||||
if(new_name)
|
||||
to_chat(src, "<span class='notice'>Your name is now <b>\"new_name\"</b>!</span>")
|
||||
name = new_name
|
||||
|
||||
/mob/living/simple_animal/pet/cat/cak/Life()
|
||||
..()
|
||||
if(stat)
|
||||
return
|
||||
if(health < maxHealth)
|
||||
adjustBruteLoss(-8) //Fast life regen
|
||||
for(var/obj/item/reagent_containers/food/snacks/donut/D in range(1, src)) //Frosts nearby donuts!
|
||||
if(!D.is_decorated)
|
||||
D.decorate_donut()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/cak/attack_hand(mob/living/L)
|
||||
. = ..()
|
||||
if(.) //the attack was blocked
|
||||
return
|
||||
if(L.a_intent == INTENT_HARM && L.reagents && !stat)
|
||||
L.reagents.add_reagent(/datum/reagent/consumable/nutriment, 0.4)
|
||||
L.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.4)
|
||||
|
||||
//Cat made
|
||||
/mob/living/simple_animal/pet/cat/custom_cat
|
||||
name = "White cat" //Incase it somehow gets spawned without an ID
|
||||
desc = "A cute white catto!"
|
||||
icon_state = "custom_cat"
|
||||
icon_living = "custom_cat"
|
||||
icon_dead = "custom_cat_dead"
|
||||
gender = FEMALE
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
health = 50 //So people can't instakill it s
|
||||
maxHealth = 50
|
||||
speak = list("Meowrowr!", "Mew!", "Miauen!")
|
||||
speak_emote = list("wigglepurrs", "mewls")
|
||||
emote_hear = list("meows.", "mews.")
|
||||
emote_see = list("looks at you eagerly for pets!", "wiggles enthusiastically.")
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
var/pseudo_death = FALSE
|
||||
var/mob/living/carbon/human/origin
|
||||
|
||||
/mob/living/simple_animal/pet/cat/custom_cat/death()
|
||||
if (pseudo_death == TRUE) //secret cat chem
|
||||
icon_state = "custom_cat_dead"
|
||||
Stun(1000)
|
||||
friendly = "deads at"
|
||||
return
|
||||
else
|
||||
..()
|
||||
//Cat
|
||||
/mob/living/simple_animal/pet/cat
|
||||
name = "cat"
|
||||
desc = "Kitty!!"
|
||||
icon = 'icons/mob/pets.dmi'
|
||||
icon_state = "cat2"
|
||||
icon_living = "cat2"
|
||||
icon_dead = "cat2_dead"
|
||||
gender = MALE
|
||||
speak = list("Meow!", "Esp!", "Purr!", "HSSSSS")
|
||||
speak_emote = list("purrs", "meows")
|
||||
emote_hear = list("meows.", "mews.")
|
||||
emote_see = list("shakes its head.", "shivers.")
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
pass_flags = PASSTABLE
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
|
||||
minbodytemp = 200
|
||||
maxbodytemp = 400
|
||||
unsuitable_atmos_damage = 1
|
||||
animal_species = /mob/living/simple_animal/pet/cat
|
||||
childtype = list(/mob/living/simple_animal/pet/cat/kitten)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/organ/ears/cat = 1, /obj/item/organ/tail/cat = 1)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
var/turns_since_scan = 0
|
||||
var/mob/living/simple_animal/mouse/movement_target
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
collar_type = "cat"
|
||||
var/held_icon = "cat2"
|
||||
do_footstep = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Initialize()
|
||||
. = ..()
|
||||
verbs += /mob/living/proc/lay_down
|
||||
|
||||
/mob/living/simple_animal/pet/cat/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/wuv, "purrs!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "hisses!", EMOTE_AUDIBLE)
|
||||
AddElement(/datum/element/mob_holder, held_icon)
|
||||
|
||||
/mob/living/simple_animal/pet/cat/update_mobility()
|
||||
. = ..()
|
||||
if(client && stat != DEAD)
|
||||
if(!CHECK_BITFIELD(mobility_flags, MOBILITY_STAND))
|
||||
icon_state = "[icon_living]_rest"
|
||||
collar_type = "[initial(collar_type)]_rest"
|
||||
else
|
||||
icon_state = "[icon_living]"
|
||||
collar_type = "[initial(collar_type)]"
|
||||
regenerate_icons()
|
||||
|
||||
|
||||
/mob/living/simple_animal/pet/cat/space
|
||||
name = "space cat"
|
||||
desc = "It's a cat... in space!"
|
||||
icon_state = "spacecat"
|
||||
icon_living = "spacecat"
|
||||
icon_dead = "spacecat_dead"
|
||||
held_icon = "spacecat"
|
||||
unsuitable_atmos_damage = 0
|
||||
minbodytemp = TCMB
|
||||
maxbodytemp = T0C + 40
|
||||
|
||||
/mob/living/simple_animal/pet/cat/original
|
||||
name = "Batsy"
|
||||
desc = "The product of alien DNA and bored geneticists."
|
||||
gender = FEMALE
|
||||
icon_state = "original"
|
||||
icon_living = "original"
|
||||
icon_dead = "original_dead"
|
||||
held_icon = "original"
|
||||
collar_type = null
|
||||
unique_pet = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/cat/kitten
|
||||
name = "kitten"
|
||||
desc = "D'aaawwww."
|
||||
icon_state = "kitten"
|
||||
icon_living = "kitten"
|
||||
icon_dead = "kitten_dead"
|
||||
density = FALSE
|
||||
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
|
||||
name = "Runtime"
|
||||
desc = "GCAT"
|
||||
icon_state = "cat"
|
||||
icon_living = "cat"
|
||||
icon_dead = "cat_dead"
|
||||
gender = FEMALE
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
unique_pet = TRUE
|
||||
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
|
||||
var/memory_saved = FALSE
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/Initialize()
|
||||
if(prob(5))
|
||||
icon_state = "original"
|
||||
icon_living = "original"
|
||||
icon_dead = "original_dead"
|
||||
Read_Memory()
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/Life()
|
||||
if(!cats_deployed && SSticker.current_state >= GAME_STATE_SETTING_UP)
|
||||
Deploy_The_Cats()
|
||||
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
Write_Memory()
|
||||
memory_saved = TRUE
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/make_babies()
|
||||
var/mob/baby = ..()
|
||||
if(baby)
|
||||
children += baby
|
||||
return baby
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/death()
|
||||
if(!memory_saved)
|
||||
Write_Memory(TRUE)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory()
|
||||
if(fexists("data/npc_saves/Runtime.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Runtime.sav")
|
||||
S["family"] >> family
|
||||
fdel("data/npc_saves/Runtime.sav")
|
||||
else
|
||||
var/json_file = file("data/npc_saves/Runtime.json")
|
||||
if(!fexists(json_file))
|
||||
return
|
||||
var/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/json_file = file("data/npc_saves/Runtime.json")
|
||||
var/list/file_data = list()
|
||||
family = list()
|
||||
if(!dead)
|
||||
for(var/mob/living/simple_animal/pet/cat/kitten/C in children)
|
||||
if(istype(C,type) || C.stat || !C.z || !C.butcher_results) //That last one is a work around for hologram cats
|
||||
continue
|
||||
if(C.type in family)
|
||||
family[C.type] += 1
|
||||
else
|
||||
family[C.type] = 1
|
||||
file_data["family"] = family
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Deploy_The_Cats()
|
||||
cats_deployed = 1
|
||||
for(var/cat_type in family)
|
||||
if(family[cat_type] > 0)
|
||||
for(var/i in 1 to min(family[cat_type],100)) //Limits to about 500 cats, you wouldn't think this would be needed (BUT IT IS)
|
||||
new cat_type(loc)
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Proc
|
||||
name = "Proc"
|
||||
gender = MALE
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
unique_pet = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Life()
|
||||
if(!stat && !buckled && !client)
|
||||
if(prob(1))
|
||||
emote("me", EMOTE_VISIBLE, pick("stretches out for a belly rub.", "wags its tail.", "lies down."))
|
||||
icon_state = "[icon_living]_rest"
|
||||
collar_type = "[initial(collar_type)]_rest"
|
||||
set_resting(TRUE)
|
||||
else if (prob(1))
|
||||
emote("me", EMOTE_VISIBLE, pick("sits down.", "crouches on its hind legs.", "looks alert."))
|
||||
icon_state = "[icon_living]_sit"
|
||||
collar_type = "[initial(collar_type)]_sit"
|
||||
set_resting(TRUE)
|
||||
else if (prob(1))
|
||||
if (resting)
|
||||
emote("me", EMOTE_VISIBLE, pick("gets up and meows.", "walks around.", "stops resting."))
|
||||
icon_state = "[icon_living]"
|
||||
collar_type = "[initial(collar_type)]"
|
||||
set_resting(FALSE)
|
||||
else
|
||||
emote("me", EMOTE_VISIBLE, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat."))
|
||||
|
||||
//MICE!
|
||||
if((src.loc) && isturf(src.loc))
|
||||
if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled)
|
||||
for(var/mob/living/simple_animal/mouse/M in view(1,src))
|
||||
if(!M.stat && Adjacent(M))
|
||||
emote("me", EMOTE_VISIBLE, "splats \the [M]!")
|
||||
M.splat()
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
break
|
||||
for(var/obj/item/toy/cattoy/T in view(1,src))
|
||||
if (T.cooldown < (world.time - 400))
|
||||
emote("me", EMOTE_VISIBLE, "bats \the [T] around with its paw!")
|
||||
T.cooldown = world.time
|
||||
|
||||
..()
|
||||
|
||||
make_babies()
|
||||
|
||||
if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled)
|
||||
turns_since_scan++
|
||||
if(turns_since_scan > 5)
|
||||
walk_to(src,0)
|
||||
turns_since_scan = 0
|
||||
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
if( !movement_target || !(movement_target.loc in oview(src, 3)) )
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
for(var/mob/living/simple_animal/mouse/snack in oview(src,3))
|
||||
if(isturf(snack.loc) && !snack.stat)
|
||||
movement_target = snack
|
||||
break
|
||||
if(movement_target)
|
||||
stop_automated_movement = 1
|
||||
walk_to(src,movement_target,0,3)
|
||||
|
||||
/mob/living/simple_animal/pet/cat/cak //I told you I'd do it, Remie
|
||||
name = "Keeki"
|
||||
desc = "It's a cat made out of cake."
|
||||
icon_state = "cak"
|
||||
icon_living = "cak"
|
||||
icon_dead = "cak_dead"
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
gender = FEMALE
|
||||
harm_intent_damage = 10
|
||||
butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/reagent_containers/food/snacks/cakeslice/birthday = 3, \
|
||||
/obj/item/reagent_containers/food/snacks/meat/slab = 2)
|
||||
response_harm = "takes a bite out of"
|
||||
attacked_sound = 'sound/items/eatfood.ogg'
|
||||
deathmessage = "loses its false life and collapses!"
|
||||
death_sound = "bodyfall"
|
||||
held_icon = "cak"
|
||||
|
||||
/mob/living/simple_animal/pet/cat/cak/CheckParts(list/parts)
|
||||
..()
|
||||
var/obj/item/organ/brain/B = locate(/obj/item/organ/brain) in contents
|
||||
if(!B || !B.brainmob || !B.brainmob.mind)
|
||||
return
|
||||
B.brainmob.mind.transfer_to(src)
|
||||
to_chat(src, "<span class='big bold'>You are a cak!</span><b> You're a harmless cat/cake hybrid that everyone loves. People can take bites out of you if they're hungry, but you regenerate health \
|
||||
so quickly that it generally doesn't matter. You're remarkably resilient to any damage besides this and it's hard for you to really die at all. You should go around and bring happiness and \
|
||||
free cake to the station!</b>")
|
||||
var/new_name = stripped_input(src, "Enter your name, or press \"Cancel\" to stick with Keeki.", "Name Change")
|
||||
if(new_name)
|
||||
to_chat(src, "<span class='notice'>Your name is now <b>\"new_name\"</b>!</span>")
|
||||
name = new_name
|
||||
|
||||
/mob/living/simple_animal/pet/cat/cak/Life()
|
||||
..()
|
||||
if(stat)
|
||||
return
|
||||
if(health < maxHealth)
|
||||
adjustBruteLoss(-8) //Fast life regen
|
||||
for(var/obj/item/reagent_containers/food/snacks/donut/D in range(1, src)) //Frosts nearby donuts!
|
||||
if(!D.is_decorated)
|
||||
D.decorate_donut()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/cak/attack_hand(mob/living/L)
|
||||
. = ..()
|
||||
if(.) //the attack was blocked
|
||||
return
|
||||
if(L.a_intent == INTENT_HARM && L.reagents && !stat)
|
||||
L.reagents.add_reagent(/datum/reagent/consumable/nutriment, 0.4)
|
||||
L.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.4)
|
||||
|
||||
//Cat made
|
||||
/mob/living/simple_animal/pet/cat/custom_cat
|
||||
name = "White cat" //Incase it somehow gets spawned without an ID
|
||||
desc = "A cute white catto!"
|
||||
icon_state = "custom_cat"
|
||||
icon_living = "custom_cat"
|
||||
icon_dead = "custom_cat_dead"
|
||||
gender = FEMALE
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
health = 50 //So people can't instakill it s
|
||||
maxHealth = 50
|
||||
speak = list("Meowrowr!", "Mew!", "Miauen!")
|
||||
speak_emote = list("wigglepurrs", "mewls")
|
||||
emote_hear = list("meows.", "mews.")
|
||||
emote_see = list("looks at you eagerly for pets!", "wiggles enthusiastically.")
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
var/pseudo_death = FALSE
|
||||
var/mob/living/carbon/human/origin
|
||||
|
||||
/mob/living/simple_animal/pet/cat/custom_cat/death()
|
||||
if (pseudo_death == TRUE) //secret cat chem
|
||||
icon_state = "custom_cat_dead"
|
||||
Stun(1000)
|
||||
friendly = "deads at"
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -13,13 +13,14 @@
|
||||
see_in_dark = 5
|
||||
speak_chance = 1
|
||||
turns_per_move = 10
|
||||
var/held_icon = "corgi"
|
||||
|
||||
do_footstep = TRUE
|
||||
can_be_held = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/dog/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/wuv, "yaps_happily!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "growls!", EMOTE_AUDIBLE)
|
||||
AddElement(/datum/element/wuv, "yaps happily!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "growls!", EMOTE_AUDIBLE)
|
||||
AddElement(/datum/element/mob_holder, held_icon)
|
||||
|
||||
//Corgis and pugs are now under one dog subtype
|
||||
|
||||
@@ -34,13 +35,11 @@
|
||||
childtype = list(/mob/living/simple_animal/pet/dog/corgi/puppy = 95, /mob/living/simple_animal/pet/dog/corgi/puppy/void = 5)
|
||||
animal_species = /mob/living/simple_animal/pet/dog
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
can_be_held = TRUE
|
||||
collar_type = "corgi"
|
||||
var/obj/item/inventory_head
|
||||
var/obj/item/inventory_back
|
||||
var/shaved = FALSE
|
||||
var/nofur = FALSE //Corgis that have risen past the material plane of existence.
|
||||
can_be_held = "corgi"
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Destroy()
|
||||
QDEL_NULL(inventory_head)
|
||||
@@ -69,7 +68,7 @@
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/pug = 3)
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
collar_type = "pug"
|
||||
can_be_held = "pug"
|
||||
held_icon = "pug"
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/exoticcorgi
|
||||
name = "Exotic Corgi"
|
||||
@@ -156,13 +155,6 @@
|
||||
..()
|
||||
update_corgi_fluff()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/mob_pickup(mob/living/L)
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, "corgi", null, 'icons/mob/pets_held_lh.dmi', 'icons/mob/pets_held_rh.dmi', FALSE)
|
||||
if(!L.put_in_hands(holder))
|
||||
qdel(holder)
|
||||
else
|
||||
L.visible_message("<span class='warning'>[L] scoops up [src]!</span>")
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Topic(href, href_list)
|
||||
if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
usr << browse(null, "window=mob[REF(src)]")
|
||||
@@ -371,7 +363,10 @@
|
||||
icon_dead = "old_corgi_dead"
|
||||
desc = "At a ripe old age of [record_age] Ian's not as spry as he used to be, but he'll always be the HoP's beloved corgi." //RIP
|
||||
turns_per_move = 20
|
||||
can_be_held = "old_corgi"
|
||||
var/datum/element/mob_holder/ele = SSdcs.GetElement(/datum/element/mob_holder, held_icon)
|
||||
if(ele)
|
||||
ele.Detach(src)
|
||||
AddElement(/datum/element/mob_holder, "old_corgi")
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/Life()
|
||||
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
@@ -594,7 +589,7 @@
|
||||
unsuitable_atmos_damage = 0
|
||||
minbodytemp = TCMB
|
||||
maxbodytemp = T0C + 40
|
||||
can_be_held = "void_puppy"
|
||||
held_icon = "void_puppy"
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/puppy/void/Process_Spacemove(movement_dir = 0)
|
||||
return 1 //Void puppies can navigate space.
|
||||
@@ -616,7 +611,7 @@
|
||||
response_harm = "kicks"
|
||||
var/turns_since_scan = 0
|
||||
var/puppies = 0
|
||||
can_be_held = "lisa"
|
||||
held_icon = "lisa"
|
||||
|
||||
//Lisa already has a cute bow!
|
||||
/mob/living/simple_animal/pet/dog/corgi/Lisa/Topic(href, href_list)
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
see_in_dark = 7
|
||||
blood_volume = 0
|
||||
can_be_held = TRUE
|
||||
var/can_be_held = TRUE //mob holder element.
|
||||
held_items = list(null, null)
|
||||
var/staticChoice = "static"
|
||||
var/list/staticChoices = list("static", "blank", "letter", "animal")
|
||||
@@ -101,6 +101,11 @@
|
||||
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
|
||||
diag_hud.add_to_hud(src)
|
||||
|
||||
/mob/living/simple_animal/drone/ComponentInitialize()
|
||||
. = ..()
|
||||
if(can_be_held)
|
||||
//icon/item state is defined in mob_holder/drone_worn_icon()
|
||||
AddElement(/datum/element/mob_holder, null, 'icons/mob/head.dmi', 'icons/mob/inhands/clothing_righthand.dmi', 'icons/mob/inhands/clothing_lefthand.dmi', TRUE, /datum/element/mob_holder.proc/drone_worn_icon)
|
||||
|
||||
/mob/living/simple_animal/drone/med_hud_set_health()
|
||||
var/image/holder = hud_list[DIAG_HUD]
|
||||
@@ -283,7 +288,3 @@
|
||||
var/obj/item/clothing/H = head
|
||||
if(H.clothing_flags & SCAN_REAGENTS)
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/drone/generate_mob_holder()
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, "[visualAppearence]_hat", null, null, null, TRUE)
|
||||
return holder
|
||||
|
||||
@@ -29,12 +29,6 @@
|
||||
if("Nothing")
|
||||
return
|
||||
|
||||
//picky up the drone c:
|
||||
/mob/living/simple_animal/drone/attack_hand(mob/user)
|
||||
if(user.a_intent != INTENT_HELP)
|
||||
return ..() // TODO: convert picking up mobs into an element or component.
|
||||
mob_try_pickup(user)
|
||||
|
||||
/mob/living/simple_animal/drone/proc/try_reactivate(mob/living/user)
|
||||
var/mob/dead/observer/G = get_ghost()
|
||||
if(!client && (!G || !G.client))
|
||||
|
||||
@@ -18,9 +18,12 @@
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
can_be_held = "fox"
|
||||
do_footstep = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/fox/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/mob_holder, "fox")
|
||||
|
||||
//Captain fox
|
||||
/mob/living/simple_animal/pet/fox/Renault
|
||||
name = "Renault"
|
||||
|
||||
@@ -23,7 +23,10 @@
|
||||
obj_damage = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
var/static/list/edibles = typecacheof(list(/mob/living/simple_animal/butterfly, /mob/living/simple_animal/cockroach)) //list of atoms, however turfs won't affect AI, but will affect consumption.
|
||||
can_be_held = "lizard" //you can hold lizards now.
|
||||
|
||||
/mob/living/simple_animal/hostile/lizard/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/mob_holder, "lizard", null, null, null, SLOT_HEAD) //you can hold lizards now.
|
||||
|
||||
/mob/living/simple_animal/hostile/lizard/CanAttack(atom/the_target)//Can we actually attack a possible target?
|
||||
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
|
||||
@@ -40,7 +43,3 @@
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/lizard/generate_mob_holder()
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, "lizard", 'icons/mob/animals_held.dmi', 'icons/mob/animals_held_lh.dmi', 'icons/mob/animals_held_rh.dmi', TRUE)
|
||||
return holder
|
||||
|
||||
@@ -26,17 +26,16 @@
|
||||
var/body_color //brown, gray and white, leave blank for random
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
var/chew_probability = 1
|
||||
can_be_held = TRUE
|
||||
|
||||
/mob/living/simple_animal/mouse/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak, list('sound/effects/mousesqueek.ogg'=1), 100)
|
||||
if(!body_color)
|
||||
body_color = pick( list("brown","gray","white") )
|
||||
body_color = pick(list("brown","gray","white"))
|
||||
AddElement(/datum/element/mob_holder, "mouse_[body_color]")
|
||||
icon_state = "mouse_[body_color]"
|
||||
icon_living = "mouse_[body_color]"
|
||||
icon_dead = "mouse_[body_color]_dead"
|
||||
can_be_held = "mouse_[body_color]"
|
||||
|
||||
/mob/living/simple_animal/mouse/proc/splat()
|
||||
src.health = 0
|
||||
@@ -89,17 +88,14 @@
|
||||
/mob/living/simple_animal/mouse/white
|
||||
body_color = "white"
|
||||
icon_state = "mouse_white"
|
||||
can_be_held = "mouse_white"
|
||||
|
||||
/mob/living/simple_animal/mouse/gray
|
||||
body_color = "gray"
|
||||
icon_state = "mouse_gray"
|
||||
can_be_held = "mouse_gray"
|
||||
|
||||
/mob/living/simple_animal/mouse/brown
|
||||
body_color = "brown"
|
||||
icon_state = "mouse_brown"
|
||||
can_be_held = "mouse_brown"
|
||||
|
||||
//TOM IS ALIVE! SQUEEEEEEEE~K :)
|
||||
/mob/living/simple_animal/mouse/brown/Tom
|
||||
@@ -124,7 +120,3 @@
|
||||
/obj/item/reagent_containers/food/snacks/deadmouse/on_grind()
|
||||
reagents.clear_reagents()
|
||||
|
||||
/mob/living/simple_animal/mouse/generate_mob_holder()
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, (istext(can_be_held) ? can_be_held : ""), 'icons/mob/animals_held.dmi', 'icons/mob/animals_held_lh.dmi', 'icons/mob/animals_held_rh.dmi')
|
||||
holder.w_class = WEIGHT_CLASS_TINY
|
||||
return holder
|
||||
|
||||
@@ -22,9 +22,11 @@
|
||||
maxHealth = 50
|
||||
speed = 10
|
||||
glide_size = 2
|
||||
can_be_held = "sloth" //finally oranges can be held
|
||||
do_footstep = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/fox/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/mob_holder, "sloth") //finally oranges can be held
|
||||
|
||||
//Cargo Sloth
|
||||
/mob/living/simple_animal/sloth/paperwork
|
||||
|
||||
@@ -17,10 +17,9 @@
|
||||
emote_taunt = list("gnashes")
|
||||
taunt_chance = 30
|
||||
speed = 0
|
||||
maxHealth = 25
|
||||
health = 25
|
||||
maxHealth = 35
|
||||
health = 35
|
||||
spacewalk = TRUE
|
||||
|
||||
harm_intent_damage = 8
|
||||
obj_damage = 50
|
||||
melee_damage_lower = 15
|
||||
@@ -28,7 +27,6 @@
|
||||
attacktext = "bites"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
speak_emote = list("gnashes")
|
||||
|
||||
//Space carp aren't affected by cold.
|
||||
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)
|
||||
minbodytemp = 0
|
||||
@@ -37,6 +35,19 @@
|
||||
movement_type = FLYING
|
||||
pressure_resistance = 200
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
//some carps heal over time
|
||||
var/regen_cooldown = 0 //Used for how long it takes before a healing will take place default in 60 seconds
|
||||
var/regen_amount = 0 //How much is healed pre regen cooldown
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
. = ..()
|
||||
if(regen_amount)
|
||||
regen_cooldown = world.time + REGENERATION_DELAY
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/Life()
|
||||
. = ..()
|
||||
if(regen_amount && regen_cooldown < world.time)
|
||||
heal_overall_damage(regen_amount)
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/AttackingTarget()
|
||||
. = ..()
|
||||
@@ -59,8 +70,11 @@
|
||||
icon_living = "megacarp"
|
||||
icon_dead = "megacarp_dead"
|
||||
icon_gib = "megacarp_gib"
|
||||
maxHealth = 20
|
||||
health = 20
|
||||
|
||||
regen_amount = 6
|
||||
|
||||
maxHealth = 30
|
||||
health = 30
|
||||
pixel_x = -16
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
|
||||
@@ -68,35 +82,26 @@
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 20
|
||||
|
||||
var/regen_cooldown = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/megacarp/Initialize()
|
||||
. = ..()
|
||||
name = "[pick(GLOB.megacarp_first_names)] [pick(GLOB.megacarp_last_names)]"
|
||||
melee_damage_lower += rand(2, 10)
|
||||
melee_damage_lower += rand(4, 10)
|
||||
melee_damage_upper += rand(10,20)
|
||||
maxHealth += rand(30,60)
|
||||
maxHealth += rand(40,60)
|
||||
move_to_delay = rand(3,7)
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/megacarp/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
regen_cooldown = world.time + REGENERATION_DELAY
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/megacarp/Life()
|
||||
. = ..()
|
||||
if(regen_cooldown < world.time)
|
||||
heal_overall_damage(4)
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne
|
||||
name = "Cayenne"
|
||||
desc = "A failed Syndicate experiment in weaponized space carp technology, it now serves as a lovable mascot."
|
||||
gender = FEMALE
|
||||
|
||||
regen_amount = 8
|
||||
|
||||
speak_emote = list("squeaks")
|
||||
maxHealth = 90
|
||||
health = 90
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
faction = list(ROLE_SYNDICATE)
|
||||
faction = list(ROLE_SYNDICATE, "carp") //They are still a carp
|
||||
AIStatus = AI_OFF
|
||||
|
||||
harm_intent_damage = 12
|
||||
|
||||
@@ -432,6 +432,7 @@ Difficulty: Very Hard
|
||||
H.dropItemToGround(W)
|
||||
var/datum/job/clown/C = new /datum/job/clown()
|
||||
C.equip(H)
|
||||
C.after_spawn(H, H, TRUE)
|
||||
qdel(C)
|
||||
affected_targets.Add(H)
|
||||
|
||||
|
||||
@@ -197,8 +197,6 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/ranged
|
||||
var/obj/item/gun/TrueGun = null
|
||||
var/obj/item/gun/magic/Zapstick
|
||||
@@ -229,14 +227,13 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
|
||||
casingtype = initial(M.ammo_type)
|
||||
if(istype(G, /obj/item/gun/energy))
|
||||
Zapgun = G
|
||||
var/selectfiresetting = Zapgun.select
|
||||
var/obj/item/ammo_casing/energy/E = Zapgun.ammo_type[selectfiresetting]
|
||||
var/obj/item/ammo_casing/energy/E = Zapgun.ammo_type[Zapgun.current_firemode_index]
|
||||
projectiletype = initial(E.projectile_type)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/ranged/OpenFire(the_target)
|
||||
if(Zapgun)
|
||||
if(Zapgun.cell)
|
||||
var/obj/item/ammo_casing/energy/shot = Zapgun.ammo_type[Zapgun.select]
|
||||
var/obj/item/ammo_casing/energy/shot = Zapgun.ammo_type[Zapgun.current_firemode_index]
|
||||
if(Zapgun.cell.charge >= shot.e_cost)
|
||||
Zapgun.cell.use(shot.e_cost)
|
||||
Zapgun.update_icon()
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
|
||||
/obj/item/projectile/temp/basilisk/magmawing/on_hit(atom/target, blocked = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(. && isliving(target))
|
||||
var/mob/living/L = target
|
||||
if (istype(L))
|
||||
L.adjust_fire_stacks(0.1)
|
||||
@@ -144,7 +144,7 @@
|
||||
|
||||
/obj/item/projectile/temp/basilisk/icewing/on_hit(atom/target, blocked = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(. && isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.apply_status_effect(/datum/status_effect/freon/watcher)
|
||||
|
||||
|
||||
@@ -62,8 +62,9 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/elite/herald/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
|
||||
. = ..()
|
||||
playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE)
|
||||
|
||||
if(.)
|
||||
playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE)
|
||||
|
||||
/datum/action/innate/elite_attack/herald_trishot
|
||||
name = "Triple Shot"
|
||||
button_icon_state = "herald_trishot"
|
||||
|
||||
@@ -321,20 +321,18 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
|
||||
set name = "Examine"
|
||||
set category = "IC"
|
||||
|
||||
if(!client)
|
||||
return
|
||||
|
||||
if(!(SEND_SIGNAL(src, COMSIG_MOB_EXAMINATE, A) & COMPONENT_ALLOW_EXAMINE) && ((client.eye != src && client.eye != loc) || (isturf(A) && !(sight & SEE_TURFS) && !(A in view(client ? client.view : world.view, src)))))
|
||||
//cameras & co don't allow users to examine far away things, also shift-click catcher may issue examinate() calls for out-of-sight turfs
|
||||
if(isturf(A) && !(sight & SEE_TURFS) && !(A in view(client ? client.view : world.view, src)))
|
||||
// shift-click catcher may issue examinate() calls for out-of-sight turfs
|
||||
return
|
||||
|
||||
if(is_blind(src))
|
||||
to_chat(src, "<span class='notice'>Something is there but you can't see it.</span>")
|
||||
to_chat(src, "<span class='warning'>Something is there but you can't see it!</span>")
|
||||
return
|
||||
|
||||
face_atom(A)
|
||||
var/list/result = A.examine(src)
|
||||
to_chat(src, result.Join("\n"))
|
||||
SEND_SIGNAL(src, COMSIG_MOB_EXAMINATE, A)
|
||||
|
||||
//same as above
|
||||
//note: ghosts can point, this is intended
|
||||
@@ -808,7 +806,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
|
||||
//Can the mob interact() with an atom?
|
||||
/mob/proc/can_interact_with(atom/A)
|
||||
return IsAdminGhost(src) || Adjacent(A)
|
||||
return IsAdminGhost(src) || Adjacent(A) || A.hasSiliconAccessInArea(src)
|
||||
|
||||
//Can the mob use Topic to interact with machines
|
||||
/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
|
||||
|
||||
@@ -120,4 +120,7 @@
|
||||
|
||||
var/mob/audiovisual_redirect //Mob to redirect messages, speech, and sounds to
|
||||
|
||||
var/voluntary_ghosted = FALSE //whether or not they voluntarily ghosted.
|
||||
var/siliconaccessareas = list()
|
||||
var/siliconaccesstoggle = FALSE
|
||||
|
||||
var/voluntary_ghosted = FALSE //whether or not they voluntarily ghosted.
|
||||
@@ -147,6 +147,10 @@
|
||||
. += newletter
|
||||
return sanitize(.)
|
||||
|
||||
//Ratvarian Slurring!
|
||||
|
||||
#define CLOCK_CULT_SLUR(phrase) sanitize(text2ratvar(phrase))
|
||||
|
||||
///Adds stuttering to the message passed in
|
||||
/proc/stutter(phrase)
|
||||
phrase = html_decode(phrase)
|
||||
@@ -402,6 +406,41 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/atom/proc/hasSiliconAccessInArea(mob/user)
|
||||
return user && (issilicon(user) || (user.siliconaccesstoggle && (get_area(src) in user.siliconaccessareas)))
|
||||
|
||||
/mob/proc/toggleSiliconAccessArea(area/area)
|
||||
if (area in siliconaccessareas)
|
||||
siliconaccessareas -= area
|
||||
to_chat(src,"<span class='warning'>You lost control of [area]!</span>")
|
||||
return FALSE
|
||||
else
|
||||
if (LAZYLEN(siliconaccessareas) < HIJACK_APC_MAX_AMOUNT)
|
||||
siliconaccessareas += area
|
||||
to_chat(src,"<span class='notice'>You successfully took control of [area].</span>")
|
||||
else
|
||||
to_chat(src,"<span class='warning'>You are connected to too many APCs! Too many more will fry your brain.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/mob/proc/getImplant(type)
|
||||
return
|
||||
|
||||
/mob/living/getImplant(type)
|
||||
return locate(type) in implants
|
||||
|
||||
/proc/canGhostWrite(var/mob/A, var/obj/target, var/desc="", var/allow_all=FALSE)
|
||||
if(allow_all & TRUE)
|
||||
if(!target.GetComponent(/datum/component/anti_magic))
|
||||
return 1
|
||||
if(IsAdminGhost(A))
|
||||
if (desc != "")
|
||||
log_admin("GHOST: [key_name(A)] [desc] ([target.name] at [loc_name(target)])")
|
||||
else
|
||||
log_admin("GHOST: [key_name(A)] fucked with the [target.name] at [loc_name(target)]")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/offer_control(mob/M)
|
||||
to_chat(M, "Control of your mob has been offered to dead players.")
|
||||
if(usr)
|
||||
|
||||
Reference in New Issue
Block a user