-
-
Notifications
You must be signed in to change notification settings - Fork 444
/
Copy pathsimple_animal.dm
607 lines (512 loc) · 20.1 KB
/
simple_animal.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
/mob/living/simple_animal
name = "animal"
icon = 'icons/mob/animal.dmi'
health = 20
maxHealth = 20
gender = PLURAL //placeholder
status_flags = CANPUSH
var/icon_living = ""
var/icon_dead = "" //icon when the animal is dead. Don't use animated icons for this.
var/icon_gib = null //We only try to show a gibbing animation if this exists.
var/flip_on_death = FALSE //Flip the sprite upside down on death. Mostly here for things lacking custom dead sprites.
var/list/speak = list()
var/list/speak_emote = list()// Emotes while speaking IE: Ian [emote], [text] -- Ian barks, "WOOF!". Spoken text is generated from the speak variable.
var/speak_chance = 0
var/list/emote_hear = list() //Hearable emotes
var/list/emote_see = list() //Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps
var/turns_per_move = 1
var/turns_since_move = 0
var/stop_automated_movement = 0 //Use this to temporarely stop random movement or to if you write special movement code for animals.
var/wander = 1 // Does the mob wander around when idle?
var/stop_automated_movement_when_pulled = 1 //When set to 1 this stops the animal from moving when someone is pulling it.
//Interaction
var/response_help = "pokes"
var/response_disarm = "shoves"
var/response_harm = "hits"
var/harm_intent_damage = 3
var/force_threshold = 0 //Minimum force required to deal any damage
//Temperature effect
var/minbodytemp = 250
var/maxbodytemp = 350
//Healable by medical stacks? Defaults to yes.
var/healable = 1
//Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage
var/list/atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) //Leaving something at 0 means it's off - has no maximum
var/unsuitable_atmos_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
//LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly
var/melee_damage_lower = 0
var/melee_damage_upper = 0
var/obj_damage = 0 //how much damage this simple animal does to objects, if any
var/armour_penetration = 0 //How much armour they ignore, as a flat reduction from the targets armour value
var/melee_damage_type = BRUTE //Damage type of a simple mob's melee attack, should it do damage.
var/list/damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) // 1 for full damage , 0 for none , -1 for 1:1 heal from that source
var/attacktext = "attacks"
/// Sound played when the critter attacks.
var/attack_sound
/// Override for the visual attack effect shown on 'do_attack_animation()'.
var/attack_vis_effect
var/friendly = "nuzzles" //If the mob does no damage with it's attack
var/environment_smash = ENVIRONMENT_SMASH_NONE //Set to 1 to allow breaking of crates,lockers,racks,tables; 2 for walls; 3 for Rwalls
var/speed = 1 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster
//Hot simple_animal baby making vars
var/list/childtype = null
var/next_scan_time = 0
var/animal_species //Sorry, no spider+corgi buttbabies.
//simple_animal access
var/obj/item/card/id/access_card = null //innate access uses an internal ID card
var/buffed = 0 //In the event that you want to have a buffing effect on the mob, but don't want it to stack with other effects, any outside force that applies a buff to a simple mob should at least set this to 1, so we have something to check against
var/gold_core_spawnable = NO_SPAWN //If the mob can be spawned with a gold slime core. HOSTILE_SPAWN are spawned with plasma, FRIENDLY_SPAWN are spawned with blood
var/datum/component/spawner/nest
var/sentience_type = SENTIENCE_ORGANIC // Sentience type, for slime potions
var/list/loot = list() //list of things spawned at mob's loc when it dies
var/del_on_death = 0 //causes mob to be deleted on death, useful for mobs that spawn lootable corpses
var/deathmessage = ""
var/allow_movement_on_non_turfs = FALSE
var/attacked_sound = "punch" //Played when someone punches the creature
var/dextrous = FALSE //If the creature has, and can use, hands
var/dextrous_hud_type = /datum/hud/dextrous
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever), AI_Z_OFF (Temporarily off due to nonpresence of players)
var/can_have_ai = TRUE //once we have become sentient, we can never go back
var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check.
//domestication
var/tame = 0
var/my_z // I don't want to confuse this with client registered_z
///What kind of footstep this mob should have. Null if it shouldn't have any.
var/footstep_type
var/do_footstep = FALSE
var/magic_tameable = TRUE //For special cases with the enchanted flowers
///How much wounding power it has
var/wound_bonus = CANT_WOUND
///How much bare wounding power it has
var/bare_wound_bonus = 0
///If the attacks from this are sharp
var/sharpness = SHARP_NONE
//Music
var/music_component = null
var/music_path = null
/mob/living/simple_animal/Initialize(mapload)
. = ..()
GLOB.simple_animals[AIStatus] += src
if(gender == PLURAL)
gender = pick(MALE,FEMALE)
if(!real_name)
real_name = name
if(!loc)
stack_trace("Simple animal being instantiated in nullspace")
update_simplemob_varspeed()
if(dextrous)
AddComponent(/datum/component/personal_crafting)
if(music_component && music_path)
AddComponent(music_component, music_path)
if(footstep_type)
AddElement(/datum/element/footstep, footstep_type)
/mob/living/simple_animal/Destroy()
GLOB.simple_animals[AIStatus] -= src
if (SSnpcpool.state == SS_PAUSED && LAZYLEN(SSnpcpool.currentrun))
SSnpcpool.currentrun -= src
if(nest)
nest.spawned_things -= src
nest = null
var/turf/T = get_turf(src)
if (T && AIStatus == AI_Z_OFF)
SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src
return ..()
/mob/living/simple_animal/examine(mob/user)
. = ..()
if(stat == DEAD)
. += span_deadsay("Upon closer examination, [p_they()] appear[p_s()] to be dead.")
/mob/living/simple_animal/updatehealth()
..()
health = clamp(health, 0, maxHealth)
/mob/living/simple_animal/update_stat()
if(status_flags & GODMODE)
return
if(stat != DEAD)
if(health <= 0)
death()
else
set_stat(CONSCIOUS)
med_hud_set_status()
/mob/living/simple_animal/proc/handle_automated_action()
set waitfor = FALSE
return
/mob/living/simple_animal/proc/handle_automated_movement()
set waitfor = FALSE
if(!stop_automated_movement && wander)
if((isturf(loc) || allow_movement_on_non_turfs) && (mobility_flags & MOBILITY_MOVE)) //This is so it only moves if it's not inside a closet, gentics machine, etc.
turns_since_move++
if(turns_since_move >= turns_per_move)
if(!(stop_automated_movement_when_pulled && pulledby)) //Some animals don't move when pulled
var/anydir = pick(GLOB.cardinals)
if(Process_Spacemove(anydir))
Move(get_step(src, anydir), anydir)
turns_since_move = 0
return 1
/mob/living/simple_animal/proc/handle_automated_speech(override)
set waitfor = FALSE
if(speak_chance)
if(prob(speak_chance) || override)
if(speak && speak.len)
if((emote_hear && emote_hear.len) || (emote_see && emote_see.len))
var/length = speak.len
if(emote_hear && emote_hear.len)
length += emote_hear.len
if(emote_see && emote_see.len)
length += emote_see.len
var/randomValue = rand(1,length)
if(randomValue <= speak.len)
say(pick(speak), forced = "poly")
else
randomValue -= speak.len
if(emote_see && randomValue <= emote_see.len)
emote("me [pick(emote_see)]", 1, TRUE)
else
emote("me [pick(emote_hear)]", 2, TRUE)
else
say(pick(speak), forced = "poly")
else
if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len))
emote("me", 1, pick(emote_see))
if((emote_hear && emote_hear.len) && !(emote_see && emote_see.len))
emote("me", 2, pick(emote_hear))
if((emote_hear && emote_hear.len) && (emote_see && emote_see.len))
var/length = emote_hear.len + emote_see.len
var/pick = rand(1,length)
if(pick <= emote_see.len)
emote("me", 1, pick(emote_see), TRUE)
else
emote("me", 2, pick(emote_hear), TRUE)
/mob/living/simple_animal/proc/environment_is_safe(datum/gas_mixture/environment, check_temp = FALSE)
. = TRUE
if(pulledby && pulledby.grab_state >= GRAB_KILL && atmos_requirements["min_oxy"])
. = FALSE //getting choked
if(isturf(src.loc) && isopenturf(src.loc))
var/turf/open/ST = src.loc
if(ST.air)
var/tox = ST.air.get_moles(GAS_PLASMA)
var/oxy = ST.air.get_moles(GAS_O2)
var/n2 = ST.air.get_moles(GAS_N2)
var/co2 = ST.air.get_moles(GAS_CO2)
if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
. = FALSE
else if(atmos_requirements["max_oxy"] && oxy > atmos_requirements["max_oxy"])
. = FALSE
else if(atmos_requirements["min_tox"] && tox < atmos_requirements["min_tox"])
. = FALSE
else if(atmos_requirements["max_tox"] && tox > atmos_requirements["max_tox"])
. = FALSE
else if(atmos_requirements["min_n2"] && n2 < atmos_requirements["min_n2"])
. = FALSE
else if(atmos_requirements["max_n2"] && n2 > atmos_requirements["max_n2"])
. = FALSE
else if(atmos_requirements["min_co2"] && co2 < atmos_requirements["min_co2"])
. = FALSE
else if(atmos_requirements["max_co2"] && co2 > atmos_requirements["max_co2"])
. = FALSE
else
if(atmos_requirements["min_oxy"] || atmos_requirements["min_tox"] || atmos_requirements["min_n2"] || atmos_requirements["min_co2"])
. = FALSE
if(check_temp)
var/areatemp = get_temperature(environment)
if((areatemp < minbodytemp) || (areatemp > maxbodytemp))
. = FALSE
/mob/living/simple_animal/handle_environment(datum/gas_mixture/environment)
var/atom/A = src.loc
if(isturf(A))
var/areatemp = get_temperature(environment)
var/heat_capacity_factor = min(1, environment.heat_capacity() / environment.return_volume())
if( abs(areatemp - bodytemperature) > 5)
var/diff = areatemp - bodytemperature
diff = diff / 5 * heat_capacity_factor
adjust_bodytemperature(diff)
if(!environment_is_safe(environment))
adjustHealth(unsuitable_atmos_damage)
handle_temperature_damage()
/mob/living/simple_animal/proc/handle_temperature_damage()
if((bodytemperature < minbodytemp) || (bodytemperature > maxbodytemp))
adjustHealth(unsuitable_atmos_damage)
/mob/living/simple_animal/gib(no_brain, no_organs, no_bodyparts, no_items)
var/atom/Tsec = drop_location()
if(butcher_results)
for(var/path in butcher_results)
for(var/i in 1 to butcher_results[path])
new path(Tsec)
if(guaranteed_butcher_results)
for(var/path in guaranteed_butcher_results)
for(var/i in 1 to guaranteed_butcher_results[path])
new path(Tsec)
..()
/mob/living/simple_animal/gib_animation()
if(icon_gib)
new /obj/effect/temp_visual/gib_animation/animal(loc, icon_gib)
/mob/living/simple_animal/say_mod(input, list/message_mods = list())
if(length(speak_emote))
verb_say = pick(speak_emote)
return ..()
/mob/living/simple_animal/emote(act, m_type=1, message = null, intentional = FALSE, is_keybind = FALSE)
if(stat)
return FALSE
return ..()
/mob/living/simple_animal/proc/set_varspeed(var_value)
speed = var_value
update_simplemob_varspeed()
/mob/living/simple_animal/proc/update_simplemob_varspeed()
if(speed == 0)
remove_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE)
add_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE, 100, multiplicative_slowdown = speed, override = TRUE)
/mob/living/simple_animal/get_status_tab_items()
. = ..()
. += ""
. += "Health: [round((health / maxHealth) * 100)]%"
/mob/living/simple_animal/proc/drop_loot()
if(loot.len)
for(var/i in loot)
new i(loc)
/mob/living/simple_animal/death(gibbed)
movement_type &= ~FLYING
if(nest)
nest.spawned_things -= src
nest = null
drop_loot()
if(dextrous)
drop_all_held_items()
if(!gibbed)
if(deathsound || deathmessage || !del_on_death)
emote("deathgasp")
if(del_on_death)
..()
//Prevent infinite loops if the mob Destroy() is overridden in such
//a manner as to cause a call to death() again
del_on_death = FALSE
qdel(src)
return
health = 0
icon_state = icon_dead
if(flip_on_death)
transform = transform.Turn(180)
density = FALSE
update_appearance()
return ..()
/mob/living/simple_animal/proc/CanAttack(atom/the_target)
if(see_invisible < the_target.invisibility)
return FALSE
if(ismob(the_target))
var/mob/M = the_target
if(M.status_flags & GODMODE)
return FALSE
if (isliving(the_target))
var/mob/living/L = the_target
if(L.stat != CONSCIOUS)
return FALSE
if (ismecha(the_target))
var/obj/mecha/M = the_target
if (M.occupant)
return FALSE
// yogs start
if(isspacepod(the_target))
var/obj/spacepod/SP = the_target
if(SP.pilot || SP.passengers.len)
return FALSE
// yogs end
return TRUE
/mob/living/simple_animal/ignite_mob()
return FALSE
/mob/living/simple_animal/extinguish_mob()
return
/mob/living/simple_animal/revive(full_heal = 0, admin_revive = 0)
if(..()) //successfully ressuscitated from death
icon = initial(icon)
icon_state = icon_living
density = initial(density)
mobility_flags = MOBILITY_FLAGS_DEFAULT
update_mobility()
. = 1
setMovetype(initial(movement_type))
/mob/living/simple_animal/proc/make_babies() // <3 <3 <3
if(gender != FEMALE || stat || next_scan_time > world.time || !childtype || !animal_species || !SSticker.IsRoundInProgress())
return
next_scan_time = world.time + 400
var/alone = 1
var/mob/living/simple_animal/partner
var/children = 0
for(var/mob/M in view(7, src))
if(M.stat != CONSCIOUS) //Check if it's conscious FIRST.
continue
else if(istype(M, childtype)) //Check for children SECOND.
children++
else if(istype(M, animal_species))
if(M.ckey)
continue
else if(!istype(M, childtype) && M.gender == MALE) //Better safe than sorry ;_;
partner = M
else if(isliving(M) && !faction_check_mob(M)) //shyness check. we're not shy in front of things that share a faction with us.
return //we never mate when not alone, so just abort early
if(alone && partner && children < 3)
var/childspawn = pickweight(childtype)
var/turf/target = get_turf(loc)
if(target)
return new childspawn(target)
/mob/living/simple_animal/canUseTopic(atom/movable/M, be_close=FALSE, no_dexterity=FALSE, no_tk=FALSE)
if(incapacitated())
to_chat(src, span_warning("You can't do that right now!"))
return FALSE
if(be_close && !in_range(M, src))
to_chat(src, span_warning("You are too far away!"))
return FALSE
if(!(no_dexterity || dextrous))
to_chat(src, span_warning("You don't have the dexterity to do this!"))
return FALSE
return TRUE
/mob/living/simple_animal/update_mobility(value_otherwise = TRUE)
if(IsUnconscious() || IsParalyzed() || IsStun() || IsKnockdown() || IsParalyzed() || stat || resting)
drop_all_held_items()
mobility_flags = NONE
else if(buckled)
mobility_flags = MOBILITY_FLAGS_INTERACTION
else
if(value_otherwise)
mobility_flags = MOBILITY_FLAGS_DEFAULT
else
mobility_flags = NONE
if(!(mobility_flags & MOBILITY_MOVE))
walk(src, 0) //stop mid walk
update_transform()
update_mob_action_buttons()
/mob/living/simple_animal/update_transform()
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/changed = FALSE
if(resize != RESIZE_DEFAULT_SIZE)
changed = TRUE
ntransform.Scale(resize)
resize = RESIZE_DEFAULT_SIZE
if(changed)
animate(src, transform = ntransform, time = 0.2 SECONDS, easing = EASE_IN|EASE_OUT)
/mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion
toggle_ai(AI_OFF) // To prevent any weirdness.
can_have_ai = FALSE
/mob/living/simple_animal/update_sight()
if(!client)
return
if(stat == DEAD)
if(SSmapping.level_trait(z, ZTRAIT_NOXRAY))
set_sight(null)
else if(is_secret_level(z))
set_sight(initial(sight))
else
set_sight(SEE_TURFS|SEE_MOBS|SEE_OBJS)
set_invis_see(SEE_INVISIBLE_OBSERVER)
return
lighting_color_cutoffs = list(lighting_cutoff_red, lighting_cutoff_green, lighting_cutoff_blue)
set_invis_see(initial(see_invisible))
if(SSmapping.level_trait(z, ZTRAIT_NOXRAY))
set_sight(null)
else
set_sight(initial(sight))
if(client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
return ..()
/mob/living/simple_animal/get_idcard(hand_first)
return access_card
/mob/living/simple_animal/can_hold_items()
return dextrous
/mob/living/simple_animal/IsAdvancedToolUser()
return dextrous
/mob/living/simple_animal/activate_hand(selhand)
if(!dextrous)
return ..()
if(!selhand)
selhand = (active_hand_index % held_items.len)+1
if(istext(selhand))
selhand = lowertext(selhand)
if(selhand == "right" || selhand == "r")
selhand = 2
if(selhand == "left" || selhand == "l")
selhand = 1
if(selhand != active_hand_index)
swap_hand(selhand)
else
mode()
/mob/living/simple_animal/perform_hand_swap(hand_index)
. = ..()
if(!.)
return
if(!dextrous)
return ..()
if(!hand_index)
hand_index = (active_hand_index % held_items.len)+1
var/oindex = active_hand_index
active_hand_index = hand_index
if(hud_used)
var/atom/movable/screen/inventory/hand/H
H = hud_used.hand_slots["[hand_index]"]
if(H)
H.update_appearance(UPDATE_ICON)
H = hud_used.hand_slots["[oindex]"]
if(H)
H.update_appearance(UPDATE_ICON)
/mob/living/simple_animal/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE, forced = FALSE, no_sound = FALSE)
. = ..(I, del_on_fail, merge_stacks)
update_inv_hands()
/mob/living/simple_animal/update_inv_hands()
. = ..()
if(!client || !hud_used || hud_used.hud_version == HUD_STYLE_NOHUD)
return
var/turf/our_turf = get_turf(src)
for(var/obj/item/I in held_items)
var/index = get_held_index_of_item(I)
SET_PLANE(I, ABOVE_HUD_PLANE, our_turf)
I.screen_loc = ui_hand_position(index)
client.screen |= I
//ANIMAL RIDING
/mob/living/simple_animal/user_buckle_mob(mob/living/M, mob/user)
var/datum/component/riding/riding_datum = GetComponent(/datum/component/riding)
if(riding_datum)
if(user.incapacitated())
return
for(var/atom/movable/A in get_turf(src))
if(A != src && A != M && A.density)
return
M.forceMove(get_turf(src))
return ..()
/mob/living/simple_animal/relaymove(mob/user, direction)
var/datum/component/riding/riding_datum = GetComponent(/datum/component/riding)
if(tame && riding_datum)
riding_datum.handle_ride(user, direction)
/mob/living/simple_animal/buckle_mob(mob/living/buckled_mob, force = 0, check_loc = 1)
. = ..()
LoadComponent(/datum/component/riding)
/mob/living/simple_animal/proc/toggle_ai(togglestatus)
if(!can_have_ai && (togglestatus != AI_OFF))
return
if (AIStatus != togglestatus)
if (togglestatus > 0 && togglestatus < 5)
if (togglestatus == AI_Z_OFF || AIStatus == AI_Z_OFF)
var/turf/T = get_turf(src)
if (AIStatus == AI_Z_OFF)
SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src
else
SSidlenpcpool.idle_mobs_by_zlevel[T.z] += src
GLOB.simple_animals[AIStatus] -= src
GLOB.simple_animals[togglestatus] += src
AIStatus = togglestatus
else
stack_trace("Something attempted to set simple animals AI to an invalid state: [togglestatus]")
/mob/living/simple_animal/proc/consider_wakeup()
if (pulledby || shouldwakeup)
toggle_ai(AI_ON)
/mob/living/simple_animal/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
. = ..()
if(!ckey && !stat)//Not unconscious
if(AIStatus == AI_IDLE)
toggle_ai(AI_ON)
/mob/living/simple_animal/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents)
..()
if (old_turf && AIStatus == AI_Z_OFF)
SSidlenpcpool.idle_mobs_by_zlevel[old_turf.z] -= src
toggle_ai(initial(AIStatus))
//YOGS EDIT
/mob/living/simple_animal/proc/return_standard_turns_per_move()
turns_per_move = initial(turns_per_move)
//YOGS END