Conflicts!!!

This commit is contained in:
Artur
2020-06-22 17:39:24 +03:00
395 changed files with 84463 additions and 336540 deletions
+3 -3
View File
@@ -68,7 +68,7 @@ INITIALIZE_IMMEDIATE(/mob/dead)
set category = "OOC"
set name = "Server Hop!"
set desc= "Jump to the other server"
if(notransform)
if(mob_transforming)
return
var/list/csa = CONFIG_GET(keyed_list/cross_server)
var/pick
@@ -93,9 +93,9 @@ INITIALIZE_IMMEDIATE(/mob/dead)
to_chat(C, "<span class='notice'>Sending you to [pick].</span>")
new /obj/screen/splash(C)
notransform = TRUE
mob_transforming = TRUE
sleep(29) //let the animation play
notransform = FALSE
mob_transforming = FALSE
if(!C)
return
+3 -1
View File
@@ -94,7 +94,9 @@
//We want an accurate reading of .len
listclearnulls(BP.embedded_objects)
temp_bleed += 0.5 * BP.embedded_objects.len
for(var/obj/item/embeddies in BP.embedded_objects)
if(!embeddies.isEmbedHarmless())
temp_bleed += 0.5
if(brutedamage >= 20)
temp_bleed += (brutedamage * 0.013)
+3 -3
View File
@@ -37,10 +37,10 @@
C.put_in_hands(B1)
C.put_in_hands(B2)
C.regenerate_icons()
src.notransform = TRUE
src.mob_transforming = TRUE
spawn(0)
bloodpool_sink(B)
src.notransform = FALSE
src.mob_transforming = FALSE
return 1
/mob/living/proc/bloodpool_sink(obj/effect/decal/cleanable/B)
@@ -155,7 +155,7 @@
addtimer(CALLBACK(src, /atom/.proc/remove_atom_colour, TEMPORARY_COLOUR_PRIORITY, newcolor), 6 SECONDS)
/mob/living/proc/phasein(obj/effect/decal/cleanable/B)
if(src.notransform)
if(src.mob_transforming)
to_chat(src, "<span class='warning'>Finish eating first!</span>")
return 0
B.visible_message("<span class='warning'>[B] starts to bubble...</span>")
+2 -6
View File
@@ -1,11 +1,7 @@
/mob/living/brain/Life()
set invisibility = 0
if (notransform)
/mob/living/brain/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(!loc)
return
. = ..()
handle_emp_damage()
/mob/living/brain/update_stat()
@@ -8,9 +8,6 @@
/mob/living/carbon/alien/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
return ..(AM, skipcatch = TRUE, hitpush = FALSE)
/mob/living/carbon/alien/can_embed(obj/item/I)
return FALSE
/*Code for aliens attacking aliens. Because aliens act on a hivemind, I don't see them as very aggressive with each other.
As such, they can either help or harm other aliens. Help works like the human help command while harm is a simple nibble.
In all, this is a lot like the monkey code. /N
@@ -54,6 +51,8 @@ In all, this is a lot like the monkey code. /N
return
switch(M.a_intent)
if(INTENT_HELP)
if(M == src && check_self_for_injuries())
return
help_shake_act(M)
if(INTENT_GRAB)
grabbedby(M)
@@ -1,14 +1,10 @@
/mob/living/carbon/alien/larva/Life()
set invisibility = 0
if (notransform)
/mob/living/carbon/alien/larva/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(..()) //not dead
// GROW!
if(amount_grown < max_grown)
amount_grown++
update_icons()
// GROW!
if(amount_grown < max_grown)
amount_grown++
update_icons()
/mob/living/carbon/alien/larva/update_stat()
+3 -2
View File
@@ -1,6 +1,7 @@
/mob/living/carbon/alien/Life()
/mob/living/carbon/alien/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
findQueen()
return..()
/mob/living/carbon/alien/check_breath(datum/gas_mixture/breath)
if(status_flags & GODMODE)
@@ -92,7 +92,7 @@
ghost.transfer_ckey(new_xeno, FALSE)
SEND_SOUND(new_xeno, sound('sound/voice/hiss5.ogg',0,0,0,100)) //To get the player's attention
new_xeno.Paralyze(6)
new_xeno.notransform = TRUE
new_xeno.mob_transforming = TRUE
new_xeno.invisibility = INVISIBILITY_MAXIMUM
sleep(6)
@@ -102,7 +102,7 @@
if(new_xeno)
new_xeno.SetParalyzed(0)
new_xeno.notransform = FALSE
new_xeno.mob_transforming = FALSE
new_xeno.invisibility = 0
var/mob/living/carbon/old_owner = owner
+10 -2
View File
@@ -247,7 +247,7 @@
/mob/living/carbon/Topic(href, href_list)
..()
//strip panel
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
if(usr.canUseTopic(src, BE_CLOSE))
if(href_list["internal"] && !HAS_TRAIT(src, TRAIT_NO_INTERNALS))
var/slot = text2num(href_list["internal"])
var/obj/item/ITEM = get_item_by_slot(slot)
@@ -267,7 +267,15 @@
visible_message("<span class='danger'>[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].</span>", \
"<span class='userdanger'>[usr] [internal ? "opens" : "closes"] the valve on your [ITEM.name].</span>", \
target = usr, target_message = "<span class='danger'>You [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].</span>")
if(href_list["embedded_object"] && usr.canUseTopic(src, BE_CLOSE))
var/obj/item/bodypart/L = locate(href_list["embedded_limb"]) in bodyparts
if(!L)
return
var/obj/item/I = locate(href_list["embedded_object"]) in L.embedded_objects
if(!I || I.loc != src) //no item, no limb, or item is not in limb or in the person anymore
return
SEND_SIGNAL(src, COMSIG_CARBON_EMBED_RIP, I, L)
return
/mob/living/carbon/fall(forced)
loc.handle_fall(src, forced)//it's loc so it doesn't call the mob's handle_fall which does nothing
@@ -65,17 +65,6 @@
throw_mode_off()
return TRUE
/mob/living/carbon/embed_item(obj/item/I)
throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
var/obj/item/bodypart/L = pick(bodyparts)
L.embedded_objects |= I
I.add_mob_blood(src)//it embedded itself in you, of course it's bloody!
I.forceMove(src)
I.embedded()
L.receive_damage(I.w_class*I.embedding.embedded_impact_pain_multiplier)
visible_message("<span class='danger'>[I] embeds itself in [src]'s [L.name]!</span>","<span class='userdanger'>[I] embeds itself in your [L.name]!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded)
/mob/living/carbon/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
var/totitemdamage = pre_attacked_by(I, user) * damage_multiplier
var/impacting_zone = (user == src)? check_zone(user.zone_selected) : ran_zone(user.zone_selected)
@@ -274,6 +263,9 @@
to_chat(M, "<span class='warning'>You can't put [p_them()] out with just your bare hands!</span>")
return
if(M == src && check_self_for_injuries())
return
if(health >= 0 && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
var/friendly_check = FALSE
if(mob_run_block(M, 0, M.name, ATTACK_TYPE_UNARMED, 0, null, null, null))
@@ -341,6 +333,26 @@
update_mobility()
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
/// Check ourselves to see if we've got any shrapnel, return true if we do. This is a much simpler version of what humans do, we only indicate we're checking ourselves if there's actually shrapnel
/mob/living/carbon/proc/check_self_for_injuries()
if(stat == DEAD || stat == UNCONSCIOUS)
return
var/embeds = FALSE
for(var/X in bodyparts)
var/obj/item/bodypart/LB = X
for(var/obj/item/I in LB.embedded_objects)
if(!embeds)
embeds = TRUE
// this way, we only visibly try to examine ourselves if we have something embedded, otherwise we'll still hug ourselves :)
visible_message("<span class='notice'>[src] examines [p_them()]self.</span>", \
"<span class='notice'>You check yourself for shrapnel.</span>")
if(I.isEmbedHarmless())
to_chat(src, "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] stuck to your [LB.name]!</a>")
else
to_chat(src, "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
return embeds
/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
. = ..()
+10 -9
View File
@@ -1,20 +1,21 @@
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE)
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone)
var/hit_percent = (100-blocked)/100
if(!forced && hit_percent <= 0)
return 0
var/obj/item/bodypart/BP = null
if(isbodypart(def_zone)) //we specified a bodypart object
BP = def_zone
else
if(!def_zone)
def_zone = ran_zone(def_zone)
BP = get_bodypart(check_zone(def_zone))
if(!BP)
BP = bodyparts[1]
if(!spread_damage)
if(isbodypart(def_zone)) //we specified a bodypart object
BP = def_zone
else
if(!def_zone)
def_zone = ran_zone(def_zone)
BP = get_bodypart(check_zone(def_zone))
if(!BP)
BP = bodyparts[1]
var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
+25 -4
View File
@@ -31,14 +31,35 @@
else if(get_bodypart(BODY_ZONE_HEAD))
. += "<span class='deadsay'>It appears that [t_his] brain is missing...</span>"
var/list/missing = get_missing_limbs()
var/list/msg = list("<span class='warning'>")
var/list/missing = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)
var/list/disabled = list()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if(BP.disabled)
disabled += BP
missing -= BP.body_zone
for(var/obj/item/I in BP.embedded_objects)
if(I.isEmbedHarmless())
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] stuck to [t_his] [BP.name]!</B>\n"
else
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!</B>\n"
for(var/X in disabled)
var/obj/item/bodypart/BP = X
var/damage_text
if(!(BP.get_damage(include_stamina = FALSE) >= BP.max_damage)) //Stamina is disabling the limb
damage_text = "limp and lifeless"
else
damage_text = (BP.brute_dam >= BP.burn_dam) ? BP.heavy_brute_msg : BP.heavy_burn_msg
msg += "<B>[capitalize(t_his)] [BP.name] is [damage_text]!</B>\n"
for(var/t in missing)
if(t==BODY_ZONE_HEAD)
. += "<span class='deadsay'><B>[t_His] [parse_zone(t)] is missing!</B></span>"
msg += "<span class='deadsay'><B>[t_His] [parse_zone(t)] is missing!</B></span>\n"
continue
. += "<span class='warning'><B>[t_His] [parse_zone(t)] is missing!</B></span>"
msg += "<span class='warning'><B>[t_His] [parse_zone(t)] is missing!</B></span>\n"
var/list/msg = list()
var/temp = getBruteLoss()
if(!(user == src && src.hal_screwyhud == SCREWYHUD_HEALTHY)) //fake healthy
if(temp)
@@ -1,5 +1,5 @@
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage)
// depending on the species, it will run the corresponding apply_damage code there
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced)
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage)
@@ -159,7 +159,10 @@
disabled += BP
missing -= BP.body_zone
for(var/obj/item/I in BP.embedded_objects)
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!</B>\n"
if(I.isEmbedHarmless())
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] stuck to [t_his] [BP.name]!</B>\n"
else
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!</B>\n"
for(var/X in disabled)
var/obj/item/bodypart/BP = X
+1 -16
View File
@@ -222,22 +222,7 @@
var/obj/item/I = locate(href_list["embedded_object"]) in L.embedded_objects
if(!I || I.loc != src) //no item, no limb, or item is not in limb or in the person anymore
return
var/time_taken = I.embedding.embedded_unsafe_removal_time/I.w_class //Citadel Change from * to /
usr.visible_message("<span class='warning'>[usr] attempts to remove [I] from [usr.p_their()] [L.name].</span>","<span class='notice'>You attempt to remove [I] from your [L.name]... (It will take [DisplayTimeText(time_taken)].)</span>")
if(do_after(usr, time_taken, needhand = 1, target = src))
remove_embedded_unsafe(L, I, usr)
/* CITADEL EDIT: remove_embedded_unsafe replaces this code
if(!I || !L || I.loc != src || !(I in L.embedded_objects))
return
L.embedded_objects -= I
L.receive_damage(I.embedding.embedded_unsafe_removal_pain_multiplier*I.w_class)//It hurts to rip it out, get surgery you dingus.
I.forceMove(get_turf(src))
usr.put_in_hands(I)
usr.emote("scream")
usr.visible_message("[usr] successfully rips [I] out of [usr.p_their()] [L.name]!","<span class='notice'>You successfully remove [I] from your [L.name].</span>")
if(!has_embedded_objects())
clear_alert("embeddedobject")
SEND_SIGNAL(usr, COMSIG_CLEAR_MOOD_EVENT, "embedded") */
SEND_SIGNAL(src, COMSIG_CARBON_EMBED_RIP, I, L)
return
if(href_list["item"])
@@ -52,11 +52,6 @@
return martial_art_result
return ..()
/mob/living/carbon/human/can_embed(obj/item/I)
if(I.get_sharpness() || is_pointed(I) || is_type_in_typecache(I, GLOB.can_embed_types))
return TRUE
return FALSE
/mob/living/carbon/human/proc/check_martial_melee_block()
if(mind)
if(mind.martial_art && prob(mind.martial_art.block_chance) && mind.martial_art.can_use(src) && in_throw_mode && !incapacitated(FALSE, TRUE))
@@ -620,7 +615,10 @@
to_send += "\t <span class='[no_damage ? "notice" : "warning"]'>Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].</span>\n"
for(var/obj/item/I in LB.embedded_objects)
to_send += "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>\n"
if(I.isEmbedHarmless())
to_chat(src, "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] stuck to your [LB.name]!</a>")
else
to_chat(src, "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
for(var/t in missing)
to_send += "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>\n"
+10 -44
View File
@@ -18,36 +18,21 @@
#define THERMAL_PROTECTION_HAND_LEFT 0.025
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
/mob/living/carbon/human/Life(seconds, times_fired)
set invisibility = 0
if (notransform)
/mob/living/carbon/human/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
handle_active_genes()
//heart attack stuff
handle_heart()
dna.species.spec_life(src) // for mutantraces
return (stat != DEAD) && !QDELETED(src)
. = ..()
if (QDELETED(src))
return 0
if(.) //not dead
handle_active_genes()
if(stat != DEAD)
//heart attack stuff
handle_heart()
if(stat != DEAD)
//Stuff jammed in your limbs hurts
handle_embedded_objects()
/mob/living/carbon/human/PhysicalLife(seconds, times_fired)
if(!(. = ..()))
return
//Update our name based on whether our face is obscured/disfigured
name = get_visible_name()
dna.species.spec_life(src) // for mutantraces
if(stat != DEAD)
return 1
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
var/headless = !get_bodypart(BODY_ZONE_HEAD) //should the mob be perennially headless (see dullahans), we only take the suit into account, so they can into space.
if (wear_suit && istype(wear_suit, /obj/item/clothing) && (headless || (head && istype(head, /obj/item/clothing))))
@@ -303,25 +288,6 @@
return TRUE
return ..()
/mob/living/carbon/human/proc/handle_embedded_objects()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
for(var/obj/item/I in BP.embedded_objects)
if(prob(I.embedding.embedded_pain_chance))
BP.receive_damage(I.w_class*I.embedding.embedded_pain_multiplier)
to_chat(src, "<span class='userdanger'>[I] embedded in your [BP.name] hurts!</span>")
if(prob(I.embedding.embedded_fall_chance))
BP.receive_damage(I.w_class*I.embedding.embedded_fall_pain_multiplier)
BP.embedded_objects -= I
I.forceMove(drop_location())
I.unembedded()
visible_message("<span class='danger'>[I] falls out of [name]'s [BP.name]!</span>","<span class='userdanger'>[I] falls out of your [BP.name]!</span>")
if(!has_embedded_objects())
clear_alert("embeddedobject")
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "embedded")
/mob/living/carbon/human/proc/handle_active_genes()
if(HAS_TRAIT(src, TRAIT_MUTATION_STASIS))
return
+17 -17
View File
@@ -1494,12 +1494,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/miss_chance = 100//calculate the odds that a punch misses entirely. considers stamina and brute damage of the puncher. punches miss by default to prevent weird cases
if(user.dna.species.punchdamagelow)
if(HAS_TRAIT(user, TRAIT_PUGILIST)) //pugilists have a flat 10% miss chance
miss_chance = 10
if(atk_verb == ATTACK_EFFECT_KICK) //kicks never miss (provided your species deals more than 0 damage)
miss_chance = 0
else if(HAS_TRAIT(user, TRAIT_PUGILIST)) //pugilists have a flat 10% miss chance
miss_chance = 10
else
miss_chance = min(10 + ((puncherstam + puncherbrute)*0.5), 100) //probability of miss has a base of 10, and modified based on half brute total. Capped at max 100 to prevent weirdness in prob()
miss_chance = min(10 + max(puncherstam * 0.5, puncherbrute * 0.5), 100) //probability of miss has a base of 10, and modified based on half brute total. Capped at max 100 to prevent weirdness in prob()
if(!damage || !affecting || prob(miss_chance))//future-proofing for species that have 0 damage/weird cases where no zone is targeted
playsound(target.loc, user.dna.species.miss_sound, 25, TRUE, -1)
@@ -1941,7 +1941,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
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)
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE)
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone)
var/hit_percent = (100-(blocked+armor))/100
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
@@ -1949,20 +1949,20 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
return 0
var/obj/item/bodypart/BP = null
if(isbodypart(def_zone))
if(damagetype == STAMINA && istype(def_zone, /obj/item/bodypart/head))
BP = H.get_bodypart(check_zone(BODY_ZONE_CHEST))
if(!spread_damage)
if(isbodypart(def_zone))
if(damagetype == STAMINA && istype(def_zone, /obj/item/bodypart/head))
BP = H.get_bodypart(check_zone(BODY_ZONE_CHEST))
else
BP = def_zone
else
BP = def_zone
else
if(!def_zone)
def_zone = ran_zone(def_zone)
if(damagetype == STAMINA && def_zone == BODY_ZONE_HEAD)
def_zone = BODY_ZONE_CHEST
BP = H.get_bodypart(check_zone(def_zone))
if(!BP)
BP = H.bodyparts[1]
if(!def_zone)
def_zone = ran_zone(def_zone)
if(damagetype == STAMINA && def_zone == BODY_ZONE_HEAD)
def_zone = BODY_ZONE_CHEST
BP = H.get_bodypart(check_zone(def_zone))
if(!BP)
BP = H.bodyparts[1]
switch(damagetype)
if(BRUTE)
@@ -1,6 +1,7 @@
/datum/species/insect
name = "Anthromorphic Insect"
id = "insect"
say_mod = "chitters"
default_color = "00FF00"
species_traits = list(LIPS,EYECOLOR,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR)
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG
@@ -13,6 +14,7 @@
liked_food = MEAT | FRUIT
disliked_food = TOXIC
icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
exotic_bloodtype = "BUG"
/datum/species/insect/spec_death(gibbed, mob/living/carbon/human/H)
if(H)
@@ -42,4 +44,4 @@
H.update_body()
/datum/species/insect/qualifies_for_rank(rank, list/features)
return TRUE
return TRUE
@@ -239,7 +239,7 @@
"<span class='notice'>You focus intently on moving your body while \
standing perfectly still...</span>")
H.notransform = TRUE
H.mob_transforming = TRUE
if(do_after(owner, delay=60, needhand=FALSE, target=owner, progress=TRUE))
if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT)
@@ -249,7 +249,7 @@
else
to_chat(H, "<span class='warning'>...but fail to stand perfectly still!</span>")
H.notransform = FALSE
H.mob_transforming = FALSE
/datum/action/innate/split_body/proc/make_dupe()
var/mob/living/carbon/human/H = owner
@@ -267,7 +267,7 @@
spare.Move(get_step(H.loc, pick(NORTH,SOUTH,EAST,WEST)))
H.blood_volume *= 0.45
H.notransform = 0
H.mob_transforming = 0
var/datum/species/jelly/slime/origin_datum = H.dna.species
origin_datum.bodies |= spare
@@ -466,7 +466,7 @@
if(new_color)
var/temp_hsv = RGBtoHSV(new_color)
if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright
H.dna.features["mcolor"] = sanitize_hexcolor(new_color)
H.dna.features["mcolor"] = sanitize_hexcolor(new_color, 6)
H.update_body()
else
to_chat(H, "<span class='notice'>Invalid color. Your color is not bright enough.</span>")
+15 -20
View File
@@ -1,29 +1,19 @@
/mob/living/carbon/Life()
set invisibility = 0
if(notransform)
return
if(damageoverlaytemp)
damageoverlaytemp = 0
update_damage_hud()
/mob/living/carbon/BiologicalLife(seconds, times_fired)
if(stat == DEAD)
return FALSE
//Reagent processing needs to come before breathing, to prevent edge cases.
handle_organs()
. = ..()
if (QDELETED(src))
if(!(. = ..()))
return
if(.) //not dead
handle_blood()
handle_blood()
// handle_blood *could* kill us.
// we should probably have a better system for if we need to check for death or something in the future hmw
if(stat != DEAD)
var/bprv = handle_bodyparts()
if(bprv & BODYPART_LIFE_UPDATE_HEALTH)
updatehealth()
update_stamina()
doSprintBufferRegen()
if(stat != DEAD)
handle_brain_damage()
@@ -35,12 +25,17 @@
stop_sound_channel(CHANNEL_HEARTBEAT)
handle_death()
rot()
. = FALSE
//Updates the number of stored chemicals for powers
handle_changeling()
if(stat != DEAD)
return 1
/mob/living/carbon/PhysicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(damageoverlaytemp)
damageoverlaytemp = 0
update_damage_hud()
//Procs called while dead
/mob/living/carbon/proc/handle_death()
+18 -22
View File
@@ -3,30 +3,26 @@
/mob/living/carbon/monkey
/mob/living/carbon/monkey/Life()
set invisibility = 0
if (notransform)
/mob/living/carbon/monkey/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(..())
if(!client)
if(stat == CONSCIOUS)
if(on_fire || buckled || restrained() || (!CHECK_MOBILITY(src, MOBILITY_STAND) && CHECK_MOBILITY(src, MOBILITY_MOVE))) //CIT CHANGE - makes it so monkeys attempt to resist if they're resting)
if(!resisting && prob(MONKEY_RESIST_PROB))
resisting = TRUE
walk_to(src,0)
resist()
else if(resisting)
resisting = FALSE
else if((mode == MONKEY_IDLE && !pickupTarget && !prob(MONKEY_SHENANIGAN_PROB)) || !handle_combat())
if(prob(25) && CHECK_MOBILITY(src, MOBILITY_MOVE) && isturf(loc) && !pulledby)
step(src, pick(GLOB.cardinals))
else if(prob(1))
emote(pick("scratch","jump","roll","tail"))
else
if(client)
return
if(stat == CONSCIOUS)
if(on_fire || buckled || restrained() || (!CHECK_MOBILITY(src, MOBILITY_STAND) && CHECK_MOBILITY(src, MOBILITY_MOVE))) //CIT CHANGE - makes it so monkeys attempt to resist if they're resting)
if(!resisting && prob(MONKEY_RESIST_PROB))
resisting = TRUE
walk_to(src,0)
resist()
else if(resisting)
resisting = FALSE
else if((mode == MONKEY_IDLE && !pickupTarget && !prob(MONKEY_SHENANIGAN_PROB)) || !handle_combat())
if(prob(25) && CHECK_MOBILITY(src, MOBILITY_MOVE) && isturf(loc) && !pulledby)
step(src, pick(GLOB.cardinals))
else if(prob(1))
emote(pick("scratch","jump","roll","tail"))
else
walk_to(src,0)
/mob/living/carbon/monkey/handle_mutations_and_radiation()
if(radiation)
@@ -31,11 +31,12 @@
if(relic_mask)
equip_to_slot_or_del(new relic_mask, SLOT_WEAR_MASK)
/mob/living/carbon/monkey/punpun/Life()
/mob/living/carbon/monkey/punpun/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
Write_Memory(FALSE, FALSE)
memory_saved = TRUE
..()
/mob/living/carbon/monkey/punpun/death(gibbed)
if(!memory_saved)
@@ -12,7 +12,7 @@
overlays_standing[cache_index] = null
/mob/living/carbon/regenerate_icons()
if(notransform)
if(mob_transforming)
return 1
update_inv_hands()
update_inv_handcuffed()
+16 -10
View File
@@ -1,14 +1,20 @@
/*
apply_damage(a,b,c)
args
a:damage - How much damage to take
b:damage_type - What type of damage to take, brute, burn
c:def_zone - Where to take the damage if its brute or burn
Returns
standard 0 if fail
*/
/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
/**
* Applies damage to this mob
*
* Sends [COMSIG_MOB_APPLY_DAMGE]
*
* Arguuments:
* * damage - amount of damage
* * damagetype - one of [BRUTE], [BURN], [TOX], [OXY], [CLONE], [STAMINA]
* * def_zone - zone that is being hit if any
* * blocked - armor value applied
* * forced - bypass hit percentage
* * spread_damage - used in overrides
*
* Returns TRUE if damage applied
*/
/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE)
var/hit_percent = (100-blocked)/100
if(!damage || (hit_percent <= 0))
return 0
+1
View File
@@ -457,6 +457,7 @@
message = params
if(type_override)
emote_type = type_override
message = user.say_emphasis(message)
. = ..()
message = null
emote_type = EMOTE_VISIBLE
+61 -39
View File
@@ -1,12 +1,20 @@
/**
* Called by SSmobs at (hopefully) an interval of 1 second.
* Splits off into PhysicalLife() and BiologicalLife(). Override those instead of this.
*/
/mob/living/proc/Life(seconds, times_fired)
set waitfor = FALSE
set invisibility = 0
set waitfor = FALSE // yeah hey we're kind of on a subsystem, no sleeping will be tolerated here!
if(mob_transforming)
return
if(digitalinvis)
handle_diginvis() //AI becomes unable to see mob
. = SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds, times_fired)
if(!(. & COMPONENT_INTERRUPT_LIFE_PHYSICAL))
PhysicalLife(seconds, times_fired)
if(!(. & COMPONENT_INTERRUPT_LIFE_BIOLOGICAL))
BiologicalLife(seconds, times_fired)
if((movement_type & FLYING) && !(movement_type & FLOATING)) //TODO: Better floating
float(on = TRUE)
// CODE BELOW SHOULD ONLY BE THINGS THAT SHOULD HAPPEN NO MATTER WHAT AND CAN NOT BE SUSPENDED!
// Otherwise, it goes into one of the two split Life procs!
if (client)
var/turf/T = get_turf(src)
@@ -30,28 +38,54 @@
log_game("Z-TRACKING: [src] of type [src.type] has a Z-registration despite not having a client.")
update_z(null)
if (notransform)
return
if(!loc)
return
var/datum/gas_mixture/environment = loc.return_air()
if(stat != DEAD)
//Mutations and radiation
handle_mutations_and_radiation()
if(stat != DEAD)
//Breathing, if applicable
handle_breathing(times_fired)
/**
* Handles biological life processes like chemical metabolism, breathing, etc
* Returns TRUE or FALSE based on if we were interrupted. This is used by overridden variants to check if they should stop.
*/
/mob/living/proc/BiologicalLife(seconds, times_fired)
handle_diseases()// DEAD check is in the proc itself; we want it to spread even if the mob is dead, but to handle its disease-y properties only if you're not.
if (QDELETED(src)) // diseases can qdel the mob via transformations
return
// Everything after this shouldn't process while dead (as of the time of writing)
if(stat == DEAD)
return FALSE
if(stat != DEAD)
//Random events (vomiting etc)
handle_random_events()
//Mutations and radiation
handle_mutations_and_radiation()
//Breathing, if applicable
handle_breathing(times_fired)
if (QDELETED(src)) // diseases can qdel the mob via transformations
return FALSE
//Random events (vomiting etc)
handle_random_events()
//stuff in the stomach
handle_stomach()
handle_block_parry(seconds)
// These two MIGHT need to be moved to base Life() if we get any in the future that's a "physical" effect that needs to fire even while in stasis.
handle_traits() // eye, ear, brain damages
handle_status_effects() //all special effects, stun, knockdown, jitteryness, hallucination, sleeping, etc
return TRUE
/**
* Handles physical life processes like being on fire. Don't ask why this is considered "Life".
* Returns TRUE or FALSE based on if we were interrupted. This is used by overridden variants to check if they should stop.
*/
/mob/living/proc/PhysicalLife(seconds, times_fired)
if(digitalinvis)
handle_diginvis() //AI becomes unable to see mob
if((movement_type & FLYING) && !(movement_type & FLOATING)) //TODO: Better floating
float(on = TRUE)
if(!loc)
return FALSE
var/datum/gas_mixture/environment = loc.return_air()
//Handle temperature/pressure differences between body and environment
if(environment)
@@ -59,23 +93,11 @@
handle_fire()
//stuff in the stomach
handle_stomach()
handle_gravity()
handle_block_parry(seconds)
if(machine)
machine.check_eye(src)
if(stat != DEAD)
handle_traits() // eye, ear, brain damages
if(stat != DEAD)
handle_status_effects() //all special effects, stun, knockdown, jitteryness, hallucination, sleeping, etc
if(stat != DEAD)
return 1
return TRUE
/mob/living/proc/handle_breathing(times_fired)
return
@@ -168,4 +190,4 @@
/mob/living/proc/handle_high_gravity(gravity)
if(gravity >= GRAVITY_DAMAGE_TRESHOLD) //Aka gravity values of 3 or more
var/grav_stregth = gravity - GRAVITY_DAMAGE_TRESHOLD
adjustBruteLoss(min(grav_stregth,3))
adjustBruteLoss(min(grav_stregth,3))
+9 -25
View File
@@ -1,7 +1,10 @@
/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = "Your armor absorbs the blow!", soften_text = "Your armor softens the blow!", armour_penetration, penetrated_text = "Your armor was penetrated!")
/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = "Your armor absorbs the blow!", soften_text = "Your armor softens the blow!", armour_penetration, penetrated_text = "Your armor was penetrated!", silent=FALSE)
var/armor = getarmor(def_zone, attack_flag)
if(silent)
return max(0, armor - armour_penetration)
//the if "armor" check is because this is used for everything on /living, including humans
if(armor && armour_penetration)
armor = max(0, armor - armour_penetration)
@@ -105,12 +108,6 @@
/mob/living/proc/catch_item(obj/item/I, skip_throw_mode_check = FALSE)
return FALSE
/mob/living/proc/embed_item(obj/item/I)
return
/mob/living/proc/can_embed(obj/item/I)
return FALSE
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
// Throwingdatum can be null if someone had an accident() while slipping with an item in hand.
var/obj/item/I
@@ -126,30 +123,17 @@
skipcatch = TRUE
blocked = TRUE
total_damage = block_calculate_resultant_damage(total_damage, block_return)
else if(I && I.throw_speed >= EMBED_THROWSPEED_THRESHOLD && can_embed(I, src) && prob(I.embedding.embed_chance) && !HAS_TRAIT(src, TRAIT_PIERCEIMMUNE) && (!HAS_TRAIT(src, TRAIT_AUTO_CATCH_ITEM) || incapacitated() || get_active_held_item()))
embed_item(I)
hitpush = FALSE
skipcatch = TRUE //can't catch the now embedded item
if(I)
var/nosell_hit = SEND_SIGNAL(I, COMSIG_MOVABLE_IMPACT_ZONE, src, impacting_zone, throwingdatum, FALSE, blocked)
if(nosell_hit)
skipcatch = TRUE
hitpush = FALSE
if(!skipcatch && isturf(I.loc) && catch_item(I))
return TRUE
var/dtype = BRUTE
var/volume = I.get_volume_by_throwforce_and_or_w_class()
SEND_SIGNAL(I, COMSIG_MOVABLE_IMPACT_ZONE, src, impacting_zone)
dtype = I.damtype
if (I.throwforce > 0) //If the weapon's throwforce is greater than zero...
if (I.throwhitsound) //...and throwhitsound is defined...
playsound(loc, I.throwhitsound, volume, 1, -1) //...play the weapon's throwhitsound.
else if(I.hitsound) //Otherwise, if the weapon's hitsound is defined...
playsound(loc, I.hitsound, volume, 1, -1) //...play the weapon's hitsound.
else if(!I.throwhitsound) //Otherwise, if throwhitsound isn't defined...
playsound(loc, 'sound/weapons/genhit.ogg',volume, 1, -1) //...play genhit.ogg.
else if(!I.throwhitsound && I.throwforce > 0) //Otherwise, if the item doesn't have a throwhitsound and has a throwforce greater than zero...
playsound(loc, 'sound/weapons/genhit.ogg', volume, 1, -1)//...play genhit.ogg
if(!I.throwforce)// Otherwise, if the item's throwforce is 0...
playsound(loc, 'sound/weapons/throwtap.ogg', 1, volume, -1)//...play throwtap.ogg.
if(!blocked)
visible_message("<span class='danger'>[src] has been hit by [I].</span>", \
"<span class='userdanger'>You have been hit by [I].</span>")
+31 -31
View File
@@ -3,48 +3,48 @@
#define POWER_RESTORATION_SEARCH_APC 2
#define POWER_RESTORATION_APC_FOUND 3
/mob/living/silicon/ai/Life()
if (stat == DEAD)
/mob/living/silicon/ai/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
else //I'm not removing that shitton of tabs, unneeded as they are. -- Urist
//I'm not removing that shitton of tabs, unneeded as they are. -- Urist
//Being dead doesn't mean your temperature never changes
update_gravity(mob_has_gravity())
update_gravity(mob_has_gravity())
handle_status_effects()
handle_status_effects()
if(malfhack && malfhack.aidisabled)
deltimer(malfhacking)
// This proc handles cleanup of screen notifications and
// messenging the client
malfhacked(malfhack)
if(malfhack && malfhack.aidisabled)
deltimer(malfhacking)
// This proc handles cleanup of screen notifications and
// messenging the client
malfhacked(malfhack)
if(isturf(loc) && (QDELETED(eyeobj) || !eyeobj.loc))
view_core()
if(isturf(loc) && (QDELETED(eyeobj) || !eyeobj.loc))
view_core()
if(machine)
machine.check_eye(src)
if(machine)
machine.check_eye(src)
// Handle power damage (oxy)
if(aiRestorePowerRoutine)
// Lost power
adjustOxyLoss(1)
else
// Gain Power
if(getOxyLoss())
adjustOxyLoss(-1)
// Handle power damage (oxy)
if(aiRestorePowerRoutine)
// Lost power
adjustOxyLoss(1)
else
// Gain Power
if(getOxyLoss())
adjustOxyLoss(-1)
if(!lacks_power())
var/area/home = get_area(src)
if(home.powered(EQUIP))
home.use_power(1000, EQUIP)
if(!lacks_power())
var/area/home = get_area(src)
if(home.powered(EQUIP))
home.use_power(1000, EQUIP)
if(aiRestorePowerRoutine >= POWER_RESTORATION_SEARCH_APC)
ai_restore_power()
return
if(aiRestorePowerRoutine >= POWER_RESTORATION_SEARCH_APC)
ai_restore_power()
return
else if(!aiRestorePowerRoutine)
ai_lose_power()
else if(!aiRestorePowerRoutine)
ai_lose_power()
/mob/living/silicon/ai/proc/lacks_power()
var/turf/T = get_turf(src)
@@ -1,5 +1,5 @@
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE)
var/hit_percent = (100-blocked)/100
if(!damage || (!forced && hit_percent <= 0))
return 0
+9 -6
View File
@@ -146,10 +146,11 @@
if(possible_chassis[chassis])
AddElement(/datum/element/mob_holder, chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', ITEM_SLOT_HEAD)
/mob/living/silicon/pai/Life()
/mob/living/silicon/pai/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(hacking)
process_hack()
return ..()
/mob/living/silicon/pai/proc/process_hack()
@@ -282,17 +283,19 @@
. = ..()
. += "A personal AI in holochassis mode. Its master ID string seems to be [master]."
/mob/living/silicon/pai/Life()
if(stat == DEAD)
return
/mob/living/silicon/pai/PhysicalLife()
. = ..()
if(cable)
if(get_dist(src, cable) > 1)
var/turf/T = get_turf(src.loc)
T.visible_message("<span class='warning'>[src.cable] rapidly retracts back into its spool.</span>", "<span class='italics'>You hear a click and the sound of wire spooling rapidly.</span>")
qdel(src.cable)
cable = null
/mob/living/silicon/pai/BiologicalLife()
if(!(. = ..()))
return
silent = max(silent - 1, 0)
. = ..()
/mob/living/silicon/pai/updatehealth()
if(status_flags & GODMODE)
@@ -1,9 +1,6 @@
/mob/living/silicon/robot/Life()
set invisibility = 0
if (src.notransform)
/mob/living/silicon/robot/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
..()
adjustOxyLoss(-10) //we're a robot!
handle_robot_hud_updates()
handle_robot_cell()
@@ -259,7 +259,7 @@
var/prev_locked_down = R.locked_down
sleep(1)
flick("[cyborg_base_icon]_transform", R)
R.notransform = TRUE
R.mob_transforming = TRUE
R.SetLockdown(1)
R.anchored = TRUE
sleep(1)
@@ -270,7 +270,7 @@
R.SetLockdown(0)
R.setDir(SOUTH)
R.anchored = FALSE
R.notransform = FALSE
R.mob_transforming = FALSE
R.update_headlamp()
R.notify_ai(NEW_MODULE)
if(R.hud_used)
@@ -62,7 +62,7 @@
log_reagent("FERMICHEM: [src] has astrally transmitted [message] into [A]")
//Delete the mob if there's no mind! Pay that mob no mind.
/mob/living/simple_animal/astral/Life()
if(!mind)
qdel(src)
/mob/living/simple_animal/astral/PhysicalLife(seconds, times_fired)
. = ..()
if(!mind && !QDELETED(src))
qdel(src)
@@ -1,7 +1,13 @@
//MEDBOT
//MEDBOT PATHFINDING
//MEDBOT ASSEMBLY
#define MEDBOT_PANIC_NONE 0
#define MEDBOT_PANIC_LOW 15
#define MEDBOT_PANIC_MED 35
#define MEDBOT_PANIC_HIGH 55
#define MEDBOT_PANIC_FUCK 70
#define MEDBOT_PANIC_ENDING 90
#define MEDBOT_PANIC_END 100
/mob/living/simple_animal/bot/medbot
name = "\improper Medibot"
@@ -64,6 +70,13 @@
var/upgraded_dispenser_3 //Do we have the nicer chemicals? - replaces bic with sal acid
var/upgraded_dispenser_4 //Do we have the nicer chemicals? - replaces charcoal/toxin with pentetic acid / pentetic jelly
//How panicked we are about being tipped over (why would you do this?)
var/tipped_status = MEDBOT_PANIC_NONE
//The name we got when we were tipped
var/tipper_name
//The last time we were tipped/righted and said a voice line, to avoid spam
var/last_tipping_action_voice = 0
/mob/living/simple_animal/bot/medbot/mysterious
name = "\improper Mysterious Medibot"
desc = "International Medibot of mystery."
@@ -373,10 +386,91 @@
else
return
/mob/living/simple_animal/bot/medbot/proc/tip_over(mob/user)
mobility_flags &= ~MOBILITY_MOVE
playsound(src, 'sound/machines/warning-buzzer.ogg', 50)
user.visible_message("<span class='danger'>[user] tips over [src]!</span>", "<span class='danger'>You tip [src] over!</span>")
mode = BOT_TIPPED
var/matrix/mat = transform
transform = mat.Turn(180)
/mob/living/simple_animal/bot/medbot/proc/set_right(mob/user)
mobility_flags &= MOBILITY_MOVE
var/list/messagevoice
if(user)
user.visible_message("<span class='notice'>[user] sets [src] right-side up!</span>", "<span class='green'>You set [src] right-side up!</span>")
if(user.name == tipper_name)
messagevoice = list("I forgive you." = 'sound/voice/medbot/forgive.ogg')
else
messagevoice = list("Thank you!" = 'sound/voice/medbot/thank_you.ogg', "You are a good person." = 'sound/voice/medbot/youre_good.ogg')
else
visible_message("<span class='notice'>[src] manages to writhe wiggle enough to right itself.</span>")
messagevoice = list("Fuck you." = 'sound/voice/medbot/fuck_you.ogg', "Your behavior has been reported, have a nice day." = 'sound/voice/medbot/reported.ogg')
tipper_name = null
if(world.time > last_tipping_action_voice + 15 SECONDS)
last_tipping_action_voice = world.time
var/message = pick(messagevoice)
speak(message)
playsound(src, messagevoice[message], 70)
tipped_status = MEDBOT_PANIC_NONE
mode = BOT_IDLE
transform = matrix()
// if someone tipped us over, check whether we should ask for help or just right ourselves eventually
/mob/living/simple_animal/bot/medbot/proc/handle_panic()
tipped_status++
var/list/messagevoice
switch(tipped_status)
if(MEDBOT_PANIC_LOW)
messagevoice = list("I require assistance." = 'sound/voice/medbot/i_require_asst.ogg')
if(MEDBOT_PANIC_MED)
messagevoice = list("Please put me back." = 'sound/voice/medbot/please_put_me_back.ogg')
if(MEDBOT_PANIC_HIGH)
messagevoice = list("Please, I am scared!" = 'sound/voice/medbot/please_im_scared.ogg')
if(MEDBOT_PANIC_FUCK)
messagevoice = list("I don't like this, I need help!" = 'sound/voice/medbot/dont_like.ogg', "This hurts, my pain is real!" = 'sound/voice/medbot/pain_is_real.ogg')
if(MEDBOT_PANIC_ENDING)
messagevoice = list("Is this the end?" = 'sound/voice/medbot/is_this_the_end.ogg', "Nooo!" = 'sound/voice/medbot/nooo.ogg')
if(MEDBOT_PANIC_END)
speak("PSYCH ALERT: Crewmember [tipper_name] recorded displaying antisocial tendencies torturing bots in [get_area(src)]. Please schedule psych evaluation.", radio_channel)
set_right() // strong independent medbot
if(prob(tipped_status))
do_jitter_animation(tipped_status * 0.1)
if(messagevoice)
var/message = pick(messagevoice)
speak(message)
playsound(src, messagevoice[message], 70)
else if(prob(tipped_status * 0.2))
playsound(src, 'sound/machines/warning-buzzer.ogg', 30, extrarange=-2)
/mob/living/simple_animal/bot/medbot/examine(mob/user)
. = ..()
if(tipped_status == MEDBOT_PANIC_NONE)
return
switch(tipped_status)
if(MEDBOT_PANIC_NONE to MEDBOT_PANIC_LOW)
. += "It appears to be tipped over, and is quietly waiting for someone to set it right."
if(MEDBOT_PANIC_LOW to MEDBOT_PANIC_MED)
. += "It is tipped over and requesting help."
if(MEDBOT_PANIC_MED to MEDBOT_PANIC_HIGH)
. += "They are tipped over and appear visibly distressed." // now we humanize the medbot as a they, not an it
if(MEDBOT_PANIC_HIGH to MEDBOT_PANIC_FUCK)
. += "<span class='warning'>They are tipped over and visibly panicking!</span>"
if(MEDBOT_PANIC_FUCK to INFINITY)
. += "<span class='warning'><b>They are freaking out from being tipped over!</b></span>"
/mob/living/simple_animal/bot/medbot/handle_automated_action()
if(!..())
return
if(mode == BOT_TIPPED)
handle_panic()
return
if(mode == BOT_HEALING)
return
@@ -392,10 +486,14 @@
if(QDELETED(patient))
if(!shut_up && prob(1))
var/list/messagevoice = list("Radar, put a mask on!" = 'sound/voice/medbot/radar.ogg',"There's always a catch, and I'm the best there is." = 'sound/voice/medbot/catch.ogg',"I knew it, I should've been a plastic surgeon." = 'sound/voice/medbot/surgeon.ogg',"What kind of medbay is this? Everyone's dropping like flies." = 'sound/voice/medbot/flies.ogg',"Delicious!" = 'sound/voice/medbot/delicious.ogg')
var/message = pick(messagevoice)
speak(message)
playsound(loc, messagevoice[message], 50, 0)
if(emagged && prob(30))
var/list/i_need_scissors = list('sound/voice/medbot/fuck_you.ogg', 'sound/voice/medbot/turn_off.ogg', 'sound/voice/medbot/im_different.ogg', 'sound/voice/medbot/close.ogg', 'sound/voice/medbot/shindemashou.ogg')
playsound(src, pick(i_need_scissors), 70)
else
var/list/messagevoice = list("Radar, put a mask on!" = 'sound/voice/medbot/radar.ogg',"There's always a catch, and I'm the best there is." = 'sound/voice/medbot/catch.ogg',"I knew it, I should've been a plastic surgeon." = 'sound/voice/medbot/surgeon.ogg',"What kind of medbay is this? Everyone's dropping like flies." = 'sound/voice/medbot/flies.ogg',"Delicious!" = 'sound/voice/medbot/delicious.ogg', "Why are we still here? Just to suffer?" = 'sound/voice/medbot/why.ogg')
var/message = pick(messagevoice)
speak(message)
playsound(src, messagevoice[message], 50)
var/scan_range = (stationary_mode ? 1 : DEFAULT_SCAN_RANGE) //If in stationary mode, scan range is limited to adjacent patients.
patient = scan(/mob/living/carbon/human, oldpatient, scan_range)
oldpatient = patient
@@ -506,6 +604,27 @@
/mob/living/simple_animal/bot/medbot/proc/get_healchem_toxin(mob/M)
return HAS_TRAIT(M, TRAIT_TOXINLOVER)? treatment_tox_toxlover : treatment_tox
/mob/living/simple_animal/bot/medbot/attack_hand(mob/living/carbon/human/H)
if(H.a_intent == INTENT_DISARM && mode != BOT_TIPPED)
H.visible_message("<span class='danger'>[H] begins tipping over [src].</span>", "<span class='warning'>You begin tipping over [src]...</span>")
if(world.time > last_tipping_action_voice + 15 SECONDS)
last_tipping_action_voice = world.time // message for tipping happens when we start interacting, message for righting comes after finishing
var/list/messagevoice = list("Hey, wait..." = 'sound/voice/medbot/hey_wait.ogg',"Please don't..." = 'sound/voice/medbot/please_dont.ogg',"I trusted you..." = 'sound/voice/medbot/i_trusted_you.ogg', "Nooo..." = 'sound/voice/medbot/nooo.ogg', "Oh fuck-" = 'sound/voice/medbot/oh_fuck.ogg')
var/message = pick(messagevoice)
speak(message)
playsound(src, messagevoice[message], 70, FALSE)
if(do_after(H, 3 SECONDS, target=src))
tip_over(H)
else if(H.a_intent == INTENT_HELP && mode == BOT_TIPPED)
H.visible_message("<span class='notice'>[H] begins righting [src].</span>", "<span class='notice'>You begin righting [src]...</span>")
if(do_after(H, 3 SECONDS, target=src))
set_right(H)
else
..()
/mob/living/simple_animal/bot/medbot/UnarmedAttack(atom/A)
if(iscarbon(A))
var/mob/living/carbon/C = A
@@ -664,3 +783,11 @@
/obj/machinery/bot_core/medbot
req_one_access = list(ACCESS_MEDICAL, ACCESS_ROBOTICS)
#undef MEDBOT_PANIC_NONE
#undef MEDBOT_PANIC_LOW
#undef MEDBOT_PANIC_MED
#undef MEDBOT_PANIC_HIGH
#undef MEDBOT_PANIC_FUCK
#undef MEDBOT_PANIC_ENDING
#undef MEDBOT_PANIC_END
@@ -115,13 +115,14 @@
Read_Memory()
. = ..()
/mob/living/simple_animal/pet/cat/Runtime/Life()
/mob/living/simple_animal/pet/cat/Runtime/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
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 = ..()
@@ -177,7 +178,9 @@
gold_core_spawnable = NO_SPAWN
unique_pet = TRUE
/mob/living/simple_animal/pet/cat/Life()
/mob/living/simple_animal/pet/cat/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(!stat && !buckled && !client)
if(prob(1))
emote("me", EMOTE_VISIBLE, pick("stretches out for a belly rub.", "wags its tail.", "lies down."))
@@ -269,8 +272,9 @@
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()
..()
/mob/living/simple_animal/pet/cat/cak/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(stat)
return
if(health < maxHealth)
@@ -27,8 +27,9 @@
var/obj/item/inventory_mask
gold_core_spawnable = FRIENDLY_SPAWN
/mob/living/simple_animal/crab/Life()
..()
/mob/living/simple_animal/crab/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
//CRAB movement
if(!ckey && !stat)
if(isturf(loc) && !resting && !buckled) //This is so it only moves if it's not inside a closet, gentics machine, etc.
@@ -366,11 +366,12 @@
RemoveElement(/datum/element/mob_holder, held_icon)
AddElement(/datum/element/mob_holder, "old_corgi")
/mob/living/simple_animal/pet/dog/corgi/Ian/Life()
/mob/living/simple_animal/pet/dog/corgi/Ian/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
Write_Memory(FALSE)
memory_saved = TRUE
..()
/mob/living/simple_animal/pet/dog/corgi/Ian/death()
if(!memory_saved)
@@ -419,8 +420,9 @@
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
/mob/living/simple_animal/pet/dog/corgi/Ian/Life()
..()
/mob/living/simple_animal/pet/dog/corgi/Ian/BiologicalLife()
if(!(. = ..()))
return
//Feeding, chasing food, FOOOOODDDD
if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled)
@@ -490,8 +492,9 @@
nofur = TRUE
unique_pet = TRUE
/mob/living/simple_animal/pet/dog/corgi/narsie/Life()
..()
/mob/living/simple_animal/pet/dog/corgi/narsie/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
for(var/mob/living/simple_animal/pet/P in range(1, src))
if(P != src && prob(5))
visible_message("<span class='warning'>[src] devours [P]!</span>", \
@@ -615,8 +618,9 @@
return
..()
/mob/living/simple_animal/pet/dog/corgi/Lisa/Life()
..()
/mob/living/simple_animal/pet/dog/corgi/Lisa/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
make_babies()
@@ -628,8 +632,9 @@
setDir(i)
sleep(1)
/mob/living/simple_animal/pet/dog/pug/Life()
..()
/mob/living/simple_animal/pet/dog/pug/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled)
if(prob(1))
emote("me", EMOTE_VISIBLE, pick("chases its tail."))
@@ -33,11 +33,12 @@
stop_automated_movement_when_pulled = 1
blood_volume = BLOOD_VOLUME_NORMAL
var/obj/item/udder/udder = null
var/datum/reagent/milk_reagent = /datum/reagent/consumable/milk
footstep_type = FOOTSTEP_MOB_SHOE
/mob/living/simple_animal/hostile/retaliate/goat/Initialize()
udder = new()
/mob/living/simple_animal/hostile/retaliate/goat/Initialize(/datum/reagent/milk_reagent)
udder = new (null, milk_reagent)
. = ..()
/mob/living/simple_animal/hostile/retaliate/goat/Destroy()
@@ -45,9 +46,10 @@
udder = null
return ..()
/mob/living/simple_animal/hostile/retaliate/goat/Life()
. = ..()
if(.)
/mob/living/simple_animal/hostile/retaliate/goat/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(stat == CONSCIOUS)
//chance to go crazy and start wacking stuff
if(!enemies.len && prob(1))
Retaliate()
@@ -56,8 +58,7 @@
enemies = list()
LoseTarget()
src.visible_message("<span class='notice'>[src] calms down.</span>")
if(stat == CONSCIOUS)
udder.generateMilk()
udder.generateMilk(milk_reagent)
eat_plants()
if(!pulledby)
for(var/direction in shuffle(list(1,2,4,8,5,6,9,10)))
@@ -137,13 +138,14 @@
health = 50
maxHealth = 50
var/obj/item/udder/udder = null
var/datum/reagent/milk_reagent = /datum/reagent/consumable/milk
gold_core_spawnable = FRIENDLY_SPAWN
blood_volume = BLOOD_VOLUME_NORMAL
footstep_type = FOOTSTEP_MOB_SHOE
/mob/living/simple_animal/cow/Initialize()
udder = new()
udder = new(null, milk_reagent)
. = ..()
/mob/living/simple_animal/cow/Destroy()
@@ -158,10 +160,11 @@
else
return ..()
/mob/living/simple_animal/cow/Life()
. = ..()
/mob/living/simple_animal/cow/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(stat == CONSCIOUS)
udder.generateMilk()
udder.generateMilk(milk_reagent)
/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M)
if(!stat && M.a_intent == INTENT_DISARM && icon_state != icon_dead)
@@ -189,6 +192,19 @@
else
..()
//Wisdom cow, speaks and bestows great wisdoms
/mob/living/simple_animal/cow/wisdom
name = "wisdom cow"
desc = "Known for its wisdom, shares it with all"
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/wisdomcow = 1) //truly the best meat
gold_core_spawnable = FALSE
speak_chance = 30 //the cow is eager to share its wisdom!
milk_reagent = /datum/reagent/medicine/liquid_wisdom
/mob/living/simple_animal/cow/wisdom/Initialize()
. = ..()
speak = GLOB.wisdoms //Done here so it's setup properly
/mob/living/simple_animal/chick
name = "\improper chick"
desc = "Adorable! They make such a racket though."
@@ -229,9 +245,8 @@
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
/mob/living/simple_animal/chick/Life()
. =..()
if(!.)
/mob/living/simple_animal/chick/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(!stat && !ckey)
amount_grown += rand(1,2)
@@ -239,8 +254,9 @@
new /mob/living/simple_animal/chicken(src.loc)
qdel(src)
/mob/living/simple_animal/chick/holo/Life()
..()
/mob/living/simple_animal/chick/holo/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
amount_grown = 0
/mob/living/simple_animal/chicken
@@ -313,9 +329,8 @@
else
..()
/mob/living/simple_animal/chicken/Life()
. =..()
if(!.)
/mob/living/simple_animal/chicken/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if((!stat && prob(3) && eggsleft > 0) && egg_type)
visible_message("<span class='alertalien'>[src] [pick(layMessage)]</span>")
@@ -388,9 +403,8 @@
. = ..()
++kiwi_count
/mob/living/simple_animal/kiwi/Life()
. =..()
if(!.)
/mob/living/simple_animal/kiwi/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if((!stat && prob(3) && eggsleft > 0) && egg_type)
visible_message("[src] [pick(layMessage)]")
@@ -463,9 +477,8 @@
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
/mob/living/simple_animal/babyKiwi/Life()
. =..()
if(!.)
/mob/living/simple_animal/babyKiwi/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(!stat && !ckey)
amount_grown += rand(1,2)
@@ -481,14 +494,16 @@
/obj/item/udder
name = "udder"
/obj/item/udder/Initialize()
/obj/item/udder/Initialize(loc, milk_reagent)
if(!milk_reagent)
milk_reagent = /datum/reagent/consumable/milk
create_reagents(50, NONE, NO_REAGENTS_VALUE)
reagents.add_reagent(/datum/reagent/consumable/milk, 20)
reagents.add_reagent(milk_reagent, 20)
. = ..()
/obj/item/udder/proc/generateMilk()
/obj/item/udder/proc/generateMilk(datum/reagent/milk_reagent)
if(prob(5))
reagents.add_reagent(/datum/reagent/consumable/milk, rand(5, 10))
reagents.add_reagent(milk_reagent, rand(5, 10))
/obj/item/udder/proc/milkAnimal(obj/O, mob/user)
var/obj/item/reagent_containers/glass/G = O
@@ -529,4 +544,4 @@
health = 75
maxHealth = 75
blood_volume = BLOOD_VOLUME_NORMAL
footstep_type = FOOTSTEP_MOB_SHOE
footstep_type = FOOTSTEP_MOB_SHOE
@@ -72,8 +72,8 @@
qdel(src)
//low regen over time
/mob/living/simple_animal/pet/plushie/Life()
if(stat)
/mob/living/simple_animal/pet/plushie/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(health < maxHealth)
heal_overall_damage(5) //Decent life regen, they're not able to hurt anyone so this shouldn't be an issue (butterbear for reference has 10 regen)
@@ -160,7 +160,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
to_chat(src, "<span class='notice'>Your new name <span class='name'>[new_name]</span> anchors itself in your mind.</span>")
fully_replace_character_name(null, new_name)
/mob/living/simple_animal/hostile/guardian/Life() //Dies if the summoner dies
/mob/living/simple_animal/hostile/guardian/PhysicalLife() //Dies if the summoner dies
. = ..()
update_health_hud() //we need to update all of our health displays to match our summoner and we can't practically give the summoner a hook to do it
med_hud_set_health()
@@ -19,8 +19,9 @@
. = ..()
stealthcooldown = 0
/mob/living/simple_animal/hostile/guardian/assassin/Life()
. = ..()
/mob/living/simple_animal/hostile/guardian/assassin/PhysicalLife()
if(!(. = ..()))
return
updatestealthalert()
if(loc == summoner && toggle)
ToggleMode(0)
@@ -11,8 +11,9 @@
var/charging = 0
var/obj/screen/alert/chargealert
/mob/living/simple_animal/hostile/guardian/charger/Life()
. = ..()
/mob/living/simple_animal/hostile/guardian/charger/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(ranged_cooldown <= world.time)
if(!chargealert)
chargealert = throw_alert("charge", /obj/screen/alert/cancharge)
@@ -13,8 +13,9 @@
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Crowd control modules activated. Holoparasite swarm online.</span>"
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught one! OH GOD, EVERYTHING'S ON FIRE. Except you and the fish.</span>"
/mob/living/simple_animal/hostile/guardian/fire/Life()
. = ..()
/mob/living/simple_animal/hostile/guardian/fire/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(summoner)
summoner.ExtinguishMob()
summoner.adjust_fire_stacks(-20)
@@ -125,7 +125,7 @@ mob/living/simple_animal/hostile/bear/butter //The mighty companion to Cak. Seve
attack_verb_continuous = "slaps"
attack_verb_simple = "slap"
/mob/living/simple_animal/hostile/bear/butter/Life() //Heals butter bear really fast when he takes damage.
/mob/living/simple_animal/hostile/bear/butter/BiologicalLife(seconds, times_fired) //Heals butter bear really fast when he takes damage.
if(stat)
return
if(health < maxHealth)
@@ -47,8 +47,9 @@
if(regen_amount)
regen_cooldown = world.time + REGENERATION_DELAY
/mob/living/simple_animal/hostile/carp/Life()
. = ..()
/mob/living/simple_animal/hostile/carp/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(regen_amount && regen_cooldown < world.time)
heal_overall_damage(regen_amount)
@@ -67,11 +67,10 @@
foes = null
return ..()
/mob/living/simple_animal/hostile/Life()
. = ..()
if(!.) //dead
/mob/living/simple_animal/hostile/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
walk(src, 0) //stops walking
return 0
return
/mob/living/simple_animal/hostile/handle_automated_action()
if(AIStatus == AI_OFF)
@@ -23,13 +23,12 @@
deathmessage = "vanishes into thin air! It was a fake!"
has_field_of_vision = FALSE //not meant to be played anyway.
/mob/living/simple_animal/hostile/illusion/Life()
..()
/mob/living/simple_animal/hostile/illusion/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(world.time > life_span)
death()
/mob/living/simple_animal/hostile/illusion/proc/Copy_Parent(mob/living/original, life = 50, hp = 100, damage = 0, replicate = 0 )
appearance = original.appearance
parent_mob = original
@@ -166,8 +166,9 @@
if(!hopping)
Hop()
/mob/living/simple_animal/hostile/jungle/leaper/Life()
. = ..()
/mob/living/simple_animal/hostile/jungle/leaper/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
update_icons()
/mob/living/simple_animal/hostile/jungle/leaper/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
@@ -197,7 +198,7 @@
hopping = TRUE
density = FALSE
pass_flags |= PASSMOB
notransform = TRUE
mob_transforming = TRUE
var/turf/new_turf = locate((target.x + rand(-3,3)),(target.y + rand(-3,3)),target.z)
if(player_hop)
new_turf = get_turf(target)
@@ -209,7 +210,7 @@
/mob/living/simple_animal/hostile/jungle/leaper/proc/FinishHop()
density = TRUE
notransform = FALSE
mob_transforming = FALSE
pass_flags &= ~PASSMOB
hopping = FALSE
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 100, 1)
@@ -220,7 +221,7 @@
/mob/living/simple_animal/hostile/jungle/leaper/proc/BellyFlop()
var/turf/new_turf = get_turf(target)
hopping = TRUE
notransform = TRUE
mob_transforming = TRUE
new /obj/effect/temp_visual/leaper_crush(new_turf)
addtimer(CALLBACK(src, .proc/BellyFlopHop, new_turf), 30)
@@ -231,7 +232,7 @@
/mob/living/simple_animal/hostile/jungle/leaper/proc/Crush()
hopping = FALSE
density = TRUE
notransform = FALSE
mob_transforming = FALSE
playsound(src, 'sound/effects/meteorimpact.ogg', 200, 1)
for(var/mob/living/L in orange(1, src))
L.adjustBruteLoss(35)
@@ -27,8 +27,9 @@
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/hostile/jungle/mega_arachnid/Life()
..()
/mob/living/simple_animal/hostile/jungle/mega_arachnid/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(target && ranged_cooldown > world.time && iscarbon(target))
var/mob/living/carbon/C = target
if(!C.legcuffed && C.health < 50)
@@ -40,7 +41,6 @@
minimum_distance = 0
alpha = 255
/mob/living/simple_animal/hostile/jungle/mega_arachnid/Aggro()
..()
alpha = 255
@@ -65,8 +65,9 @@ Difficulty: Hard
desc = "You're not quite sure how a signal can be bloody."
invisibility = 100
/mob/living/simple_animal/hostile/megafauna/bubblegum/Life()
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
move_to_delay = clamp(round((health/maxHealth) * 10), 3, 10)
/mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire()
@@ -731,7 +731,7 @@ Difficulty: Very Hard
/obj/structure/closet/stasis/Entered(atom/A)
if(isliving(A) && holder_animal)
var/mob/living/L = A
L.notransform = 1
L.mob_transforming = 1
ADD_TRAIT(L, TRAIT_MUTE, STASIS_MUTE)
L.status_flags |= GODMODE
L.mind.transfer_to(holder_animal)
@@ -744,7 +744,7 @@ Difficulty: Very Hard
for(var/mob/living/L in src)
REMOVE_TRAIT(L, TRAIT_MUTE, STASIS_MUTE)
L.status_flags &= ~GODMODE
L.notransform = 0
L.mob_transforming = 0
if(holder_animal)
holder_animal.mind.transfer_to(L)
L.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession)
@@ -88,9 +88,10 @@ Difficulty: Normal
/mob/living/simple_animal/hostile/megafauna/hierophant/spawn_crusher_loot()
new /obj/item/crusher_trophy/vortex_talisman(get_turf(spawned_beacon))
/mob/living/simple_animal/hostile/megafauna/hierophant/Life()
. = ..()
if(. && spawned_beacon && !QDELETED(spawned_beacon) && !client)
/mob/living/simple_animal/hostile/megafauna/hierophant/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(spawned_beacon && !QDELETED(spawned_beacon) && !client)
if(target || loc == spawned_beacon.loc)
timeout_time = initial(timeout_time)
else
@@ -73,14 +73,13 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
step(R, ddir) //Step the swarmers, instead of spawning them there, incase the turf is solid
/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/Life()
. = ..()
if(.)
var/createtype = GetUncappedAISwarmerType()
if(createtype && world.time > swarmer_spawn_cooldown && GLOB.AISwarmers.len < (GetTotalAISwarmerCap()*0.5))
swarmer_spawn_cooldown = world.time + swarmer_spawn_cooldown_amt
new createtype(loc)
/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
var/createtype = GetUncappedAISwarmerType()
if(createtype && world.time > swarmer_spawn_cooldown && GLOB.AISwarmers.len < (GetTotalAISwarmerCap()*0.5))
swarmer_spawn_cooldown = world.time + swarmer_spawn_cooldown_amt
new createtype(loc)
/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
. = ..()
@@ -118,8 +118,9 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
overlay_googly_eyes = FALSE
CopyObject(copy, creator, destroy_original)
/mob/living/simple_animal/hostile/mimic/copy/Life()
..()
/mob/living/simple_animal/hostile/mimic/copy/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(idledamage && !target && !ckey) //Objects eventually revert to normal if no one is around to terrorize
adjustBruteLoss(1)
for(var/mob/living/M in contents) //a fix for animated statues from the flesh to stone spell
@@ -88,8 +88,9 @@
wanted_objects = list(/obj/item/pen/survival, /obj/item/stack/ore/diamond)
field_of_vision_type = FOV_270_DEGREES //Obviously, it's one eyeball.
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/Life()
. = ..()
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(stat == CONSCIOUS)
consume_bait()
@@ -97,9 +97,8 @@
if(CALL_CHILDREN)
call_children()
/mob/living/simple_animal/hostile/asteroid/elite/broodmother/Life()
. = ..()
if(!.) //Checks if they are dead as a rock.
/mob/living/simple_animal/hostile/asteroid/elite/broodmother/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(health < maxHealth * 0.5 && rand_tent < world.time)
rand_tent = world.time + 30
@@ -95,8 +95,9 @@
if(AOE_SQUARES)
aoe_squares(target)
/mob/living/simple_animal/hostile/asteroid/elite/pandora/Life()
. = ..()
/mob/living/simple_animal/hostile/asteroid/elite/pandora/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(health >= maxHealth * 0.5)
cooldown_time = 20
return
@@ -39,8 +39,9 @@
footstep_type = FOOTSTEP_MOB_HEAVY
/mob/living/simple_animal/hostile/asteroid/goliath/Life()
. = ..()
/mob/living/simple_animal/hostile/asteroid/goliath/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
handle_preattack()
/mob/living/simple_animal/hostile/asteroid/goliath/proc/handle_preattack()
@@ -129,9 +130,8 @@
var/turf/last_location
var/tentacle_recheck_cooldown = 100
/mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient/Life()
. = ..()
if(!.) // dead
/mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(isturf(loc))
if(!LAZYLEN(cached_tentacle_turfs) || loc != last_location || tentacle_recheck_cooldown <= world.time)
@@ -114,8 +114,9 @@
name = "guthen"
gender = FEMALE
/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen/Life()
..()
/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(udder.reagents.total_volume == udder.reagents.maximum_volume) //Only breed when we're full.
make_babies()
@@ -196,12 +196,13 @@
swarming = TRUE
var/can_infest_dead = FALSE
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/Life()
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(isturf(loc))
for(var/mob/living/carbon/human/H in view(src,1)) //Only for corpse right next to/on same tile
if(H.stat == UNCONSCIOUS || (can_infest_dead && H.stat == DEAD))
infest(H)
..()
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/proc/infest(mob/living/carbon/human/H)
visible_message("<span class='warning'>[name] burrows into the flesh of [H]!</span>")
@@ -62,9 +62,10 @@
SLEEP_CHECK_DEATH(8)
return ..()
/mob/living/simple_animal/hostile/asteroid/ice_demon/Life()
. = ..()
if(!. || target)
/mob/living/simple_animal/hostile/asteroid/ice_demon/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(target)
return
adjustHealth(-maxHealth*0.025)
@@ -43,9 +43,10 @@
var/list/burn_turfs = getline(src, T) - get_turf(src)
dragon_fire_line(src, burn_turfs)
/mob/living/simple_animal/hostile/asteroid/ice_whelp/Life()
. = ..()
if(!. || target)
/mob/living/simple_animal/hostile/asteroid/ice_whelp/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(target)
return
adjustHealth(-maxHealth*0.025)
@@ -44,9 +44,10 @@
aggressive_message_said = TRUE
rapid_melee = 2
/mob/living/simple_animal/hostile/asteroid/polarbear/Life()
. = ..()
if(!. || target)
/mob/living/simple_animal/hostile/asteroid/polarbear/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(target)
return
adjustHealth(-maxHealth*0.025)
aggressive_message_said = FALSE
@@ -51,9 +51,10 @@
retreat_message_said = TRUE
retreat_distance = 30
/mob/living/simple_animal/hostile/asteroid/wolf/Life()
. = ..()
if(!. || target)
/mob/living/simple_animal/hostile/asteroid/wolf/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(target)
return
adjustHealth(-maxHealth*0.025)
retreat_message_said = FALSE
@@ -48,8 +48,9 @@
else
. += "<span class='info'>It looks like it's been roughed up.</span>"
/mob/living/simple_animal/hostile/mushroom/Life()
..()
/mob/living/simple_animal/hostile/mushroom/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(!stat)//Mushrooms slowly regenerate if conscious, for people who want to save them from being eaten
adjustBruteLoss(-2)
@@ -46,8 +46,9 @@
var/chosen_sound = pick(migo_sounds)
playsound(src, chosen_sound, 100, TRUE)
/mob/living/simple_animal/hostile/netherworld/migo/Life()
..()
/mob/living/simple_animal/hostile/netherworld/migo/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(stat)
return
if(prob(10))
@@ -51,8 +51,9 @@
..()
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, TRUE)
/mob/living/simple_animal/hostile/retaliate/clown/Life()
. = ..()
/mob/living/simple_animal/hostile/retaliate/clown/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(banana_time && banana_time < world.time)
var/turf/T = get_turf(src)
var/list/adjacent = T.GetAtmosAdjacentTurfs(1)
@@ -82,8 +82,9 @@
return 0
return ..()
/mob/living/simple_animal/hostile/statue/Life()
..()
/mob/living/simple_animal/hostile/statue/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(!client && target) // If we have a target and we're AI controlled
var/mob/watching = can_be_seen()
// If they're not our target
@@ -44,8 +44,9 @@
gold_core_spawnable = HOSTILE_SPAWN
del_on_death = 1
/mob/living/simple_animal/hostile/tree/Life()
..()
/mob/living/simple_animal/hostile/tree/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(isopenturf(loc))
var/turf/open/T = src.loc
if(T.air && T.air.gases[/datum/gas/carbon_dioxide])
@@ -100,8 +100,9 @@
/mob/living/simple_animal/hostile/venus_human_trap/ghost_playable
playable_plant = TRUE //For admins that want to buss some harmless plants
/mob/living/simple_animal/hostile/venus_human_trap/Life()
. = ..()
/mob/living/simple_animal/hostile/venus_human_trap/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
pull_vines()
/mob/living/simple_animal/hostile/venus_human_trap/AttackingTarget()
@@ -47,12 +47,13 @@
QDEL_NULL(E)
return ..()
/mob/living/simple_animal/hostile/asteroid/fugu/Life()
/mob/living/simple_animal/hostile/asteroid/fugu/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(!wumbo)
inflate_cooldown = max((inflate_cooldown - 1), 0)
if(target && AIStatus == AI_ON)
E.Activate()
..()
/mob/living/simple_animal/hostile/asteroid/fugu/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
if(!forced && wumbo)
@@ -357,9 +357,9 @@
/*
* AI - Not really intelligent, but I'm calling it AI anyway.
*/
/mob/living/simple_animal/parrot/Life()
..()
/mob/living/simple_animal/parrot/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
//Sprite update for when a parrot gets pulled
if(pulledby && !stat && parrot_state != PARROT_WANDER)
if(buckled)
@@ -369,8 +369,6 @@
parrot_state = PARROT_WANDER
pixel_x = initial(pixel_x)
pixel_y = initial(pixel_y)
return
//-----SPEECH
/* Parrot speech mimickry!
@@ -911,11 +909,12 @@
if(. && !client && prob(1) && prob(1)) //Only the one true bird may speak across dimensions.
world.TgsTargetedChatBroadcast("A stray squawk is heard... \"[message]\"", FALSE)
/mob/living/simple_animal/parrot/Poly/Life()
/mob/living/simple_animal/parrot/Poly/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
Write_Memory(FALSE)
memory_saved = TRUE
..()
/mob/living/simple_animal/parrot/Poly/death(gibbed)
if(!memory_saved)
@@ -7,19 +7,17 @@
var/SStun = 0 // stun variable
/mob/living/simple_animal/slime/Life()
set invisibility = 0
if (notransform)
/mob/living/simple_animal/slime/BiologicalLife(seconds, times_fired)
if(!(. = ..()))
return
if(..())
if(buckled)
handle_feeding()
if(!stat) // Slimes in stasis don't lose nutrition, don't change mood and don't respond to speech
handle_nutrition()
handle_targets()
if (!ckey)
handle_mood()
handle_speech()
if(buckled)
handle_feeding()
if(!stat) // Slimes in stasis don't lose nutrition, don't change mood and don't respond to speech
handle_nutrition()
handle_targets()
if (!ckey)
handle_mood()
handle_speech()
// Unlike most of the simple animals, slimes support UNCONSCIOUS
/mob/living/simple_animal/slime/update_stat()
+1 -1
View File
@@ -678,7 +678,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
return FALSE
if(anchored)
return FALSE
if(notransform)
if(mob_transforming)
return FALSE
if(restrained())
return FALSE
+3 -1
View File
@@ -37,7 +37,9 @@
var/next_move = null
var/create_area_cooldown
var/notransform = null //Carbon
/// Whether or not the mob is currently being transformed into another mob or into another state of being. This will prevent it from moving or doing realistically anything.
/// Don't you DARE use this for a cheap way to ensure someone is stunned in your code.
var/mob_transforming = FALSE
var/eye_blind = 0 //Carbon
var/eye_blurry = 0 //Carbon
var/real_name = null
+1 -1
View File
@@ -32,7 +32,7 @@
if(!n || !direction || !mob?.loc)
return FALSE
//GET RID OF THIS SOON AS MOBILITY FLAGS IS DONE
if(mob.notransform)
if(mob.mob_transforming)
return FALSE
if(mob.control_object)
+1 -1
View File
@@ -113,7 +113,7 @@
if(name != real_name)
alt_name = " (died as [real_name])"
var/spanned = say_quote(message)
var/spanned = say_quote(say_emphasis(message))
message = emoji_parse(message)
var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>[name]</span>[alt_name] <span class='message'>[emoji_parse(spanned)]</span></span>"
log_talk(message, LOG_SAY, tag="DEAD")
+2 -2
View File
@@ -60,7 +60,7 @@ proc/get_top_level_mob(var/mob/S)
return FALSE
user.log_message(message, LOG_EMOTE)
message = "<b>[user]</b> " + "<i>[message]</i>"
message = "<b>[user]</b> " + "<i>[user.say_emphasis(message)]</i>"
for(var/mob/M in GLOB.dead_mob_list)
if(!M.client || isnewplayer(M))
@@ -121,7 +121,7 @@ proc/get_top_level_mob(var/mob/S)
return FALSE
user.log_message(message, LOG_SUBTLER)
message = "<b>[user]</b> " + "<i>[message]</i>"
message = "<b>[user]</b> " + "<i>[user.say_emphasis(message)]</i>"
if(emote_type == EMOTE_AUDIBLE)
user.audible_message(message=message,hearing_distance=1, ignored_mobs = GLOB.dead_mob_list)
+15 -15
View File
@@ -313,7 +313,7 @@
qdel(src)
/mob/living/carbon/human/AIize()
if (notransform)
if (mob_transforming)
return
for(var/t in bodyparts)
qdel(t)
@@ -321,12 +321,12 @@
return ..()
/mob/living/carbon/AIize()
if(notransform)
if(mob_transforming)
return
for(var/obj/item/W in src)
dropItemToGround(W)
regenerate_icons()
notransform = TRUE
mob_transforming = TRUE
Paralyze(INFINITY)
icon = null
invisibility = INVISIBILITY_MAXIMUM
@@ -362,7 +362,7 @@
qdel(src)
/mob/living/carbon/human/proc/Robotize(delete_items = 0, transfer_after = TRUE)
if (notransform)
if (mob_transforming)
return
for(var/obj/item/W in src)
if(delete_items)
@@ -370,7 +370,7 @@
else
dropItemToGround(W)
regenerate_icons()
notransform = TRUE
mob_transforming = TRUE
Paralyze(INFINITY)
icon = null
invisibility = INVISIBILITY_MAXIMUM
@@ -407,12 +407,12 @@
//human -> alien
/mob/living/carbon/human/proc/Alienize(mind_transfer = TRUE)
if (notransform)
if (mob_transforming)
return
for(var/obj/item/W in src)
dropItemToGround(W)
regenerate_icons()
notransform = 1
mob_transforming = 1
Paralyze(INFINITY)
icon = null
invisibility = INVISIBILITY_MAXIMUM
@@ -441,12 +441,12 @@
qdel(src)
/mob/living/carbon/human/proc/slimeize(reproduce, mind_transfer = TRUE)
if (notransform)
if (mob_transforming)
return
for(var/obj/item/W in src)
dropItemToGround(W)
regenerate_icons()
notransform = 1
mob_transforming = 1
Paralyze(INFINITY)
icon = null
invisibility = INVISIBILITY_MAXIMUM
@@ -486,12 +486,12 @@
/mob/living/carbon/human/proc/corgize(mind_transfer = TRUE)
if (notransform)
if (mob_transforming)
return
for(var/obj/item/W in src)
dropItemToGround(W)
regenerate_icons()
notransform = TRUE
mob_transforming = TRUE
Paralyze(INFINITY)
icon = null
invisibility = INVISIBILITY_MAXIMUM
@@ -510,7 +510,7 @@
qdel(src)
/mob/living/carbon/proc/gorillize(mind_transfer = TRUE)
if(notransform)
if(mob_transforming)
return
SSblackbox.record_feedback("amount", "gorillas_created", 1)
@@ -521,7 +521,7 @@
dropItemToGround(W, TRUE)
regenerate_icons()
notransform = TRUE
mob_transforming = TRUE
Paralyze(INFINITY)
icon = null
invisibility = INVISIBILITY_MAXIMUM
@@ -544,13 +544,13 @@
if(mind)
mind_transfer = alert("Want to transfer their mind into the new mob", "Mind Transfer", "Yes", "No") == "Yes" ? TRUE : FALSE
if(notransform)
if(mob_transforming)
return
for(var/obj/item/W in src)
dropItemToGround(W)
regenerate_icons()
notransform = TRUE
mob_transforming = TRUE
Paralyze(INFINITY)
icon = null
invisibility = INVISIBILITY_MAXIMUM