mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Adds in a new type of securitron (#39382)
* foolish jedi * do not underestimate general beepsky * adds death handling so you don't lose his eswords :) * changes .loc to Tsec * oversight * src, TRUE, src, FALSE * src * Adds a toy sword variant. Fixes formatting * oops * fixes stuff for beepsky * makes grievous beepsky block all projectiles. * Fixes & cleanup * cyberboss pt.1 * cyberboss pt2.
This commit is contained in:
150
code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm
Normal file
150
code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm
Normal file
@@ -0,0 +1,150 @@
|
||||
/mob/living/simple_animal/bot/secbot/grievous //This bot is powerful. If you managed to get 4 eswords somehow, you deserve this horror. Emag him for best results.
|
||||
name = "General Beepsky"
|
||||
desc = "Is that a secbot with four eswords in its arms...?"
|
||||
icon = 'icons/mob/aibots.dmi'
|
||||
icon_state = "grievous"
|
||||
health = 150
|
||||
maxHealth = 150
|
||||
baton_type = /obj/item/melee/transforming/energy/sword
|
||||
base_speed = 4 //he's a fast fucker
|
||||
var/obj/item/weapon
|
||||
var/block_chance = 50
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/grievous/toy //A toy version of general beepsky!
|
||||
name = "Genewul Bweepskee"
|
||||
desc = "An adorable looking secbot with four toy swords taped to its arms"
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
baton_type = /obj/item/toy/sword
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/grievous/bullet_act(obj/item/projectile/P)
|
||||
visible_message("[src] deflects [P] with its energy swords!")
|
||||
playsound(src, 'sound/weapons/blade1.ogg', 50, TRUE)
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/grievous/Crossed(atom/movable/AM)
|
||||
..()
|
||||
if(ismob(AM) && AM == target)
|
||||
visible_message("[src] flails his swords and cuts [AM]!")
|
||||
playsound(src,'sound/effects/beepskyspinsabre.ogg',100,TRUE,-1)
|
||||
stun_attack(AM)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/grievous/Initialize()
|
||||
. = ..()
|
||||
weapon = new baton_type(src)
|
||||
weapon.attack_self(src)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/grievous/Destroy()
|
||||
QDEL_NULL(weapon)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/grievous/special_retaliate_after_attack(mob/user)
|
||||
if(mode != BOT_HUNT)
|
||||
return
|
||||
if(prob(block_chance))
|
||||
visible_message("[src] deflects [user]'s attack with his energy swords!")
|
||||
playsound(src, 'sound/weapons/blade1.ogg', 50, TRUE, -1)
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/grievous/stun_attack(mob/living/carbon/C) //Criminals don't deserve to live
|
||||
weapon.attack(C, src)
|
||||
playsound(src, 'sound/weapons/blade1.ogg', 50, TRUE, -1)
|
||||
if(C.stat == DEAD)
|
||||
addtimer(CALLBACK(src, .proc/update_icon), 2)
|
||||
back_to_idle()
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/grievous/handle_automated_action()
|
||||
if(!on)
|
||||
return
|
||||
switch(mode)
|
||||
if(BOT_IDLE) // idle
|
||||
update_icon()
|
||||
walk_to(src,0)
|
||||
look_for_perp() // see if any criminals are in range
|
||||
if(!mode && auto_patrol) // still idle, and set to patrol
|
||||
mode = BOT_START_PATROL // switch to patrol mode
|
||||
if(BOT_HUNT) // hunting for perp
|
||||
update_icon()
|
||||
playsound(src,'sound/effects/beepskyspinsabre.ogg',100,TRUE,-1)
|
||||
// general beepsky doesn't give up so easily, jedi scum
|
||||
if(frustration >= 20)
|
||||
walk_to(src,0)
|
||||
back_to_idle()
|
||||
return
|
||||
if(target) // make sure target exists
|
||||
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
|
||||
target_lastloc = target.loc //stun_attack() can clear the target if they're dead, so this needs to be set first
|
||||
stun_attack(target)
|
||||
anchored = TRUE
|
||||
return
|
||||
else // not next to perp
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
walk_to(src, target,1,4)
|
||||
if((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
else
|
||||
back_to_idle()
|
||||
|
||||
if(BOT_START_PATROL)
|
||||
look_for_perp()
|
||||
start_patrol()
|
||||
|
||||
if(BOT_PATROL)
|
||||
look_for_perp()
|
||||
bot_patrol()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/grievous/look_for_perp()
|
||||
anchored = FALSE
|
||||
var/judgement_criteria = judgement_criteria()
|
||||
for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
|
||||
if((C.stat) || (C.handcuffed))
|
||||
continue
|
||||
|
||||
if((C.name == oldtarget_name) && (world.time < last_found + 100))
|
||||
continue
|
||||
|
||||
threatlevel = C.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons))
|
||||
|
||||
if(!threatlevel)
|
||||
continue
|
||||
|
||||
else if(threatlevel >= 4)
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
speak("Level [threatlevel] infraction alert!")
|
||||
playsound(src, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, FALSE)
|
||||
playsound(src,'sound/weapons/saberon.ogg',50,TRUE,-1)
|
||||
visible_message("[src] ignites his energy swords!")
|
||||
icon_state = "grievous-c"
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action)
|
||||
break
|
||||
else
|
||||
continue
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/grievous/explode()
|
||||
|
||||
walk_to(src,0)
|
||||
visible_message("<span class='boldannounce'>[src] lets out a huge cough as it blows apart!</span>")
|
||||
var/atom/Tsec = drop_location()
|
||||
|
||||
var/obj/item/bot_assembly/secbot/Sa = new (Tsec)
|
||||
Sa.build_step = 1
|
||||
Sa.add_overlay("hs_hole")
|
||||
Sa.created_name = name
|
||||
new /obj/item/assembly/prox_sensor(Tsec)
|
||||
|
||||
if(prob(50))
|
||||
drop_part(robot_arm, Tsec)
|
||||
|
||||
do_sparks(3, TRUE, src)
|
||||
for(var/IS = 0 to 4)
|
||||
drop_part(baton_type, Tsec)
|
||||
new /obj/effect/decal/cleanable/oil(Tsec)
|
||||
qdel(src)
|
||||
@@ -379,6 +379,8 @@
|
||||
icon_state = "helmet_signaler"
|
||||
item_state = "helmet"
|
||||
created_name = "Securitron" //To preserve the name if it's a unique securitron I guess
|
||||
var/swordamt = 0 //If you're converting it into a grievousbot, how many swords have you attached
|
||||
var/toyswordamt = 0 //honk
|
||||
|
||||
/obj/item/bot_assembly/secbot/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
@@ -441,6 +443,29 @@
|
||||
S.robot_arm = robot_arm
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
if(istype(I, /obj/item/wrench))
|
||||
to_chat(user, "You adjust [src]'s arm slots to mount extra weapons")
|
||||
build_step ++
|
||||
return
|
||||
if(istype(I, /obj/item/toy/sword))
|
||||
if(toyswordamt < 3 && swordamt <= 0)
|
||||
if(!user.temporarilyRemoveItemFromInventory(I))
|
||||
return
|
||||
created_name = "General Beepsky"
|
||||
name = "helmet/signaler/prox sensor/robot arm/toy sword assembly"
|
||||
icon_state = "grievous_assembly"
|
||||
to_chat(user, "<span class='notice'>You superglue [I] onto one of [src]'s arm slots.</span>")
|
||||
qdel(I)
|
||||
toyswordamt ++
|
||||
else
|
||||
if(!can_finish_build(I, user))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You complete the Securitron!...Something seems a bit wrong with it..?</span>")
|
||||
var/mob/living/simple_animal/bot/secbot/grievous/toy/S = new(Tsec)
|
||||
S.name = created_name
|
||||
S.robot_arm = robot_arm
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
|
||||
else if(istype(I, /obj/item/screwdriver)) //deconstruct
|
||||
cut_overlay("hs_arm")
|
||||
@@ -448,3 +473,35 @@
|
||||
robot_arm = null
|
||||
to_chat(user, "<span class='notice'>You remove [dropped_arm] from [src].</span>")
|
||||
build_step--
|
||||
if(toyswordamt > 0 || toyswordamt)
|
||||
icon_state = initial(icon_state)
|
||||
to_chat(user, "<span class='notice'>The superglue binding [src]'s toy swords to its chassis snaps!</span>")
|
||||
for(var/IS in 1 to toyswordamt)
|
||||
new /obj/item/toy/sword(Tsec)
|
||||
|
||||
if(ASSEMBLY_FIFTH_STEP)
|
||||
if(istype(I, /obj/item/melee/transforming/energy/sword/saber))
|
||||
if(swordamt < 3)
|
||||
if(!user.temporarilyRemoveItemFromInventory(I))
|
||||
return
|
||||
created_name = "General Beepsky"
|
||||
name = "helmet/signaler/prox sensor/robot arm/energy sword assembly"
|
||||
icon_state = "grievous_assembly"
|
||||
to_chat(user, "<span class='notice'>You bolt [I] onto one of [src]'s arm slots.</span>")
|
||||
qdel(I)
|
||||
swordamt ++
|
||||
else
|
||||
if(!can_finish_build(I, user))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You complete the Securitron!...Something seems a bit wrong with it..?</span>")
|
||||
var/mob/living/simple_animal/bot/secbot/grievous/S = new(Tsec)
|
||||
S.name = created_name
|
||||
S.robot_arm = robot_arm
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
else if(istype(I, /obj/item/screwdriver)) //deconstruct
|
||||
build_step--
|
||||
icon_state = initial(icon_state)
|
||||
to_chat(user, "<span class='notice'>You unbolt [src]'s energy swords</span>")
|
||||
for(var/IS in 1 to swordamt)
|
||||
new /obj/item/melee/transforming/energy/sword/saber(Tsec)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
var/lastfired = 0
|
||||
var/shot_delay = 15
|
||||
var/lasercolor = ""
|
||||
var/disabled = 0//A holder for if it needs to be disabled, if true it will not seach for targets, shoot at targets, or move, currently only used for lasertag
|
||||
var/disabled = FALSE //A holder for if it needs to be disabled, if true it will not seach for targets, shoot at targets, or move, currently only used for lasertag
|
||||
|
||||
|
||||
var/mob/living/carbon/target
|
||||
@@ -34,11 +34,11 @@
|
||||
var/threatlevel = 0
|
||||
var/target_lastloc //Loc of target when arrested.
|
||||
var/last_found //There's a delay
|
||||
var/declare_arrests = 1 //When making an arrest, should it notify everyone wearing sechuds?
|
||||
var/idcheck = 1 //If true, arrest people with no IDs
|
||||
var/weaponscheck = 1 //If true, arrest people for weapons if they don't have access
|
||||
var/check_records = 1 //Does it check security records?
|
||||
var/arrest_type = 0 //If true, don't handcuff
|
||||
var/declare_arrests = TRUE //When making an arrest, should it notify everyone wearing sechuds?
|
||||
var/idcheck = TRUE //If true, arrest people with no IDs
|
||||
var/weaponscheck = TRUE //If true, arrest people for weapons if they don't have access
|
||||
var/check_records = TRUE //Does it check security records?
|
||||
var/arrest_type = FALSE //If true, don't handcuff
|
||||
var/projectile = /obj/item/projectile/energy/electrode //Holder for projectile type
|
||||
var/shoot_sound = 'sound/weapons/taser.ogg'
|
||||
var/cell_type = /obj/item/stock_parts/cell
|
||||
@@ -199,7 +199,7 @@ Auto Patrol[]"},
|
||||
to_chat(user, "<span class='warning'>You short out [src]'s target assessment circuits.</span>")
|
||||
oldtarget_name = user.name
|
||||
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
|
||||
declare_arrests = 0
|
||||
declare_arrests = FALSE
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
set_weapon()
|
||||
|
||||
@@ -357,7 +357,7 @@ Auto Patrol[]"},
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
speak("Level [threatlevel] infraction alert!")
|
||||
playsound(loc, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, 0)
|
||||
playsound(src, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, FALSE)
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
@@ -447,7 +447,7 @@ Auto Patrol[]"},
|
||||
return
|
||||
|
||||
var/obj/item/projectile/A = new projectile (loc)
|
||||
playsound(loc, shoot_sound, 50, 1)
|
||||
playsound(src, shoot_sound, 50, TRUE)
|
||||
A.preparePixelProjectile(target, src)
|
||||
A.fire()
|
||||
|
||||
@@ -538,7 +538,7 @@ Auto Patrol[]"},
|
||||
shootAt(A)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/stun_attack(mob/living/carbon/C)
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
|
||||
icon_state = "[lasercolor]ed209-c"
|
||||
spawn(2)
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
@@ -558,7 +558,7 @@ Auto Patrol[]"},
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/cuff(mob/living/carbon/C)
|
||||
mode = BOT_ARREST
|
||||
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
|
||||
playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2)
|
||||
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
|
||||
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "\improper Securitron"
|
||||
desc = "A little security robot. He looks less than thrilled."
|
||||
icon = 'icons/mob/aibots.dmi'
|
||||
icon_state = "secbot0"
|
||||
icon_state = "secbot"
|
||||
density = FALSE
|
||||
anchored = FALSE
|
||||
health = 25
|
||||
@@ -24,21 +24,21 @@
|
||||
var/baton_type = /obj/item/melee/baton
|
||||
var/mob/living/carbon/target
|
||||
var/oldtarget_name
|
||||
var/threatlevel = 0
|
||||
var/threatlevel = FALSE
|
||||
var/target_lastloc //Loc of target when arrested.
|
||||
var/last_found //There's a delay
|
||||
var/declare_arrests = 1 //When making an arrest, should it notify everyone on the security channel?
|
||||
var/idcheck = 0 //If true, arrest people with no IDs
|
||||
var/weaponscheck = 0 //If true, arrest people for weapons if they lack access
|
||||
var/check_records = 1 //Does it check security records?
|
||||
var/arrest_type = 0 //If true, don't handcuff
|
||||
var/declare_arrests = TRUE //When making an arrest, should it notify everyone on the security channel?
|
||||
var/idcheck = FALSE //If true, arrest people with no IDs
|
||||
var/weaponscheck = FALSE //If true, arrest people for weapons if they lack access
|
||||
var/check_records = TRUE //Does it check security records?
|
||||
var/arrest_type = FALSE //If true, don't handcuff
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky
|
||||
name = "Officer Beep O'sky"
|
||||
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
|
||||
idcheck = 0
|
||||
weaponscheck = 0
|
||||
auto_patrol = 1
|
||||
idcheck = FALSE
|
||||
weaponscheck = FALSE
|
||||
auto_patrol = TRUE
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky/jr
|
||||
name = "Officer Pipsqueak"
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Initialize()
|
||||
. = ..()
|
||||
icon_state = "secbot[on]"
|
||||
update_icon()
|
||||
var/datum/job/detective/J = new/datum/job/detective
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
@@ -74,13 +74,15 @@
|
||||
var/datum/atom_hud/secsensor = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
|
||||
secsensor.add_hud_to(src)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/turn_on()
|
||||
/mob/living/simple_animal/bot/secbot/update_icon()
|
||||
if(mode == BOT_HUNT)
|
||||
icon_state = "[initial(icon_state)]-c"
|
||||
return
|
||||
..()
|
||||
icon_state = "secbot[on]"
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/turn_off()
|
||||
..()
|
||||
icon_state = "secbot[on]"
|
||||
mode = BOT_IDLE
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/bot_reset()
|
||||
..()
|
||||
@@ -167,9 +169,14 @@ Auto Patrol: []"},
|
||||
final = final|JUDGE_EMAGGED
|
||||
return final
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/special_retaliate_after_attack(mob/user) //allows special actions to take place after being attacked.
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H)
|
||||
if((H.a_intent == INTENT_HARM) || (H.a_intent == INTENT_DISARM))
|
||||
retaliate(H)
|
||||
if(special_retaliate_after_attack(H))
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -179,6 +186,8 @@ Auto Patrol: []"},
|
||||
return
|
||||
if(!istype(W, /obj/item/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
|
||||
retaliate(user)
|
||||
if(special_retaliate_after_attack(user))
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/emag_act(mob/user)
|
||||
..()
|
||||
@@ -187,8 +196,8 @@ Auto Patrol: []"},
|
||||
to_chat(user, "<span class='danger'>You short out [src]'s target assessment circuits.</span>")
|
||||
oldtarget_name = user.name
|
||||
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
|
||||
declare_arrests = 0
|
||||
icon_state = "secbot[on]"
|
||||
declare_arrests = FALSE
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/bullet_act(obj/item/projectile/Proj)
|
||||
if(istype(Proj , /obj/item/projectile/beam)||istype(Proj, /obj/item/projectile/bullet))
|
||||
@@ -222,7 +231,7 @@ Auto Patrol: []"},
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C)
|
||||
mode = BOT_ARREST
|
||||
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
|
||||
playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2)
|
||||
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
|
||||
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
|
||||
addtimer(CALLBACK(src, .proc/attempt_handcuff, C), 60)
|
||||
@@ -236,14 +245,11 @@ Auto Patrol: []"},
|
||||
playsound(src, "law", 50, 0)
|
||||
back_to_idle()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/update_onsprite()
|
||||
icon_state = "secbot[on]"
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C)
|
||||
var/judgement_criteria = judgement_criteria()
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
|
||||
icon_state = "secbot-c"
|
||||
addtimer(CALLBACK(src, .proc/update_onsprite), 2)
|
||||
addtimer(CALLBACK(src, .proc/update_icon), 2)
|
||||
var/threat = 5
|
||||
if(ishuman(C))
|
||||
C.stuttering = 5
|
||||
@@ -384,7 +390,7 @@ Auto Patrol: []"},
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
speak("Level [threatlevel] infraction alert!")
|
||||
playsound(loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0)
|
||||
playsound(src, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, FALSE)
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 54 KiB |
BIN
sound/effects/beepskyspinsabre.ogg
Normal file
BIN
sound/effects/beepskyspinsabre.ogg
Normal file
Binary file not shown.
@@ -1983,6 +1983,7 @@
|
||||
#include "code\modules\mob\living\simple_animal\bot\medbot.dm"
|
||||
#include "code\modules\mob\living\simple_animal\bot\mulebot.dm"
|
||||
#include "code\modules\mob\living\simple_animal\bot\secbot.dm"
|
||||
#include "code\modules\mob\living\simple_animal\bot\SuperBeepsky.dm"
|
||||
#include "code\modules\mob\living\simple_animal\friendly\butterfly.dm"
|
||||
#include "code\modules\mob\living\simple_animal\friendly\cat.dm"
|
||||
#include "code\modules\mob\living\simple_animal\friendly\cockroach.dm"
|
||||
|
||||
Reference in New Issue
Block a user