Merge pull request #6529 from Meghan-Rossi/animalcleanup

Remove unused simple_animal files
This commit is contained in:
Atermonera
2019-12-15 11:35:57 -08:00
committed by GitHub
50 changed files with 170 additions and 10350 deletions
@@ -1,170 +1,170 @@
//Meant for simple animals to drop lootable human bodies.
//If someone can do this in a neater way, be my guest-Kor
//This has to be seperate from the Away Mission corpses, because New() doesn't work for those, and initialize() doesn't work for these.
//To do: Allow corpses to appear mangled, bloody, etc. Allow customizing the bodies appearance (they're all bald and white right now).
/obj/effect/landmark/mobcorpse
name = "Unknown"
var/mobname = "Unknown" //Unused now but it'd fuck up maps to remove it now
var/corpseuniform = null //Set this to an object path to have the slot filled with said object on the corpse.
var/corpsesuit = null
var/corpseshoes = null
var/corpsegloves = null
var/corpseradio = null
var/corpseglasses = null
var/corpsemask = null
var/corpsehelmet = null
var/corpsebelt = null
var/corpsepocket1 = null
var/corpsepocket2 = null
var/corpseback = null
var/corpseid = 0 //Just set to 1 if you want them to have an ID
var/corpseidjob = null // Needs to be in quotes, such as "Clown" or "Chef." This just determines what the ID reads as, not their access
var/corpseidaccess = null //This is for access. See access.dm for which jobs give what access. Again, put in quotes. Use "Captain" if you want it to be all access.
var/corpseidicon = null //For setting it to be a gold, silver, CentCom etc ID
/obj/effect/landmark/mobcorpse/New()
createCorpse()
/obj/effect/landmark/mobcorpse/proc/createCorpse() //Creates a mob and checks for gear in each slot before attempting to equip it.
var/mob/living/carbon/human/M = new /mob/living/carbon/human (src.loc)
M.real_name = src.name
M.stat = 2 //Kills the new mob
if(src.corpseuniform)
M.equip_to_slot_or_del(new src.corpseuniform(M), slot_w_uniform)
if(src.corpsesuit)
M.equip_to_slot_or_del(new src.corpsesuit(M), slot_wear_suit)
if(src.corpseshoes)
M.equip_to_slot_or_del(new src.corpseshoes(M), slot_shoes)
if(src.corpsegloves)
M.equip_to_slot_or_del(new src.corpsegloves(M), slot_gloves)
if(src.corpseradio)
M.equip_to_slot_or_del(new src.corpseradio(M), slot_l_ear)
if(src.corpseglasses)
M.equip_to_slot_or_del(new src.corpseglasses(M), slot_glasses)
if(src.corpsemask)
M.equip_to_slot_or_del(new src.corpsemask(M), slot_wear_mask)
if(src.corpsehelmet)
M.equip_to_slot_or_del(new src.corpsehelmet(M), slot_head)
if(src.corpsebelt)
M.equip_to_slot_or_del(new src.corpsebelt(M), slot_belt)
if(src.corpsepocket1)
M.equip_to_slot_or_del(new src.corpsepocket1(M), slot_r_store)
if(src.corpsepocket2)
M.equip_to_slot_or_del(new src.corpsepocket2(M), slot_l_store)
if(src.corpseback)
M.equip_to_slot_or_del(new src.corpseback(M), slot_back)
if(src.corpseid == 1)
var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s ID Card"
var/datum/job/jobdatum
for(var/jobtype in typesof(/datum/job))
var/datum/job/J = new jobtype
if(J.title == corpseidaccess)
jobdatum = J
break
if(src.corpseidicon)
W.icon_state = corpseidicon
if(src.corpseidaccess)
if(jobdatum)
W.access = jobdatum.get_access()
else
W.access = list()
if(corpseidjob)
W.assignment = corpseidjob
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
delete_me = 1
qdel(src)
//List of different corpse types
/obj/effect/landmark/mobcorpse/syndicatesoldier
name = "Mercenary"
corpseuniform = /obj/item/clothing/under/syndicate
corpsesuit = /obj/item/clothing/suit/armor/vest
corpseshoes = /obj/item/clothing/shoes/boots/swat
corpsegloves = /obj/item/clothing/gloves/swat
corpseradio = /obj/item/device/radio/headset
corpsemask = /obj/item/clothing/mask/gas
corpsehelmet = /obj/item/clothing/head/helmet/swat
corpseback = /obj/item/weapon/storage/backpack
corpseid = 1
corpseidjob = "Operative"
corpseidaccess = "Syndicate"
/obj/effect/landmark/mobcorpse/solarpeacekeeper
name = "Mercenary"
corpseuniform = /obj/item/clothing/under/syndicate
corpsesuit = /obj/item/clothing/suit/armor/pcarrier/blue/sol
corpseshoes = /obj/item/clothing/shoes/boots/swat
corpsegloves = /obj/item/clothing/gloves/swat
corpseradio = /obj/item/device/radio/headset
corpsemask = /obj/item/clothing/mask/gas
corpsehelmet = /obj/item/clothing/head/helmet/swat
corpseback = /obj/item/weapon/storage/backpack
corpseid = 1
corpseidjob = "Peacekeeper"
corpseidaccess = "Syndicate"
/obj/effect/landmark/mobcorpse/syndicatecommando
name = "Syndicate Commando"
corpseuniform = /obj/item/clothing/under/syndicate
corpsesuit = /obj/item/clothing/suit/space/void/merc
corpseshoes = /obj/item/clothing/shoes/boots/swat
corpsegloves = /obj/item/clothing/gloves/swat
corpseradio = /obj/item/device/radio/headset
corpsemask = /obj/item/clothing/mask/gas/syndicate
corpsehelmet = /obj/item/clothing/head/helmet/space/void/merc
corpseback = /obj/item/weapon/tank/jetpack/oxygen
corpsepocket1 = /obj/item/weapon/tank/emergency/oxygen
corpseid = 1
corpseidjob = "Operative"
corpseidaccess = "Syndicate"
/obj/effect/landmark/mobcorpse/clown
name = "Clown"
corpseuniform = /obj/item/clothing/under/rank/clown
corpseshoes = /obj/item/clothing/shoes/clown_shoes
corpseradio = /obj/item/device/radio/headset
corpsemask = /obj/item/clothing/mask/gas/clown_hat
corpsepocket1 = /obj/item/weapon/bikehorn
corpseback = /obj/item/weapon/storage/backpack/clown
corpseid = 1
corpseidjob = "Clown"
corpseidaccess = "Clown"
/obj/effect/landmark/mobcorpse/pirate
name = "Pirate"
corpseuniform = /obj/item/clothing/under/pirate
corpseshoes = /obj/item/clothing/shoes/boots/jackboots
corpseglasses = /obj/item/clothing/glasses/eyepatch
corpsehelmet = /obj/item/clothing/head/bandana
/obj/effect/landmark/mobcorpse/pirate/ranged
name = "Pirate Gunner"
corpsesuit = /obj/item/clothing/suit/pirate
corpsehelmet = /obj/item/clothing/head/pirate
/obj/effect/landmark/mobcorpse/russian
name = "Russian"
corpseuniform = /obj/item/clothing/under/soviet
corpseshoes = /obj/item/clothing/shoes/boots/jackboots
corpsehelmet = /obj/item/clothing/head/bearpelt
/obj/effect/landmark/mobcorpse/russian/ranged
//Meant for simple animals to drop lootable human bodies.
//If someone can do this in a neater way, be my guest-Kor
//This has to be seperate from the Away Mission corpses, because New() doesn't work for those, and initialize() doesn't work for these.
//To do: Allow corpses to appear mangled, bloody, etc. Allow customizing the bodies appearance (they're all bald and white right now).
/obj/effect/landmark/mobcorpse
name = "Unknown"
var/mobname = "Unknown" //Unused now but it'd fuck up maps to remove it now
var/corpseuniform = null //Set this to an object path to have the slot filled with said object on the corpse.
var/corpsesuit = null
var/corpseshoes = null
var/corpsegloves = null
var/corpseradio = null
var/corpseglasses = null
var/corpsemask = null
var/corpsehelmet = null
var/corpsebelt = null
var/corpsepocket1 = null
var/corpsepocket2 = null
var/corpseback = null
var/corpseid = 0 //Just set to 1 if you want them to have an ID
var/corpseidjob = null // Needs to be in quotes, such as "Clown" or "Chef." This just determines what the ID reads as, not their access
var/corpseidaccess = null //This is for access. See access.dm for which jobs give what access. Again, put in quotes. Use "Captain" if you want it to be all access.
var/corpseidicon = null //For setting it to be a gold, silver, CentCom etc ID
/obj/effect/landmark/mobcorpse/New()
createCorpse()
/obj/effect/landmark/mobcorpse/proc/createCorpse() //Creates a mob and checks for gear in each slot before attempting to equip it.
var/mob/living/carbon/human/M = new /mob/living/carbon/human (src.loc)
M.real_name = src.name
M.stat = 2 //Kills the new mob
if(src.corpseuniform)
M.equip_to_slot_or_del(new src.corpseuniform(M), slot_w_uniform)
if(src.corpsesuit)
M.equip_to_slot_or_del(new src.corpsesuit(M), slot_wear_suit)
if(src.corpseshoes)
M.equip_to_slot_or_del(new src.corpseshoes(M), slot_shoes)
if(src.corpsegloves)
M.equip_to_slot_or_del(new src.corpsegloves(M), slot_gloves)
if(src.corpseradio)
M.equip_to_slot_or_del(new src.corpseradio(M), slot_l_ear)
if(src.corpseglasses)
M.equip_to_slot_or_del(new src.corpseglasses(M), slot_glasses)
if(src.corpsemask)
M.equip_to_slot_or_del(new src.corpsemask(M), slot_wear_mask)
if(src.corpsehelmet)
M.equip_to_slot_or_del(new src.corpsehelmet(M), slot_head)
if(src.corpsebelt)
M.equip_to_slot_or_del(new src.corpsebelt(M), slot_belt)
if(src.corpsepocket1)
M.equip_to_slot_or_del(new src.corpsepocket1(M), slot_r_store)
if(src.corpsepocket2)
M.equip_to_slot_or_del(new src.corpsepocket2(M), slot_l_store)
if(src.corpseback)
M.equip_to_slot_or_del(new src.corpseback(M), slot_back)
if(src.corpseid == 1)
var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s ID Card"
var/datum/job/jobdatum
for(var/jobtype in typesof(/datum/job))
var/datum/job/J = new jobtype
if(J.title == corpseidaccess)
jobdatum = J
break
if(src.corpseidicon)
W.icon_state = corpseidicon
if(src.corpseidaccess)
if(jobdatum)
W.access = jobdatum.get_access()
else
W.access = list()
if(corpseidjob)
W.assignment = corpseidjob
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
delete_me = 1
qdel(src)
//List of different corpse types
/obj/effect/landmark/mobcorpse/syndicatesoldier
name = "Mercenary"
corpseuniform = /obj/item/clothing/under/syndicate
corpsesuit = /obj/item/clothing/suit/armor/vest
corpseshoes = /obj/item/clothing/shoes/boots/swat
corpsegloves = /obj/item/clothing/gloves/swat
corpseradio = /obj/item/device/radio/headset
corpsemask = /obj/item/clothing/mask/gas
corpsehelmet = /obj/item/clothing/head/helmet/swat
corpseback = /obj/item/weapon/storage/backpack
corpseid = 1
corpseidjob = "Operative"
corpseidaccess = "Syndicate"
/obj/effect/landmark/mobcorpse/solarpeacekeeper
name = "Mercenary"
corpseuniform = /obj/item/clothing/under/syndicate
corpsesuit = /obj/item/clothing/suit/armor/pcarrier/blue/sol
corpseshoes = /obj/item/clothing/shoes/boots/swat
corpsegloves = /obj/item/clothing/gloves/swat
corpseradio = /obj/item/device/radio/headset
corpsemask = /obj/item/clothing/mask/gas
corpsehelmet = /obj/item/clothing/head/helmet/swat
corpseback = /obj/item/weapon/storage/backpack
corpseid = 1
corpseidjob = "Peacekeeper"
corpseidaccess = "Syndicate"
/obj/effect/landmark/mobcorpse/syndicatecommando
name = "Syndicate Commando"
corpseuniform = /obj/item/clothing/under/syndicate
corpsesuit = /obj/item/clothing/suit/space/void/merc
corpseshoes = /obj/item/clothing/shoes/boots/swat
corpsegloves = /obj/item/clothing/gloves/swat
corpseradio = /obj/item/device/radio/headset
corpsemask = /obj/item/clothing/mask/gas/syndicate
corpsehelmet = /obj/item/clothing/head/helmet/space/void/merc
corpseback = /obj/item/weapon/tank/jetpack/oxygen
corpsepocket1 = /obj/item/weapon/tank/emergency/oxygen
corpseid = 1
corpseidjob = "Operative"
corpseidaccess = "Syndicate"
/obj/effect/landmark/mobcorpse/clown
name = "Clown"
corpseuniform = /obj/item/clothing/under/rank/clown
corpseshoes = /obj/item/clothing/shoes/clown_shoes
corpseradio = /obj/item/device/radio/headset
corpsemask = /obj/item/clothing/mask/gas/clown_hat
corpsepocket1 = /obj/item/weapon/bikehorn
corpseback = /obj/item/weapon/storage/backpack/clown
corpseid = 1
corpseidjob = "Clown"
corpseidaccess = "Clown"
/obj/effect/landmark/mobcorpse/pirate
name = "Pirate"
corpseuniform = /obj/item/clothing/under/pirate
corpseshoes = /obj/item/clothing/shoes/boots/jackboots
corpseglasses = /obj/item/clothing/glasses/eyepatch
corpsehelmet = /obj/item/clothing/head/bandana
/obj/effect/landmark/mobcorpse/pirate/ranged
name = "Pirate Gunner"
corpsesuit = /obj/item/clothing/suit/pirate
corpsehelmet = /obj/item/clothing/head/pirate
/obj/effect/landmark/mobcorpse/russian
name = "Russian"
corpseuniform = /obj/item/clothing/under/soviet
corpseshoes = /obj/item/clothing/shoes/boots/jackboots
corpsehelmet = /obj/item/clothing/head/bearpelt
/obj/effect/landmark/mobcorpse/russian/ranged
corpsehelmet = /obj/item/clothing/head/ushanka
@@ -1,142 +0,0 @@
/mob/living/simple_animal/hostile/alien
name = "alien hunter"
desc = "Hiss!"
icon = 'icons/mob/alien.dmi'
icon_state = "alienh_running"
icon_living = "alienh_running"
icon_dead = "alien_l"
icon_gib = "syndicate_gib"
icon_rest = "alienh_sleep"
faction = "xeno"
intelligence_level = SA_HUMANOID
cooperative = 1
run_at_them = 0
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
maxHealth = 100
health = 100
speed = -1
harm_intent_damage = 5
melee_damage_lower = 25
melee_damage_upper = 25
attack_sharp = 1
attack_edge = 1
attacktext = list("slashed")
attack_sound = 'sound/weapons/bladeslice.ogg'
a_intent = I_HURT
environment_smash = 2
status_flags = CANPUSH
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
heat_damage_per_tick = 20
unsuitable_atoms_damage = 15
meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat
/mob/living/simple_animal/hostile/alien/drone
name = "alien drone"
icon_state = "aliend_running"
icon_living = "aliend_running"
icon_dead = "aliend_l"
icon_rest = "aliend_sleep"
health = 60
melee_damage_lower = 15
melee_damage_upper = 15
/mob/living/simple_animal/hostile/alien/sentinel
name = "alien sentinel"
icon_state = "aliens_running"
icon_living = "aliens_running"
icon_dead = "aliens_l"
icon_rest = "aliens_sleep"
health = 120
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
projectiletype = /obj/item/projectile/energy/neurotoxin/toxic
projectilesound = 'sound/weapons/pierce.ogg'
/mob/living/simple_animal/hostile/alien/sentinel/praetorian
name = "alien praetorian"
icon = 'icons/mob/64x64.dmi'
icon_state = "prat_s"
icon_living = "prat_s"
icon_dead = "prat_dead"
icon_rest = "prat_sleep"
move_to_delay = 5
maxHealth = 200
health = 200
pixel_x = -16
old_x = -16
meat_amount = 5
/mob/living/simple_animal/hostile/alien/queen
name = "alien queen"
icon_state = "alienq_running"
icon_living = "alienq_running"
icon_dead = "alienq_l"
icon_rest = "alienq_sleep"
health = 250
maxHealth = 250
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
move_to_delay = 3
projectiletype = /obj/item/projectile/energy/neurotoxin/toxic
projectilesound = 'sound/weapons/pierce.ogg'
rapid = 1
status_flags = 0
/mob/living/simple_animal/hostile/alien/queen/empress
name = "alien empress"
icon = 'icons/mob/64x64.dmi'
icon_state = "queen_s"
icon_living = "queen_s"
icon_dead = "queen_dead"
icon_rest = "queen_sleep"
move_to_delay = 4
maxHealth = 400
health = 400
meat_amount = 5
speed = 1
pixel_x = -16
old_x = -16
/mob/living/simple_animal/hostile/alien/queen/empress/mother
name = "alien mother"
icon = 'icons/mob/96x96.dmi'
icon_state = "empress_s"
icon_living = "empress_s"
icon_dead = "empress_dead"
icon_rest = "empress_rest"
maxHealth = 600
health = 600
meat_amount = 10
melee_damage_lower = 15
melee_damage_upper = 25
speed = 2
pixel_x = -32
old_x = -32
/mob/living/simple_animal/hostile/alien/death()
..()
visible_message("[src] lets out a waning guttural screech, green blood bubbling from its maw...")
playsound(src, 'sound/voice/hiss6.ogg', 100, 1)
@@ -1,78 +0,0 @@
/mob/living/simple_animal/hostile/creature
name = "creature"
desc = "A sanity-destroying otherthing."
icon = 'icons/mob/critter.dmi'
icon_state = "otherthing"
icon_living = "otherthing"
icon_dead = "otherthing-dead"
faction = "creature"
intelligence_level = SA_ANIMAL
maxHealth = 40
health = 40
speed = 8
harm_intent_damage = 8
melee_damage_lower = 8
melee_damage_upper = 15
attack_armor_pen = 5 //It's a horror from beyond, I ain't gotta explain 5 AP
attack_sharp = 1
attack_edge = 1
attacktext = list("chomped")
attack_sound = 'sound/weapons/bite.ogg'
speak_emote = list("gibbers")
/mob/living/simple_animal/hostile/creature/cult
faction = "cult"
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
supernatural = 1
/mob/living/simple_animal/hostile/creature/cult/cultify()
return
/mob/living/simple_animal/hostile/creature/cult/Life()
..()
check_horde()
/mob/living/simple_animal/hostile/creature/strong
maxHealth = 160
health = 160
harm_intent_damage = 5
melee_damage_lower = 13
melee_damage_upper = 25
/mob/living/simple_animal/hostile/creature/strong/cult
faction = "cult"
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
supernatural = 1
/mob/living/simple_animal/hostile/creature/cult/cultify()
return
/mob/living/simple_animal/hostile/creature/cult/Life()
..()
check_horde()
@@ -1,286 +0,0 @@
//malfunctioning combat drones
/mob/living/simple_animal/hostile/malf_drone
name = "combat drone"
desc = "An automated combat drone armed with state of the art weaponry and shielding."
icon_state = "drone3"
icon_living = "drone3"
icon_dead = "drone_dead"
faction = "malf_drone"
intelligence_level = SA_ROBOTIC
maxHealth = 300
health = 300
speed = 8
stop_when_pulled = 0
turns_per_move = 3
response_help = "pokes"
response_disarm = "gently pushes aside"
response_harm = "hits"
a_intent = I_HURT
ranged = 1
rapid = 1
projectiletype = /obj/item/projectile/beam/drone
projectilesound = 'sound/weapons/laser3.ogg'
destroy_surroundings = 0
hovering = TRUE
armor = list(melee = 25, bullet = 25, laser = 25, energy = 10, bomb = 25, bio = 100, rad = 100) // Some level of armor plating makes sense
//Drones aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
speak_chance = 5
speak = list("ALERT.","Hostile-ile-ile entities dee-twhoooo-wected.","Threat parameterszzzz- szzet.","Bring sub-sub-sub-systems uuuup to combat alert alpha-a-a.")
emote_see = list("beeps menacingly","whirrs threateningly","scans its immediate vicinity")
var/datum/effect/effect/system/ion_trail_follow/ion_trail
var/turf/patrol_target
var/explode_chance = 1
var/disabled = 0
var/exploding = 0
var/has_loot = 1
/mob/living/simple_animal/hostile/malf_drone/New()
..()
if(prob(5))
projectiletype = /obj/item/projectile/beam/pulse/drone
projectilesound = 'sound/weapons/pulse2.ogg'
ion_trail = new
ion_trail.set_up(src)
ion_trail.start()
/mob/living/simple_animal/hostile/malf_drone/Process_Spacemove(var/check_drift = 0)
return 1
/mob/living/simple_animal/hostile/malf_drone/isSynthetic()
return TRUE
//self repair systems have a chance to bring the drone back to life
/mob/living/simple_animal/hostile/malf_drone/Life()
//emps and lots of damage can temporarily shut us down
if(disabled > 0)
stat = UNCONSCIOUS
icon_state = "drone_dead"
disabled--
wander = 0
speak_chance = 0
if(disabled <= 0)
stat = CONSCIOUS
icon_state = "drone0"
wander = 1
speak_chance = 5
//repair a bit of damage
if(prob(1))
src.visible_message("<font color='red'>\icon[src] [src] shudders and shakes as some of it's damaged systems come back online.</font>")
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
health += rand(25,100)
//spark for no reason
if(prob(5))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
//sometimes our targetting sensors malfunction, and we attack anyone nearby
if(prob(disabled ? 0 : 1))
if(hostile)
src.visible_message("<font color='blue'>\icon[src] [src] retracts several targetting vanes, and dulls it's running lights.</font>")
hostile = 0
else
src.visible_message("<font color='red'>\icon[src] [src] suddenly lights up, and additional targetting vanes slide into place.</font>")
hostile = 1
if(health / getMaxHealth() > 0.9)
icon_state = "drone3"
explode_chance = 0
else if(health / getMaxHealth() > 0.7)
icon_state = "drone2"
explode_chance = 0
else if(health / getMaxHealth() > 0.5)
icon_state = "drone1"
explode_chance = 0.5
else if(health / getMaxHealth() > 0.3)
icon_state = "drone0"
explode_chance = 5
else if(health > 0)
//if health gets too low, shut down
icon_state = "drone_dead"
exploding = 0
if(!disabled)
if(prob(50))
src.visible_message("<font color='blue'>\icon[src] [src] suddenly shuts down!</font>")
else
src.visible_message("<font color='blue'>\icon[src] [src] suddenly lies still and quiet.</font>")
disabled = rand(150, 600)
walk(src,0)
if(exploding && prob(20))
if(prob(50))
src.visible_message("<font color='red'>\icon[src] [src] begins to spark and shake violenty!</font>")
else
src.visible_message("<font color='red'>\icon[src] [src] sparks and shakes like it's about to explode!</font>")
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
if(!exploding && !disabled && prob(explode_chance))
exploding = 1
stat = UNCONSCIOUS
wander = 1
walk(src,0)
spawn(rand(50,150))
if(!disabled && exploding)
explosion(get_turf(src), 0, 1, 4, 7)
//proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1)
..()
//ion rifle!
/mob/living/simple_animal/hostile/malf_drone/emp_act(severity)
health -= rand(3,15) * (severity + 1)
disabled = rand(150, 600)
hostile = 0
walk(src,0)
..()
/mob/living/simple_animal/hostile/malf_drone/death()
..(null,"suddenly breaks apart.")
qdel(src)
/mob/living/simple_animal/hostile/malf_drone/Destroy()
//More advanced than the default S_A loot system, for visual effect and random tech levels.
if(has_loot)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
var/obj/O
//shards
O = new /obj/item/weapon/material/shard(src.loc)
step_to(O, get_turf(pick(view(7, src))))
if(prob(75))
O = new /obj/item/weapon/material/shard(src.loc)
step_to(O, get_turf(pick(view(7, src))))
if(prob(50))
O = new /obj/item/weapon/material/shard(src.loc)
step_to(O, get_turf(pick(view(7, src))))
if(prob(25))
O = new /obj/item/weapon/material/shard(src.loc)
step_to(O, get_turf(pick(view(7, src))))
//rods
O = new /obj/item/stack/rods(src.loc)
step_to(O, get_turf(pick(view(7, src))))
if(prob(75))
O = new /obj/item/stack/rods(src.loc)
step_to(O, get_turf(pick(view(7, src))))
if(prob(50))
O = new /obj/item/stack/rods(src.loc)
step_to(O, get_turf(pick(view(7, src))))
if(prob(25))
O = new /obj/item/stack/rods(src.loc)
step_to(O, get_turf(pick(view(7, src))))
//plasteel
O = new /obj/item/stack/material/plasteel(src.loc)
step_to(O, get_turf(pick(view(7, src))))
if(prob(75))
O = new /obj/item/stack/material/plasteel(src.loc)
step_to(O, get_turf(pick(view(7, src))))
if(prob(50))
O = new /obj/item/stack/material/plasteel(src.loc)
step_to(O, get_turf(pick(view(7, src))))
if(prob(25))
O = new /obj/item/stack/material/plasteel(src.loc)
step_to(O, get_turf(pick(view(7, src))))
//also drop dummy circuit boards deconstructable for research (loot)
var/obj/item/weapon/circuitboard/C
//spawn 1-4 boards of a random type
var/spawnees = 0
var/num_boards = rand(1,4)
var/list/options = list(1,2,4,8,16,32,64,128,256,512)
for(var/i=0, i<num_boards, i++)
var/chosen = pick(options)
options.Remove(options.Find(chosen))
spawnees |= chosen
if(spawnees & 1)
C = new(src.loc)
C.name = "Drone CPU motherboard"
C.origin_tech = list(TECH_DATA = rand(3, 6))
if(spawnees & 2)
C = new(src.loc)
C.name = "Drone neural interface"
C.origin_tech = list(TECH_BIO = rand(3,6))
if(spawnees & 4)
C = new(src.loc)
C.name = "Drone suspension processor"
C.origin_tech = list(TECH_MAGNET = rand(3,6))
if(spawnees & 8)
C = new(src.loc)
C.name = "Drone shielding controller"
C.origin_tech = list(TECH_BLUESPACE = rand(3,6))
if(spawnees & 16)
C = new(src.loc)
C.name = "Drone power capacitor"
C.origin_tech = list(TECH_POWER = rand(3,6))
if(spawnees & 32)
C = new(src.loc)
C.name = "Drone hull reinforcer"
C.origin_tech = list(TECH_MATERIAL = rand(3,6))
if(spawnees & 64)
C = new(src.loc)
C.name = "Drone auto-repair system"
C.origin_tech = list(TECH_ENGINEERING = rand(3,6))
if(spawnees & 128)
C = new(src.loc)
C.name = "Drone phoron overcharge counter"
C.origin_tech = list(TECH_PHORON = rand(3,6))
if(spawnees & 256)
C = new(src.loc)
C.name = "Drone targetting circuitboard"
C.origin_tech = list(TECH_COMBAT = rand(3,6))
if(spawnees & 512)
C = new(src.loc)
C.name = "Corrupted drone morality core"
C.origin_tech = list(TECH_ILLEGAL = rand(3,6))
..()
/obj/item/projectile/beam/drone
damage = 15
/obj/item/projectile/beam/pulse/drone
damage = 10
// A slightly easier drone, for POIs.
// Difference is that it should not be faster than you.
/mob/living/simple_animal/hostile/malf_drone/lesser
desc = "An automated combat drone with an aged apperance."
returns_home = TRUE
move_to_delay = 6
@@ -1,84 +0,0 @@
/mob/living/simple_animal/hostile/faithless
name = "Faithless"
desc = "The Wish Granter's faith in humanity, incarnate"
icon_state = "faithless"
icon_living = "faithless"
icon_dead = "faithless_dead"
faction = "faithless"
intelligence_level = SA_HUMANOID
maxHealth = 50
health = 50
speed = 8
turns_per_move = 5
response_help = "passes through"
response_disarm = "shoves"
response_harm = "hits"
harm_intent_damage = 10
melee_damage_lower = 10
melee_damage_upper = 18
attack_armor_pen = 5 //It's a horror from beyond, I ain't gotta explain 5 AP
attacktext = list("gripped")
attack_sound = 'sound/hallucinations/growl1.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
speak_chance = 0
/mob/living/simple_animal/hostile/faithless/Process_Spacemove(var/check_drift = 0)
return 1
/mob/living/simple_animal/hostile/faithless/set_target()
. = ..()
if(.)
audible_emote("wails at [target_mob]")
/mob/living/simple_animal/hostile/faithless/PunchTarget()
. = ..()
var/mob/living/L = .
if(istype(L))
if(prob(12))
L.Weaken(3)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
/mob/living/simple_animal/hostile/faithless/cult
faction = "cult"
supernatural = 1
/mob/living/simple_animal/hostile/faithless/cult/cultify()
return
/mob/living/simple_animal/hostile/faithless/cult/Life()
..()
check_horde()
/mob/living/simple_animal/hostile/faithless/strong
maxHealth = 100
health = 100
harm_intent_damage = 5
melee_damage_lower = 13
melee_damage_upper = 28
/mob/living/simple_animal/hostile/faithless/strong/cult
faction = "cult"
supernatural = 1
/mob/living/simple_animal/hostile/faithless/cult/cultify()
return
/mob/living/simple_animal/hostile/faithless/cult/Life()
..()
check_horde()
@@ -1,241 +0,0 @@
// Hivebots are tuned towards how many default lasers are needed to kill them.
// As such, if laser damage is ever changed, you should change this define.
#define LASERS_TO_KILL * 40
// Default hivebot is melee, and a bit more meaty, so it can meatshield for their ranged friends.
/mob/living/simple_animal/hostile/hivebot
name = "hivebot"
desc = "A robot. It appears to be somewhat resilient, but lacks a true weapon."
icon = 'icons/mob/hivebot.dmi'
icon_state = "basic"
icon_living = "basic"
icon_dead = "basic"
faction = "hivebot"
intelligence_level = SA_ROBOTIC
maxHealth = 3 LASERS_TO_KILL
health = 3 LASERS_TO_KILL
speed = 4
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = list("clawed")
projectilesound = 'sound/weapons/Gunshot.ogg'
projectiletype = /obj/item/projectile/bullet/hivebot
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
cooperative = TRUE
firing_lines = TRUE
investigates = TRUE
speak_chance = 1
speak = list(
"Resuming task: Protect area.",
"No threats found.",
"Error: No targets found."
)
emote_hear = list("hums ominously", "whirrs softly", "grinds a gear")
emote_see = list("looks around the area", "turns from side to side")
say_understood = list("Affirmative.", "Positive.")
say_cannot = list("Denied.", "Negative.")
say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.")
say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.")
/mob/living/simple_animal/hostile/hivebot/isSynthetic()
return TRUE
// Subtypes.
// Melee like the base type, but more fragile.
/mob/living/simple_animal/hostile/hivebot/swarm
name = "swarm hivebot"
desc = "A robot. It looks fragile and weak"
maxHealth = 1 LASERS_TO_KILL
health = 1 LASERS_TO_KILL
melee_damage_lower = 8
melee_damage_upper = 8
// This one has a semi-weak ranged attack.
/mob/living/simple_animal/hostile/hivebot/range
name = "ranged hivebot"
desc = "A robot. It has a simple ballistic weapon."
ranged = 1
maxHealth = 2 LASERS_TO_KILL
health = 2 LASERS_TO_KILL
// This one shoots a burst of three, and is considerably more dangerous.
/mob/living/simple_animal/hostile/hivebot/range/rapid
name = "rapid hivebot"
desc = "A robot. It has a fast firing ballistic rifle."
icon_living = "strong"
rapid = 1
maxHealth = 2 LASERS_TO_KILL
health = 2 LASERS_TO_KILL
// Shoots EMPs, to screw over other robots.
/mob/living/simple_animal/hostile/hivebot/range/ion
name = "engineering hivebot"
desc = "A robot. It has a tool which emits focused electromagnetic pulses, which are deadly to synthetic adverseries."
projectiletype = /obj/item/projectile/ion
projectilesound = 'sound/weapons/Laser.ogg'
icon_living = "engi"
ranged = TRUE
maxHealth = 2 LASERS_TO_KILL
health = 2 LASERS_TO_KILL
// Shoots deadly lasers.
/mob/living/simple_animal/hostile/hivebot/range/laser
name = "laser hivebot"
desc = "A robot. It has an energy weapon."
projectiletype = /obj/item/projectile/beam/blue
projectilesound = 'sound/weapons/Laser.ogg'
maxHealth = 2 LASERS_TO_KILL
health = 2 LASERS_TO_KILL
// Beefy and ranged.
/mob/living/simple_animal/hostile/hivebot/range/strong
name = "strong hivebot"
desc = "A robot. This one has reinforced plating, and looks tougher."
icon_living = "strong"
maxHealth = 4 LASERS_TO_KILL
health = 4 LASERS_TO_KILL
melee_damage_lower = 15
melee_damage_upper = 15
// Also beefy, but tries to stay at their 'home', ideal for base defense.
/mob/living/simple_animal/hostile/hivebot/range/guard
name = "guard hivebot"
desc = "A robot. It seems to be guarding something."
returns_home = TRUE
maxHealth = 4 LASERS_TO_KILL
health = 4 LASERS_TO_KILL
// This one is intended for players to use. Well rounded and can make other hivebots follow them with verbs.
/mob/living/simple_animal/hostile/hivebot/range/player
name = "commander hivebot"
desc = "A robot. This one seems to direct the others, and it has a laser weapon."
icon_living = "commander"
maxHealth = 5 LASERS_TO_KILL
health = 5 LASERS_TO_KILL
projectiletype = /obj/item/projectile/beam/blue
projectilesound = 'sound/weapons/Laser.ogg'
melee_damage_lower = 15 // Needed to force open airlocks.
melee_damage_upper = 15
// Procs.
/mob/living/simple_animal/hostile/hivebot/death()
..()
visible_message("<b>[src]</b> blows apart!")
new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
qdel(src)
/mob/living/simple_animal/hostile/hivebot/speech_bubble_appearance()
return "synthetic_evil"
/mob/living/simple_animal/hostile/hivebot/verb/command_follow()
set name = "Command - Follow"
set category = "Hivebot"
set desc = "This will ask other hivebots to follow you."
say("Delegating new task: Follow.")
for(var/mob/living/simple_animal/hostile/hivebot/buddy in hearers(src))
if(buddy.faction != faction)
continue
if(buddy == src)
continue
buddy.set_follow(src)
buddy.FollowTarget()
spawn(rand(5, 10))
buddy.say( pick(buddy.say_understood) )
/mob/living/simple_animal/hostile/hivebot/verb/command_stop()
set name = "Command - Stop Following"
set category = "Hivebot"
set desc = "This will ask other hivebots to cease following you."
say("Delegating new task: Stop following.")
for(var/mob/living/simple_animal/hostile/hivebot/buddy in hearers(src))
if(buddy.faction != faction)
continue
if(buddy == src)
continue
buddy.LoseFollow()
spawn(rand(5, 10))
buddy.say( pick(buddy.say_understood) )
/mob/living/simple_animal/hostile/hivebot/tele//this still needs work
name = "Beacon"
desc = "Some odd beacon thing"
icon = 'icons/mob/hivebot.dmi'
icon_state = "def_radar-off"
icon_living = "def_radar-off"
health = 200
maxHealth = 200
status_flags = 0
anchored = 1
wander = 0
stop_automated_movement = 1
var/bot_type = "norm"
var/bot_amt = 10
var/spawn_delay = 600
var/turn_on = 0
var/auto_spawn = 1
proc
warpbots()
New()
..()
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
smoke.set_up(5, 0, src.loc)
smoke.start()
visible_message("<font color='red'><B>The [src] warps in!</font></B>")
playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
warpbots()
icon_state = "def_radar"
visible_message("<font color='red'>The [src] turns on!</font>")
while(bot_amt > 0)
bot_amt--
switch(bot_type)
if("norm")
new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
if("range")
new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
if("rapid")
new /mob/living/simple_animal/hostile/hivebot/range/rapid(get_turf(src))
spawn(100)
qdel(src)
return
Life()
..()
if(stat == 0)
if(prob(2))//Might be a bit low, will mess with it likely
warpbots()
/obj/item/projectile/bullet/hivebot
damage = 10
damage_type = BRUTE
#undef LASERS_TO_KILL
@@ -1,201 +0,0 @@
//
// Abstract Class
//
/mob/living/simple_animal/hostile/mimic
name = "crate"
desc = "A rectangular steel crate."
icon = 'icons/obj/storage.dmi'
icon_state = "crate"
icon_living = "crate"
faction = "mimic"
intelligence_level = SA_ANIMAL
maxHealth = 250
health = 250
speed = 4
move_to_delay = 8
response_help = "touches"
response_disarm = "pushes"
response_harm = "hits"
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 12
attacktext = list("attacked")
attack_sound = 'sound/weapons/bite.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
/mob/living/simple_animal/hostile/mimic/set_target()
. = ..()
if(.)
audible_emote("growls at [.]")
/mob/living/simple_animal/hostile/mimic/death()
..()
qdel(src)
/mob/living/simple_animal/hostile/mimic/will_show_tooltip()
return FALSE
//
// Crate Mimic
//
// Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies.
/mob/living/simple_animal/hostile/mimic/crate
attacktext = list("bitten")
stop_automated_movement = 1
wander = 0
var/attempt_open = 0
// Pickup loot
/mob/living/simple_animal/hostile/mimic/crate/Initialize()
. = ..()
for(var/obj/item/I in loc)
I.forceMove(src)
/mob/living/simple_animal/hostile/mimic/crate/DestroySurroundings()
..()
if(prob(90))
icon_state = "[initial(icon_state)]open"
else
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/mimic/crate/ListTargets()
if(attempt_open)
return ..()
else
return ..(1)
/mob/living/simple_animal/hostile/mimic/crate/set_target()
. = ..()
if(.)
trigger()
/mob/living/simple_animal/hostile/mimic/crate/PunchTarget()
. = ..()
if(.)
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/mimic/crate/proc/trigger()
if(!attempt_open)
visible_message("<b>[src]</b> starts to move!")
attempt_open = 1
/mob/living/simple_animal/hostile/mimic/crate/adjustBruteLoss(var/damage)
trigger()
..(damage)
/mob/living/simple_animal/hostile/mimic/crate/LoseTarget()
..()
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/mimic/crate/LostTarget()
..()
icon_state = initial(icon_state)
/mob/living/simple_animal/hostile/mimic/crate/death()
var/obj/structure/closet/crate/C = new(get_turf(src))
// Put loot in crate
for(var/obj/O in src)
O.forceMove(C)
..()
/mob/living/simple_animal/hostile/mimic/crate/PunchTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(2)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
//
// Copy Mimic
//
var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window, /obj/item/projectile/animate)
/mob/living/simple_animal/hostile/mimic/copy
health = 100
maxHealth = 100
var/mob/living/creator = null // the creator
var/destroy_objects = 0
var/knockdown_people = 0
/mob/living/simple_animal/hostile/mimic/copy/New(loc, var/obj/copy, var/mob/living/creator)
..(loc)
CopyObject(copy, creator)
/mob/living/simple_animal/hostile/mimic/copy/death()
for(var/atom/movable/M in src)
M.forceMove(get_turf(src))
..()
/mob/living/simple_animal/hostile/mimic/copy/ListTargets()
// Return a list of targets that isn't the creator
. = ..()
return . - creator
/mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(var/obj/O, var/mob/living/creator)
if((istype(O, /obj/item) || istype(O, /obj/structure)) && !is_type_in_list(O, protected_objects))
O.forceMove(src)
name = O.name
desc = O.desc
icon = O.icon
icon_state = O.icon_state
icon_living = icon_state
if(istype(O, /obj/structure))
health = (anchored * 50) + 50
destroy_objects = 1
if(O.density && O.anchored)
knockdown_people = 1
melee_damage_lower *= 2
melee_damage_upper *= 2
else if(istype(O, /obj/item))
var/obj/item/I = O
health = 15 * I.w_class
melee_damage_lower = 2 + I.force
melee_damage_upper = 2 + I.force
move_to_delay = 2 * I.w_class
maxHealth = health
if(creator)
src.creator = creator
faction = "\ref[creator]" // very unique
return 1
return
/mob/living/simple_animal/hostile/mimic/copy/DestroySurroundings()
if(destroy_objects)
..()
/mob/living/simple_animal/hostile/mimic/copy/PunchTarget()
. =..()
if(knockdown_people)
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(1)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
@@ -1,61 +0,0 @@
/mob/living/simple_animal/shade
name = "Shade"
real_name = "Shade"
desc = "A bound spirit"
icon = 'icons/mob/mob.dmi'
icon_state = "shade"
icon_living = "shade"
icon_dead = "shade_dead"
faction = "cult"
intelligence_level = SA_HUMANOID
maxHealth = 50
health = 50
speed = -1
response_help = "puts their hand through"
response_disarm = "flails at"
response_harm = "punches"
melee_damage_lower = 5
melee_damage_upper = 15
attack_armor_pen = 100 //It's a ghost/horror from beyond, I ain't gotta explain 100 AP
attacktext = list("drained the life from")
minbodytemp = 0
maxbodytemp = 4000
min_oxy = 0
max_co2 = 0
max_tox = 0
stop_automated_movement = 1
wander = 0
status_flags = 0
speak_chance = 5
universal_speak = 1
speak_emote = list("hisses")
emote_hear = list("wails","screeches")
loot_list = list(/obj/item/weapon/ectoplasm = 100)
/mob/living/simple_animal/shade/cultify()
return
/mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O, /obj/item/device/soulstone))
var/obj/item/device/soulstone/S = O;
S.transfer_soul("SHADE", src, user)
return
..()
/mob/living/simple_animal/shade/death()
..()
for(var/mob/M in viewers(src, null))
if((M.client && !( M.blinded )))
M.show_message("<font color='red'>[src] lets out a contented sigh as their form unwinds.</font>")
ghostize()
qdel(src)
return
@@ -1,457 +0,0 @@
// A mob which only moves when it isn't being watched by living beings.
//Weeping angels/SCP-173 hype
//Horrible shitcoding and stolen code adaptations below. You have been warned.
/mob/living/simple_animal/hostile/statue
name = "statue" // matches the name of the statue with the flesh-to-stone spell
desc = "An incredibly lifelike marble carving. Its eyes seems to follow you..." // same as an ordinary statue with the added "eye following you" description
icon = 'icons/obj/statue.dmi'
tt_desc = "angelum weepicus"
icon_state = "human_male"
icon_living = "human_male"
icon_dead = "human_male"
intelligence_level = SA_HUMANOID
stop_automated_movement = 1
var/annoyance = 30 //stop staring you creep
var/respond = 1
var/banishable = 0
faction = "statue"
mob_size = MOB_HUGE
response_help = "touches"
response_disarm = "pushes"
environment_smash = 2
can_be_antagged = 1
speed = -1
maxHealth = 3000
health = 3000
status_flags = CANPUSH
// investigates = 1
a_intent = I_HURT
density = 1
mob_bump_flag = HEAVY
mob_push_flags = ~HEAVY
mob_swap_flags = ~HEAVY
harm_intent_damage = 60
melee_damage_lower = 50
melee_damage_upper = 70
attacktext = "clawed"
attack_sound = 'sound/hallucinations/growl1.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
maxbodytemp = 9000
run_at_them = 0
move_to_delay = 0 // Very fast
animate_movement = NO_STEPS // Do not animate movement, you jump around as you're a scary statue.
see_in_dark = 13
view_range = 35 //So it can run at the victim when out of the view
melee_miss_chance = 0
armor = list(
"melee" = 30,
"bullet" = 60,
"laser" = 80,
"energy" = 30,
"bomb" = 30,
"bio" = 100,
"rad" = 100)
resistance = 20
see_invisible = SEE_INVISIBLE_NOLIGHTING
sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS
var/last_hit = 0
var/cannot_be_seen = 1
var/mob/living/creator = null
var/drilled = FALSE
// No movement while seen code.
/mob/living/simple_animal/hostile/statue/New(loc)
..()
// Give spells
add_spell(new/spell/aoe_turf/flicker_lights)
add_spell(new/spell/aoe_turf/blindness)
add_spell(new/spell/aoe_turf/shatter)
/mob/living/simple_animal/hostile/statue/DestroySurroundings()
if(can_be_seen(get_turf(loc)))
if(client)
to_chat(src, "<span class='warning'>You cannot move, there are eyes on you!</span>")
return 0
return ..()
/mob/living/simple_animal/hostile/statue/attackby(var/obj/item/O as obj, var/mob/user as mob) //banishing the statue is a risky job
if(istype(O, /obj/item/weapon/nullrod))
visible_message("<span class='warning'>[user] tries to banish [src] with [O]!</span>")
if(do_after(user, 15, src))
if(banishable)
visible_message("<span class='warning'>[src] crumbles into dust!</span>")
gib()
else
visible_message("<span class='warning'>[src] is too strong to be banished!</span>")
Paralyse(rand(8,15))
if(istype(O, /obj/item/weapon/pickaxe) || istype(O, /obj/item/weapon/pickaxe/plasmacutter) && !drilled)
drilled = TRUE
resistance = 0
spawn(300)
drilled = FALSE
resistance = initial(resistance)
..()
/mob/living/simple_animal/hostile/statue/death()
var/chunks_to_spawn = rand(2,5)
for(var/I = 1 to chunks_to_spawn)
new /obj/item/stack/material/marble(get_turf(loc))
new /obj/item/cursed_marble(get_turf(loc))
..()
/mob/living/simple_animal/hostile/statue/Move(turf/NewLoc)
if(can_be_seen(NewLoc))
if(client)
to_chat(src, "<span class='warning'>You cannot move, there are eyes on you!</span>")
return 0
return ..()
/mob/living/simple_animal/hostile/statue/Life()
..()
handle_target()
handleAnnoyance()
if(target_mob) //if there's a victim, statue will use its powers
if((annoyance + 4) < 800)
annoyance += 4
if(drilled && (annoyance + 4) < 800) //Being hit with a drill makes them weaker, and angrier.
annoyance += 4
else if ((annoyance - 2) > 0)
annoyance -= 2
/mob/living/simple_animal/hostile/statue/proc/handle_target()
if(target_mob) // If we have a target and we're AI controlled
var/mob/watching = can_be_seen()
// If they're not our target
if(watching && (watching != target_mob))
// This one is closer.
if(get_dist(watching, src) > get_dist(target_mob, src))
LoseTarget()
target_mob = watching
/mob/living/simple_animal/hostile/statue/proc/handleAnnoyance()
if(respond) //so it won't blind people 24/7
respond = 0
if (annoyance > 30)
AI_blind()
annoyance -= 30
if (prob(30) && annoyance > 30)
var/turf/T = get_turf(loc)
if(T.get_lumcount() * 10 > 1.5)
AI_flash()
annoyance -= 30
spawn(20)
respond = 1
/mob/living/simple_animal/hostile/statue/proc/AI_blind()
for(var/mob/living/L in oviewers(12, src)) //the range is so big, because it tries to keep out of sight and can't reengage if you get too far
if (prob(70))
if(ishuman(L))
var/mob/living/carbon/human/H = L
if (H.species == "Diona" || H.species == "Promethean" || H == creator)// can't blink and organic
return
to_chat(L, pick("<span class='notice'>Your eyes feel very heavy.</span>", "<span class='notice'>You blink suddenly!</span>", "<span class='notice'>Your eyes close involuntarily!</span>"))
L.Blind(2)
return
/mob/living/simple_animal/hostile/statue/proc/AI_flash()
if (prob(60))
visible_message("The statue slowly points at the light.")
for(var/obj/machinery/light/L in oview(12, src))
L.flicker()
return
/mob/living/simple_animal/hostile/statue/proc/AI_mirrorshmash()
for(var/obj/structure/mirror/M in oview(4, src))
if ((!M.shattered )||(!M.glass))
visible_message("The statue slowly points at the mirror!")
sleep(5)
M.shatter()
return
/mob/living/simple_animal/hostile/statue/AttackTarget()
if(can_be_seen(get_turf(loc)))
if(client)
to_chat(src, "<span class='warning'>You cannot attack, there are eyes on you!</span>")
return
else
spawn(3) //a small delay
..()
/mob/living/simple_animal/hostile/statue/DoPunch(var/atom/A) //had to redo that, since it's supposed to target only head and upper body
if(!Adjacent(A)) // They could've moved in the meantime.
return FALSE
var/damage_to_do = rand(melee_damage_lower, melee_damage_upper)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.outgoing_melee_damage_percent))
damage_to_do *= M.outgoing_melee_damage_percent
// SA attacks can be blocked with shields.
if(ishuman(A))
var/mob/living/carbon/human/H = A
H.adjustBruteLossByPart(damage_to_do*0.9, pick(BP_HEAD, BP_TORSO))
playsound(src, attack_sound, 75, 1)
else if(A.attack_generic(src, damage_to_do, pick(attacktext), attack_armor_type, attack_armor_pen, attack_sharp, attack_edge) && attack_sound)
playsound(src, attack_sound, 75, 1)
return TRUE
/mob/living/simple_animal/hostile/statue/face_atom()
if(!can_be_seen(get_turf(loc)))
..()
/mob/living/simple_animal/hostile/statue/proc/can_be_seen(turf/destination)
if(!cannot_be_seen)
return null
var/turf/T = get_turf(loc)
/* if(T && destination && T.lighting_overlay)
if(T.get_lumcount() * 10 < 0.9 && destination.get_lumcount() * 10 < 0.9) // No one can see us in the darkness, right?
return null
if(T == destination)
destination = null*/
// loop for viewers.
var/list/check_list = list(src)
if(destination)
check_list += destination
//&& (M.see_in_dark > 5)
// This loop will, at most, loop twice.
for(var/atom/check in check_list)
for(var/mob/living/M in viewers(world.view + 1, check) - src)
if(M != creator)
if(!(M.sdisabilities & BLIND) || !(M.blinded)) //if not blinded
if(M.has_vision() && !M.isSynthetic()) //is able to see the statue
if(T && destination && T.lighting_overlay) // Check for darkness
if(T.get_lumcount() * 10 < 0.9 && destination.get_lumcount() * 10 < 0.9) // No one can see us in the darkness, right? WRONG! Damn cats.
if(M.see_in_dark > 5)
return M
return null
return M
for(var/obj/mecha/M in view(world.view + 1, check)) //assuming if you can see them they can see you
if(M.occupant && M.occupant.client && M.occupant != creator)
if(M.occupant.has_vision() && !M.occupant.isSynthetic())
return M.occupant
for(var/obj/structure/mirror/M in view(3, check)) //Weeping angels hate mirrors. Probably because they're ugly af
if ((!M.shattered )||(!M.glass))
annoyance += 3
if (prob(5) && (ai_inactive == 0))
AI_mirrorshmash()
annoyance -= 50
return src //if it sees the mirror, it sees itself, right?
return null
// Cannot talk
/mob/living/simple_animal/hostile/statue/say()
return 0
// Turn to dust when gibbed
/mob/living/simple_animal/hostile/statue/gib()
dust()
// Stop attacking clientless mobs
/mob/living/simple_animal/hostile/statue/proc/CanAttack(atom/the_target) //ignore clientless mobs
if(isliving(the_target))
var/mob/living/L = the_target
if(!L.client && !L.ckey)
return 0
return ..()
// Statue powers
// Flicker lights
/spell/aoe_turf/flicker_lights
name = "Flicker Lights"
desc = "You will trigger a large amount of lights around you to flicker."
spell_flags = 0
charge_max = 400
range = 10
/spell/aoe_turf/flicker_lights/cast(list/targets, mob/user = usr)
for(var/turf/T in targets)
for(var/obj/machinery/light/L in T)
L.flicker()
return
//Blind AOE
/spell/aoe_turf/blindness
name = "Blindness"
desc = "Your prey will be momentarily blind for you to advance on them."
message = "<span class='notice'>You glare your eyes.</span>"
charge_max = 250
spell_flags = 0
range = 10
/spell/aoe_turf/blindness/cast(list/targets, mob/living/simple_animal/hostile/statue/user = usr)
for(var/mob/living/L in targets)
if(L == user || L == user.creator)
continue
var/turf/T = get_turf(L.loc)
if(T && T in targets)
L.Blind(4)
return
/spell/aoe_turf/shatter
name = "Shatter mirrors!"
desc = "That handsome devil has to wait. You have people to make into corpses."
message = "<span class='notice'>You glare your eyes.</span>"
charge_max = 300
spell_flags = 0
range = 8
/spell/aoe_turf/shatter/cast(list/targets, mob/user = usr)
spawn(50)
for(var/obj/structure/mirror/M in view(5, src))
if ((!M.shattered )||(!M.glass))
M.shatter()
return
/mob/living/simple_animal/hostile/statue/verb/toggle_darkness()
set name = "Toggle Darkness"
set desc = "You ARE the darkness."
set category = "Abilities"
seedarkness = !seedarkness
plane_holder.set_vis(VIS_FULLBRIGHT, !seedarkness)
to_chat(src,"You [seedarkness ? "now" : "no longer"] see darkness.")
/mob/living/simple_animal/hostile/statue/restrained()
. = ..()
if(can_be_seen(loc))
return 1
/mob/living/simple_animal/hostile/statue/ListTargets(dist = view_range)
var/list/L = mobs_in_xray_view(dist, src)
for(var/obj/mecha/M in mechas_list)
if ((M.z == src.z) && (get_dist(src, M) <= dist) && (isInSight(src,M)))
L += M
if(creator)
L -= creator
return L
/obj/item/cursed_marble //slime cube copypaste
name = "marble slab"
desc = "A peculiar slab of marble, radiating with dark energy."
icon = 'icons/obj/stacks.dmi'
icon_state = "sheet-marble"
description_info = "Summons the Statue - a mysterious powerful creature, that can move only when unsurveyed by living eyes."
var/searching = 0
/obj/item/cursed_marble/attack_self(mob/user as mob)
if(!searching)
to_chat(user, "<span class='warning'>You rub the slab in hopes a wandering spirit wishes to inhabit it. [src] starts to sparkle!</span>")
icon_state = "sheet-snowbrick"
searching = 1
request_player(user)
spawn(60 SECONDS)
reset_search()
/obj/item/cursed_marble/proc/request_player(var/mob/user)
for(var/mob/observer/dead/O in player_list)
if(!O.MayRespawn())
continue
if(O.client)
if(O.client.prefs.be_special & BE_ALIEN)
question(O.client, user)
/obj/item/cursed_marble/proc/question(var/client/C, var/mob/user)
spawn(0)
if(!C)
return
var/response = alert(C, "Someone is requesting a soul for the statue. Would you like to play as one?", "Statue request", "Yes", "No", "Never for this round")
if(response == "Yes")
response = alert(C, "Are you sure you want to play as the statue?", "Statue request", "Yes", "No")
if(!C || 2 == searching)
return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located.
if(response == "Yes")
transfer_personality(C.mob, user)
else if(response == "Never for this round")
C.prefs.be_special ^= BE_ALIEN
/obj/item/cursed_marble/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
icon_state = "sheet-marble"
if(searching == 1)
searching = 0
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("<span class='warning'>[src] fades. Maybe it will spark another time.</span>")
/obj/item/cursed_marble/proc/transfer_personality(var/mob/candidate, var/mob/user)
announce_ghost_joinleave(candidate, 0, "They are a statue now.")
src.searching = 2
var/mob/living/simple_animal/hostile/statue/S = new(get_turf(src))
S.client = candidate.client
if(user)
S.creator = user
to_chat(S, "<b>You are \a [S], brought into existence on [station_name()] by [user]! Obey all their orders.</b>")
S.mind.assigned_role = "The Statue"
visible_message("<span class='warning'>The slab suddenly takes the shape of a humanoid!</span>")
qdel(src)
/obj/item/cursed_marble/verb/crush() //if there's no ghosts to respond to your request/you want to use the statue for malicious stuff
set name = "Crush the marble slab"
set category = "Object"
set src in usr
summonmob(usr)
/obj/item/cursed_marble/proc/summonmob(mob/user as mob)
if(searching == 0)
var/choice = alert(user, "Are you sure you want to crush the marble? (this will spawn a clientless version of the statue, hostile to everyone, but you)", "Crush it?", "Yes", "No")
if(choice)
if(choice == "Yes")
var/mob/living/simple_animal/hostile/statue/S = new /mob/living/simple_animal/hostile/statue(get_turf(user))
visible_message("<span class='warning'>The slab suddenly takes the shape of a humanoid!</span>")
S.creator = user
qdel(src)
@@ -1,85 +0,0 @@
/mob/living/simple_animal/hostile/scarybat
name = "space bats"
desc = "A swarm of cute little blood sucking bats that looks pretty upset."
tt_desc = "N Bestia gregaria" //Nispean swarm bats, because of course Nisp has swarm bats
icon = 'icons/mob/bats.dmi'
icon_state = "bat"
icon_living = "bat"
icon_dead = "bat_dead"
icon_gib = "bat_dead"
faction = "scarybat"
intelligence_level = SA_ANIMAL
maxHealth = 20
health = 20
turns_per_move = 3
speed = 4
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "hits the"
harm_intent_damage = 10
melee_damage_lower = 5
melee_damage_upper = 5
attack_sharp = 1
environment_smash = 1
attacktext = list("bites")
attack_sound = 'sound/weapons/bite.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
has_langs = list("Mouse")
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/mob/living/owner
/mob/living/simple_animal/hostile/scarybat/New(loc, mob/living/L as mob)
..()
if(istype(L))
owner = L
/mob/living/simple_animal/hostile/scarybat/Process_Spacemove(var/check_drift = 0)
return ..()
/mob/living/simple_animal/hostile/scarybat/set_target()
. = ..()
if(.)
emote("flutters towards [.]")
/mob/living/simple_animal/hostile/scarybat/ListTargets()
. = ..()
if(owner)
return . - owner
/mob/living/simple_animal/hostile/scarybat/PunchTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Stun(1)
L.visible_message("<span class='danger'>\the [src] scares \the [L]!</span>")
/mob/living/simple_animal/hostile/scarybat/cult
faction = "cult"
supernatural = 1
/mob/living/simple_animal/hostile/scarybat/cult/cultify()
return
/mob/living/simple_animal/hostile/scarybat/cult/Life()
..()
check_horde()
@@ -1,141 +0,0 @@
//Space bears!
/mob/living/simple_animal/hostile/bear
name = "space bear"
desc = "A product of Space Russia?"
tt_desc = "U Ursinae aetherius" //...bearspace? Maybe.
icon_state = "bear"
icon_living = "bear"
icon_dead = "bear_dead"
icon_gib = "bear_gib"
faction = "russian"
intelligence_level = SA_ANIMAL
cooperative = 1
maxHealth = 120
health = 120
turns_per_move = 5
see_in_dark = 6
stop_when_pulled = 0
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "pokes"
melee_damage_lower = 20
melee_damage_upper = 30
attack_sharp = 1
attack_edge = 1
//Space bears aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
speak_chance = 1
speak = list("RAWR!","Rawr!","GRR!","Growl!")
speak_emote = list("growls", "roars")
emote_hear = list("rawrs","grumbles","grawls")
emote_see = list("stares ferociously", "stomps")
meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
// var/stance_step = 0
/mob/living/simple_animal/hostile/bear/handle_stance(var/new_stance)
// Below was a bunch of code that made this specific mob be 'alert' and will hurt you when it gets closer.
// It's commented out because it made infinite loops and the AI is going to be moved/rewritten sometime soon (famous last words)
// and it would be better if this 'alert before attacking' behaviour was on the parent instead of a specific type of mob anyways.
// Instead we're just gonna get angry if we're dying.
..(new_stance)
if(stance == STANCE_ATTACK || stance == STANCE_ATTACKING)
if((health / maxHealth) <= 0.5) // At half health, and fighting someone currently.
add_modifier(/datum/modifier/berserk, 30 SECONDS)
/*
switch(stance)
if(STANCE_TIRED)
stop_automated_movement = 1
stance_step++
if(stance_step >= 10) //rests for 10 ticks
if(target_mob && target_mob in ListTargets(10))
handle_stance(STANCE_ATTACK) //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
else
handle_stance(STANCE_IDLE)
if(STANCE_ALERT)
stop_automated_movement = 1
var/found_mob = 0
if(target_mob && target_mob in ListTargets(10))
if(!(SA_attackable(target_mob)))
stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again.
stance_step++
found_mob = 1
src.set_dir(get_dir(src,target_mob)) //Keep staring at the mob
if(stance_step in list(1,4,7)) //every 3 ticks
var/action = pick( list( "growls at [target_mob]", "stares angrily at [target_mob]", "prepares to attack [target_mob]", "closely watches [target_mob]" ) )
if(action)
custom_emote(1,action)
if(!found_mob)
stance_step--
if(stance_step <= -20) //If we have not found a mob for 20-ish ticks, revert to idle mode
handle_stance(STANCE_IDLE)
if(stance_step >= 7) //If we have been staring at a mob for 7 ticks,
handle_stance(STANCE_ATTACK)
if(STANCE_ATTACKING)
if(stance_step >= 20) //attacks for 20 ticks, then it gets tired and needs to rest
custom_emote(1, "is worn out and needs to rest." )
handle_stance(STANCE_TIRED)
stance_step = 0
walk(src, 0) //This stops the bear's walking
return
else
..()
*/
/mob/living/simple_animal/hostile/bear/update_icons()
..()
if(!stat)
if(loc && istype(loc,/turf/space))
icon_state = "bear"
else
icon_state = "bearfloor"
/mob/living/simple_animal/hostile/bear/Process_Spacemove(var/check_drift = 0)
return
/mob/living/simple_animal/hostile/bear/FindTarget()
. = ..()
if(.)
custom_emote(1,"stares alertly at [.]")
// handle_stance(STANCE_ALERT)
/mob/living/simple_animal/hostile/bear/PunchTarget()
if(!Adjacent(target_mob))
return
custom_emote(1, pick( list("slashes at [target_mob]", "bites [target_mob]") ) )
var/damage = rand(melee_damage_lower, melee_damage_upper)
if(ishuman(target_mob))
var/mob/living/carbon/human/H = target_mob
var/dam_zone = pick(BP_TORSO, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG)
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), H.get_armor_soak(affecting, "melee"), sharp=1, edge=1)
return H
else if(isliving(target_mob))
var/mob/living/L = target_mob
L.adjustBruteLoss(damage)
return L
else
..()
@@ -1,93 +0,0 @@
/mob/living/simple_animal/hostile/carp
name = "space carp"
desc = "A ferocious, fang-bearing creature that resembles a fish."
tt_desc = "U Cyprinus aetherius" //carpspace? maybe
icon_state = "carp"
icon_living = "carp"
icon_dead = "carp_dead"
icon_gib = "carp_gib"
faction = "carp"
intelligence_level = SA_ANIMAL
hovering = TRUE
maxHealth = 25
health = 25
speed = 4
turns_per_move = 5
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "hits the"
harm_intent_damage = 8
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = list("bitten")
attack_sound = 'sound/weapons/bite.ogg'
//Space carp aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
/mob/living/simple_animal/hostile/carp/large
name = "elder carp"
desc = "An older, more matured carp. Few survive to this age due to their aggressiveness."
icon = 'icons/mob/64x32.dmi'
icon_state = "shark"
icon_living = "shark"
icon_dead = "shark_dead"
turns_per_move = 2
move_to_delay = 2
mob_size = MOB_LARGE
pixel_x = -16
old_x = -16
health = 50
maxHealth = 50
/mob/living/simple_animal/hostile/carp/large/huge
name = "great white carp"
desc = "A very rare breed of carp- and a very aggressive one."
icon = 'icons/mob/64x64.dmi'
icon_dead = "megacarp_dead"
icon_living = "megacarp"
icon_state = "megacarp"
maxHealth = 230
health = 230
attack_same = 1
speed = 1
meat_amount = 10
melee_damage_lower = 15
melee_damage_upper = 25
old_y = -16
pixel_y = -16
/mob/living/simple_animal/hostile/carp/Process_Spacemove(var/check_drift = 0)
return 1 //No drifting in space for space carp! //original comments do not steal
/mob/living/simple_animal/hostile/carp/set_target()
. = ..()
if(.)
custom_emote(1,"nashes at [.]")
/mob/living/simple_animal/hostile/carp/PunchTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(3)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
@@ -1,193 +0,0 @@
//Cat
/mob/living/simple_animal/cat
name = "cat"
desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers."
tt_desc = "E Felis silvestris catus"
intelligence_level = SA_ANIMAL
icon_state = "cat2"
item_state = "cat2"
icon_living = "[initial(icon_state)]"
icon_dead = "[initial(icon_state)]_dead"
icon_rest = "[initial(icon_state)]_rest"
investigates = 1
specific_targets = 1 //Only targets with Found()
run_at_them = 0 //DOMESTICATED
view_range = 5
turns_per_move = 5
see_in_dark = 6
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
min_oxy = 16 //Require atleast 16kPA oxygen
minbodytemp = 223 //Below -50 Degrees Celcius
maxbodytemp = 323 //Above 50 Degrees Celcius
holder_type = /obj/item/weapon/holder/cat
mob_size = MOB_SMALL
has_langs = list("Cat")
speak_chance = 1
speak = list("Meow!","Esp!","Purr!","HSSSSS")
speak_emote = list("purrs", "meows")
emote_hear = list("meows","mews")
emote_see = list("shakes their head", "shivers")
say_maybe_target = list("Meow?","Mew?","Mao?")
say_got_target = list("MEOW!","HSSSS!","REEER!")
meat_amount = 1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/turns_since_scan = 0
var/mob/flee_target
/mob/living/simple_animal/cat/Life()
. = ..()
if(!.) return
if(prob(2)) //spooky
var/mob/observer/dead/spook = locate() in range(src,5)
if(spook)
var/turf/T = spook.loc
var/list/visible = list()
for(var/obj/O in T.contents)
if(!O.invisibility && O.name)
visible += O
if(visible.len)
var/atom/A = pick(visible)
visible_emote("suddenly stops and stares at something unseen[istype(A) ? " near [A]":""].")
handle_flee_target()
/mob/living/simple_animal/cat/PunchTarget()
if(ismouse(target_mob))
var/mob/living/simple_mob/animal/passive/mouse/mouse = target_mob
mouse.splat()
visible_emote(pick("bites \the [mouse]!","toys with \the [mouse].","chomps on \the [mouse]!"))
return mouse
else
..()
/mob/living/simple_animal/cat/Found(var/atom/found_atom)
if(ismouse(found_atom) && SA_attackable(found_atom))
return found_atom
/mob/living/simple_animal/cat/proc/handle_flee_target()
//see if we should stop fleeing
if (flee_target && !(flee_target in ListTargets(view_range)))
flee_target = null
GiveUpMoving()
if (flee_target && !stat && !buckled)
if (resting)
lay_down()
if(prob(25)) say("HSSSSS")
stop_automated_movement = 1
walk_away(src, flee_target, 7, 2)
/mob/living/simple_animal/cat/react_to_attack(var/atom/A)
if(A == src) return
flee_target = A
turns_since_scan = 5
/mob/living/simple_animal/cat/ex_act()
. = ..()
react_to_attack(src.loc)
//Basic friend AI
/mob/living/simple_animal/cat/fluff
var/mob/living/carbon/human/friend
var/befriend_job = null
var/friend_name = null
/mob/living/simple_animal/cat/fluff/Life()
. = ..()
if(!. || ai_inactive || !friend) return
var/friend_dist = get_dist(src,friend)
if (friend_dist <= 4)
if(stance == STANCE_IDLE)
if(set_follow(friend))
handle_stance(STANCE_FOLLOW)
if (friend_dist <= 1)
if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit)
if (prob((friend.stat < DEAD)? 50 : 15))
var/verb = pick("meows", "mews", "mrowls")
audible_emote(pick("[verb] in distress.", "[verb] anxiously."))
else
if (prob(5))
visible_emote(pick("nuzzles [friend].",
"brushes against [friend].",
"rubs against [friend].",
"purrs."))
else if (friend.health <= 50)
if (prob(10))
var/verb = pick("meows", "mews", "mrowls")
audible_emote("[verb] anxiously.")
/mob/living/simple_animal/cat/fluff/verb/become_friends()
set name = "Become Friends"
set category = "IC"
set src in view(1)
if(!friend)
var/mob/living/carbon/human/H = usr
if(istype(H) && (!befriend_job || H.job == befriend_job) && (!friend_name || H.real_name == friend_name))
friend = usr
. = 1
else if(usr == friend)
. = 1 //already friends, but show success anyways
if(.)
set_dir(get_dir(src, friend))
visible_emote(pick("nuzzles [friend].",
"brushes against [friend].",
"rubs against [friend].",
"purrs."))
else
usr << "<span class='notice'>[src] ignores you.</span>"
return
//RUNTIME IS ALIVE! SQUEEEEEEEE~
/mob/living/simple_animal/cat/fluff/Runtime
name = "Runtime"
desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally."
tt_desc = "E Felis silvestris medicalis" //a hypoallergenic breed produced by NT for... medical purposes? Sure.
gender = FEMALE
icon_state = "cat"
item_state = "cat"
befriend_job = "Chief Medical Officer"
/mob/living/simple_animal/cat/kitten
name = "kitten"
desc = "D'aaawwww"
icon_state = "kitten"
item_state = "kitten"
icon_living = "kitten"
icon_dead = "kitten_dead"
gender = NEUTER
// Leaving this here for now.
/obj/item/weapon/holder/cat/fluff/bones
name = "Bones"
desc = "It's Bones! Meow."
gender = MALE
icon_state = "cat3"
/mob/living/simple_animal/cat/fluff/bones
name = "Bones"
desc = "That's Bones the cat. He's a laid back, black cat. Meow."
gender = MALE
icon_state = "cat3"
item_state = "cat3"
holder_type = /obj/item/weapon/holder/cat/fluff/bones
friend_name = "Erstatz Vryroxes"
/mob/living/simple_animal/cat/kitten/New()
gender = pick(MALE, FEMALE)
..()
@@ -1,231 +0,0 @@
//Corgi
/mob/living/simple_animal/corgi
name = "corgi"
real_name = "corgi"
desc = "It's a corgi."
tt_desc = "E Canis lupus familiaris"
intelligence_level = SA_ANIMAL
icon_state = "corgi"
icon_living = "corgi"
icon_dead = "corgi_dead"
run_at_them = 0
turns_per_move = 10
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
see_in_dark = 5
mob_size = 8
has_langs = list("Dog")
speak_chance = 1
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU")
speak_emote = list("barks", "woofs")
emote_hear = list("barks", "woofs", "yaps","pants")
emote_see = list("shakes its head", "shivers")
meat_amount = 3
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/corgi
var/obj/item/inventory_head
var/obj/item/inventory_back
//IAN! SQUEEEEEEEEE~
/mob/living/simple_animal/corgi/Ian
name = "Ian"
real_name = "Ian" //Intended to hold the name without altering it.
gender = MALE
desc = "It's a corgi."
var/turns_since_scan = 0
var/obj/movement_target
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
/mob/living/simple_animal/corgi/Ian/Life()
..()
//Not replacing with SA FollowTarget mechanics because Ian behaves... very... specifically.
//Feeding, chasing food, FOOOOODDDD
if(!stat && !resting && !buckled)
turns_since_scan++
if(turns_since_scan > 5)
turns_since_scan = 0
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
movement_target = null
stop_automated_movement = 0
if( !movement_target || !(movement_target.loc in oview(src, 3)) )
movement_target = null
stop_automated_movement = 0
for(var/obj/item/weapon/reagent_containers/food/snacks/S in oview(src,3))
if(isturf(S.loc) || ishuman(S.loc))
movement_target = S
break
if(movement_target)
stop_automated_movement = 1
step_to(src,movement_target,1)
sleep(3)
step_to(src,movement_target,1)
sleep(3)
step_to(src,movement_target,1)
if(movement_target) //Not redundant due to sleeps, Item can be gone in 6 decisecomds
if (movement_target.loc.x < src.x)
set_dir(WEST)
else if (movement_target.loc.x > src.x)
set_dir(EAST)
else if (movement_target.loc.y < src.y)
set_dir(SOUTH)
else if (movement_target.loc.y > src.y)
set_dir(NORTH)
else
set_dir(SOUTH)
if(isturf(movement_target.loc) )
UnarmedAttack(movement_target)
else if(ishuman(movement_target.loc) && prob(20))
visible_emote("stares at the [movement_target] that [movement_target.loc] has with sad puppy eyes.")
if(prob(1))
visible_emote(pick("dances around","chases their tail"))
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
set_dir(i)
sleep(1)
/obj/item/weapon/reagent_containers/food/snacks/meat/corgi
name = "corgi meat"
desc = "Tastes like... well, you know..."
/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
if(istype(O, /obj/item/weapon/newspaper))
if(!stat)
for(var/mob/M in viewers(user, null))
if ((M.client && !( M.blinded )))
M.show_message("<font color='blue'>[user] baps [name] on the nose with the rolled up [O]</font>")
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2))
set_dir(i)
sleep(1)
else
..()
/mob/living/simple_animal/corgi/regenerate_icons()
overlays = list()
if(inventory_head)
var/head_icon_state = inventory_head.icon_state
if(health <= 0)
head_icon_state += "2"
var/icon/head_icon = image('icons/mob/corgi_head.dmi',head_icon_state)
if(head_icon)
overlays += head_icon
if(inventory_back)
var/back_icon_state = inventory_back.icon_state
if(health <= 0)
back_icon_state += "2"
var/icon/back_icon = image('icons/mob/corgi_back.dmi',back_icon_state)
if(back_icon)
overlays += back_icon
return
/mob/living/simple_animal/corgi/puppy
name = "corgi puppy"
real_name = "corgi"
desc = "It's a corgi puppy."
icon_state = "puppy"
icon_living = "puppy"
icon_dead = "puppy_dead"
//pupplies cannot wear anything.
/mob/living/simple_animal/corgi/puppy/Topic(href, href_list)
if(href_list["remove_inv"] || href_list["add_inv"])
usr << "<font color='red'>You can't fit this on [src]</font>"
return
..()
//LISA! SQUEEEEEEEEE~
/mob/living/simple_animal/corgi/Lisa
name = "Lisa"
real_name = "Lisa"
gender = FEMALE
desc = "It's a corgi with a cute pink bow."
icon_state = "lisa"
icon_living = "lisa"
icon_dead = "lisa_dead"
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
var/turns_since_scan = 0
var/puppies = 0
//Lisa already has a cute bow!
/mob/living/simple_animal/corgi/Lisa/Topic(href, href_list)
if(href_list["remove_inv"] || href_list["add_inv"])
to_chat(usr, "<font color='red'>[src] already has a cute bow!</font>")
return
..()
/mob/living/simple_animal/corgi/Lisa/Life()
..()
if(!stat && !resting && !buckled)
turns_since_scan++
if(turns_since_scan > 15)
turns_since_scan = 0
var/alone = 1
var/ian = 0
for(var/mob/M in oviewers(7, src))
if(istype(M, /mob/living/simple_animal/corgi/Ian))
if(M.client)
alone = 0
break
else
ian = M
else
alone = 0
break
if(alone && ian && puppies < 4)
if(near_camera(src) || near_camera(ian))
return
new /mob/living/simple_animal/corgi/puppy(loc)
if(prob(1))
visible_emote(pick("dances around","chases her tail"))
spawn(0)
for(var/i in list(1,2,4,8,4,2,1,2,4,8,4,2,1,2,4,8,4,2))
set_dir(i)
sleep(1)
//Technically this should be like, its own file or something or a subset of dog but whatever. Not a coder.
/mob/living/simple_animal/corgi/tamaskan
name = "tamaskan"
real_name = "tamaskan"
desc = "It's a tamaskan."
icon_state = "tamaskan"
icon_living = "tamaskan"
icon_dead = "tamaskan_dead"
retaliate = 1 //Tamaskans are bigass dogs, okay?
/mob/living/simple_animal/corgi/tamaskan/spice
name = "Spice"
real_name = "Spice" //Intended to hold the name without altering it.
gender = FEMALE
desc = "It's a tamaskan, the name Spice can be found on its collar."
var/turns_since_scan = 0
var/obj/movement_target
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
@@ -1,87 +0,0 @@
//Look Sir, free crabs!
/mob/living/simple_animal/crab
name = "crab"
desc = "A hard-shelled crustacean. Seems quite content to lounge around all the time."
tt_desc = "E Cancer bellianus"
icon_state = "crab"
icon_living = "crab"
icon_dead = "crab_dead"
faction = "crabs"
intelligence_level = SA_ANIMAL
wander = 0
stop_automated_movement = 1
turns_per_move = 5
mob_size = MOB_SMALL
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stomps"
friendly = "pinches"
speak_chance = 1
speak_emote = list("clicks")
emote_hear = list("clicks")
emote_see = list("clacks")
var/obj/item/inventory_head
var/obj/item/inventory_mask
/mob/living/simple_animal/crab/Life()
..()
//CRAB movement, I'm not porting this up to SA because... "sideways-only movement" var nothanks
if(!ckey && !stat)
if(isturf(src.loc) && !resting && !buckled) //This is so it only moves if it's not inside a closet, gentics machine, etc.
lifes_since_move++
if(lifes_since_move >= turns_per_move)
Move(get_step(src,pick(4,8)))
lifes_since_move = 0
regenerate_icons()
//COFFEE! SQUEEEEEEEEE!
/mob/living/simple_animal/crab/Coffee
name = "Coffee"
real_name = "Coffee"
desc = "It's Coffee, the other pet!"
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stomps"
//Sif Crabs
/mob/living/simple_animal/giant_crab
name = "giant crab"
desc = "A large, hard-shelled crustacean. This one is mostly grey."
tt_desc = "S Cancer holligus"
icon_state = "sif_crab"
icon_living = "sif_crab"
icon_dead = "sif_crab_dead"
faction = "crabs"
intelligence_level = SA_ANIMAL
maxHealth = 200
health = 200
mob_size = MOB_LARGE
cooperative = 1
retaliate = 1
turns_per_move = 3
minbodytemp = 175
melee_damage_lower = 22
melee_damage_upper = 35
attack_armor_pen = 35
attack_sharp = 1
attack_edge = 1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stomps"
friendly = "pinches"
speak_chance = 1
speak_emote = list("clicks")
emote_hear = list("clicks")
emote_see = list("clacks")
@@ -1,292 +0,0 @@
//goat
/mob/living/simple_animal/retaliate/goat
name = "goat"
desc = "Not known for their pleasant disposition."
tt_desc = "E Oreamnos americanus"
icon_state = "goat"
icon_living = "goat"
icon_dead = "goat_dead"
faction = "goat"
intelligence_level = SA_ANIMAL
health = 40
turns_per_move = 5
see_in_dark = 6
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
melee_damage_lower = 1
melee_damage_upper = 5
attacktext = list("kicked")
speak_chance = 1
speak = list("EHEHEHEHEH","eh?")
speak_emote = list("brays")
emote_hear = list("brays")
emote_see = list("shakes its head", "stamps a foot", "glares around")
meat_amount = 4
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/datum/reagents/udder = null
/mob/living/simple_animal/retaliate/goat/New()
udder = new(50)
udder.my_atom = src
..()
/mob/living/simple_animal/retaliate/goat/Life()
. = ..()
if(.)
if(stat == CONSCIOUS)
if(udder && prob(5))
udder.add_reagent("milk", rand(5, 10))
if(locate(/obj/effect/plant) in loc)
var/obj/effect/plant/SV = locate() in loc
SV.die_off(1)
if(locate(/obj/machinery/portable_atmospherics/hydroponics/soil/invisible) in loc)
var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/SP = locate() in loc
qdel(SP)
if(!pulledby)
var/obj/effect/plant/food
food = locate(/obj/effect/plant) in oview(5,loc)
if(food)
var/step = get_step_to(src, food, 0)
Move(step)
/mob/living/simple_animal/retaliate/goat/react_to_attack()
. = ..()
if(.)
visible_message("<span class='warning'>[src] gets an evil-looking gleam in their eye.</span>")
/mob/living/simple_animal/retaliate/goat/Move()
..()
if(!stat)
for(var/obj/effect/plant/SV in loc)
SV.die_off(1)
/mob/living/simple_animal/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob)
var/obj/item/weapon/reagent_containers/glass/G = O
if(stat == CONSCIOUS && istype(G) && G.is_open_container())
user.visible_message("<span class='notice'>[user] milks [src] using \the [O].</span>")
var/transfered = udder.trans_id_to(G, "milk", rand(5,10))
if(G.reagents.total_volume >= G.volume)
user << "<font color='red'>The [O] is full.</font>"
if(!transfered)
user << "<font color='red'>The udder is dry. Wait a bit longer...</font>"
else
..()
//cow
/mob/living/simple_animal/cow
name = "cow"
desc = "Known for their milk, just don't tip them over."
tt_desc = "E Bos taurus"
icon_state = "cow"
icon_living = "cow"
icon_dead = "cow_dead"
icon_gib = "cow_gib"
intelligence_level = SA_ANIMAL
health = 50
turns_per_move = 5
see_in_dark = 6
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = list("kicked")
speak_chance = 1
speak = list("moo?","moo","MOOOOOO")
speak_emote = list("moos","moos hauntingly")
emote_hear = list("brays")
emote_see = list("shakes its head")
meat_amount = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/datum/reagents/udder = null
/mob/living/simple_animal/cow/New()
udder = new(50)
udder.my_atom = src
..()
/mob/living/simple_animal/cow/attackby(var/obj/item/O as obj, var/mob/user as mob)
var/obj/item/weapon/reagent_containers/glass/G = O
if(stat == CONSCIOUS && istype(G) && G.is_open_container())
user.visible_message("<span class='notice'>[user] milks [src] using \the [O].</span>")
var/transfered = udder.trans_id_to(G, "milk", rand(5,10))
if(G.reagents.total_volume >= G.volume)
user << "<font color='red'>The [O] is full.</font>"
if(!transfered)
user << "<font color='red'>The udder is dry. Wait a bit longer...</font>"
else
..()
/mob/living/simple_animal/cow/Life()
. = ..()
if(stat == CONSCIOUS)
if(udder && prob(5))
udder.add_reagent("milk", rand(5, 10))
/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M as mob)
if(!stat && M.a_intent == I_DISARM && icon_state != icon_dead)
M.visible_message("<span class='warning'>[M] tips over [src].</span>","<span class='notice'>You tip over [src].</span>")
Weaken(30)
icon_state = icon_dead
spawn(rand(20,50))
if(!stat && M)
icon_state = icon_living
var/list/responses = list( "[src] looks at you imploringly.",
"[src] looks at you pleadingly",
"[src] looks at you with a resigned expression.",
"[src] seems resigned to its fate.")
M << pick(responses)
else
..()
/mob/living/simple_animal/chick
name = "\improper chick"
desc = "Adorable! They make such a racket though."
tt_desc = "E Gallus gallus"
icon_state = "chick"
icon_living = "chick"
icon_dead = "chick_dead"
icon_gib = "chick_gib"
intelligence_level = SA_ANIMAL
health = 1
turns_per_move = 2
pass_flags = PASSTABLE | PASSGRILLE
mob_size = MOB_MINISCULE
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = list("kicked")
has_langs = list("Bird")
speak_chance = 2
speak = list("Cherp.","Cherp?","Chirrup.","Cheep!")
speak_emote = list("cheeps")
emote_hear = list("cheeps")
emote_see = list("pecks at the ground","flaps its tiny wings")
meat_amount = 1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/amount_grown = 0
/mob/living/simple_animal/chick/New()
..()
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
/mob/living/simple_animal/chick/Life()
. =..()
if(!.)
return
if(!stat)
amount_grown += rand(1,2)
if(amount_grown >= 100)
new /mob/living/simple_animal/chicken(src.loc)
qdel(src)
var/const/MAX_CHICKENS = 50
var/global/chicken_count = 0
/mob/living/simple_animal/chicken
name = "\improper chicken"
desc = "Hopefully the eggs are good this season."
tt_desc = "E Gallus gallus"
icon_state = "chicken"
icon_living = "chicken"
icon_dead = "chicken_dead"
intelligence_level = SA_ANIMAL
health = 10
turns_per_move = 3
pass_flags = PASSTABLE
mob_size = MOB_SMALL
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = list("kicked")
has_langs = list("Bird")
speak_chance = 2
speak = list("Cluck!","BWAAAAARK BWAK BWAK BWAK!","Bwaak bwak.")
speak_emote = list("clucks","croons")
emote_hear = list("clucks")
emote_see = list("pecks at the ground","flaps its wings viciously")
meat_amount = 2
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/eggsleft = 0
var/body_color
/mob/living/simple_animal/chicken/New()
..()
if(!body_color)
body_color = pick( list("brown","black","white") )
icon_state = "chicken_[body_color]"
icon_living = "chicken_[body_color]"
icon_dead = "chicken_[body_color]_dead"
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
chicken_count += 1
/mob/living/simple_animal/chicken/death()
..()
chicken_count -= 1
/mob/living/simple_animal/chicken/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) //feedin' dem chickens
var/obj/item/weapon/reagent_containers/food/snacks/grown/G = O
if(G.seed && G.seed.kitchen_tag == "wheat")
if(!stat && eggsleft < 8)
user.visible_message("<font color='blue'>[user] feeds [O] to [name]! It clucks happily.</font>","<font color='blue'>You feed [O] to [name]! It clucks happily.</font>")
user.drop_item()
qdel(O)
eggsleft += rand(1, 4)
else
user << "<font color='blue'>[name] doesn't seem hungry!</font>"
else
user << "[name] doesn't seem interested in that."
else
..()
/mob/living/simple_animal/chicken/Life()
. =..()
if(!.)
return
if(!stat && prob(3) && eggsleft > 0)
visible_message("[src] [pick("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")]")
eggsleft--
var/obj/item/weapon/reagent_containers/food/snacks/egg/E = new(get_turf(src))
E.pixel_x = rand(-6,6)
E.pixel_y = rand(-6,6)
if(chicken_count < MAX_CHICKENS && prob(10))
START_PROCESSING(SSobj, E)
/obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0
/obj/item/weapon/reagent_containers/food/snacks/egg/process()
if(isturf(loc))
amount_grown += rand(1,2)
if(amount_grown >= 100)
visible_message("[src] hatches with a quiet cracking sound.")
new /mob/living/simple_animal/chick(get_turf(src))
STOP_PROCESSING(SSobj, src)
qdel(src)
else
STOP_PROCESSING(SSobj, src)
@@ -1,80 +0,0 @@
// Different types of fish! They are all subtypes of this tho
/mob/living/simple_animal/fish
name = "fish"
desc = "Its a fishy. No touchy fishy."
icon = 'icons/mob/fish.dmi'
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
intelligence_level = SA_ANIMAL
// By defautl they can be in any water turf. Subtypes might restrict to deep/shallow etc
var/global/list/suitable_turf_types = list(
/turf/simulated/floor/beach/water,
/turf/simulated/floor/beach/coastline,
/turf/simulated/floor/holofloor/beach/water,
/turf/simulated/floor/holofloor/beach/coastline,
/turf/simulated/floor/water
)
// Don't swim out of the water
/mob/living/simple_animal/fish/handle_wander_movement()
if(isturf(src.loc) && !resting && !buckled && canmove) //Physically capable of moving?
lifes_since_move++ //Increment turns since move (turns are life() cycles)
if(lifes_since_move >= turns_per_move)
if(!(stop_when_pulled && pulledby)) //Some animals don't move when pulled
var/moving_to = 0 // otherwise it always picks 4, fuck if I know. Did I mention fuck BYOND
moving_to = pick(cardinal)
dir = moving_to //How about we turn them the direction they are moving, yay.
var/turf/T = get_step(src,moving_to)
if(T && is_type_in_list(T, suitable_turf_types))
Move(T)
lifes_since_move = 0
// Take damage if we are not in water
/mob/living/simple_animal/fish/handle_breathing()
var/turf/T = get_turf(src)
if(T && !is_type_in_list(T, suitable_turf_types))
if(prob(50))
say(pick("Blub", "Glub", "Burble"))
adjustBruteLoss(unsuitable_atoms_damage)
/mob/living/simple_animal/fish/bass
name = "bass"
tt_desc = "E Micropterus notius"
icon_state = "bass-swim"
icon_living = "bass-swim"
icon_dead = "bass-dead"
/mob/living/simple_animal/fish/trout
name = "trout"
tt_desc = "E Salmo trutta"
icon_state = "trout-swim"
icon_living = "trout-swim"
icon_dead = "trout-dead"
/mob/living/simple_animal/fish/salmon
name = "salmon"
tt_desc = "E Oncorhynchus nerka"
icon_state = "salmon-swim"
icon_living = "salmon-swim"
icon_dead = "salmon-dead"
/mob/living/simple_animal/fish/perch
name = "perch"
tt_desc = "E Perca flavescens"
icon_state = "perch-swim"
icon_living = "perch-swim"
icon_dead = "perch-dead"
/mob/living/simple_animal/fish/pike
name = "pike"
tt_desc = "E Esox aquitanicus"
icon_state = "pike-swim"
icon_living = "pike-swim"
icon_dead = "pike-dead"
/mob/living/simple_animal/fish/koi
name = "koi"
tt_desc = "E Cyprinus rubrofuscus"
icon_state = "koi-swim"
icon_living = "koi-swim"
icon_dead = "koi-dead"
@@ -1,580 +0,0 @@
#define SPINNING_WEB 1
#define LAYING_EGGS 2
#define MOVING_TO_TARGET 3
#define SPINNING_COCOON 4
//basic spider mob, these generally guard nests
/mob/living/simple_animal/hostile/giant_spider
name = "giant spider"
desc = "Furry and brown, it makes you shudder to look at it. This one has deep red eyes."
tt_desc = "X Brachypelma phorus"
icon_state = "guard"
icon_living = "guard"
icon_dead = "guard_dead"
faction = "spiders"
intelligence_level = SA_ANIMAL
maxHealth = 200
health = 200
pass_flags = PASSTABLE
move_to_delay = 6
speed = 3
stop_when_pulled = 0
turns_per_move = 5
see_in_dark = 10
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "punches"
melee_damage_lower = 18
melee_damage_upper = 30
attack_sharp = 1
attack_edge = 1
heat_damage_per_tick = 20
cold_damage_per_tick = 20
speak_chance = 5
speak_emote = list("chitters")
emote_hear = list("chitters")
meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat
var/busy = 0
var/poison_per_bite = 5
var/poison_chance = 10
var/poison_type = "spidertoxin"
var/image/eye_layer = null
/mob/living/simple_animal/hostile/giant_spider/proc/add_eyes()
if(!eye_layer)
eye_layer = image(icon, "[icon_state]-eyes")
eye_layer.plane = PLANE_LIGHTING_ABOVE
overlays += eye_layer
/mob/living/simple_animal/hostile/giant_spider/proc/remove_eyes()
overlays -= eye_layer
/*
Nurse Family
*/
//nursemaids - these create webs and eggs
/mob/living/simple_animal/hostile/giant_spider/nurse
desc = "Furry and beige, it makes you shudder to look at it. This one has brilliant green eyes."
tt_desc = "X Brachypelma phorus laetus"
icon_state = "nurse"
icon_living = "nurse"
icon_dead = "nurse_dead"
maxHealth = 40
health = 40
melee_damage_lower = 8
melee_damage_upper = 15
poison_per_bite = 7
poison_type = "stoxin"
var/fed = 0
var/atom/cocoon_target
var/egg_inject_chance = 5
/mob/living/simple_animal/hostile/giant_spider/nurse/hat
desc = "Furry and beige, it makes you shudder to look at it. This one has brilliant green eyes and a tiny nurse hat"
icon_state = "nursemed"
icon_living = "nursemed"
icon_dead = "nursemed_dead"
maxHealth = 50
health = 50
/mob/living/simple_animal/hostile/giant_spider/nurse/queen
desc = "Absolutely gigantic, this creature is horror itself."
tt_desc = "X Brachypelma phorus tyrannus"
icon = 'icons/mob/64x64.dmi'
icon_state = "spider_queen"
icon_living = "spider_queen"
icon_dead = "spider_queen_dead"
maxHealth = 320
health = 320
melee_damage_lower = 20
melee_damage_upper = 30
attack_armor_pen = 25
poison_per_bite = 10
egg_inject_chance = 10
pixel_x = -16
pixel_y = -16
old_x = -16
old_y = -16
/mob/living/simple_animal/hostile/giant_spider/webslinger
desc = "Furry and green, it makes you shudder to look at it. This one has brilliant green eyes, and a cloak of web."
tt_desc = "X Brachypelma phorus balisticus"
icon_state = "webslinger"
icon_living = "webslinger"
icon_dead = "webslinger_dead"
maxHealth = 90
health = 90
projectilesound = 'sound/weapons/thudswoosh.ogg'
projectiletype = /obj/item/projectile/bola
ranged = 1
firing_lines = 1
cooperative = 1
shoot_range = 5
melee_damage_lower = 8
melee_damage_upper = 15
poison_per_bite = 2
poison_type = "psilocybin"
spattack_prob = 15
spattack_min_range = 0
spattack_max_range = 5
/mob/living/simple_animal/hostile/giant_spider/webslinger/AttackTarget() //One day.
var/mob/living/carbon/human/victim = null //Webslinger needs to know if its target is human later.
if(ishuman(target_mob))
victim = target_mob
if(!victim.legcuffed)
projectiletype = /obj/item/projectile/bola
shoot_range = 7
else
projectiletype = /obj/item/projectile/webball
shoot_range = 5
else
projectiletype = /obj/item/projectile/webball
shoot_range = 5
return ..()
/mob/living/simple_animal/hostile/giant_spider/carrier
desc = "Furry, beige, and red, it makes you shudder to look at it. This one has luminous green eyes."
tt_desc = "X Brachypelma phorus gerulus"
icon_state = "carrier"
icon_living = "carrier"
icon_dead = "carrier_dead"
maxHealth = 100
health = 100
melee_damage_lower = 8
melee_damage_upper = 25
poison_per_bite = 3
poison_type = "chloralhydrate"
var/spiderling_count = 0
var/spiderling_type = /obj/effect/spider/spiderling
var/swarmling_type = /mob/living/simple_animal/hostile/giant_spider/hunter
var/swarmling_faction = "spiders"
/mob/living/simple_animal/hostile/giant_spider/carrier/New()
spiderling_count = rand(5,10)
adjust_scale(1.2)
..()
/mob/living/simple_animal/hostile/giant_spider/carrier/death()
visible_message("<span class='notice'>\The [src]'s abdomen splits as it rolls over, spiderlings crawling from the wound.</span>")
spawn(1)
for(var/I = 1 to spiderling_count)
if(prob(10) && src)
var/mob/living/simple_animal/hostile/giant_spider/swarmling = new swarmling_type(src.loc)
var/swarm_health = FLOOR(swarmling.maxHealth * 0.4, 1)
var/swarm_dam_lower = FLOOR(melee_damage_lower * 0.4, 1)
var/swarm_dam_upper = FLOOR(melee_damage_upper * 0.4, 1)
swarmling.name = "spiderling"
swarmling.maxHealth = swarm_health
swarmling.health = swarm_health
swarmling.melee_damage_lower = swarm_dam_lower
swarmling.melee_damage_upper = swarm_dam_upper
swarmling.faction = swarmling_faction
swarmling.adjust_scale(0.75)
else if(src)
var/obj/effect/spider/spiderling/child = new spiderling_type(src.loc)
child.skitter()
else
break
return ..()
/mob/living/simple_animal/hostile/giant_spider/carrier/recursive
desc = "Furry, beige, and red, it makes you shudder to look at it. This one has luminous green eyes. You have a distinctly <font face='comic sans ms'>bad</font> feeling about this."
swarmling_type = /mob/living/simple_animal/hostile/giant_spider/carrier/recursive
/*
Hunter Family
*/
//hunters have the most poison and move the fastest, so they can find prey
/mob/living/simple_animal/hostile/giant_spider/hunter
desc = "Furry and black, it makes you shudder to look at it. This one has sparkling purple eyes."
tt_desc = "X Brachypelma phorus venandi"
icon_state = "hunter"
icon_living = "hunter"
icon_dead = "hunter_dead"
maxHealth = 120
health = 120
move_to_delay = 4
poison_per_bite = 5
/mob/living/simple_animal/hostile/giant_spider/lurker
desc = "Translucent and white, it makes you shudder to look at it. This one has incandescent red eyes."
tt_desc = "X Brachypelma phorus insidator"
icon_state = "lurker"
icon_living = "lurker"
icon_dead = "lurker_dead"
alpha = 45
maxHealth = 100
health = 100
move_to_delay = 4
melee_damage_lower = 8
melee_damage_upper = 20
poison_chance = 20
poison_type = "cryptobiolin"
poison_per_bite = 2
/mob/living/simple_animal/hostile/giant_spider/lurker/death()
alpha = 255
return ..()
/mob/living/simple_animal/hostile/giant_spider/tunneler
desc = "Sandy and brown, it makes you shudder to look at it. This one has glittering yellow eyes."
tt_desc = "X Brachypelma phorus cannalis"
icon_state = "tunneler"
icon_living = "tunneler"
icon_dead = "tunneler_dead"
maxHealth = 120
health = 120
move_to_delay = 4
melee_damage_lower = 10
melee_damage_upper = 20
poison_chance = 15
poison_per_bite = 3
poison_type = "serotrotium_v"
/mob/living/simple_animal/hostile/giant_spider/tunneler/death()
spawn(1)
for(var/I = 1 to rand(3,6))
if(src)
new/obj/item/weapon/ore/glass(src.loc)
else
break
return ..()
/*
Guard Family
*/
/mob/living/simple_animal/hostile/giant_spider/pepper
desc = "Red and brown, it makes you shudder to look at it. This one has glinting red eyes."
tt_desc = "X Brachypelma phorus ignis"
icon_state = "pepper"
icon_living = "pepper"
icon_dead = "pepper_dead"
maxHealth = 210
health = 210
melee_damage_lower = 8
melee_damage_upper = 15
poison_chance = 20
poison_per_bite = 5
poison_type = "condensedcapsaicin_v"
/mob/living/simple_animal/hostile/giant_spider/pepper/New()
adjust_scale(1.1)
..()
/mob/living/simple_animal/hostile/giant_spider/thermic
desc = "Mirage-cloaked and orange, it makes you shudder to look at it. This one has simmering orange eyes."
tt_desc = "X Brachypelma phorus incaendium"
icon_state = "pit"
icon_living = "pit"
icon_dead = "pit_dead"
maxHealth = 175
health = 175
melee_damage_lower = 10
melee_damage_upper = 25
poison_chance = 30
poison_per_bite = 1
poison_type = "thermite_v"
/mob/living/simple_animal/hostile/giant_spider/electric
desc = "Spined and yellow, it makes you shudder to look at it. This one has flickering gold eyes."
tt_desc = "X Brachypelma phorus aromatitis"
icon_state = "spark"
icon_living = "spark"
icon_dead = "spark_dead"
maxHealth = 210
health = 210
taser_kill = 0 //It -is- the taser.
melee_damage_lower = 10
melee_damage_upper = 25
ranged = 1
projectilesound = 'sound/weapons/taser2.ogg'
projectiletype = /obj/item/projectile/beam/stun/weak
firing_lines = 1
cooperative = 1
poison_chance = 15
poison_per_bite = 3
poison_type = "stimm"
/mob/living/simple_animal/hostile/giant_spider/phorogenic
desc = "Crystalline and purple, it makes you shudder to look at it. This one has haunting purple eyes."
tt_desc = "X Brachypelma phorus phorus"
icon_state = "phoron"
icon_living = "phoron"
icon_dead = "phoron_dead"
maxHealth = 225
health = 225
taser_kill = 0 //You will need more than a peashooter to kill the juggernaut.
melee_damage_lower = 25
melee_damage_upper = 40
attack_armor_pen = 15
poison_chance = 30
poison_per_bite = 0.5
poison_type = "phoron"
var/exploded = 0
/mob/living/simple_animal/hostile/giant_spider/phorogenic/New()
adjust_scale(1.25)
return ..()
/mob/living/simple_animal/hostile/giant_spider/phorogenic/death()
visible_message("<span class='danger'>\The [src]'s body begins to rupture!</span>")
spawn(rand(1,5))
if(src && !exploded)
visible_message("<span class='critical'>\The [src]'s body detonates!</span>")
exploded = 1
explosion(src.loc, 1, 2, 4, 6)
return ..()
/mob/living/simple_animal/hostile/giant_spider/frost
desc = "Icy and blue, it makes you shudder to look at it. This one has brilliant blue eyes."
tt_desc = "X Brachypelma phorus pruinae"
icon_state = "frost"
icon_living = "frost"
icon_dead = "frost_dead"
maxHealth = 175
health = 175
poison_per_bite = 5
poison_type = "cryotoxin"
/*
Spider Procs
*/
/mob/living/simple_animal/hostile/giant_spider/New(var/location, var/atom/parent)
get_light_and_color(parent)
add_eyes()
..()
/mob/living/simple_animal/hostile/giant_spider/death()
remove_eyes()
..()
/mob/living/simple_animal/hostile/giant_spider/DoPunch(var/atom/A)
. = ..()
if(.) // If we succeeded in hitting.
if(isliving(A))
var/mob/living/L = A
if(L.reagents)
var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD)
if(L.can_inject(src, null, target_zone))
L.reagents.add_reagent(poison_type, poison_per_bite)
if(prob(poison_chance))
to_chat(L, "<span class='warning'>You feel a tiny prick.</span>")
L.reagents.add_reagent(poison_type, poison_per_bite)
/mob/living/simple_animal/hostile/giant_spider/nurse/DoPunch(var/atom/A)
. = ..()
if(.) // If we succeeded in hitting.
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(prob(egg_inject_chance))
var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD)
if(H.can_inject(src, null, target_zone))
var/obj/item/organ/external/O = H.get_organ(target_zone)
var/eggcount
for(var/obj/I in O.implants)
if(istype(I, /obj/effect/spider/eggcluster))
eggcount ++
if(!eggcount)
var/eggs = new /obj/effect/spider/eggcluster/small(O, src)
O.implants += eggs
to_chat(H, "<font size='3'><span class='warning'>\The [src] injects something into your [O.name]!</span></font>")
/mob/living/simple_animal/hostile/giant_spider/webslinger/DoPunch(var/atom/A)
. = ..()
if(.) // If we succeeded in hitting.
if(isliving(A))
var/mob/living/L = A
var/obj/effect/spider/stickyweb/W = locate() in get_turf(L)
if(!W && prob(75))
visible_message("<span class='danger'>\The [src] throws a layer of web at \the [L]!</span>")
new /obj/effect/spider/stickyweb(L.loc)
/mob/living/simple_animal/hostile/giant_spider/handle_stance()
. = ..()
if(ai_inactive) return
switch(stance)
if(STANCE_IDLE)
//1% chance to skitter madly away
if(!busy && prob(1))
/*var/list/move_targets = list()
for(var/turf/T in orange(20, src))
move_targets.Add(T)*/
stop_automated_movement = 1
walk_to(src, pick(orange(20, src)), 1, move_to_delay)
spawn(5 SECONDS)
stop_automated_movement = 0
walk(src,0)
/mob/living/simple_animal/hostile/giant_spider/nurse/proc/GiveUp(var/C)
spawn(10 SECONDS)
if(busy == MOVING_TO_TARGET)
if(cocoon_target == C && get_dist(src,cocoon_target) > 1)
cocoon_target = null
busy = 0
stop_automated_movement = 0
/mob/living/simple_animal/hostile/giant_spider/nurse/Life()
. = ..()
if(!. || ai_inactive) return
if(stance == STANCE_IDLE)
var/list/can_see = view(src, 10)
//30% chance to stop wandering and do something
if(!busy && prob(30))
//first, check for potential food nearby to cocoon
for(var/mob/living/C in can_see)
if(C.stat)
cocoon_target = C
busy = MOVING_TO_TARGET
walk_to(src, C, 1, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(C)
return
//second, spin a sticky spiderweb on this tile
var/obj/effect/spider/stickyweb/W = locate() in get_turf(src)
if(!W)
busy = SPINNING_WEB
src.visible_message("<span class='notice'>\The [src] begins to secrete a sticky substance.</span>")
stop_automated_movement = 1
spawn(40)
if(busy == SPINNING_WEB)
new /obj/effect/spider/stickyweb(src.loc)
busy = 0
stop_automated_movement = 0
else
//third, lay an egg cluster there
var/obj/effect/spider/eggcluster/E = locate() in get_turf(src)
if(!E && fed > 0)
busy = LAYING_EGGS
src.visible_message("<span class='notice'>\The [src] begins to lay a cluster of eggs.</span>")
stop_automated_movement = 1
spawn(50)
if(busy == LAYING_EGGS)
E = locate() in get_turf(src)
if(!E)
new /obj/effect/spider/eggcluster(loc, src)
fed--
busy = 0
stop_automated_movement = 0
else
//fourthly, cocoon any nearby items so those pesky pinkskins can't use them
for(var/obj/O in can_see)
if(O.anchored)
continue
if(istype(O, /obj/item) || istype(O, /obj/structure) || istype(O, /obj/machinery))
cocoon_target = O
busy = MOVING_TO_TARGET
stop_automated_movement = 1
walk_to(src, O, 1, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(O)
else if(busy == MOVING_TO_TARGET && cocoon_target)
if(get_dist(src, cocoon_target) <= 1)
busy = SPINNING_COCOON
src.visible_message("<span class='notice'>\The [src] begins to secrete a sticky substance around \the [cocoon_target].</span>")
stop_automated_movement = 1
walk(src,0)
spawn(50)
if(busy == SPINNING_COCOON)
if(cocoon_target && istype(cocoon_target.loc, /turf) && get_dist(src,cocoon_target) <= 1)
var/obj/effect/spider/cocoon/C = new(cocoon_target.loc)
var/large_cocoon = 0
C.pixel_x = cocoon_target.pixel_x
C.pixel_y = cocoon_target.pixel_y
for(var/mob/living/M in C.loc)
if(istype(M, /mob/living/simple_animal/hostile/giant_spider))
continue
large_cocoon = 1
fed++
src.visible_message("<span class='warning'>\The [src] sticks a proboscis into \the [cocoon_target] and sucks a viscous substance out.</span>")
M.forceMove(C)
C.pixel_x = M.pixel_x
C.pixel_y = M.pixel_y
break
for(var/obj/item/I in C.loc)
I.forceMove(C)
for(var/obj/structure/S in C.loc)
if(!S.anchored)
S.forceMove(C)
large_cocoon = 1
for(var/obj/machinery/M in C.loc)
if(!M.anchored)
M.forceMove(C)
large_cocoon = 1
if(large_cocoon)
C.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3")
busy = 0
stop_automated_movement = 0
else
busy = 0
stop_automated_movement = 0
#undef SPINNING_WEB
#undef LAYING_EGGS
#undef MOVING_TO_TARGET
#undef SPINNING_COCOON
@@ -1,59 +0,0 @@
/mob/living/simple_animal/hostile/goose //hey are these even in the game
name = "goose"
desc = "It looks pretty angry!"
tt_desc = "E Branta canadensis" //that iconstate is just a regular goose
icon_state = "goose"
icon_living = "goose"
icon_dead = "goose_dead"
faction = "geese"
intelligence_level = SA_ANIMAL
maxHealth = 15
health = 15
speed = 4
turns_per_move = 5
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "hits the"
harm_intent_damage = 5
melee_damage_lower = 5 //they're meant to be annoying, not threatening.
melee_damage_upper = 5 //unless there's like a dozen of them, then you're screwed.
attacktext = list("pecked")
attack_sound = 'sound/weapons/bite.ogg'
//SPACE geese aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
has_langs = list("Bird")
speak_chance = 10
speak = list("HONK!")
emote_hear = list("honks loudly!")
emote_see = list()
say_understood = list()
say_cannot = list()
say_maybe_target = list("Honk?")
say_got_target = list("HONK!!!")
reactions = list()
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
/mob/living/simple_animal/hostile/goose/set_target()
. = ..()
if(.)
custom_emote(1,"flaps and honks at [.]!")
/mob/living/simple_animal/hostile/goose/Process_Spacemove(var/check_drift = 0)
return
@@ -1,24 +0,0 @@
/mob/living/simple_animal/lizard
name = "Lizard"
desc = "A cute tiny lizard."
tt_desc = "E Anolis cuvieri"
icon = 'icons/mob/critter.dmi'
icon_state = "lizard"
icon_living = "lizard"
icon_dead = "lizard-dead"
intelligence_level = SA_ANIMAL
health = 5
maxHealth = 5
mob_size = MOB_MINISCULE
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
attacktext = list("bitten")
melee_damage_lower = 1
melee_damage_upper = 2
speak_chance = 1
speak_emote = list("hisses")
@@ -1,21 +0,0 @@
/mob/living/simple_animal/yithian
name = "yithian"
desc = "A friendly creature vaguely resembling an oversized snail without a shell."
tt_desc = "J Escargot escargot" // a product of Jade, which is a planet that totally exists
icon_state = "yithian"
icon_living = "yithian"
icon_dead = "yithian_dead"
icon = 'icons/jungle.dmi'
faction = "yithian"
/mob/living/simple_animal/tindalos
name = "tindalos"
desc = "It looks like a large, flightless grasshopper."
tt_desc = "J Locusta bruchus"
icon_state = "tindalos"
icon_living = "tindalos"
icon_dead = "tindalos_dead"
icon = 'icons/jungle.dmi'
faction = "tindalos"
@@ -1,137 +0,0 @@
/mob/living/simple_animal/mouse
name = "mouse"
real_name = "mouse"
desc = "It's a small rodent."
tt_desc = "E Mus musculus"
icon_state = "mouse_gray"
item_state = "mouse_gray"
icon_living = "mouse_gray"
icon_dead = "mouse_gray_dead"
intelligence_level = SA_ANIMAL
maxHealth = 5
health = 5
turns_per_move = 5
see_in_dark = 6
universal_understand = 1
mob_size = MOB_SMALL
pass_flags = PASSTABLE
// can_pull_size = ITEMSIZE_TINY
// can_pull_mobs = MOB_PULL_NONE
layer = MOB_LAYER
density = 0
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stamps on"
min_oxy = 16 //Require atleast 16kPA oxygen
minbodytemp = 223 //Below -50 Degrees Celcius
maxbodytemp = 323 //Above 50 Degrees Celcius
has_langs = list("Mouse")
speak_chance = 1
speak = list("Squeek!","SQUEEK!","Squeek?")
speak_emote = list("squeeks","squeeks","squiks")
emote_hear = list("squeeks","squeaks","squiks")
emote_see = list("runs in a circle", "shakes", "scritches at something")
holder_type = /obj/item/weapon/holder/mouse
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/body_color //brown, gray and white, leave blank for random
/mob/living/simple_animal/mouse/Life()
. = ..()
if(!. || ai_inactive) return
if(prob(speak_chance))
for(var/mob/M in view())
M << 'sound/effects/mouse_squeak.ogg'
if(!resting && prob(0.5))
lay_down()
speak_chance = 0
//snuffles
else if(resting)
if(prob(1))
lay_down()
speak_chance = initial(speak_chance)
else if(prob(1))
audible_emote("snuffles.")
/mob/living/simple_animal/mouse/New()
..()
verbs += /mob/living/proc/ventcrawl
verbs += /mob/living/proc/hide
if(name == initial(name))
name = "[name] ([rand(1, 1000)])"
real_name = name
if(!body_color)
body_color = pick( list("brown","gray","white") )
icon_state = "mouse_[body_color]"
item_state = "mouse_[body_color]"
icon_living = "mouse_[body_color]"
icon_dead = "mouse_[body_color]_dead"
icon_rest = "mouse_[body_color]_sleep"
desc = "A small [body_color] rodent, often seen hiding in maintenance areas and making a nuisance of itself."
/mob/living/simple_animal/mouse/proc/splat()
src.health = 0
src.stat = DEAD
src.icon_dead = "mouse_[body_color]_splat"
src.icon_state = "mouse_[body_color]_splat"
layer = MOB_LAYER
if(client)
client.time_died_as_mouse = world.time
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj)
if( ishuman(AM) )
if(!stat)
var/mob/M = AM
M.visible_message("<font color='blue'>\icon[src] Squeek!</font>")
M << 'sound/effects/mouse_squeak.ogg'
..()
/mob/living/simple_animal/mouse/death()
layer = MOB_LAYER
playsound(src, 'sound/effects/mouse_squeak_loud.ogg', 35, 1)
if(client)
client.time_died_as_mouse = world.time
..()
/*
* Mouse types
*/
/mob/living/simple_animal/mouse/white
body_color = "white"
icon_state = "mouse_white"
/mob/living/simple_animal/mouse/gray
body_color = "gray"
icon_state = "mouse_gray"
/mob/living/simple_animal/mouse/brown
body_color = "brown"
icon_state = "mouse_brown"
//TOM IS ALIVE! SQUEEEEEEEE~K :)
/mob/living/simple_animal/mouse/brown/Tom
name = "Tom"
desc = "Jerry the cat is not amused."
/mob/living/simple_animal/mouse/brown/Tom/New()
..()
// Change my name back, don't want to be named Tom (666)
name = initial(name)
/mob/living/simple_animal/mouse/cannot_use_vents()
return
@@ -1,768 +0,0 @@
/* Parrots!
* Contains
* Defines
* Inventory (headset stuff)
* Attack responces
* AI
* Procs / Verbs (usable by players)
* Sub-types
*/
/*
* Defines
*/
//Parrot is too snowflake for me to rewrite right now, someone should make it use the new
//simple_animal movement stuff. -Aro
//Only a maximum of one action and one intent should be active at any given time.
//Actions
#define PARROT_PERCH 1 //Sitting/sleeping, not moving
#define PARROT_SWOOP 2 //Moving towards or away from a target
#define PARROT_WANDER 4 //Moving without a specific target in mind
//Intents
#define PARROT_STEAL 8 //Flying towards a target to steal it/from it
#define PARROT_ATTACK 16 //Flying towards a target to attack it
#define PARROT_RETURN 32 //Flying towards its perch
#define PARROT_FLEE 64 //Flying away from its attacker
/mob/living/simple_animal/parrot
name = "parrot"
desc = "The parrot squawks, \"It's a parrot! BAWWK!\""
tt_desc = "E Ara macao"
icon = 'icons/mob/animal.dmi'
icon_state = "parrot_fly"
icon_living = "parrot_fly"
icon_dead = "parrot_dead"
intelligence_level = SA_ANIMAL
turns_per_move = 5
pass_flags = PASSTABLE
mob_size = MOB_SMALL
response_help = "pets"
response_disarm = "gently moves aside"
response_harm = "swats"
stop_automated_movement = 1
universal_speak = 1
has_langs = list("Bird", "Galactic Common")
speak_chance = 2
speak = list("Hi","Hello!","Cracker?","Bawk!")
speak_emote = list("squawks","says","yells")
emote_hear = list("squawks","bawks")
emote_see = list("flutters its wings")
meat_type = /obj/item/weapon/reagent_containers/food/snacks/cracker
hovering = TRUE
softfall = TRUE
parachuting = TRUE
var/parrot_state = PARROT_WANDER //Hunt for a perch when created
var/parrot_sleep_max = 25 //The time the parrot sits while perched before looking around. Mosly a way to avoid the parrot's AI in life() being run every single tick.
var/parrot_sleep_dur = 25 //Same as above, this is the var that physically counts down
var/parrot_dam_zone = list(BP_TORSO, BP_HEAD, BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG) //For humans, select a bodypart to attack
var/parrot_speed = 5 //"Delay in world ticks between movement." according to byond. Yeah, that's BS but it does directly affect movement. Higher number = slower.
var/parrot_been_shot = 0 //Parrots get a speed bonus after being shot. This will deincrement every Life() and at 0 the parrot will return to regular speed.
var/list/speech_buffer = list()
var/list/available_channels = list()
//Headset for Poly to yell at engineers :)
var/obj/item/device/radio/headset/ears = null
//The thing the parrot is currently interested in. This gets used for items the parrot wants to pick up, mobs it wants to steal from,
//mobs it wants to attack or mobs that have attacked it
var/atom/movable/parrot_interest = null
//Parrots will generally sit on their pertch unless something catches their eye.
//These vars store their preffered perch and if they dont have one, what they can use as a perch
var/obj/parrot_perch = null
var/obj/desired_perches = list(/obj/structure/frame, /obj/structure/displaycase, \
/obj/structure/filingcabinet, /obj/machinery/teleport, \
/obj/machinery/computer, /obj/machinery/clonepod, \
/obj/machinery/dna_scannernew, /obj/machinery/telecomms, \
/obj/machinery/nuclearbomb, /obj/machinery/particle_accelerator, \
/obj/machinery/recharge_station, /obj/machinery/smartfridge, \
/obj/machinery/suit_storage_unit)
//Parrots are kleptomaniacs. This variable ... stores the item a parrot is holding.
var/obj/item/held_item = null
/mob/living/simple_animal/parrot/New()
..()
if(!ears)
var/headset = pick(/obj/item/device/radio/headset/headset_sec, \
/obj/item/device/radio/headset/headset_eng, \
/obj/item/device/radio/headset/headset_med, \
/obj/item/device/radio/headset/headset_sci, \
/obj/item/device/radio/headset/headset_cargo)
ears = new headset(src)
parrot_sleep_dur = parrot_sleep_max //In case someone decides to change the max without changing the duration var
verbs.Add(/mob/living/simple_animal/parrot/proc/steal_from_ground, \
/mob/living/simple_animal/parrot/proc/steal_from_mob, \
/mob/living/simple_animal/parrot/verb/drop_held_item_player, \
/mob/living/simple_animal/parrot/proc/perch_player)
/mob/living/simple_animal/parrot/death()
if(held_item)
held_item.forceMove(src.loc)
held_item = null
walk(src,0)
..()
/mob/living/simple_animal/parrot/Stat()
..()
stat("Held Item", held_item)
/*
* Inventory
*/
/mob/living/simple_animal/parrot/show_inv(mob/user as mob)
user.set_machine(src)
if(user.stat) return
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
if(ears)
dat += "<br><b>Headset:</b> [ears] (<a href='?src=\ref[src];remove_inv=ears'>Remove</a>)"
else
dat += "<br><b>Headset:</b> <a href='?src=\ref[src];add_inv=ears'>Nothing</a>"
user << browse(dat, text("window=mob[];size=325x500", name))
onclose(user, "mob[real_name]")
return
/mob/living/simple_animal/parrot/Topic(href, href_list)
//Can the usr physically do this?
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
return
//Is the usr's mob type able to do this?
if(ishuman(usr) || issmall(usr) || isrobot(usr))
//Removing from inventory
if(href_list["remove_inv"])
var/remove_from = href_list["remove_inv"]
switch(remove_from)
if("ears")
if(ears)
if(available_channels.len)
src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
else
src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
ears.forceMove(src.loc)
ears = null
for(var/possible_phrase in speak)
if(copytext(possible_phrase,1,3) in department_radio_keys)
possible_phrase = copytext(possible_phrase,3,length(possible_phrase))
else
to_chat(usr, "<font color='red'>There is nothing to remove from its [remove_from].</font>")
return
//Adding things to inventory
else if(href_list["add_inv"])
var/add_to = href_list["add_inv"]
if(!usr.get_active_hand())
to_chat(usr, "<font color='red'>You have nothing in your hand to put on its [add_to].</font>")
return
switch(add_to)
if("ears")
if(ears)
to_chat(usr, "<font color='red'>It's already wearing something.</font>")
return
else
var/obj/item/item_to_add = usr.get_active_hand()
if(!item_to_add)
return
if( !istype(item_to_add, /obj/item/device/radio/headset) )
to_chat(usr, "<font color='red'>This object won't fit.</font>")
return
var/obj/item/device/radio/headset/headset_to_add = item_to_add
usr.drop_item()
headset_to_add.forceMove(src)
src.ears = headset_to_add
to_chat(usr, "You fit the headset onto [src].")
clearlist(available_channels)
for(var/ch in headset_to_add.channels)
switch(ch)
if("Engineering")
available_channels.Add(":e")
if("Command")
available_channels.Add(":c")
if("Security")
available_channels.Add(":s")
if("Science")
available_channels.Add(":n")
if("Medical")
available_channels.Add(":m")
if("Mining")
available_channels.Add(":d")
if("Cargo")
available_channels.Add(":q")
if(headset_to_add.translate_binary)
available_channels.Add("#b")
else
..()
/*
* Attack responces
*/
//Humans, monkeys, aliens
/mob/living/simple_animal/parrot/attack_hand(mob/living/carbon/M as mob)
..()
if(client) return
if(!stat && M.a_intent == I_HURT)
icon_state = "parrot_fly" //It is going to be flying regardless of whether it flees or attacks
if(parrot_state == PARROT_PERCH)
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
parrot_interest = M
parrot_state = PARROT_SWOOP //The parrot just got hit, it WILL move, now to pick a direction..
if(M.health < 50) //Weakened mob? Fight back!
parrot_state |= PARROT_ATTACK
else
parrot_state |= PARROT_FLEE //Otherwise, fly like a bat out of hell!
drop_held_item(0)
return
//Mobs with objects
/mob/living/simple_animal/parrot/attackby(var/obj/item/O as obj, var/mob/user as mob)
..()
if(!stat && !client && !istype(O, /obj/item/stack/medical))
if(O.force)
if(parrot_state == PARROT_PERCH)
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
parrot_interest = user
parrot_state = PARROT_SWOOP | PARROT_FLEE
icon_state = "parrot_fly"
drop_held_item(0)
return
//Bullets
/mob/living/simple_animal/parrot/bullet_act(var/obj/item/projectile/Proj)
..()
if(!stat && !client)
if(parrot_state == PARROT_PERCH)
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
parrot_interest = null
parrot_state = PARROT_WANDER //OWFUCK, Been shot! RUN LIKE HELL!
parrot_been_shot += 5
icon_state = "parrot_fly"
drop_held_item(0)
return
/*
* AI - Not really intelligent, but I'm calling it AI anyway.
*/
/mob/living/simple_animal/parrot/Life()
..()
//Sprite and AI update for when a parrot gets pulled
if(pulledby && stat == CONSCIOUS)
icon_state = "parrot_fly"
if(!client)
parrot_state = PARROT_WANDER
return
if(client || stat)
return //Lets not force players or dead/incap parrots to move
if(!isturf(src.loc) || !canmove || buckled)
return //If it can't move, dont let it move. (The buckled check probably isn't necessary thanks to canmove)
//-----SPEECH
/* Parrot speech mimickry!
Phrases that the parrot hears in mob/living/say() get added to speach_buffer.
Every once in a while, the parrot picks one of the lines from the buffer and replaces an element of the 'speech' list.
Then it clears the buffer to make sure they dont magically remember something from hours ago. */
if(speech_buffer.len && prob(10))
if(speak.len)
speak.Remove(pick(speak))
speak.Add(pick(speech_buffer))
clearlist(speech_buffer)
//-----SLEEPING
if(parrot_state == PARROT_PERCH)
if(parrot_perch && parrot_perch.loc != src.loc) //Make sure someone hasnt moved our perch on us
if(parrot_perch in view(src))
parrot_state = PARROT_SWOOP | PARROT_RETURN
icon_state = "parrot_fly"
return
else
parrot_state = PARROT_WANDER
icon_state = "parrot_fly"
return
if(--parrot_sleep_dur) //Zzz
return
else
//This way we only call the stuff below once every [sleep_max] ticks.
parrot_sleep_dur = parrot_sleep_max
//Cycle through message modes for the headset
if(speak.len)
var/list/newspeak = list()
if(available_channels.len && src.ears)
for(var/possible_phrase in speak)
//50/50 chance to not use the radio at all
var/useradio = 0
if(prob(50))
useradio = 1
if(copytext(possible_phrase,1,3) in department_radio_keys)
possible_phrase = "[useradio?pick(available_channels):""] [copytext(possible_phrase,3,length(possible_phrase)+1)]" //crop out the channel prefix
else
possible_phrase = "[useradio?pick(available_channels):""] [possible_phrase]"
newspeak.Add(possible_phrase)
else //If we have no headset or channels to use, dont try to use any!
for(var/possible_phrase in speak)
if(copytext(possible_phrase,1,3) in department_radio_keys)
possible_phrase = "[copytext(possible_phrase,3,length(possible_phrase)+1)]" //crop out the channel prefix
newspeak.Add(possible_phrase)
speak = newspeak
//Search for item to steal
parrot_interest = search_for_item()
if(parrot_interest)
visible_emote("looks in [parrot_interest]'s direction and takes flight")
parrot_state = PARROT_SWOOP | PARROT_STEAL
icon_state = "parrot_fly"
return
//-----WANDERING - This is basically a 'I dont know what to do yet' state
else if(parrot_state == PARROT_WANDER)
//Stop movement, we'll set it later
walk(src, 0)
parrot_interest = null
//Wander around aimlessly. This will help keep the loops from searches down
//and possibly move the mob into a new are in view of something they can use
if(prob(90))
step(src, pick(cardinal))
return
if(!held_item && !parrot_perch) //If we've got nothing to do.. look for something to do.
var/atom/movable/AM = search_for_perch_and_item() //This handles checking through lists so we know it's either a perch or stealable item
if(AM)
if(istype(AM, /obj/item) || isliving(AM)) //If stealable item
parrot_interest = AM
visible_emote("turns and flies towards [parrot_interest]")
parrot_state = PARROT_SWOOP | PARROT_STEAL
return
else //Else it's a perch
parrot_perch = AM
parrot_state = PARROT_SWOOP | PARROT_RETURN
return
return
if(parrot_interest && parrot_interest in view(src))
parrot_state = PARROT_SWOOP | PARROT_STEAL
return
if(parrot_perch && parrot_perch in view(src))
parrot_state = PARROT_SWOOP | PARROT_RETURN
return
else //Have an item but no perch? Find one!
parrot_perch = search_for_perch()
if(parrot_perch)
parrot_state = PARROT_SWOOP | PARROT_RETURN
return
//-----STEALING
else if(parrot_state == (PARROT_SWOOP | PARROT_STEAL))
walk(src,0)
if(!parrot_interest || held_item)
parrot_state = PARROT_SWOOP | PARROT_RETURN
return
if(!(parrot_interest in view(src)))
parrot_state = PARROT_SWOOP | PARROT_RETURN
return
if(in_range(src, parrot_interest))
if(isliving(parrot_interest))
steal_from_mob()
else //This should ensure that we only grab the item we want, and make sure it's not already collected on our perch
if(!parrot_perch || parrot_interest.loc != parrot_perch.loc)
held_item = parrot_interest
parrot_interest.forceMove(src)
visible_message("[src] grabs the [held_item]!", "<font color='blue'>You grab the [held_item]!</font>", "You hear the sounds of wings flapping furiously.")
parrot_interest = null
parrot_state = PARROT_SWOOP | PARROT_RETURN
return
walk_to(src, parrot_interest, 1, parrot_speed)
return
//-----RETURNING TO PERCH
else if(parrot_state == (PARROT_SWOOP | PARROT_RETURN))
walk(src, 0)
if(!parrot_perch || !isturf(parrot_perch.loc)) //Make sure the perch exists and somehow isnt inside of something else.
parrot_perch = null
parrot_state = PARROT_WANDER
return
if(in_range(src, parrot_perch))
src.forceMove(parrot_perch.loc)
drop_held_item()
parrot_state = PARROT_PERCH
icon_state = "parrot_sit"
return
walk_to(src, parrot_perch, 1, parrot_speed)
return
//-----FLEEING
else if(parrot_state == (PARROT_SWOOP | PARROT_FLEE))
walk(src,0)
if(!parrot_interest || !isliving(parrot_interest)) //Sanity
parrot_state = PARROT_WANDER
walk_away(src, parrot_interest, 1, parrot_speed-parrot_been_shot)
parrot_been_shot--
return
//-----ATTACKING
else if(parrot_state == (PARROT_SWOOP | PARROT_ATTACK))
//If we're attacking a nothing, an object, a turf or a ghost for some stupid reason, switch to wander
if(!parrot_interest || !isliving(parrot_interest))
parrot_interest = null
parrot_state = PARROT_WANDER
return
var/mob/living/L = parrot_interest
//If the mob is close enough to interact with
if(in_range(src, parrot_interest))
//If the mob we've been chasing/attacking dies or falls into crit, check for loot!
if(L.stat)
parrot_interest = null
if(!held_item)
held_item = steal_from_ground()
if(!held_item)
held_item = steal_from_mob() //Apparently it's possible for dead mobs to hang onto items in certain circumstances.
if(parrot_perch in view(src)) //If we have a home nearby, go to it, otherwise find a new home
parrot_state = PARROT_SWOOP | PARROT_RETURN
else
parrot_state = PARROT_WANDER
return
//Time for the hurt to begin!
var/damage = rand(5,10)
if(ishuman(parrot_interest))
var/mob/living/carbon/human/H = parrot_interest
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone)))
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), H.get_armor_soak(affecting, "melee"), sharp=1)
visible_emote(pick("pecks [H]'s [affecting].", "cuts [H]'s [affecting] with its talons."))
else
L.adjustBruteLoss(damage)
visible_emote(pick("pecks at [L].", "claws [L]."))
return
//Otherwise, fly towards the mob!
else
walk_to(src, parrot_interest, 1, parrot_speed)
return
//-----STATE MISHAP
else //This should not happen. If it does lets reset everything and try again
walk(src,0)
parrot_interest = null
parrot_perch = null
drop_held_item()
parrot_state = PARROT_WANDER
return
/*
* Procs
*/
/mob/living/simple_animal/parrot/movement_delay()
if(client && stat == CONSCIOUS && parrot_state != "parrot_fly")
icon_state = "parrot_fly"
..()
/mob/living/simple_animal/parrot/proc/search_for_item()
for(var/atom/movable/AM in view(src))
//Skip items we already stole or are wearing or are too big
if(parrot_perch && AM.loc == parrot_perch.loc || AM.loc == src)
continue
if(istype(AM, /obj/item))
var/obj/item/I = AM
if(I.w_class < ITEMSIZE_SMALL)
return I
if(iscarbon(AM))
var/mob/living/carbon/C = AM
if((C.l_hand && C.l_hand.w_class <= ITEMSIZE_SMALL) || (C.r_hand && C.r_hand.w_class <= ITEMSIZE_SMALL))
return C
return null
/mob/living/simple_animal/parrot/proc/search_for_perch()
for(var/obj/O in view(src))
for(var/path in desired_perches)
if(istype(O, path))
return O
return null
//This proc was made to save on doing two 'in view' loops seperatly
/mob/living/simple_animal/parrot/proc/search_for_perch_and_item()
for(var/atom/movable/AM in view(src))
for(var/perch_path in desired_perches)
if(istype(AM, perch_path))
return AM
//Skip items we already stole or are wearing or are too big
if(parrot_perch && AM.loc == parrot_perch.loc || AM.loc == src)
continue
if(istype(AM, /obj/item))
var/obj/item/I = AM
if(I.w_class <= ITEMSIZE_SMALL)
return I
if(iscarbon(AM))
var/mob/living/carbon/C = AM
if(C.l_hand && C.l_hand.w_class <= ITEMSIZE_SMALL || C.r_hand && C.r_hand.w_class <= ITEMSIZE_SMALL)
return C
return null
/*
* Verbs - These are actually procs, but can be used as verbs by player-controlled parrots.
*/
/mob/living/simple_animal/parrot/proc/steal_from_ground()
set name = "Steal from ground"
set category = "Parrot"
set desc = "Grabs a nearby item."
if(stat)
return -1
if(held_item)
to_chat(src, "<font color='red'>You are already holding the [held_item]</font>")
return 1
for(var/obj/item/I in view(1,src))
//Make sure we're not already holding it and it's small enough
if(I.loc != src && I.w_class <= ITEMSIZE_SMALL)
//If we have a perch and the item is sitting on it, continue
if(!client && parrot_perch && I.loc == parrot_perch.loc)
continue
held_item = I
I.forceMove(src)
visible_message("[src] grabs the [held_item]!", "<font color='blue'>You grab the [held_item]!</font>", "You hear the sounds of wings flapping furiously.")
return held_item
to_chat(src, "<font color='red'>There is nothing of interest to take.</font>")
return 0
/mob/living/simple_animal/parrot/proc/steal_from_mob()
set name = "Steal from mob"
set category = "Parrot"
set desc = "Steals an item right out of a person's hand!"
if(stat)
return -1
if(held_item)
to_chat(src, "<font color='red'>You are already holding the [held_item]</font>")
return 1
var/obj/item/stolen_item = null
for(var/mob/living/carbon/C in view(1,src))
if(C.l_hand && C.l_hand.w_class <= ITEMSIZE_SMALL)
stolen_item = C.l_hand
if(C.r_hand && C.r_hand.w_class <= ITEMSIZE_SMALL)
stolen_item = C.r_hand
if(stolen_item)
C.remove_from_mob(stolen_item)
held_item = stolen_item
stolen_item.forceMove(src)
visible_message("[src] grabs the [held_item] out of [C]'s hand!", "<font color='blue'>You snag the [held_item] out of [C]'s hand!</font>", "You hear the sounds of wings flapping furiously.")
return held_item
to_chat(src, "<font color='red'>There is nothing of interest to take.</font>")
return 0
/mob/living/simple_animal/parrot/verb/drop_held_item_player()
set name = "Drop held item"
set category = "Parrot"
set desc = "Drop the item you're holding."
if(stat)
return
src.drop_held_item()
return
/mob/living/simple_animal/parrot/proc/drop_held_item(var/drop_gently = 1)
set name = "Drop held item"
set category = "Parrot"
set desc = "Drop the item you're holding."
if(stat)
return -1
if(!held_item)
to_chat(usr, "<font color='red'>You have nothing to drop!</font>")
return 0
if(!drop_gently)
if(istype(held_item, /obj/item/weapon/grenade))
var/obj/item/weapon/grenade/G = held_item
G.forceMove(src.loc)
G.detonate()
to_chat(src, "You let go of the [held_item]!")
held_item = null
return 1
to_chat(src, "You drop the [held_item].")
held_item.forceMove(src.loc)
held_item = null
return 1
/mob/living/simple_animal/parrot/proc/perch_player()
set name = "Sit"
set category = "Parrot"
set desc = "Sit on a nice comfy perch."
if(stat || !client)
return
if(icon_state == "parrot_fly")
for(var/atom/movable/AM in view(src,1))
for(var/perch_path in desired_perches)
if(istype(AM, perch_path))
src.forceMove(AM.loc)
icon_state = "parrot_sit"
return
to_chat(src, "<font color='red'>There is no perch nearby to sit on.</font>")
return
/*
* Sub-types
*/
/mob/living/simple_animal/parrot/Poly
name = "Poly"
desc = "Poly the Parrot. An expert on quantum cracker theory."
speak = list("Poly wanna cracker!", ":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS FREE CALL THE SHUTTLE")
/mob/living/simple_animal/parrot/Poly/New()
ears = new /obj/item/device/radio/headset/headset_eng(src)
available_channels = list(":e")
..()
/mob/living/simple_animal/parrot/say(var/message)
if(stat)
return
var/verb = "says"
if(speak_emote.len)
verb = pick(speak_emote)
var/message_mode=""
if(copytext(message,1,2) == ";")
message_mode = "headset"
message = copytext(message,2)
if(length(message) >= 2)
var/channel_prefix = copytext(message, 1 ,3)
message_mode = department_radio_keys[channel_prefix]
if(copytext(message,1,2) == ":")
var/positioncut = 3
message = trim(copytext(message,positioncut))
message = capitalize(trim_left(message))
if(message_mode)
if(message_mode in radiochannels)
if(ears && istype(ears,/obj/item/device/radio))
ears.talk_into(src,sanitize(message), message_mode, verb, null)
..(message)
/mob/living/simple_animal/parrot/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null)
if(prob(50))
parrot_hear(message)
..(message,verb,language,alt_name,italics,speaker)
/mob/living/simple_animal/parrot/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0)
if(prob(50))
parrot_hear("[pick(available_channels)] [message]")
..(message,verb,language,part_a,part_b,speaker,hard_to_hear)
/mob/living/simple_animal/parrot/proc/parrot_hear(var/message="")
if(!message || stat)
return
speech_buffer.Add(message)
/mob/living/simple_animal/parrot/attack_generic(var/mob/user, var/damage, var/attack_message)
var/success = ..()
if(client)
return success
if(parrot_state == PARROT_PERCH)
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
if(!success)
return 0
parrot_interest = user
parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless
icon_state = "parrot_fly"
return success
@@ -1,27 +0,0 @@
/mob/living/simple_animal/penguin
name = "space penguin"
desc = "An ungainly, waddling, cute, and VERY well-dressed bird."
tt_desc = "E Aptenodytes forsteri"
icon_state = "penguin"
icon_living = "penguin"
icon_dead = "penguin_dead"
intelligence_level = SA_ANIMAL
maxHealth = 20
health = 20
turns_per_move = 5
response_help = "pets"
response_disarm = "pushes aside"
response_harm = "hits"
harm_intent_damage = 5
melee_damage_lower = 10
melee_damage_upper = 15
attacktext = list("pecked")
has_langs = list("Bird")
speak_chance = 0
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
@@ -1,29 +0,0 @@
/mob/living/simple_animal/retaliate/diyaab
name = "diyaab"
desc = "A small pack animal. Although omnivorous, it will hunt meat on occasion."
tt_desc = "S Choeros hirtus" //diyaab and shantak are technically reletives!
faction = "diyaab"
icon_state = "diyaab"
icon_living = "diyaab"
icon_dead = "diyaab_dead"
icon = 'icons/jungle.dmi'
faction = "diyaab"
cooperative = 1
maxHealth = 25
health = 25
speed = 1
move_to_delay = 1
melee_damage_lower = 4
melee_damage_upper = 12
attack_sharp = 1 //Bleeds, but it shouldn't rip off a limb?
attacktext = list("gouged")
cold_damage_per_tick = 0
speak_chance = 5
speak = list("Awrr?","Aowrl!","Worrl")
emote_see = list("sniffs the air cautiously","looks around")
emote_hear = list("snuffles")
@@ -1,36 +0,0 @@
/mob/living/simple_animal/hostile/savik
name = "savik"
desc = "A fast, armoured predator accustomed to hiding and ambushing in cold terrain."
tt_desc = "S Pistris tellus" //landshark
faction = "savik"
icon_state = "savik"
icon_living = "savik"
icon_dead = "savik_dead"
icon = 'icons/jungle.dmi'
faction = "savik"
maxHealth = 125
health = 125
speed = 2
move_to_delay = 2
melee_damage_lower = 15
melee_damage_upper = 35
attack_armor_pen = 15
attack_sharp = 1
attack_edge = 1
attacktext = list("mauled")
cold_damage_per_tick = 0
speak_chance = 5
speak = list("Hruuugh!","Hrunnph")
emote_see = list("paws the ground","shakes its mane","stomps")
emote_hear = list("snuffles")
/mob/living/simple_animal/hostile/savik/handle_stance(var/new_stance)
..(new_stance)
if(stance == STANCE_ATTACK || stance == STANCE_ATTACKING)
if((health / maxHealth) <= 0.5) // At half health, and fighting someone currently.
add_modifier(/datum/modifier/berserk, 30 SECONDS)
@@ -1,29 +0,0 @@
/mob/living/simple_animal/hostile/shantak
name = "shantak"
desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. Don't be fooled by its beauty though."
tt_desc = "S Choeros shantak"
faction = "shantak"
icon_state = "shantak"
icon_living = "shantak"
icon_dead = "shantak_dead"
icon = 'icons/jungle.dmi'
faction = "shantak"
maxHealth = 75
health = 75
speed = 1
move_to_delay = 1
melee_damage_lower = 12
melee_damage_upper = 28
attack_armor_pen = 5
attack_sharp = 1
attack_edge = 1
attacktext = list("gouged")
cold_damage_per_tick = 0
speak_chance = 5
speak = list("Shuhn","Shrunnph?","Shunpf")
emote_see = list("scratches the ground","shakes out its mane","clinks gently as it moves")
@@ -1,70 +0,0 @@
/mob/living/simple_animal/slime
name = "pet slime"
desc = "A lovable, domesticated slime."
tt_desc = "Amorphidae proteus"
icon = 'icons/mob/slimes.dmi'
icon_state = "grey baby slime"
icon_living = "grey baby slime"
icon_dead = "grey baby slime dead"
maxHealth = 100
health = 100
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
speak_chance = 1
speak_emote = list("chirps")
emote_see = list("jiggles", "bounces in place")
var/colour = "grey"
/mob/living/simple_animal/slime/science
name = "Kendrick"
colour = "rainbow"
icon_state = "rainbow baby slime"
icon_living = "rainbow baby slime"
icon_dead = "rainbow baby slime dead"
/mob/living/simple_animal/slime/science/Initialize()
. = ..()
overlays.Cut()
overlays += "aslime-:33"
/mob/living/simple_animal/adultslime
name = "pet slime"
desc = "A lovable, domesticated slime."
icon = 'icons/mob/slimes.dmi'
icon_state = "grey adult slime"
icon_living = "grey adult slime"
icon_dead = "grey baby slime dead"
maxHealth = 200
health = 200
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
speak_chance = 1
emote_see = list("jiggles", "bounces in place")
var/colour = "grey"
/mob/living/simple_animal/adultslime/New()
..()
overlays += "aslime-:33"
/mob/living/simple_animal/adultslime/death()
var/mob/living/simple_animal/slime/S1 = new /mob/living/simple_animal/slime (src.loc)
S1.icon_state = "[src.colour] baby slime"
S1.icon_living = "[src.colour] baby slime"
S1.icon_dead = "[src.colour] baby slime dead"
S1.colour = "[src.colour]"
var/mob/living/simple_animal/slime/S2 = new /mob/living/simple_animal/slime (src.loc)
S2.icon_state = "[src.colour] baby slime"
S2.icon_living = "[src.colour] baby slime"
S2.icon_dead = "[src.colour] baby slime dead"
S2.colour = "[src.colour]"
qdel(src)
@@ -1,302 +0,0 @@
/mob/living/simple_animal/spiderbot
name = "spider-bot"
desc = "A skittering robotic friend!"
tt_desc = "Maintenance Robot"
icon = 'icons/mob/robots.dmi'
icon_state = "spiderbot-chassis"
icon_living = "spiderbot-chassis"
icon_dead = "spiderbot-smashed"
intelligence_level = SA_HUMANOID // Because its piloted by players.
health = 10
maxHealth = 10
wander = 0
speed = -1 //Spiderbots gotta go fast.
pass_flags = PASSTABLE
mob_size = MOB_SMALL
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
melee_damage_lower = 1
melee_damage_upper = 3
attacktext = list("shocked")
min_oxy = 0
max_tox = 0
max_co2 = 0
minbodytemp = 0
maxbodytemp = 500
speak_chance = 1
speak_emote = list("beeps","clicks","chirps")
var/obj/item/device/radio/borg/radio = null
var/mob/living/silicon/ai/connected_ai = null
var/obj/item/weapon/cell/cell = null
var/obj/machinery/camera/camera = null
var/obj/item/device/mmi/mmi = null
var/list/req_access = list(access_robotics) //Access needed to pop out the brain.
var/positronic
can_enter_vent_with = list(
/obj/item/weapon/implant,
/obj/item/device/radio/borg,
/obj/item/weapon/holder,
/obj/machinery/camera,
/mob/living/simple_mob/animal/borer,
/obj/item/device/mmi,
)
var/emagged = 0
var/obj/item/held_item = null //Storage for single item they can hold.
/mob/living/simple_animal/spiderbot/New()
..()
add_language(LANGUAGE_GALCOM)
default_language = all_languages[LANGUAGE_GALCOM]
verbs |= /mob/living/proc/ventcrawl
verbs |= /mob/living/proc/hide
/mob/living/simple_animal/spiderbot/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O, /obj/item/device/mmi))
var/obj/item/device/mmi/B = O
if(src.mmi)
user << "<span class='warning'>There's already a brain in [src]!</span>"
return
if(!B.brainmob)
user << "<span class='warning'>Sticking an empty MMI into the frame would sort of defeat the purpose.</span>"
return
if(!B.brainmob.key)
var/ghost_can_reenter = 0
if(B.brainmob.mind)
for(var/mob/observer/dead/G in player_list)
if(G.can_reenter_corpse && G.mind == B.brainmob.mind)
ghost_can_reenter = 1
break
if(!ghost_can_reenter)
user << "<span class='notice'>[O] is completely unresponsive; there's no point.</span>"
return
if(B.brainmob.stat == DEAD)
user << "<span class='warning'>[O] is dead. Sticking it into the frame would sort of defeat the purpose.</span>"
return
if(jobban_isbanned(B.brainmob, "Cyborg"))
user << "<span class='warning'>\The [O] does not seem to fit.</span>"
return
user << "<span class='notice'>You install \the [O] in \the [src]!</span>"
if(istype(O, /obj/item/device/mmi/digital))
positronic = 1
add_language("Robot Talk")
user.drop_item()
src.mmi = O
src.transfer_personality(O)
O.forceMove(src)
src.update_icon()
return 1
if (istype(O, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = O
if (WT.remove_fuel(0))
if(health < getMaxHealth())
health += pick(1,1,1,2,2,3)
if(health > getMaxHealth())
health = getMaxHealth()
add_fingerprint(user)
src.visible_message("<span class='notice'>\The [user] has spot-welded some of the damage to \the [src]!</span>")
else
user << "<span class='warning'>\The [src] is undamaged!</span>"
else
user << "<span class='danger'>You need more welding fuel for this task!</span>"
return
else if(istype(O, /obj/item/weapon/card/id)||istype(O, /obj/item/device/pda))
if (!mmi)
user << "<span class='danger'>There's no reason to swipe your ID - \the [src] has no brain to remove.</span>"
return 0
var/obj/item/weapon/card/id/id_card
if(istype(O, /obj/item/weapon/card/id))
id_card = O
else
var/obj/item/device/pda/pda = O
id_card = pda.id
if(access_robotics in id_card.access)
user << "<span class='notice'>You swipe your access card and pop the brain out of \the [src].</span>"
eject_brain()
if(held_item)
held_item.forceMove(src.loc)
held_item = null
return 1
else
user << "<span class='danger'>You swipe your card with no effect.</span>"
return 0
else
O.attack(src, user, user.zone_sel.selecting)
/mob/living/simple_animal/spiderbot/emag_act(var/remaining_charges, var/mob/user)
if (emagged)
user << "<span class='warning'>[src] is already overloaded - better run.</span>"
return 0
else
user << "<span class='notice'>You short out the security protocols and overload [src]'s cell, priming it to explode in a short time.</span>"
spawn(100)
to_chat(src, "<span class='danger'>Your cell seems to be outputting a lot of power...</span>")
spawn(200)
to_chat(src, "<span class='danger'>Internal heat sensors are spiking! Something is badly wrong with your cell!</span>")
spawn(300) src.explode()
/mob/living/simple_animal/spiderbot/proc/transfer_personality(var/obj/item/device/mmi/M as obj)
src.mind = M.brainmob.mind
src.mind.key = M.brainmob.key
src.ckey = M.brainmob.ckey
src.name = "spider-bot ([M.brainmob.name])"
src.languages = M.brainmob.languages
/mob/living/simple_animal/spiderbot/proc/explode() //When emagged.
src.visible_message("<span class='danger'>\The [src] makes an odd warbling noise, fizzles, and explodes!</span>")
explosion(get_turf(loc), -1, -1, 3, 5)
eject_brain()
death()
/mob/living/simple_animal/spiderbot/update_icon()
if(mmi)
if(positronic)
icon_state = "spiderbot-chassis-posi"
icon_living = "spiderbot-chassis-posi"
else
icon_state = "spiderbot-chassis-mmi"
icon_living = "spiderbot-chassis-mmi"
else
icon_state = "spiderbot-chassis"
icon_living = "spiderbot-chassis"
/mob/living/simple_animal/spiderbot/proc/eject_brain()
if(mmi)
var/turf/T = get_turf(loc)
if(T)
mmi.forceMove(T)
if(mind) mind.transfer_to(mmi.brainmob)
mmi = null
real_name = initial(real_name)
name = real_name
update_icon()
remove_language("Robot Talk")
positronic = null
/mob/living/simple_animal/spiderbot/Destroy()
eject_brain()
..()
/mob/living/simple_animal/spiderbot/New()
radio = new /obj/item/device/radio/borg(src)
camera = new /obj/machinery/camera(src)
camera.c_tag = "spiderbot-[real_name]"
camera.replace_networks(list("SS13"))
..()
/mob/living/simple_animal/spiderbot/death()
living_mob_list -= src
dead_mob_list += src
if(camera)
camera.status = 0
held_item.forceMove(src.loc)
held_item = null
gibs(loc, null, null, /obj/effect/gibspawner/robot) //TODO: use gib() or refactor spiderbots into synthetics.
qdel(src)
return
//Cannibalized from the parrot mob. ~Zuhayr
/mob/living/simple_animal/spiderbot/verb/drop_held_item()
set name = "Drop held item"
set category = "Spiderbot"
set desc = "Drop the item you're holding."
if(stat)
return
if(!held_item)
usr << "<font color='red'>You have nothing to drop!</font>"
return 0
if(istype(held_item, /obj/item/weapon/grenade))
visible_message("<span class='danger'>\The [src] launches \the [held_item]!</span>", \
"<span class='danger'>You launch \the [held_item]!</span>", \
"You hear a skittering noise and a thump!")
var/obj/item/weapon/grenade/G = held_item
G.forceMove(src.loc)
G.detonate()
held_item = null
return 1
visible_message("<span class='notice'>\The [src] drops \the [held_item].</span>", \
"<span class='notice'>You drop \the [held_item].</span>", \
"You hear a skittering noise and a soft thump.")
held_item.forceMove(src.loc)
held_item = null
return 1
return
/mob/living/simple_animal/spiderbot/verb/get_item()
set name = "Pick up item"
set category = "Spiderbot"
set desc = "Allows you to take a nearby small item."
if(stat)
return -1
if(held_item)
to_chat(src, "<span class='warning'>You are already holding \the [held_item]</span>")
return 1
var/list/items = list()
for(var/obj/item/I in view(1,src))
if(I.loc != src && I.w_class <= ITEMSIZE_SMALL && I.Adjacent(src) )
items.Add(I)
var/obj/selection = input("Select an item.", "Pickup") in items
if(selection)
for(var/obj/item/I in view(1, src))
if(selection == I)
held_item = selection
selection.forceMove(src)
visible_message("<span class='notice'>\The [src] scoops up \the [held_item].</span>", \
"<span class='notice'>You grab \the [held_item].</span>", \
"You hear a skittering noise and a clink.")
return held_item
to_chat(src, "<span class='warning'>\The [selection] is too far away.</span>")
return 0
to_chat(src, "<span class='warning'>There is nothing of interest to take.</span>")
return 0
/mob/living/simple_animal/spiderbot/examine(mob/user)
..(user)
if(src.held_item)
user << "It is carrying \icon[src.held_item] \a [src.held_item]."
/mob/living/simple_animal/spiderbot/cannot_use_vents()
return
/mob/living/simple_animal/spiderbot/binarycheck()
return positronic
@@ -1,24 +0,0 @@
/mob/living/simple_animal/hostile/tomato
name = "tomato"
desc = "It's a horrifyingly enormous beef tomato, and it's packing extra beef!"
tt_desc = "X Solanum abominable"
icon_state = "tomato"
icon_living = "tomato"
icon_dead = "tomato_dead"
intelligence_level = SA_PLANT
faction = "plants"
maxHealth = 15
health = 15
turns_per_move = 5
response_help = "prods"
response_disarm = "pushes aside"
response_harm = "smacks"
harm_intent_damage = 5
melee_damage_upper = 15
melee_damage_lower = 10
attacktext = list("mauled")
meat_type = /obj/item/weapon/reagent_containers/food/snacks/tomatomeat
@@ -1,60 +0,0 @@
/mob/living/simple_animal/hostile/tree
name = "pine tree"
desc = "A pissed off tree-like alien. It seems annoyed with the festivities..."
tt_desc = "X Festivus tyrannus"
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "pine_1"
icon_living = "pine_1"
icon_dead = "pine_1"
icon_gib = "pine_1"
intelligence_level = SA_PLANT
faction = "carp" //Trees can be carp friends?
maxHealth = 250
health = 250
speed = -1
turns_per_move = 5
response_help = "brushes"
response_disarm = "pushes"
response_harm = "hits"
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 12
attacktext = list("bitten")
attack_sound = 'sound/weapons/bite.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
pixel_x = -16
/mob/living/simple_animal/hostile/tree/FindTarget()
. = ..()
if(.)
audible_emote("growls at [.]")
/mob/living/simple_animal/hostile/tree/PunchTarget()
. =..()
var/mob/living/L = .
if(istype(L))
if(prob(15))
L.Weaken(3)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
/mob/living/simple_animal/hostile/tree/death()
..(null,"is hacked into pieces!")
playsound(loc, 'sound/effects/woodcutting.ogg', 100, 1)
new /obj/item/stack/material/wood(loc)
qdel(src)
@@ -1,199 +0,0 @@
/mob/living/simple_animal/space_worm
name = "space worm segment"
desc = "A part of a space worm."
icon = 'icons/mob/animal.dmi'
icon_state = "spaceworm"
icon_living = "spaceworm"
icon_dead = "spacewormdead"
intelligence_level = SA_ANIMAL
maxHealth = 30
health = 30
speed = -1
status_flags = 0
universal_speak = 1
stop_automated_movement = 1
wander = 0
animate_movement = SYNC_STEPS
response_help = "touches"
response_disarm = "flails at"
response_harm = "punches the"
harm_intent_damage = 2
minbodytemp = 0
maxbodytemp = 350
min_oxy = 0
max_co2 = 0
max_tox = 0
environment_smash = 2
speak_emote = list("transmits") //not supposed to be used under AI control
emote_hear = list("transmits") //I'm just adding it so it doesn't runtime if controlled by player who speaks
var/mob/living/simple_animal/space_worm/previous //next/previous segments, correspondingly
var/mob/living/simple_animal/space_worm/next //head is the nextest segment
var/stomachProcessProbability = 50
var/digestionProbability = 20
var/flatPlasmaValue = 5 //flat plasma amount given for non-items
var/atom/currentlyEating //what the worm is currently eating
var/eatingDuration = 0 //how long he's been eating it for
head
name = "space worm head"
icon_state = "spacewormhead"
icon_living = "spacewormhead"
icon_dead = "spacewormdead"
maxHealth = 20
health = 20
melee_damage_lower = 10
melee_damage_upper = 15
attacktext = list("bitten")
animate_movement = SLIDE_STEPS
New(var/location, var/segments = 6)
..()
var/mob/living/simple_animal/space_worm/current = src
for(var/i = 1 to segments)
var/mob/living/simple_animal/space_worm/newSegment = new /mob/living/simple_animal/space_worm(loc)
current.Attach(newSegment)
current = newSegment
update_icon()
if(stat == CONSCIOUS || stat == UNCONSCIOUS)
icon_state = "spacewormhead[previous?1:0]"
if(previous)
set_dir(get_dir(previous,src))
else
icon_state = "spacewormheaddead"
Life()
..()
if(next && !(next in view(src,1)))
Detach()
if(stat == DEAD) //dead chunks fall off and die immediately
if(previous)
previous.Detach()
if(next)
Detach(1)
if(prob(stomachProcessProbability))
ProcessStomach()
update_icon()
return
Destroy() //if a chunk a destroyed, make a new worm out of the split halves
if(previous)
previous.Detach()
..()
Move()
var/attachementNextPosition = loc
if(..())
if(previous)
previous.Move(attachementNextPosition)
update_icon()
Bump(atom/obstacle)
if(currentlyEating != obstacle)
currentlyEating = obstacle
eatingDuration = 0
if(!AttemptToEat(obstacle))
eatingDuration++
else
currentlyEating = null
eatingDuration = 0
return
update_icon() //only for the sake of consistency with the other update icon procs
if(stat == CONSCIOUS || stat == UNCONSCIOUS)
if(previous) //midsection
icon_state = "spaceworm[get_dir(src,previous) | get_dir(src,next)]" //see 3 lines below
else //tail
icon_state = "spacewormtail"
set_dir(get_dir(src,next)) //next will always be present since it's not a head and if it's dead, it goes in the other if branch
else
icon_state = "spacewormdead"
return
proc/AttemptToEat(var/atom/target)
if(istype(target,/turf/simulated/wall))
var/turf/simulated/wall/W = target
if((!W.reinf_material && eatingDuration >= 100) || eatingDuration >= 200) //need 20 ticks to eat an rwall, 10 for a regular one
W.dismantle_wall()
return 1
else if(istype(target,/atom/movable))
if(istype(target,/mob) || eatingDuration >= 50) //5 ticks to eat stuff like airlocks
var/atom/movable/objectOrMob = target
contents += objectOrMob
return 1
return 0
proc/Attach(var/mob/living/simple_animal/space_worm/attachement)
if(!attachement)
return
previous = attachement
attachement.next = src
return
proc/Detach(die = 0)
var/mob/living/simple_animal/space_worm/newHead = new /mob/living/simple_animal/space_worm/head(loc,0)
var/mob/living/simple_animal/space_worm/newHeadPrevious = previous
previous = null //so that no extra heads are spawned
newHead.Attach(newHeadPrevious)
if(die)
newHead.death()
qdel(src)
proc/ProcessStomach()
for(var/atom/movable/stomachContent in contents)
if(prob(digestionProbability))
if(istype(stomachContent,/obj/item/stack)) //converts to plasma, keeping the stack value
if(!istype(stomachContent,/obj/item/stack/material/phoron))
var/obj/item/stack/oldStack = stomachContent
new /obj/item/stack/material/phoron(src, oldStack.get_amount())
qdel(oldStack)
continue
else if(istype(stomachContent,/obj/item)) //converts to plasma, keeping the w_class
var/obj/item/oldItem = stomachContent
new /obj/item/stack/material/phoron(src, oldItem.w_class)
qdel(oldItem)
continue
else
new /obj/item/stack/material/phoron(src, flatPlasmaValue) //just flat amount
qdel(stomachContent)
continue
if(previous)
for(var/atom/movable/stomachContent in contents) //transfer it along the digestive tract
previous.contents += stomachContent
else
for(var/atom/movable/stomachContent in contents) //or poop it out
loc.contents += stomachContent
return
@@ -1,213 +0,0 @@
/mob/living/simple_mob/animal/borer
name = "cortical borer"
real_name = "cortical borer"
desc = "A small, quivering sluglike creature."
speak_emote = list("chirrups")
emote_hear = list("chirrups")
intelligence_level = SA_HUMANOID // Player controlled.
response_help = "pokes"
response_disarm = "prods"
response_harm = "stomps on"
icon_state = "brainslug"
item_state = "brainslug"
icon_living = "brainslug"
icon_dead = "brainslug_dead"
speed = 5
a_intent = I_HURT
stop_automated_movement = 1
status_flags = CANPUSH
attacktext = list("nipped")
friendly = "prods"
wander = 0
pass_flags = PASSTABLE
universal_understand = 1
holder_type = /obj/item/weapon/holder/borer
var/used_dominate
var/chemicals = 10 // Chemicals used for reproduction and spitting neurotoxin.
var/mob/living/carbon/human/host // Human host for the brain worm.
var/truename // Name used for brainworm-speak.
var/mob/living/captive_brain/host_brain // Used for swapping control of the body back and forth.
var/controlling // Used in human death check.
var/docile = 0 // Sugar can stop borers from acting.
var/has_reproduced
var/roundstart
can_be_antagged = TRUE
/mob/living/simple_mob/animal/borer/roundstart
roundstart = 1
/mob/living/simple_mob/animal/borer/Login()
..()
if(mind)
borers.add_antagonist(mind)
/mob/living/simple_mob/animal/borer/New()
..()
add_language("Cortical Link")
verbs += /mob/living/proc/ventcrawl
verbs += /mob/living/proc/hide
truename = "[pick("Primary","Secondary","Tertiary","Quaternary")] [rand(1000,9999)]"
if(!roundstart) request_player()
/mob/living/simple_mob/animal/borer/Life()
..()
if(host)
if(!stat && !host.stat)
if(host.reagents.has_reagent("sugar"))
if(!docile)
if(controlling)
host << "<font color='blue'>You feel the soporific flow of sugar in your host's blood, lulling you into docility.</font>"
else
to_chat(src, "<font color='blue'>You feel the soporific flow of sugar in your host's blood, lulling you into docility.</font>")
docile = 1
else
if(docile)
if(controlling)
host << "<font color='blue'>You shake off your lethargy as the sugar leaves your host's blood.</font>"
else
to_chat(src, "<font color='blue'>You shake off your lethargy as the sugar leaves your host's blood.</font>")
docile = 0
if(chemicals < 250)
chemicals++
if(controlling)
if(docile)
host << "<font color='blue'>You are feeling far too docile to continue controlling your host...</font>"
host.release_control()
return
if(prob(5))
host.adjustBrainLoss(0.1)
if(prob(host.brainloss/20))
host.say("*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_v","gasp"))]")
/mob/living/simple_mob/animal/borer/Stat()
..()
statpanel("Status")
if(emergency_shuttle)
var/eta_status = emergency_shuttle.get_status_panel_eta()
if(eta_status)
stat(null, eta_status)
if (client.statpanel == "Status")
stat("Chemicals", chemicals)
/mob/living/simple_mob/animal/borer/proc/detatch()
if(!host || !controlling) return
if(istype(host,/mob/living/carbon/human))
var/mob/living/carbon/human/H = host
var/obj/item/organ/external/head = H.get_organ(BP_HEAD)
head.implants -= src
controlling = 0
host.remove_language("Cortical Link")
host.verbs -= /mob/living/carbon/proc/release_control
host.verbs -= /mob/living/carbon/proc/punish_host
host.verbs -= /mob/living/carbon/proc/spawn_larvae
if(host_brain)
// these are here so bans and multikey warnings are not triggered on the wrong people when ckey is changed.
// computer_id and IP are not updated magically on their own in offline mobs -walter0o
// host -> self
var/h2s_id = host.computer_id
var/h2s_ip= host.lastKnownIP
host.computer_id = null
host.lastKnownIP = null
src.ckey = host.ckey
if(!src.computer_id)
src.computer_id = h2s_id
if(!host_brain.lastKnownIP)
src.lastKnownIP = h2s_ip
// brain -> host
var/b2h_id = host_brain.computer_id
var/b2h_ip= host_brain.lastKnownIP
host_brain.computer_id = null
host_brain.lastKnownIP = null
host.ckey = host_brain.ckey
if(!host.computer_id)
host.computer_id = b2h_id
if(!host.lastKnownIP)
host.lastKnownIP = b2h_ip
qdel(host_brain)
/mob/living/simple_mob/animal/borer/proc/leave_host()
if(!host) return
if(host.mind)
borers.remove_antagonist(host.mind)
src.forceMove(get_turf(host))
reset_view(null)
machine = null
host.reset_view(null)
host.machine = null
host = null
return
//Procs for grabbing players.
/mob/living/simple_mob/animal/borer/proc/request_player()
for(var/mob/observer/dead/O in player_list)
if(jobban_isbanned(O, "Borer"))
continue
if(O.client)
if(O.client.prefs.be_special & BE_ALIEN)
question(O.client)
/mob/living/simple_mob/animal/borer/proc/question(var/client/C)
spawn(0)
if(!C) return
var/response = alert(C, "A cortical borer needs a player. Are you interested?", "Cortical borer request", "Yes", "No", "Never for this round")
if(!C || ckey)
return
if(response == "Yes")
transfer_personality(C)
else if (response == "Never for this round")
C.prefs.be_special ^= BE_ALIEN
/mob/living/simple_mob/animal/borer/proc/transfer_personality(var/client/candidate)
if(!candidate || !candidate.mob || !candidate.mob.mind)
return
src.mind = candidate.mob.mind
candidate.mob.mind.current = src
src.ckey = candidate.ckey
if(src.mind)
src.mind.assigned_role = "Cortical Borer"
src.mind.special_role = "Cortical Borer"
to_chat(src, "<span class='notice'>You are a cortical borer!</span> You are a brain slug that worms its way \
into the head of its victim. Use stealth, persuasion and your powers of mind control to keep you, \
your host and your eventual spawn safe and warm.")
to_chat(src, "You can speak to your victim with <b>say</b>, to other borers with <b>say :x</b>, and use your Abilities tab to access powers.")
/mob/living/simple_mob/animal/borer/cannot_use_vents()
return
@@ -1,57 +0,0 @@
/mob/living/captive_brain
name = "host brain"
real_name = "host brain"
universal_understand = 1
/mob/living/captive_brain/say(var/message)
if (src.client)
if(client.prefs.muted & MUTE_IC)
to_chat(src, "<font color='red'>You cannot speak in IC (muted).</font>")
return
if(istype(src.loc,/mob/living/simple_mob/animal/borer))
message = sanitize(message)
if (!message)
return
log_say(message,src)
if (stat == 2)
return say_dead(message)
var/mob/living/simple_mob/animal/borer/B = src.loc
to_chat(src, "You whisper silently, \"[message]\"")
B.host << "The captive mind of [src] whispers, \"[message]\""
for (var/mob/M in player_list)
if (istype(M, /mob/new_player))
continue
else if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
M << "The captive mind of [src] whispers, \"[message]\""
/mob/living/captive_brain/emote(var/message)
return
/mob/living/captive_brain/process_resist()
//Resisting control by an alien mind.
if(istype(src.loc,/mob/living/simple_mob/animal/borer))
var/mob/living/simple_mob/animal/borer/B = src.loc
var/mob/living/captive_brain/H = src
H << "<span class='danger'>You begin doggedly resisting the parasite's control (this will take approximately sixty seconds).</span>"
B.host << "<span class='danger'>You feel the captive mind of [src] begin to resist your control.</span>"
spawn(rand(200,250)+B.host.brainloss)
if(!B || !B.controlling) return
B.host.adjustBrainLoss(rand(0.1,0.5))
H << "<span class='danger'>With an immense exertion of will, you regain control of your body!</span>"
B.host << "<span class='danger'>You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you.</span>"
B.detatch()
verbs -= /mob/living/carbon/proc/release_control
verbs -= /mob/living/carbon/proc/punish_host
verbs -= /mob/living/carbon/proc/spawn_larvae
return
..()
@@ -1,337 +0,0 @@
/mob/living/simple_mob/animal/borer/verb/release_host()
set category = "Abilities"
set name = "Release Host"
set desc = "Slither out of your host."
if(!host)
to_chat(src, "You are not inside a host body.")
return
if(stat)
to_chat(src, "You cannot leave your host in your current state.")
if(docile)
to_chat(src, "<font color='blue'>You are feeling far too docile to do that.</font>")
return
if(!host || !src) return
to_chat(src, "You begin disconnecting from [host]'s synapses and prodding at their internal ear canal.")
if(!host.stat)
host << "An odd, uncomfortable pressure begins to build inside your skull, behind your ear..."
spawn(100)
if(!host || !src) return
if(src.stat)
to_chat(src, "You cannot release your host in your current state.")
return
to_chat(src, "You wiggle out of [host]'s ear and plop to the ground.")
if(host.mind)
if(!host.stat)
host << "<span class='danger'>Something slimy wiggles out of your ear and plops to the ground!</span>"
host << "<span class='danger'>As though waking from a dream, you shake off the insidious mind control of the brain worm. Your thoughts are your own again.</span>"
detatch()
leave_host()
/mob/living/simple_mob/animal/borer/verb/infest()
set category = "Abilities"
set name = "Infest"
set desc = "Infest a suitable humanoid host."
if(host)
to_chat(src, "You are already within a host.")
return
if(stat)
to_chat(src, "You cannot infest a target in your current state.")
return
var/list/choices = list()
for(var/mob/living/carbon/C in view(1,src))
if(src.Adjacent(C))
choices += C
if(!choices.len)
to_chat(src, "There are no viable hosts within range...")
return
var/mob/living/carbon/M = input(src,"Who do you wish to infest?") in null|choices
if(!M || !src) return
if(!(src.Adjacent(M))) return
if(M.has_brain_worms())
to_chat(src, "You cannot infest someone who is already infested!")
return
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/E = H.organs_by_name[BP_HEAD]
if(!E || E.is_stump())
to_chat(src, "\The [H] does not have a head!")
if(!H.should_have_organ("brain"))
to_chat(src, "\The [H] does not seem to have an ear canal to breach.")
return
if(H.check_head_coverage())
to_chat(src, "You cannot get through that host's protective gear.")
return
M << "Something slimy begins probing at the opening of your ear canal..."
to_chat(src, "You slither up [M] and begin probing at their ear canal...")
if(!do_after(src,30))
to_chat(src, "As [M] moves away, you are dislodged and fall to the ground.")
return
if(!M || !src) return
if(src.stat)
to_chat(src, "You cannot infest a target in your current state.")
return
if(M in view(1, src))
to_chat(src, "You wiggle into [M]'s ear.")
if(!M.stat)
M << "Something disgusting and slimy wiggles into your ear!"
src.host = M
src.forceMove(M)
//Update their traitor status.
if(host.mind)
borers.add_antagonist_mind(host.mind, 1, borers.faction_role_text, borers.faction_welcome)
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/I = H.internal_organs_by_name["brain"]
if(!I) // No brain organ, so the borer moves in and replaces it permanently.
replace_brain()
else
// If they're in normally, implant removal can get them out.
var/obj/item/organ/external/head = H.get_organ(BP_HEAD)
head.implants += src
return
else
to_chat(src, "They are no longer in range!")
return
/*
/mob/living/simple_mob/animal/borer/verb/devour_brain()
set category = "Abilities"
set name = "Devour Brain"
set desc = "Take permanent control of a dead host."
if(!host)
to_chat(src, "You are not inside a host body.")
return
if(host.stat != 2)
to_chat(src, "Your host is still alive.")
return
if(stat)
to_chat(src, "You cannot do that in your current state.")
if(docile)
to_chat(src, "<font color='blue'>You are feeling far too docile to do that.</font>")
return
to_chat(src, "<span class = 'danger'>It only takes a few moments to render the dead host brain down into a nutrient-rich slurry...</span>")
replace_brain()
*/
// BRAIN WORM ZOMBIES AAAAH.
/mob/living/simple_mob/animal/borer/proc/replace_brain()
var/mob/living/carbon/human/H = host
if(!istype(host))
to_chat(src, "This host does not have a suitable brain.")
return
to_chat(src, "<span class = 'danger'>You settle into the empty brainpan and begin to expand, fusing inextricably with the dead flesh of [H].</span>")
H.add_language("Cortical Link")
if(host.stat == 2)
H.verbs |= /mob/living/carbon/human/proc/jumpstart
H.verbs |= /mob/living/carbon/human/proc/psychic_whisper
H.verbs |= /mob/living/carbon/human/proc/tackle
H.verbs |= /mob/living/carbon/proc/spawn_larvae
if(H.client)
H.ghostize(0)
if(src.mind)
src.mind.special_role = "Borer Husk"
src.mind.transfer_to(host)
H.ChangeToHusk()
var/obj/item/organ/internal/borer/B = new(H)
H.internal_organs_by_name["brain"] = B
H.internal_organs |= B
var/obj/item/organ/external/affecting = H.get_organ(BP_HEAD)
affecting.implants -= src
var/s2h_id = src.computer_id
var/s2h_ip= src.lastKnownIP
src.computer_id = null
src.lastKnownIP = null
if(!H.computer_id)
H.computer_id = s2h_id
if(!H.lastKnownIP)
H.lastKnownIP = s2h_ip
/mob/living/simple_mob/animal/borer/verb/secrete_chemicals()
set category = "Abilities"
set name = "Secrete Chemicals"
set desc = "Push some chemicals into your host's bloodstream."
if(!host)
to_chat(src, "You are not inside a host body.")
return
if(stat)
to_chat(src, "You cannot secrete chemicals in your current state.")
if(docile)
to_chat(src, "<font color='blue'>You are feeling far too docile to do that.</font>")
return
if(chemicals < 50)
to_chat(src, "You don't have enough chemicals!")
var/chem = input("Select a chemical to secrete.", "Chemicals") as null|anything in list("alkysine","bicaridine","hyperzine","tramadol")
if(!chem || chemicals < 50 || !host || controlling || !src || stat) //Sanity check.
return
to_chat(src, "<font color='red'><B>You squirt a measure of [chem] from your reservoirs into [host]'s bloodstream.</B></font>")
host.reagents.add_reagent(chem, 10)
chemicals -= 50
/mob/living/simple_mob/animal/borer/verb/dominate_victim()
set category = "Abilities"
set name = "Paralyze Victim"
set desc = "Freeze the limbs of a potential host with supernatural fear."
if(world.time - used_dominate < 150)
to_chat(src, "You cannot use that ability again so soon.")
return
if(host)
to_chat(src, "You cannot do that from within a host body.")
return
if(src.stat)
to_chat(src, "You cannot do that in your current state.")
return
var/list/choices = list()
for(var/mob/living/carbon/C in view(3,src))
if(C.stat != 2)
choices += C
if(world.time - used_dominate < 150)
to_chat(src, "You cannot use that ability again so soon.")
return
var/mob/living/carbon/M = input(src,"Who do you wish to dominate?") in null|choices
if(!M || !src) return
if(M.has_brain_worms())
to_chat(src, "You cannot infest someone who is already infested!")
return
to_chat(src, "<font color='red'>You focus your psychic lance on [M] and freeze their limbs with a wave of terrible dread.</font>")
M << "<font color='red'>You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing.</font>"
M.Weaken(10)
used_dominate = world.time
/mob/living/simple_mob/animal/borer/verb/bond_brain()
set category = "Abilities"
set name = "Assume Control"
set desc = "Fully connect to the brain of your host."
if(!host)
to_chat(src, "You are not inside a host body.")
return
if(src.stat)
to_chat(src, "You cannot do that in your current state.")
return
if(docile)
to_chat(src, "<font color='blue'>You are feeling far too docile to do that.</font>")
return
to_chat(src, "You begin delicately adjusting your connection to the host brain...")
spawn(100+(host.brainloss*5))
if(!host || !src || controlling)
return
else
to_chat(src, "<font color='red'><B>You plunge your probosci deep into the cortex of the host brain, interfacing directly with their nervous system.</B></font>")
host << "<font color='red'><B>You feel a strange shifting sensation behind your eyes as an alien consciousness displaces yours.</B></font>"
host.add_language("Cortical Link")
// host -> brain
var/h2b_id = host.computer_id
var/h2b_ip= host.lastKnownIP
host.computer_id = null
host.lastKnownIP = null
qdel(host_brain)
host_brain = new(src)
host_brain.ckey = host.ckey
host_brain.name = host.name
if(!host_brain.computer_id)
host_brain.computer_id = h2b_id
if(!host_brain.lastKnownIP)
host_brain.lastKnownIP = h2b_ip
// self -> host
var/s2h_id = src.computer_id
var/s2h_ip= src.lastKnownIP
src.computer_id = null
src.lastKnownIP = null
host.ckey = src.ckey
if(!host.computer_id)
host.computer_id = s2h_id
if(!host.lastKnownIP)
host.lastKnownIP = s2h_ip
controlling = 1
host.verbs += /mob/living/carbon/proc/release_control
host.verbs += /mob/living/carbon/proc/punish_host
host.verbs += /mob/living/carbon/proc/spawn_larvae
return
@@ -1,40 +0,0 @@
/mob/living/simple_mob/animal/borer/say(var/message)
message = sanitize(message)
message = capitalize(message)
if(!message)
return
if (stat == 2)
return say_dead(message)
if (stat)
return
if (src.client)
if(client.prefs.muted & MUTE_IC)
to_chat(src, "<font color='red'>You cannot speak in IC (muted).</font>")
return
if (copytext(message, 1, 2) == "*")
return emote(copytext(message, 2))
var/datum/language/L = parse_language(message)
if(L && L.flags & HIVEMIND)
L.broadcast(src,trim(copytext(message,3)),src.truename)
return
if(!host)
//TODO: have this pick a random mob within 3 tiles to speak for the borer.
to_chat(src, "You have no host to speak to.")
return //No host, no audible speech.
to_chat(src, "You drop words into [host]'s mind: \"[message]\"")
host << "Your own thoughts speak: \"[message]\""
for (var/mob/M in player_list)
if (istype(M, /mob/new_player))
continue
else if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
M << "[src.truename] whispers to [host], \"[message]\""
@@ -1,49 +0,0 @@
/mob/living/simple_animal/hostile/clown
name = "clown"
desc = "A denizen of clown planet"
tt_desc = "E Homo sapiens corydon" //this is an actual clown, as opposed to someone dressed up as one
icon_state = "clown"
icon_living = "clown"
icon_dead = "clown_dead"
icon_gib = "clown_gib"
intelligence_level = SA_HUMANOID
faction = "clown"
maxHealth = 75
health = 75
speed = -1
move_to_delay = 2
run_at_them = 0
cooperative = 1
turns_per_move = 5
stop_when_pulled = 0
response_help = "pokes"
response_disarm = "gently pushes aside"
response_harm = "hits"
harm_intent_damage = 8
melee_damage_lower = 10
melee_damage_upper = 10
attacktext = list("attacked")
attack_sound = 'sound/items/bikehorn.ogg'
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
minbodytemp = 270
maxbodytemp = 370
heat_damage_per_tick = 15 //amount of damage applied if animal's body temperature is higher than maxbodytemp
cold_damage_per_tick = 10 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
unsuitable_atoms_damage = 10
speak_chance = 1
speak = list("HONK", "Honk!", "Welcome to clown planet!")
emote_see = list("honks")
@@ -1,123 +0,0 @@
/mob/living/simple_animal/hostile/mecha
name = "mercenary gygax"
desc = "Well that's forboding."
icon = 'icons/mecha/mecha.dmi'
icon_state = "darkgygax"
icon_living = "darkgygax"
icon_dead = "darkgygax-broken"
intelligence_level = SA_HUMANOID // Piloted by a human.
faction = "syndicate"
maxHealth = 300
health = 300
speed = 7
move_to_delay = 8
run_at_them = 0
cooperative = 1
investigates = 1
firing_lines = 1
turns_per_move = 5
stop_when_pulled = 0
response_help = "taps on"
response_disarm = "knocks on"
response_harm = "uselessly hits"
harm_intent_damage = 0
melee_damage_lower = 35
melee_damage_upper = 35
attacktext = list("slashed")
attack_sound = 'sound/weapons/bladeslice.ogg'
armor = list(melee = 40, bullet = 40, laser = 50, energy = 45, bomb = 20, bio = 100, rad = 100) // As close to the actual Dark Gygax as possible
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 0
ranged = 1
rapid = 1
projectiletype = /obj/item/projectile/beam/midlaser
projectilesound = 'sound/weapons/laser.ogg'
speak_chance = 1
speak = list("Know what we need? More meatshields.",
"Glad I finally got a mech.",
"I'll stomp those NanoTrasen dogs into paste.",
"Glad I didn't become a line chef.",
"This anti-fog visor is nice...",
"Did I refill the air tank?")
emote_hear = list("humms ominously","whirrs softly","grinds a gear")
emote_see = list("looks around the area","turns from side to side")
say_understood = list()
say_cannot = list()
say_maybe_target = list("Just my sensors?","Detecting something?","Is that...?","What was that?")
say_got_target = list("ENGAGING!!!","CONTACT!!!","TARGET SPOTTED!","FOUND ONE!")
reactions = list()
var/datum/effect/effect/system/spark_spread/sparks
var/wreckage = /obj/effect/decal/mecha_wreckage/gygax/dark
/mob/living/simple_animal/hostile/mecha/New()
..()
sparks = new (src)
sparks.set_up(3, 1, src)
/mob/living/simple_animal/hostile/mecha/Destroy()
qdel(sparks)
..()
/mob/living/simple_animal/hostile/mecha/Life()
. = ..()
if(!.) return
if((health < getMaxHealth()*0.3) && prob(10))
sparks.start()
/mob/living/simple_animal/hostile/mecha/bullet_act()
..()
sparks.start()
/mob/living/simple_animal/hostile/mecha/death()
..(0,"explodes!")
sparks.start()
explosion(get_turf(src), 0, 0, 1, 3)
qdel(src)
new /obj/effect/decal/mecha_wreckage/gygax/dark(get_turf(src))
/mob/living/simple_animal/hostile/mecha/Move()
..()
playsound(src,'sound/mecha/mechstep.ogg',40,1)
// This is a PoI mob, not the normal, floaty drones that hang out around windows
/mob/living/simple_animal/hostile/mecha/malf_drone
name = "autonomous mechanized drone"
desc = "It appears to be an exosuit, piloted by a drone intelligence. It looks scary."
intelligence_level = SA_ROBOTIC
faction = "malf_drone"
speak_chance = 1
speak = list(
"Resuming task: Protect area.",
"No threats found.",
"Error: No targets found."
)
emote_hear = list("humms ominously", "whirrs softly", "grinds a gear")
emote_see = list("looks around the area", "turns from side to side")
say_understood = list("Affirmative.", "Positive.")
say_cannot = list("Denied.", "Negative.")
say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.")
say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.")
returns_home = TRUE
/mob/living/simple_animal/hostile/mecha/malf_drone/isSynthetic()
return TRUE
/mob/living/simple_animal/hostile/mecha/malf_drone/speech_bubble_appearance()
return "synthetic_evil"
@@ -1,72 +0,0 @@
/mob/living/simple_animal/hostile/pirate
name = "Pirate"
desc = "Does what he wants cause a pirate is free."
tt_desc = "E Homo sapiens"
icon_state = "piratemelee"
icon_living = "piratemelee"
icon_dead = "piratemelee_dead"
intelligence_level = SA_HUMANOID
faction = "pirate"
maxHealth = 100
health = 100
speed = 4
run_at_them = 0
cooperative = 1
investigates = 1
firing_lines = 1
returns_home = 1
reacts = 1
turns_per_move = 5
stop_when_pulled = 0
response_help = "pushes"
response_disarm = "shoves"
response_harm = "hits"
harm_intent_damage = 5
melee_damage_lower = 30
melee_damage_upper = 30
attack_armor_pen = 50
attack_sharp = 1
attack_edge = 1
attacktext = list("slashed")
attack_sound = 'sound/weapons/bladeslice.ogg'
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 15
loot_list = list(/obj/item/weapon/melee/energy/sword/pirate = 100)
var/corpse = /obj/effect/landmark/mobcorpse/pirate
/mob/living/simple_animal/hostile/pirate/ranged
name = "Pirate Gunner"
icon_state = "pirateranged"
icon_living = "pirateranged"
icon_dead = "piratemelee_dead"
ranged = 1
projectiletype = /obj/item/projectile/beam
projectilesound = 'sound/weapons/laser.ogg'
loot_list = list(/obj/item/weapon/gun/energy/laser = 100)
corpse = /obj/effect/landmark/mobcorpse/pirate/ranged
/mob/living/simple_animal/hostile/pirate/death()
..()
if(corpse)
new corpse (src.loc)
qdel(src)
return
@@ -1,68 +0,0 @@
/mob/living/simple_animal/hostile/russian
name = "russian"
desc = "For the Motherland!"
tt_desc = "E Homo sapiens"
icon_state = "russianmelee"
icon_living = "russianmelee"
icon_dead = "russianmelee_dead"
icon_gib = "syndicate_gib"
intelligence_level = SA_HUMANOID
faction = "russian"
maxHealth = 100
health = 100
speed = 4
run_at_them = 0
cooperative = 1
investigates = 1
firing_lines = 1
returns_home = 1
reacts = 1
turns_per_move = 5
stop_when_pulled = 0
status_flags = CANPUSH
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
harm_intent_damage = 5
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = list("punched")
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 15
loot_list = list(/obj/item/weapon/material/knife = 100)
var/corpse = /obj/effect/landmark/mobcorpse/russian
/mob/living/simple_animal/hostile/russian/ranged
icon_state = "russianranged"
icon_living = "russianranged"
ranged = 1
projectiletype = /obj/item/projectile/bullet
casingtype = /obj/item/ammo_casing/spent
projectilesound = 'sound/weapons/Gunshot.ogg'
loot_list = list(/obj/item/weapon/gun/projectile/revolver/mateba = 100)
corpse = /obj/effect/landmark/mobcorpse/russian/ranged
/mob/living/simple_animal/hostile/russian/death()
..()
if(corpse)
new corpse (src.loc)
qdel(src)
return
@@ -1,265 +0,0 @@
/mob/living/simple_animal/hostile/syndicate
name = "mercenary"
desc = "Death to the Company."
tt_desc = "E Homo sapiens"
icon_state = "syndicate"
icon_living = "syndicate"
icon_dead = "syndicate_dead"
icon_gib = "syndicate_gib"
intelligence_level = SA_HUMANOID
faction = "syndicate"
maxHealth = 100
health = 100
speed = 4
run_at_them = 0
cooperative = 1
investigates = 1
firing_lines = 1
returns_home = 1
reacts = 1
turns_per_move = 5
stop_when_pulled = 0
status_flags = CANPUSH
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
harm_intent_damage = 5
melee_damage_lower = 15 //Tac Knife damage
melee_damage_upper = 15
environment_smash = 1
attack_sharp = 1
attack_edge = 1
attacktext = list("slashed", "stabbed")
armor = list(melee = 40, bullet = 30, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 100) // Same armor values as the vest they drop, plus simple mob immunities
min_oxy = 5
max_oxy = 0
min_tox = 0
max_tox = 1
min_co2 = 0
max_co2 = 5
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 15
speak_chance = 1
speak = list("Fuckin' NT, man.",
"When are we gonna get out of this chicken-shit outfit?",
"Wish I had better equipment...",
"I knew I should have been a line chef...",
"Fuckin' helmet keeps fogging up.",
"Anyone else smell that?")
emote_hear = list("sniffs","coughs","taps his foot")
emote_see = list("looks around","checks his equipment")
say_understood = list()
say_cannot = list()
say_maybe_target = list("What's that?","Is someone there?","Is that...?","Hmm?")
say_got_target = list("ENGAGING!!!","CONTACT!!!","TARGET SPOTTED!","FOUND ONE!")
reactions = list("Hey guys, you ready?" = "Fuck yeah!")
var/corpse = /obj/effect/landmark/mobcorpse/syndicatesoldier
/mob/living/simple_animal/hostile/syndicate/death()
if(corpse)
..()
new corpse (src.loc)
else
..(0,"explodes!")
new /obj/effect/gibspawner/human(src.loc)
explosion(get_turf(src), -1, 0, 1, 3)
qdel(src)
return
///////////////Sword and shield////////////
/mob/living/simple_animal/hostile/syndicate/melee
icon_state = "syndicatemelee"
icon_living = "syndicatemelee"
melee_damage_lower = 30
melee_damage_upper = 30
attack_armor_pen = 50
attack_sharp = 1
attack_edge = 1
attacktext = list("slashed")
status_flags = 0
loot_list = list(/obj/item/weapon/melee/energy/sword/red = 100, /obj/item/weapon/shield/energy = 100)
/mob/living/simple_animal/hostile/syndicate/melee/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(O.force)
if(prob(20))
visible_message("<span class='danger'>\The [src] blocks \the [O] with its shield!</span>")
if(user)
react_to_attack(user)
return
else
..()
else
usr << "<span class='warning'>This weapon is ineffective, it does no damage.</span>"
visible_message("<span class='warning'>\The [user] gently taps [src] with \the [O].</span>")
/mob/living/simple_animal/hostile/syndicate/melee/bullet_act(var/obj/item/projectile/Proj)
if(!Proj) return
if(prob(35))
visible_message("<font color='red'><B>[src] blocks [Proj] with its shield!</B></font>")
if(Proj.firer)
react_to_attack(Proj.firer)
return
else
..()
/mob/living/simple_animal/hostile/syndicate/melee/space
name = "syndicate commando"
icon_state = "syndicatemeleespace"
icon_living = "syndicatemeleespace"
speed = 0
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 100) // Same armor as their voidsuit
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
corpse = /obj/effect/landmark/mobcorpse/syndicatecommando
/mob/living/simple_animal/hostile/syndicate/melee/space/Process_Spacemove(var/check_drift = 0)
return
/mob/living/simple_animal/hostile/syndicate/ranged
icon_state = "syndicateranged"
icon_living = "syndicateranged"
ranged = 1
rapid = 1
projectiletype = /obj/item/projectile/bullet/pistol/medium
// casingtype = /obj/item/ammo_casing/spent //Makes infinite stacks of bullets when put in PoIs.
projectilesound = 'sound/weapons/Gunshot_light.ogg'
loot_list = list(/obj/item/weapon/gun/projectile/automatic/c20r = 100)
/mob/living/simple_animal/hostile/syndicate/ranged/laser
icon_state = "syndicateranged_laser"
icon_living = "syndicateranged_laser"
rapid = 0
projectiletype = /obj/item/projectile/beam/midlaser
projectilesound = 'sound/weapons/Laser.ogg'
loot_list = list(/obj/item/weapon/gun/energy/laser = 100)
/mob/living/simple_animal/hostile/syndicate/ranged/ionrifle
icon_state = "syndicateranged_ionrifle"
icon_living = "syndicateranged_ionrifle"
rapid = 0
projectiletype = /obj/item/projectile/ion
projectilesound = 'sound/weapons/Laser.ogg'
loot_list = list(/obj/item/weapon/gun/energy/ionrifle = 100)
/mob/living/simple_animal/hostile/syndicate/ranged/space
name = "syndicate sommando"
icon_state = "syndicaterangedpsace"
icon_living = "syndicaterangedpsace"
speed = 0
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
corpse = /obj/effect/landmark/mobcorpse/syndicatecommando
/mob/living/simple_animal/hostile/syndicate/ranged/space/Process_Spacemove(var/check_drift = 0)
return
///////////////////////////////////////////////
// POI Mobs
// Don't leave corpses, to help balance loot.
///////////////////////////////////////////////
/mob/living/simple_animal/hostile/syndicate/poi
loot_list = list()
corpse = null
/mob/living/simple_animal/hostile/syndicate/melee/poi
loot_list = list()
corpse = null
/mob/living/simple_animal/hostile/syndicate/melee/space/poi
loot_list = list()
corpse = null
/mob/living/simple_animal/hostile/syndicate/ranged/poi
loot_list = list()
corpse = null
/mob/living/simple_animal/hostile/syndicate/ranged/laser/poi
loot_list = list()
corpse = null
/mob/living/simple_animal/hostile/syndicate/ranged/ionrifle/poi
loot_list = list()
corpse = null
/mob/living/simple_animal/hostile/syndicate/ranged/space/poi
loot_list = list()
corpse = null
//Viscerators
/mob/living/simple_animal/hostile/viscerator
name = "viscerator"
desc = "A small, twin-bladed machine capable of inflicting very deadly lacerations."
icon = 'icons/mob/critter.dmi'
icon_state = "viscerator_attack"
icon_living = "viscerator_attack"
intelligence_level = SA_ROBOTIC
hovering = TRUE
faction = "syndicate"
maxHealth = 15
health = 15
pass_flags = PASSTABLE
melee_damage_lower = 15
melee_damage_upper = 15
attack_sharp = 1
attack_edge = 1
attack_sound = 'sound/weapons/bladeslice.ogg'
attacktext = list("cut")
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
/mob/living/simple_animal/hostile/viscerator/death()
..(null,"is smashed into pieces!")
qdel(src)
File diff suppressed because it is too large Load Diff
@@ -1,311 +0,0 @@
/mob/living/simple_animal/instantiate_hud(var/datum/hud/hud)
if(!client)
return //Why bother.
var/ui_style = 'icons/mob/screen1_animal.dmi'
if(ui_icons)
ui_style = ui_icons
var/ui_color = "#ffffff"
var/ui_alpha = 255
var/list/adding = list()
var/list/other = list()
var/list/hotkeybuttons = list()
var/list/slot_info = list()
hud.adding = adding
hud.other = other
hud.hotkeybuttons = hotkeybuttons
var/list/hud_elements = list()
var/obj/screen/using
var/obj/screen/inventory/inv_box
var/has_hidden_gear
if(LAZYLEN(hud_gears))
for(var/gear_slot in hud_gears)
inv_box = new /obj/screen/inventory()
inv_box.icon = ui_style
inv_box.color = ui_color
inv_box.alpha = ui_alpha
var/list/slot_data = hud_gears[gear_slot]
inv_box.name = gear_slot
inv_box.screen_loc = slot_data["loc"]
inv_box.slot_id = slot_data["slot"]
inv_box.icon_state = slot_data["state"]
slot_info["[inv_box.slot_id]"] = inv_box.screen_loc
if(slot_data["dir"])
inv_box.set_dir(slot_data["dir"])
if(slot_data["toggle"])
other += inv_box
has_hidden_gear = 1
else
adding += inv_box
if(has_hidden_gear)
using = new /obj/screen()
using.name = "toggle"
using.icon = ui_style
using.icon_state = "other"
using.screen_loc = ui_inventory
using.hud_layerise()
using.color = ui_color
using.alpha = ui_alpha
adding += using
//Intent Backdrop
using = new /obj/screen()
using.name = "act_intent"
using.icon = ui_style
using.icon_state = "intent_"+a_intent
using.screen_loc = ui_acti
using.color = ui_color
using.alpha = ui_alpha
hud.adding += using
hud.action_intent = using
hud_elements |= using
//Small intent quarters
var/icon/ico
ico = new(ui_style, "black")
ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height())
using = new /obj/screen()
using.name = I_HELP
using.icon = ico
using.screen_loc = ui_acti
using.alpha = ui_alpha
using.layer = LAYER_HUD_ITEM //These sit on the intent box
hud.adding += using
hud.help_intent = using
ico = new(ui_style, "black")
ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height())
using = new /obj/screen()
using.name = I_DISARM
using.icon = ico
using.screen_loc = ui_acti
using.alpha = ui_alpha
using.layer = LAYER_HUD_ITEM
hud.adding += using
hud.disarm_intent = using
ico = new(ui_style, "black")
ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2)
using = new /obj/screen()
using.name = I_GRAB
using.icon = ico
using.screen_loc = ui_acti
using.alpha = ui_alpha
using.layer = LAYER_HUD_ITEM
hud.adding += using
hud.grab_intent = using
ico = new(ui_style, "black")
ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2)
using = new /obj/screen()
using.name = I_HURT
using.icon = ico
using.screen_loc = ui_acti
using.alpha = ui_alpha
using.layer = LAYER_HUD_ITEM
hud.adding += using
hud.hurt_intent = using
//Move intent (walk/run)
using = new /obj/screen()
using.name = "mov_intent"
using.icon = ui_style
using.icon_state = (m_intent == "run" ? "running" : "walking")
using.screen_loc = ui_movi
using.color = ui_color
using.alpha = ui_alpha
hud.adding += using
hud.move_intent = using
//Resist button
using = new /obj/screen()
using.name = "resist"
using.icon = ui_style
using.icon_state = "act_resist"
using.screen_loc = ui_pull_resist
using.color = ui_color
using.alpha = ui_alpha
hud.hotkeybuttons += using
//Pull button
pullin = new /obj/screen()
pullin.icon = ui_style
pullin.icon_state = "pull0"
pullin.name = "pull"
pullin.screen_loc = ui_pull_resist
hud.hotkeybuttons += pullin
hud_elements |= pullin
//Health status
healths = new /obj/screen()
healths.icon = ui_style
healths.icon_state = "health0"
healths.name = "health"
healths.screen_loc = ui_health
hud_elements |= healths
//Oxygen dep icon
oxygen = new /obj/screen()
oxygen.icon = ui_style
oxygen.icon_state = "oxy0"
oxygen.name = "oxygen"
oxygen.screen_loc = ui_oxygen
hud_elements |= oxygen
//Toxins present icon
toxin = new /obj/screen()
toxin.icon = ui_style
toxin.icon_state = "tox0"
toxin.name = "toxin"
toxin.screen_loc = ui_toxin
hud_elements |= toxin
//Fire warning
fire = new /obj/screen()
fire.icon = ui_style
fire.icon_state = "fire0"
fire.name = "fire"
fire.screen_loc = ui_fire
hud_elements |= fire
//Pressure warning
pressure = new /obj/screen()
pressure.icon = ui_style
pressure.icon_state = "pressure0"
pressure.name = "pressure"
pressure.screen_loc = ui_pressure
hud_elements |= pressure
//Body temp warning
bodytemp = new /obj/screen()
bodytemp.icon = ui_style
bodytemp.icon_state = "temp0"
bodytemp.name = "body temperature"
bodytemp.screen_loc = ui_temp
hud_elements |= bodytemp
//Nutrition status
nutrition_icon = new /obj/screen()
nutrition_icon.icon = ui_style
nutrition_icon.icon_state = "nutrition0"
nutrition_icon.name = "nutrition"
nutrition_icon.screen_loc = ui_nutrition
hud_elements |= nutrition_icon
pain = new /obj/screen( null )
zone_sel = new /obj/screen/zone_sel( null )
zone_sel.icon = ui_style
zone_sel.color = ui_color
zone_sel.alpha = ui_alpha
zone_sel.overlays.Cut()
zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]")
hud_elements |= zone_sel
//Hand things
if(has_hands)
//Drop button
using = new /obj/screen()
using.name = "drop"
using.icon = ui_style
using.icon_state = "act_drop"
using.screen_loc = ui_drop_throw
using.color = ui_color
using.alpha = ui_alpha
hud.hotkeybuttons += using
//Equip detail
using = new /obj/screen()
using.name = "equip"
using.icon = ui_style
using.icon_state = "act_equip"
using.screen_loc = ui_equip
using.color = ui_color
using.alpha = ui_alpha
hud.adding += using
//Hand slots themselves
inv_box = new /obj/screen/inventory/hand()
inv_box.hud = src
inv_box.name = "r_hand"
inv_box.icon = ui_style
inv_box.icon_state = "r_hand_inactive"
if(!hand) //This being 0 or null means the right hand is in use
inv_box.icon_state = "r_hand_active"
inv_box.screen_loc = ui_rhand
inv_box.slot_id = slot_r_hand
inv_box.color = ui_color
inv_box.alpha = ui_alpha
hud.r_hand_hud_object = inv_box
hud.adding += inv_box
slot_info["[slot_r_hand]"] = inv_box.screen_loc
inv_box = new /obj/screen/inventory/hand()
inv_box.hud = src
inv_box.name = "l_hand"
inv_box.icon = ui_style
inv_box.icon_state = "l_hand_inactive"
if(hand) //This being 1 means the left hand is in use
inv_box.icon_state = "l_hand_active"
inv_box.screen_loc = ui_lhand
inv_box.slot_id = slot_l_hand
inv_box.color = ui_color
inv_box.alpha = ui_alpha
hud.l_hand_hud_object = inv_box
hud.adding += inv_box
slot_info["[slot_l_hand]"] = inv_box.screen_loc
//Swaphand titlebar
using = new /obj/screen/inventory()
using.name = "hand"
using.icon = ui_style
using.icon_state = "hand1"
using.screen_loc = ui_swaphand1
using.color = ui_color
using.alpha = ui_alpha
hud.adding += using
using = new /obj/screen/inventory()
using.name = "hand"
using.icon = ui_style
using.icon_state = "hand2"
using.screen_loc = ui_swaphand2
using.color = ui_color
using.alpha = ui_alpha
hud.adding += using
//Throw button
throw_icon = new /obj/screen()
throw_icon.icon = ui_style
throw_icon.icon_state = "act_throw_off"
throw_icon.name = "throw"
throw_icon.screen_loc = ui_drop_throw
throw_icon.color = ui_color
throw_icon.alpha = ui_alpha
hud.hotkeybuttons += throw_icon
hud_elements |= throw_icon
extra_huds(hud,ui_style,hud_elements)
client.screen = list()
client.screen += hud_elements
client.screen += adding + hotkeybuttons
client.screen += client.void
return
@@ -1,91 +0,0 @@
/mob/living/simple_animal/slime/FindTarget()
if(victim) // Don't worry about finding another target if we're eatting someone.
return
if(follow_mob && can_command(follow_mob)) // If following someone, don't attack until the leader says so, something hits you, or the leader is no longer worthy.
return
..()
/mob/living/simple_animal/slime/Found(mob/living/L)
if(isliving(L))
if(SA_attackable(L))
if(L.faction == faction && !attack_same)
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too.
return H // Monkeys are always food.
else
return
if(L in friends)
return
if(istype(L, /mob/living/simple_animal/slime))
var/mob/living/simple_animal/slime/buddy = L
if(buddy.slime_color == src.slime_color || discipline || unity || buddy.unity)
return // Don't hurt same colored slimes.
else
return buddy //do hurt others
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too.
return H // Monkeys are always food.
if(issilicon(L) || isbot(L))
if(discipline && !rabid)
return // We're a good slime. For now at least.
return
return
/mob/living/simple_animal/slime/special_target_check(mob/living/L)
if(L.faction == faction && !attack_same && !istype(L, /mob/living/simple_animal/slime))
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too.
return TRUE // Monkeys are always food.
else
return FALSE
if(L in friends)
return FALSE
if(istype(L, /mob/living/simple_animal/slime))
var/mob/living/simple_animal/slime/buddy = L
if(buddy.slime_color == src.slime_color || discipline || unity || buddy.unity)
return FALSE // Don't hurt same colored slimes.
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.species && H.species.name == "Promethean")
return FALSE // Prometheans are always our friends.
else if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too.
return TRUE // Monkeys are always food.
if(discipline && !rabid)
return FALSE // We're a good slime. For now at least
if(issilicon(L) || isbot(L) )
if(discipline && !rabid)
return FALSE // We're a good slime. For now at least.
return ..() // Other colors and nonslimes are jerks however.
/mob/living/simple_animal/slime/ClosestDistance()
if(target_mob.stat == DEAD)
return 1 // Melee (eat) the target if dead, don't shoot it.
return ..()
/mob/living/simple_animal/slime/HelpRequested(var/mob/living/simple_animal/slime/buddy)
if(istype(buddy))
if(buddy.slime_color != src.slime_color && (!unity || !buddy.unity)) // We only help slimes of the same color, if it's another slime calling for help.
ai_log("HelpRequested() by [buddy] but they are a [buddy.slime_color] while we are a [src.slime_color].",2)
return
if(buddy.target_mob)
if(!special_target_check(buddy.target_mob))
ai_log("HelpRequested() by [buddy] but special_target_check() failed when passed [buddy.target_mob].",2)
return
..()
/mob/living/simple_animal/slime/handle_resist()
if(buckled && victim && isliving(buckled) && victim == buckled) // If it's buckled to a living thing it's probably eating it.
return
else
..()
@@ -1,277 +0,0 @@
/*
// Check target_mob if worthy of attack
/mob/living/simple_animal/slime/SA_attackable(target_mob)
ai_log("SA_attackable([target_mob])",3)
if(isliving(target_mob))
var/mob/living/L = target_mob
if(L.stat == DEAD)
if(can_consume(L)) // If we can eat them, then it doesn't matter if they're dead.
return TRUE
..()
*/
/mob/living/simple_animal/slime/PunchTarget()
if(victim)
return // Already eatting someone.
if(!client) // AI controlled.
if( (!target_mob.lying && prob(60 + (power_charge * 4) ) || (!target_mob.lying && optimal_combat) )) // "Smart" slimes always stun first.
a_intent = I_DISARM // Stun them first.
else if(can_consume(target_mob) && target_mob.lying)
a_intent = I_GRAB // Then eat them.
else
a_intent = I_HURT // Otherwise robust them.
ai_log("PunchTarget() will [a_intent] [target_mob]",2)
..()
/mob/living/simple_animal/slime/proc/can_consume(var/mob/living/L)
if(!L || !istype(L))
to_chat(src, "This subject is incomparable...")
return FALSE
if(L.isSynthetic())
to_chat(src, "This subject is not biological...")
return FALSE
if(L.getarmor(null, "bio") >= 75)
to_chat(src, "I cannot reach this subject's biological matter...")
return FALSE
if(istype(L, /mob/living/simple_animal/slime))
to_chat(src, "I cannot feed on other slimes...")
return FALSE
if(!Adjacent(L))
to_chat(src, "This subject is too far away...")
return FALSE
if(istype(L, /mob/living/carbon) && L.getCloneLoss() >= L.getMaxHealth() * 1.5 || istype(L, /mob/living/simple_animal) && L.stat == DEAD)
to_chat(src, "This subject does not have an edible life energy...")
return FALSE
if(L.has_buckled_mobs())
for(var/A in L.buckled_mobs)
if(istype(A, /mob/living/simple_animal/slime))
if(A != src)
to_chat(src, "\The [A] is already feeding on this subject...")
return FALSE
return TRUE
/mob/living/simple_animal/slime/proc/start_consuming(var/mob/living/L)
if(!can_consume(L))
return
if(!Adjacent(L))
return
step_towards(src, L) // Get on top of them to feed.
if(loc != L.loc)
return
if(L.buckle_mob(src, forced = TRUE))
victim = L
update_icon()
victim.visible_message("<span class='danger'>\The [src] latches onto [victim]!</span>",
"<span class='danger'>\The [src] latches onto you!</span>")
/mob/living/simple_animal/slime/proc/stop_consumption()
if(!victim)
return
victim.unbuckle_mob()
victim.visible_message("<span class='notice'>\The [src] slides off of [victim]!</span>",
"<span class='notice'>\The [src] slides off of you!</span>")
victim = null
update_icon()
/mob/living/simple_animal/slime/proc/handle_consumption()
if(victim && can_consume(victim) && !stat)
var/armor_modifier = abs((victim.getarmor(null, "bio") / 100) - 1)
if(istype(victim, /mob/living/carbon))
victim.adjustCloneLoss(rand(5,6) * armor_modifier)
victim.adjustToxLoss(rand(1,2) * armor_modifier)
if(victim.health <= 0)
victim.adjustToxLoss(rand(2,4) * armor_modifier)
else if(istype(victim, /mob/living/simple_animal))
victim.adjustBruteLoss(is_adult ? rand(7, 15) : rand(4, 12))
else
to_chat(src, "<span class='warning'>[pick("This subject is incompatable", \
"This subject does not have a life energy", "This subject is empty", "I am not satisified", \
"I can not feed from this subject", "I do not feel nourished", "This subject is not food")]...</span>")
stop_consumption()
adjust_nutrition(50 * armor_modifier)
adjustOxyLoss(-10 * armor_modifier) //Heal yourself
adjustBruteLoss(-10 * armor_modifier)
adjustFireLoss(-10 * armor_modifier)
adjustCloneLoss(-10 * armor_modifier)
updatehealth()
if(victim)
victim.updatehealth()
else
stop_consumption()
/mob/living/simple_animal/slime/DoPunch(var/mob/living/L)
if(!Adjacent(L)) // Might've moved away in the meantime.
return
if(istype(L))
if(ishuman(L))
var/mob/living/carbon/human/H = L
// Slime attacks can be blocked with shields.
if(H.check_shields(damage = 0, damage_source = null, attacker = src, def_zone = null, attack_text = "the attack"))
return
switch(a_intent)
if(I_HELP)
ai_log("DoPunch() against [L], helping.",2)
L.visible_message("<span class='notice'>[src] gently pokes [L]!</span>",
"<span class='notice'>[src] gently pokes you!</span>")
do_attack_animation(L)
post_attack(L, a_intent)
if(I_DISARM)
ai_log("DoPunch() against [L], disarming.",2)
var/stun_power = between(0, power_charge + rand(0, 3), 10)
if(ishuman(L))
var/mob/living/carbon/human/H = L
stun_power *= max(H.species.siemens_coefficient,0)
if(prob(stun_power * 10))
power_charge = max(0, power_charge - 3)
L.visible_message("<span class='danger'>[src] has shocked [L]!</span>", "<span class='danger'>[src] has shocked you!</span>")
playsound(src, 'sound/weapons/Egloves.ogg', 75, 1)
L.Weaken(4)
L.Stun(4)
do_attack_animation(L)
if(L.buckled)
L.buckled.unbuckle_mob() // To prevent an exploit where being buckled prevents slimes from jumping on you.
L.stuttering = max(L.stuttering, stun_power)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, L)
s.start()
if(prob(stun_power * 10) && stun_power >= 8)
L.adjustFireLoss(power_charge * rand(1, 2))
post_attack(L, a_intent)
else if(prob(40))
L.visible_message("<span class='danger'>[src] has pounced at [L]!</span>", "<span class='danger'>[src] has pounced at you!</span>")
playsound(src, 'sound/weapons/thudswoosh.ogg', 75, 1)
L.Weaken(2)
do_attack_animation(L)
if(L.buckled)
L.buckled.unbuckle_mob() // To prevent an exploit where being buckled prevents slimes from jumping on you.
post_attack(L, a_intent)
else
L.visible_message("<span class='danger'>[src] has tried to pounce at [L]!</span>", "<span class='danger'>[src] has tried to pounce at you!</span>")
playsound(src, 'sound/weapons/punchmiss.ogg', 75, 1)
do_attack_animation(L)
L.updatehealth()
return L
if(I_GRAB)
ai_log("DoPunch() against [L], grabbing.",2)
start_consuming(L)
post_attack(L, a_intent)
if(I_HURT)
ai_log("DoPunch() against [L], hurting.",2)
var/damage_to_do = rand(melee_damage_lower, melee_damage_upper)
var/armor_modifier = abs((L.getarmor(null, "bio") / 100) - 1)
L.attack_generic(src, damage_to_do, pick(attacktext))
playsound(src, 'sound/weapons/bite.ogg', 75, 1)
// Give the slime some nutrition, if applicable.
if(!L.isSynthetic())
if(ishuman(L))
if(L.getCloneLoss() < L.getMaxHealth() * 1.5)
adjust_nutrition(damage_to_do * armor_modifier)
else if(istype(L, /mob/living/simple_animal))
if(!isslime(L))
var/mob/living/simple_animal/SA = L
if(!SA.stat)
adjust_nutrition(damage_to_do)
post_attack(L, a_intent)
if(istype(L,/obj/mecha))
var/obj/mecha/M = L
M.attack_generic(src, rand(melee_damage_lower, melee_damage_upper), pick(attacktext))
/mob/living/simple_animal/slime/proc/post_attack(var/mob/living/L, var/intent = I_HURT)
if(intent != I_HELP)
if(L.reagents && L.can_inject() && reagent_injected)
L.reagents.add_reagent(reagent_injected, injection_amount)
/mob/living/simple_animal/slime/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/clothing/head)) // Handle hat simulator.
give_hat(W, user)
return
// Otherwise they're probably fighting the slime.
if(prob(25))
visible_message("<span class='danger'>\The [user]'s [W] passes right through [src]!</span>")
user.setClickCooldown(user.get_attack_speed(W))
return
..()
/mob/living/simple_animal/slime/hit_with_weapon(obj/item/O, mob/living/user, var/effective_force, var/hit_zone)
..()
if(!stat)
if(O.force > 0 && discipline && !rabid) // wow, buddy, why am I getting attacked??
adjust_discipline(1)
return
if(O.force >= 3)
if(victim || target_mob) // We've been a bad slime.
if(is_adult)
if(prob(5 + round(O.force / 2)) )
if(prob(80) && !client)
adjust_discipline(2)
if(user)
step_away(src, user)
else
if(prob(10 + O.force * 2))
if(prob(80) && !client)
adjust_discipline(2)
if(user)
step_away(src, user)
else
if(user in friends) // Friend attacking us for no reason.
if(prob(25))
friends -= user
say("[user]... not friend...")
/mob/living/simple_animal/slime/attack_hand(mob/living/carbon/human/M as mob)
if(victim) // Are we eating someone?
var/fail_odds = 30
if(victim == M) // Harder to get the slime off if its eating you right now.
fail_odds = 60
if(prob(fail_odds))
visible_message("<span class='warning'>[M] attempts to wrestle \the [name] off!</span>")
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
else
visible_message("<span class='warning'> [M] manages to wrestle \the [name] off!</span>")
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(prob(40) && !client)
adjust_discipline(1)
stop_consumption()
step_away(src,M)
else
if(M.a_intent == I_HELP)
if(hat)
remove_hat(M)
else
..()
else
..()
// Shocked grilles don't hurt slimes, and in fact give them charge.
/mob/living/simple_animal/slime/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null)
power_charge = between(0, power_charge + round(shock_damage / 10), 10)
to_chat(src, "<span class='notice'>\The [source] shocks you, and it charges you.</span>")
@@ -1,27 +0,0 @@
/mob/living/simple_animal/slime/death(gibbed)
if(stat == DEAD)
return
if(!gibbed && is_adult)
var/death_type = type_on_death
if(!death_type)
death_type = src.type
var/mob/living/simple_animal/slime/S = make_new_slime(death_type)
S.rabid = TRUE
step_away(S, src)
is_adult = FALSE
maxHealth = initial(maxHealth)
revive()
if(!client)
rabid = TRUE
number = rand(1, 1000)
update_name()
return
stop_consumption()
. = ..(gibbed, "stops moving and partially dissolves...")
update_icon()
return
@@ -1,183 +0,0 @@
/mob/living/simple_animal/slime/proc/adjust_nutrition(input)
nutrition = between(0, nutrition + input, get_max_nutrition())
if(input > 0)
if(prob(input * 2)) // Gain around one level per 50 nutrition
power_charge = min(power_charge++, 10)
if(power_charge == 10)
adjustToxLoss(-10)
/mob/living/simple_animal/slime/proc/get_max_nutrition() // Can't go above it
if(is_adult)
return 1200
return 1000
/mob/living/simple_animal/slime/proc/get_grow_nutrition() // Above it we grow, below it we can eat
if(is_adult)
return 1000
return 800
/mob/living/simple_animal/slime/proc/get_hunger_nutrition() // Below it we will always eat
if(is_adult)
return 600
return 500
/mob/living/simple_animal/slime/proc/get_starve_nutrition() // Below it we will eat before everything else
if(is_adult)
return 300
return 200
/mob/living/simple_animal/slime/proc/handle_nutrition()
if(docile)
return
if(prob(15))
adjust_nutrition(-1 - is_adult)
if(nutrition <= get_starve_nutrition())
handle_starvation()
else if(nutrition >= get_grow_nutrition() && amount_grown < 10)
adjust_nutrition(-20)
amount_grown = between(0, amount_grown + 1, 10)
/mob/living/simple_animal/slime/proc/handle_starvation()
if(nutrition < get_starve_nutrition() && !client) // if a slime is starving, it starts losing its friends
if(friends.len && prob(1))
var/mob/nofriend = pick(friends)
if(nofriend)
friends -= nofriend
say("[nofriend]... food now...")
if(nutrition <= 0)
adjustToxLoss(rand(1,3))
if(client && prob(5))
to_chat(src, "<span class='danger'>You are starving!</span>")
/mob/living/simple_animal/slime/proc/handle_discipline()
if(discipline > 0)
update_mood()
// if(discipline >= 5 && rabid)
// if(prob(60))
// rabid = 0
// adjust_discipline(1) // So it stops trying to murder everyone.
// Handle discipline decay.
if(!prob(75 + (obedience * 5)))
adjust_discipline(-1)
if(!discipline)
update_mood()
/mob/living/simple_animal/slime/handle_regular_status_updates()
if(stat != DEAD)
handle_nutrition()
handle_discipline()
if(prob(30))
adjustOxyLoss(-1)
adjustToxLoss(-1)
adjustFireLoss(-1)
adjustCloneLoss(-1)
adjustBruteLoss(-1)
if(victim)
handle_consumption()
if(amount_grown >= 10 && !target_mob && !client)
if(is_adult)
reproduce()
else
evolve()
handle_stuttering()
..()
// This is to make slime responses feel a bit more natural and not instant.
/mob/living/simple_animal/slime/proc/delayed_say(var/message, var/mob/target)
spawn(rand(1 SECOND, 2 SECONDS))
if(target)
face_atom(target)
say(message)
//Commands, reactions, etc
/mob/living/simple_animal/slime/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
..()
if((findtext(message, num2text(number)) || findtext(message, name) || findtext(message, "slimes"))) // Talking to us
// First make sure it's not just another slime repeating things.
if(istype(speaker, /mob/living/simple_animal/slime))
if(!speaker.client)
return
//Are all slimes being referred to?
var/mass_order = 0
if(findtext(message, "slimes"))
mass_order = 1
// Say hello back.
if(findtext(message, "hello") || findtext(message, "hi") || findtext(message, "greetings"))
delayed_say(pick("Hello...", "Hi..."), speaker)
// Follow request.
if(findtext(message, "follow") || findtext(message, "come with me"))
if(!can_command(speaker))
delayed_say(pick("No...", "I won't follow..."), speaker)
return
delayed_say("Yes... I follow \the [speaker]...", speaker)
set_follow(speaker)
FollowTarget()
// Stop request.
if(findtext(message, "stop") || findtext(message, "halt") || findtext(message, "cease"))
if(victim) // We're being asked to stop eatting someone.
if(!can_command(speaker))
delayed_say("No...", speaker)
return
else
delayed_say("Fine...", speaker)
stop_consumption()
adjust_discipline(1, TRUE)
if(target_mob) // We're being asked to stop chasing someone.
if(!can_command(speaker))
delayed_say("No...", speaker)
return
else
delayed_say("Fine...", speaker)
LoseTarget()
adjust_discipline(1, TRUE)
if(follow_mob) // We're being asked to stop following someone.
if(can_command(speaker) == SLIME_COMMAND_FRIEND || follow_mob == speaker)
delayed_say("Yes... I'll stop...", speaker)
LoseFollow()
else
delayed_say("No... I'll keep following \the [follow_mob]...", speaker)
// Murder request
if(findtext(message, "harm") || findtext(message, "kill") || findtext(message, "murder") || findtext(message, "eat") || findtext(message, "consume"))
if(can_command(speaker) < SLIME_COMMAND_FACTION)
delayed_say("No...", speaker)
return
for(var/mob/living/L in view(7, src) - list(src, speaker))
if(L == src)
continue // Don't target ourselves.
var/list/valid_names = splittext(L.name, " ") // Should output list("John", "Doe") as an example.
for(var/line in valid_names) // Check each part of someone's name.
if(findtext(message, lowertext(line))) // If part of someone's name is in the command, the slime targets them if allowed to.
if(!(mass_order && line == "slime")) //don't think random other slimes are target
if(special_target_check(L))
delayed_say("Okay... I attack \the [L]...", speaker)
LoseFollow()
set_target(L, 1)
return
else
delayed_say("No... I won't attack \the [L].", speaker)
return
// If we're here, it couldn't find anyone with that name.
delayed_say("No... I don't know who to attack...", speaker)
@@ -1,470 +0,0 @@
/mob/living/simple_animal/slime
name = "slime"
desc = "The most basic of slimes. The grey slime has no remarkable qualities, however it remains one of the most useful colors for scientists."
tt_desc = "A Macrolimbus vulgaris"
icon = 'icons/mob/slime2.dmi'
icon_state = "grey baby slime"
intelligence_level = SA_ANIMAL
pass_flags = PASSTABLE
var/shiny = FALSE // If true, will add a 'shiny' overlay.
var/glows = FALSE // If true, will glow in the same color as the color var.
var/icon_state_override = null // Used for special slime appearances like the rainbow slime.
pass_flags = PASSTABLE
makes_dirt = FALSE // Goop
speak_emote = list("chirps")
maxHealth = 150
var/maxHealth_adult = 200
melee_damage_lower = 10
melee_damage_upper = 15
melee_miss_chance = 0
gender = NEUTER
// Atmos stuff.
minbodytemp = T0C-30
heat_damage_per_tick = 0
cold_damage_per_tick = 40
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 0
response_help = "pets"
speak = list(
"Blorp...",
"Blop..."
)
emote_hear = list(
)
emote_see = list(
"bounces",
"jiggles",
"sways"
)
hostile = 1
retaliate = 1
attack_same = 1
cooperative = 1
faction = "slime" // Slimes will help other slimes, provided they share the same color.
color = "#CACACA"
var/is_adult = FALSE
var/cores = 1 // How many cores you get when placed in a Processor.
var/power_charge = 0 // 0-10 controls how much electricity they are generating. High numbers encourage the slime to stun someone with electricity.
var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces
var/number = 0 // This is used to make the slime semi-unique for indentification.
var/mob/living/victim = null // the person the slime is currently feeding on
var/rabid = FALSE // If true, will attack anyone and everyone.
var/docile = FALSE // Basically the opposite of above. If true, will never harm anything and won't get hungry.
var/discipline = 0 // Beating slimes makes them less likely to lash out. In theory.
var/resentment = 0 // 'Unjustified' beatings make this go up, and makes it more likely for abused slimes to go berserk.
var/obedience = 0 // Conversely, 'justified' beatings make this go up, and makes discipline decay slowly, potentially making it not decay at all.
var/unity = FALSE // If true, slimes will consider other colors as their own. Other slimes will see this slime as the same color as well. A rainbow slime is required to get this.
var/optimal_combat = FALSE // Used to dumb down the combat AI somewhat. If true, the slime tends to be really dangerous to fight alone due to stunlocking.
var/mood = ":3" // Icon to use to display 'mood'.
var/obj/item/clothing/head/hat = null // The hat the slime may be wearing.
var/slime_color = "grey"
var/mutation_chance = 25 // Odds of spawning as a new color when reproducing. Can be modified by certain xenobio products. Carried across generations of slimes.
var/coretype = /obj/item/slime_extract/grey
// List of potential slime color mutations. This must have exactly four types.
var/list/slime_mutation = list(
/mob/living/simple_animal/slime/orange,
/mob/living/simple_animal/slime/metal,
/mob/living/simple_animal/slime/blue,
/mob/living/simple_animal/slime/purple
)
var/type_on_death = null // Set this if you want dying slimes to split into a specific type and not their type.
var/rainbow_core_candidate = TRUE // If false, rainbow cores cannot make this type randomly.
var/reagent_injected = null // Some slimes inject reagents on attack. This tells the game what reagent to use.
var/injection_amount = 5 // This determines how much.
can_enter_vent_with = list(
/obj/item/clothing/head,
)
/mob/living/simple_animal/slime/New(var/location, var/start_as_adult = FALSE)
verbs += /mob/living/proc/ventcrawl
if(start_as_adult)
make_adult()
health = maxHealth
// slime_mutation = mutation_table(slime_color)
update_icon()
number = rand(1, 1000)
update_name()
..(location)
/mob/living/simple_animal/slime/Destroy()
if(hat)
drop_hat()
return ..()
/mob/living/simple_animal/slime/proc/make_adult()
if(is_adult)
return
is_adult = TRUE
melee_damage_lower = 20
melee_damage_upper = 40
maxHealth = maxHealth_adult
amount_grown = 0
update_icon()
update_name()
/mob/living/simple_animal/slime/proc/update_name()
if(docile) // Docile slimes are generally named, so we shouldn't mess with it.
return
name = "[slime_color] [is_adult ? "adult" : "baby"] [initial(name)] ([number])"
real_name = name
/mob/living/simple_animal/slime/update_icon()
if(stat == DEAD)
icon_state = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"] dead"
set_light(0)
else
if(incapacitated(INCAPACITATION_DISABLED))
icon_state = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"] dead"
else
icon_state = "[icon_state_override ? "[icon_state_override] slime" : "slime"] [is_adult ? "adult" : "baby"][victim ? " eating":""]"
overlays.Cut()
if(stat != DEAD)
var/image/I = image(icon, src, "slime light")
I.appearance_flags = RESET_COLOR
overlays += I
if(shiny)
I = image(icon, src, "slime shiny")
I.appearance_flags = RESET_COLOR
overlays += I
I = image(icon, src, "aslime-[mood]")
I.appearance_flags = RESET_COLOR
overlays += I
if(glows)
set_light(3, 2, color)
if(hat)
var/hat_state = hat.item_state ? hat.item_state : hat.icon_state
var/image/I = image('icons/mob/head.dmi', src, hat_state)
I.pixel_y = -7 // Slimes are small.
I.appearance_flags = RESET_COLOR
overlays += I
if(modifier_overlay) // Restore our modifier overlay.
overlays += modifier_overlay
/mob/living/simple_animal/slime/proc/update_mood()
var/old_mood = mood
if(incapacitated(INCAPACITATION_DISABLED))
mood = "sad"
else if(rabid)
mood = "angry"
else if(target_mob)
mood = "mischevous"
else if(discipline)
mood = "pout"
else if(docile)
mood = ":33"
else
mood = ":3"
if(old_mood != mood)
update_icon()
// Makes the slime very angry and dangerous.
/mob/living/simple_animal/slime/proc/enrage()
if(docile)
return
rabid = TRUE
update_mood()
visible_message("<span class='danger'>\The [src] enrages!</span>")
// Makes the slime safe and harmless.
/mob/living/simple_animal/slime/proc/pacify()
rabid = FALSE
docile = TRUE
hostile = FALSE
retaliate = FALSE
cooperative = FALSE
// If for whatever reason the mob AI decides to try to attack something anyways.
melee_damage_upper = 0
melee_damage_lower = 0
update_mood()
/mob/living/simple_animal/slime/proc/unify()
unity = TRUE
attack_same = FALSE
/mob/living/simple_animal/slime/examine(mob/user)
..()
if(hat)
to_chat(user, "It is wearing \a [hat].")
if(stat == DEAD)
to_chat(user, "It appears to be dead.")
else if(incapacitated(INCAPACITATION_DISABLED))
to_chat(user, "It appears to be incapacitated.")
else if(rabid)
to_chat(user, "It seems very, very angry and upset.")
else if(obedience >= 5)
to_chat(user, "It looks rather obedient.")
else if(discipline)
to_chat(user, "It has been subjugated by force, at least for now.")
else if(docile)
to_chat(user, "It appears to have been pacified.")
/mob/living/simple_animal/slime/water_act(amount) // This is called if a slime enters a water tile.
adjustBruteLoss(40 * amount)
/mob/living/simple_animal/slime/proc/adjust_discipline(amount, silent)
if(amount > 0)
if(!rabid)
var/justified = is_justified_to_discipline()
spawn(0)
stop_consumption()
LoseTarget()
if(!silent)
if(justified)
say(pick("Fine...", "Okay...", "Sorry...", "I yield...", "Mercy..."))
else
say(pick("Why...?", "I don't understand...?", "Cruel...", "Stop...", "Nooo..."))
if(justified)
obedience++
else
if(prob(resentment * 20))
enrage() // Pushed the slime too far.
say(pick("Evil...", "Kill...", "Tyrant..."))
resentment++ // Done after check so first time will never enrage.
discipline = between(0, discipline + amount, 10)
/mob/living/simple_animal/slime/movement_delay()
if(bodytemperature >= 330.23) // 135 F or 57.08 C
return -1 // slimes become supercharged at high temperatures
. = ..()
var/health_deficiency = (maxHealth - health)
if(health_deficiency >= 45)
. += (health_deficiency / 25)
if(bodytemperature < 183.222)
. += (283.222 - bodytemperature) / 10 * 1.75
. += config.slime_delay
/mob/living/simple_animal/slime/Process_Spacemove()
return 2
/mob/living/simple_animal/slime/verb/evolve()
set category = "Slime"
set desc = "This will let you evolve from baby to adult slime."
if(stat)
to_chat(src, "<span class='notice'>I must be conscious to do this...</span>")
return
if(docile)
to_chat(src, "<span class='notice'>I have been pacified. I cannot evolve...</span>")
return
if(!is_adult)
if(amount_grown >= 10)
make_adult()
else
to_chat(src, "<span class='notice'>I am not ready to evolve yet...</span>")
else
to_chat(src, "<span class='notice'>I have already evolved...</span>")
/mob/living/simple_animal/slime/verb/reproduce()
set category = "Slime"
set desc = "This will make you split into four Slimes."
if(stat)
to_chat(src, "<span class='notice'>I must be conscious to do this...</span>")
return
if(docile)
to_chat(src, "<span class='notice'>I have been pacified. I cannot reproduce...</span>")
return
if(is_adult)
if(amount_grown >= 10)
// Check if there's enough 'room' to split.
var/list/nearby_things = orange(1, src)
var/free_tiles = 0
for(var/turf/T in nearby_things)
var/free = TRUE
if(T.density) // No walls.
continue
for(var/atom/movable/AM in T)
if(AM.density)
free = FALSE
break
if(free)
free_tiles++
if(free_tiles < 3) // Three free tiles are needed, as four slimes are made and the 4th tile is from the center tile that the current slime occupies.
to_chat(src, "<span class='warning'>It is too cramped here to reproduce...</span>")
return
var/list/babies = list()
for(var/i = 1 to 4)
babies.Add(make_new_slime())
var/mob/living/simple_animal/slime/new_slime = pick(babies)
new_slime.universal_speak = universal_speak
if(src.mind)
src.mind.transfer_to(new_slime)
else
new_slime.key = src.key
qdel(src)
else
to_chat(src, "<span class='notice'>I am not ready to reproduce yet...</span>")
else
to_chat(src, "<span class='notice'>I am not old enough to reproduce yet...</span>")
// Used for reproducing and dying.
/mob/living/simple_animal/slime/proc/make_new_slime(var/desired_type)
var/t = src.type
if(desired_type)
t = desired_type
if(prob(mutation_chance / 10))
t = /mob/living/simple_animal/slime/rainbow
else if(prob(mutation_chance) && slime_mutation.len)
t = slime_mutation[rand(1, slime_mutation.len)]
var/mob/living/simple_animal/slime/baby = new t(loc)
// Handle 'inheriting' from parent slime.
baby.mutation_chance = mutation_chance
baby.power_charge = round(power_charge / 4)
baby.resentment = max(resentment - 1, 0)
if(!istype(baby, /mob/living/simple_animal/slime/light_pink))
baby.discipline = max(discipline - 1, 0)
baby.obedience = max(obedience - 1, 0)
if(!istype(baby, /mob/living/simple_animal/slime/rainbow))
baby.unity = unity
baby.faction = faction
baby.attack_same = attack_same
baby.friends = friends.Copy()
if(rabid)
baby.enrage()
step_away(baby, src)
return baby
/mob/living/simple_animal/slime/speech_bubble_appearance()
return "slime"
// Called after they finish eatting someone.
/mob/living/simple_animal/slime/proc/befriend(var/mob/living/friend)
if(!(friend in friends))
friends |= friend
say("[friend]... friend...")
/mob/living/simple_animal/slime/proc/can_command(var/mob/living/commander)
if(rabid)
return FALSE
if(docile)
return SLIME_COMMAND_OBEY
if(commander in friends)
return SLIME_COMMAND_FRIEND
if(faction == commander.faction)
return SLIME_COMMAND_FACTION
if(discipline > resentment && obedience >= 5)
return SLIME_COMMAND_OBEY
return FALSE
/mob/living/simple_animal/slime/proc/give_hat(var/obj/item/clothing/head/new_hat, var/mob/living/user)
if(!istype(new_hat))
to_chat(user, "<span class='warning'>\The [new_hat] isn't a hat.</span>")
return
if(hat)
to_chat(user, "<span class='warning'>\The [src] is already wearing \a [hat].</span>")
return
else
user.drop_item(new_hat)
hat = new_hat
new_hat.forceMove(src)
to_chat(user, "<span class='notice'>You place \a [new_hat] on \the [src]. How adorable!</span>")
update_icon()
return
/mob/living/simple_animal/slime/proc/remove_hat(var/mob/living/user)
if(!hat)
to_chat(user, "<span class='warning'>\The [src] doesn't have a hat to remove.</span>")
else
hat.forceMove(get_turf(src))
user.put_in_hands(hat)
to_chat(user, "<span class='warning'>You take away \the [src]'s [hat.name]. How mean.</span>")
hat = null
update_icon()
/mob/living/simple_animal/slime/proc/drop_hat()
if(!hat)
return
hat.forceMove(get_turf(src))
hat = null
update_icon()
// Checks if disciplining the slime would be 'justified' right now.
/mob/living/simple_animal/slime/proc/is_justified_to_discipline()
if(rabid)
return TRUE
if(target_mob)
if(ishuman(target_mob))
var/mob/living/carbon/human/H = target_mob
if(istype(H.species, /datum/species/monkey))
return FALSE
return TRUE
return FALSE
/mob/living/simple_animal/slime/get_description_interaction()
var/list/results = list()
if(!stat)
results += "[desc_panel_image("slimebaton")]to stun the slime, if it's being bad."
results += ..()
return results
/mob/living/simple_animal/slime/get_description_info()
var/list/lines = list()
var/intro_line = "Slimes are generally the test subjects of Xenobiology, with different colors having different properties. \
They can be extremely dangerous if not handled properly."
lines.Add(intro_line)
lines.Add(null) // To pad the line breaks.
var/list/rewards = list()
for(var/potential_color in slime_mutation)
var/mob/living/simple_animal/slime/S = potential_color
rewards.Add(initial(S.slime_color))
var/reward_line = "This color of slime can mutate into [english_list(rewards)] colors, when it reproduces. It will do so when it has eatten enough."
lines.Add(reward_line)
lines.Add(null)
lines.Add(description_info)
return lines.Join("\n")
@@ -1,748 +0,0 @@
// Tier 1
/mob/living/simple_animal/slime/purple
desc = "This slime is rather toxic to handle, as it is poisonous."
color = "#CC23FF"
slime_color = "purple"
coretype = /obj/item/slime_extract/purple
reagent_injected = "toxin"
description_info = "This slime spreads a toxin when it attacks. A biosuit or other thick armor can protect from the toxic attack."
slime_mutation = list(
/mob/living/simple_animal/slime/dark_purple,
/mob/living/simple_animal/slime/dark_blue,
/mob/living/simple_animal/slime/green,
/mob/living/simple_animal/slime
)
/mob/living/simple_animal/slime/orange
desc = "This slime is known to be flammable and can ignite enemies."
color = "#FFA723"
slime_color = "orange"
coretype = /obj/item/slime_extract/orange
description_info = "Attacks from this slime can ignite you. A firesuit can protect from the burning attacks of this slime."
slime_mutation = list(
/mob/living/simple_animal/slime/dark_purple,
/mob/living/simple_animal/slime/yellow,
/mob/living/simple_animal/slime/red,
/mob/living/simple_animal/slime
)
/mob/living/simple_animal/slime/orange/post_attack(mob/living/L, intent)
if(intent != I_HELP)
L.adjust_fire_stacks(1)
if(prob(25))
L.IgniteMob()
..()
/mob/living/simple_animal/slime/blue
desc = "This slime produces 'cryotoxin' and uses it against their foes. Very deadly to other slimes."
color = "#19FFFF"
slime_color = "blue"
coretype = /obj/item/slime_extract/blue
reagent_injected = "cryotoxin"
description_info = "Attacks from this slime can chill you. A biosuit or other thick armor can protect from the chilling attack."
slime_mutation = list(
/mob/living/simple_animal/slime/dark_blue,
/mob/living/simple_animal/slime/silver,
/mob/living/simple_animal/slime/pink,
/mob/living/simple_animal/slime
)
/mob/living/simple_animal/slime/metal
desc = "This slime is a lot more resilient than the others, due to having a metamorphic metallic and sloped surface."
color = "#5F5F5F"
slime_color = "metal"
shiny = 1
coretype = /obj/item/slime_extract/metal
description_info = "This slime is a lot more durable and tough to damage than the others."
resistance = 10 // Sloped armor is strong.
maxHealth = 250
maxHealth_adult = 350
slime_mutation = list(
/mob/living/simple_animal/slime/silver,
/mob/living/simple_animal/slime/yellow,
/mob/living/simple_animal/slime/gold,
/mob/living/simple_animal/slime
)
// Tier 2
/mob/living/simple_animal/slime/yellow
desc = "This slime is very conductive, and is known to use electricity as a means of defense moreso than usual for slimes."
color = "#FFF423"
slime_color = "yellow"
coretype = /obj/item/slime_extract/yellow
ranged = 1
shoot_range = 3
firing_lines = 1
projectiletype = /obj/item/projectile/beam/lightning/slime
projectilesound = 'sound/weapons/gauss_shoot.ogg' // Closest thing to a 'thunderstrike' sound we have.
glows = TRUE
description_info = "This slime will fire lightning attacks at enemies if they are at range, and generate electricity \
for their stun attack faster than usual. Insulative or reflective armor can protect from the lightning."
slime_mutation = list(
/mob/living/simple_animal/slime/bluespace,
/mob/living/simple_animal/slime/bluespace,
/mob/living/simple_animal/slime/metal,
/mob/living/simple_animal/slime/orange
)
/mob/living/simple_animal/slime/yellow/handle_regular_status_updates()
if(stat == CONSCIOUS)
if(prob(25))
power_charge = between(0, power_charge + 1, 10)
..()
/obj/item/projectile/beam/lightning/slime
power = 15
/mob/living/simple_animal/slime/yellow/ClosestDistance() // Needed or else they won't eat monkeys outside of melee range.
if(target_mob && ishuman(target_mob))
var/mob/living/carbon/human/H = target_mob
if(istype(H.species, /datum/species/monkey))
return 1
return ..()
/mob/living/simple_animal/slime/dark_purple
desc = "This slime produces ever-coveted phoron. Risky to handle but very much worth it."
color = "#660088"
slime_color = "dark purple"
coretype = /obj/item/slime_extract/dark_purple
reagent_injected = "phoron"
description_info = "This slime applies phoron to enemies it attacks. A biosuit or other thick armor can protect from the toxic attack. \
If hit with a burning attack, it will erupt in flames."
slime_mutation = list(
/mob/living/simple_animal/slime/purple,
/mob/living/simple_animal/slime/orange,
/mob/living/simple_animal/slime/ruby,
/mob/living/simple_animal/slime/ruby
)
/mob/living/simple_animal/slime/dark_purple/proc/ignite()
visible_message("<span class='danger'>\The [src] erupts in an inferno!</span>")
for(var/turf/simulated/target_turf in view(2, src))
target_turf.assume_gas("phoron", 30, 1500+T0C)
spawn(0)
target_turf.hotspot_expose(1500+T0C, 400)
qdel(src)
/mob/living/simple_animal/slime/dark_purple/ex_act(severity)
log_and_message_admins("[src] ignited due to a chain reaction with an explosion.")
ignite()
/mob/living/simple_animal/slime/dark_purple/fire_act(datum/gas_mixture/air, temperature, volume)
log_and_message_admins("[src] ignited due to exposure to fire.")
ignite()
/mob/living/simple_animal/slime/dark_purple/bullet_act(var/obj/item/projectile/P, var/def_zone)
if(P.damage_type && P.damage_type == BURN && P.damage) // Most bullets won't trigger the explosion, as a mercy towards Security.
log_and_message_admins("[src] ignited due to bring hit by a burning projectile[P.firer ? " by [key_name(P.firer)]" : ""].")
ignite()
else
..()
/mob/living/simple_animal/slime/dark_purple/attackby(var/obj/item/weapon/W, var/mob/user)
if(istype(W) && W.force && W.damtype == BURN)
log_and_message_admins("[src] ignited due to being hit with a burning weapon ([W]) by [key_name(user)].")
ignite()
else
..()
/mob/living/simple_animal/slime/dark_blue
desc = "This slime makes other entities near it feel much colder, and is more resilient to the cold. It tends to kill other slimes rather quickly."
color = "#2398FF"
glows = TRUE
slime_color = "dark blue"
coretype = /obj/item/slime_extract/dark_blue
description_info = "This slime is immune to the cold, however water will still kill it. A winter coat or other cold-resistant clothing can protect from the chilling aura."
slime_mutation = list(
/mob/living/simple_animal/slime/purple,
/mob/living/simple_animal/slime/blue,
/mob/living/simple_animal/slime/cerulean,
/mob/living/simple_animal/slime/cerulean
)
minbodytemp = 0
cold_damage_per_tick = 0
/mob/living/simple_animal/slime/dark_blue/Life()
if(stat != DEAD)
cold_aura()
..()
/mob/living/simple_animal/slime/dark_blue/proc/cold_aura()
for(var/mob/living/L in view(2, src))
var/protection = L.get_cold_protection()
if(protection < 1)
var/cold_factor = abs(protection - 1)
var/delta = -20
delta *= cold_factor
L.bodytemperature = max(50, L.bodytemperature + delta)
var/turf/T = get_turf(src)
var/datum/gas_mixture/env = T.return_air()
if(env)
env.add_thermal_energy(-10 * 1000)
/mob/living/simple_animal/slime/dark_blue/get_cold_protection()
return 1 // This slime is immune to cold.
// Surface variant
/mob/living/simple_animal/slime/dark_blue/feral
name = "feral slime"
desc = "The result of slimes escaping containment from some xenobiology lab. The slime makes other entities near it feel much colder, \
and it is more resilient to the cold. These qualities have made this color of slime able to thrive on a harsh, cold world and is able to rival \
the ferocity of other apex predators in this region of Sif. As such, it is a very invasive species."
description_info = "This slime makes other entities near it feel much colder, and is more resilient to the cold. It also has learned advanced combat tactics from \
having to endure the harsh world outside its lab. Note that processing this large slime will give six cores."
icon_scale_x = 2
icon_scale_y = 2
optimal_combat = TRUE // Gotta be sharp to survive out there.
rabid = TRUE
rainbow_core_candidate = FALSE
cores = 6
maxHealth = 150
maxHealth_adult = 250
type_on_death = /mob/living/simple_animal/slime/dark_blue // Otherwise infinite slimes might occur.
pixel_y = -10 // Since the base sprite isn't centered properly, the pixel auto-adjustment needs some help.
/mob/living/simple_animal/slime/dark_blue/feral/New()
..()
make_adult()
/mob/living/simple_animal/slime/silver
desc = "This slime is shiny, and can deflect lasers or other energy weapons directed at it."
color = "#AAAAAA"
slime_color = "silver"
coretype = /obj/item/slime_extract/silver
shiny = TRUE
description_info = "Tasers, including the slime version, are ineffective against this slime. The slimebation still works."
slime_mutation = list(
/mob/living/simple_animal/slime/metal,
/mob/living/simple_animal/slime/blue,
/mob/living/simple_animal/slime/amber,
/mob/living/simple_animal/slime/amber
)
/mob/living/simple_animal/slime/silver/bullet_act(var/obj/item/projectile/P, var/def_zone)
if(istype(P,/obj/item/projectile/beam) || istype(P, /obj/item/projectile/energy))
visible_message("<span class='danger'>\The [src] reflects \the [P]!</span>")
// Find a turf near or on the original location to bounce to
var/new_x = P.starting.x + pick(0, 0, 0, -1, 1, -2, 2)
var/new_y = P.starting.y + pick(0, 0, 0, -1, 1, -2, 2)
var/turf/curloc = get_turf(src)
// redirect the projectile
P.redirect(new_x, new_y, curloc, src)
return PROJECTILE_CONTINUE // complete projectile permutation
else
..()
// Tier 3
/mob/living/simple_animal/slime/bluespace
desc = "Trapping this slime in a cell is generally futile, as it can teleport at will."
color = null
slime_color = "bluespace"
icon_state_override = "bluespace"
coretype = /obj/item/slime_extract/bluespace
description_info = "This slime will teleport to attack something if it is within a range of seven tiles. The teleport has a cooldown of five seconds."
slime_mutation = list(
/mob/living/simple_animal/slime/bluespace,
/mob/living/simple_animal/slime/bluespace,
/mob/living/simple_animal/slime/yellow,
/mob/living/simple_animal/slime/yellow
)
spattack_prob = 100
spattack_min_range = 3
spattack_max_range = 7
var/last_tele = null // Uses world.time
var/tele_cooldown = 5 SECONDS
/mob/living/simple_animal/slime/bluespace/ClosestDistance() // Needed or the SA AI won't ever try to teleport.
if(world.time > last_tele + tele_cooldown)
return spattack_max_range - 1
return ..()
/mob/living/simple_animal/slime/bluespace/SpecialAtkTarget()
// Teleport attack.
if(!target_mob)
to_chat(src, "<span class='warning'>There's nothing to teleport to.</span>")
return FALSE
if(world.time < last_tele + tele_cooldown)
to_chat(src, "<span class='warning'>You can't teleport right now, wait a few seconds.</span>")
return FALSE
var/list/nearby_things = range(1, target_mob)
var/list/valid_turfs = list()
// All this work to just go to a non-dense tile.
for(var/turf/potential_turf in nearby_things)
var/valid_turf = TRUE
if(potential_turf.density)
continue
for(var/atom/movable/AM in potential_turf)
if(AM.density)
valid_turf = FALSE
if(valid_turf)
valid_turfs.Add(potential_turf)
var/turf/T = get_turf(src)
var/turf/target_turf = pick(valid_turfs)
if(!target_turf)
to_chat(src, "<span class='warning'>There wasn't an unoccupied spot to teleport to.</span>")
return FALSE
var/datum/effect/effect/system/spark_spread/s1 = new /datum/effect/effect/system/spark_spread
s1.set_up(5, 1, T)
var/datum/effect/effect/system/spark_spread/s2 = new /datum/effect/effect/system/spark_spread
s2.set_up(5, 1, target_turf)
T.visible_message("<span class='notice'>\The [src] vanishes!</span>")
s1.start()
forceMove(target_turf)
playsound(target_turf, 'sound/effects/phasein.ogg', 50, 1)
to_chat(src, "<span class='notice'>You teleport to \the [target_turf].</span>")
target_turf.visible_message("<span class='warning'>\The [src] appears!</span>")
s2.start()
last_tele = world.time
if(Adjacent(target_mob))
PunchTarget()
return TRUE
/mob/living/simple_animal/slime/ruby
desc = "This slime has great physical strength."
color = "#FF3333"
slime_color = "ruby"
shiny = TRUE
glows = TRUE
coretype = /obj/item/slime_extract/ruby
description_info = "This slime is unnaturally stronger, allowing it to hit much harder, take less damage, and be stunned for less time. \
Their glomp attacks also send the victim flying."
slime_mutation = list(
/mob/living/simple_animal/slime/dark_purple,
/mob/living/simple_animal/slime/dark_purple,
/mob/living/simple_animal/slime/ruby,
/mob/living/simple_animal/slime/ruby
)
/mob/living/simple_animal/slime/ruby/New()
..()
add_modifier(/datum/modifier/slime_strength, null, src) // Slime is always swole.
/mob/living/simple_animal/slime/ruby/DoPunch(var/mob/living/L)
..() // Do regular attacks.
if(istype(L))
if(a_intent == I_HURT)
visible_message("<span class='danger'>\The [src] sends \the [L] flying with the impact!</span>")
playsound(src, "punch", 50, 1)
L.Weaken(1)
var/throwdir = get_dir(src, L)
L.throw_at(get_edge_target_turf(L, throwdir), 3, 1, src)
/mob/living/simple_animal/slime/amber
desc = "This slime seems to be an expert in the culinary arts, as they create their own food to share with others. \
They would probably be very important to other slimes, if the other colors didn't try to kill them."
color = "#FFBB00"
slime_color = "amber"
shiny = TRUE
glows = TRUE
coretype = /obj/item/slime_extract/amber
description_info = "This slime feeds nearby entities passively while it is alive. This can cause uncontrollable \
slime growth and reproduction if not kept in check. The amber slime cannot feed itself, but can be fed by other amber slimes."
slime_mutation = list(
/mob/living/simple_animal/slime/silver,
/mob/living/simple_animal/slime/silver,
/mob/living/simple_animal/slime/amber,
/mob/living/simple_animal/slime/amber
)
/mob/living/simple_animal/slime/amber/Life()
if(stat != DEAD)
feed_aura()
..()
/mob/living/simple_animal/slime/amber/proc/feed_aura()
for(var/mob/living/L in view(2, src))
if(L == src) // Don't feed themselves, or it is impossible to stop infinite slimes without killing all of the ambers.
continue
if(isslime(L))
var/mob/living/simple_animal/slime/S = L
S.adjust_nutrition(rand(15, 25))
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.isSynthetic())
continue
H.nutrition = between(0, H.nutrition + rand(15, 25), 600)
/mob/living/simple_animal/slime/cerulean
desc = "This slime is generally superior in a wide range of attributes, compared to the common slime. The jack of all trades, but master of none."
color = "#4F7EAA"
slime_color = "cerulean"
coretype = /obj/item/slime_extract/cerulean
// Less than the specialized slimes, but higher than the rest.
maxHealth = 200
maxHealth_adult = 250
melee_damage_lower = 10
melee_damage_upper = 30
move_to_delay = 3
slime_mutation = list(
/mob/living/simple_animal/slime/dark_blue,
/mob/living/simple_animal/slime/dark_blue,
/mob/living/simple_animal/slime/cerulean,
/mob/living/simple_animal/slime/cerulean
)
// Tier 4
/mob/living/simple_animal/slime/red
desc = "This slime is full of energy, and very aggressive. 'The red ones go faster.' seems to apply here."
color = "#FF3333"
slime_color = "red"
coretype = /obj/item/slime_extract/red
move_to_delay = 3 // The red ones go faster.
description_info = "This slime is faster than the others. Attempting to discipline this slime will always cause it to go berserk."
slime_mutation = list(
/mob/living/simple_animal/slime/red,
/mob/living/simple_animal/slime/oil,
/mob/living/simple_animal/slime/oil,
/mob/living/simple_animal/slime/orange
)
/mob/living/simple_animal/slime/red/adjust_discipline(amount)
if(amount > 0)
if(!rabid)
enrage() // How dare you try to control the red slime.
say("Grrr...!")
/mob/living/simple_animal/slime/red/enrage()
..()
add_modifier(/datum/modifier/berserk, 30 SECONDS)
/mob/living/simple_animal/slime/green
desc = "This slime is radioactive."
color = "#14FF20"
slime_color = "green"
coretype = /obj/item/slime_extract/green
glows = TRUE
reagent_injected = "radium"
var/rads = 25
description_info = "This slime will irradiate anything nearby passively, and will inject radium on attack. \
A radsuit or other thick and radiation-hardened armor can protect from this. It will only radiate while alive."
slime_mutation = list(
/mob/living/simple_animal/slime/purple,
/mob/living/simple_animal/slime/green,
/mob/living/simple_animal/slime/emerald,
/mob/living/simple_animal/slime/emerald
)
/mob/living/simple_animal/slime/green/Life()
if(stat != DEAD)
irradiate()
..()
/mob/living/simple_animal/slime/green/proc/irradiate()
SSradiation.radiate(src, rads)
/mob/living/simple_animal/slime/pink
desc = "This slime has regenerative properties."
color = "#FF0080"
slime_color = "pink"
coretype = /obj/item/slime_extract/pink
glows = TRUE
description_info = "This slime will passively heal nearby entities within two tiles, including itself. It will only do this while alive."
slime_mutation = list(
/mob/living/simple_animal/slime/blue,
/mob/living/simple_animal/slime/light_pink,
/mob/living/simple_animal/slime/light_pink,
/mob/living/simple_animal/slime/pink
)
/mob/living/simple_animal/slime/pink/Life()
if(stat != DEAD)
heal_aura()
..()
/mob/living/simple_animal/slime/pink/proc/heal_aura()
for(var/mob/living/L in view(src, 2))
if(L.stat == DEAD || L == target_mob)
continue
L.add_modifier(/datum/modifier/slime_heal, 5 SECONDS, src)
/datum/modifier/slime_heal
name = "slime mending"
desc = "You feel somewhat gooy."
mob_overlay_state = "pink_sparkles"
on_created_text = "<span class='warning'>Twinkling spores of goo surround you. It makes you feel healthier.</span>"
on_expired_text = "<span class='notice'>The spores of goo have faded, although you feel much healthier than before.</span>"
stacks = MODIFIER_STACK_EXTEND
/datum/modifier/slime_heal/tick()
if(holder.stat == DEAD) // Required or else simple animals become immortal.
expire()
if(ishuman(holder)) // Robolimbs need this code sadly.
var/mob/living/carbon/human/H = holder
for(var/obj/item/organ/external/E in H.organs)
var/obj/item/organ/external/O = E
O.heal_damage(2, 2, 0, 1)
else
holder.adjustBruteLoss(-2)
holder.adjustFireLoss(-2)
holder.adjustToxLoss(-2)
holder.adjustOxyLoss(-2)
holder.adjustCloneLoss(-1)
/mob/living/simple_animal/slime/gold
desc = "This slime absorbs energy, and cannot be stunned by normal means."
color = "#EEAA00"
shiny = TRUE
slime_color = "gold"
coretype = /obj/item/slime_extract/gold
description_info = "This slime is immune to the slimebaton and taser, and will actually charge the slime, however it will still discipline the slime."
slime_mutation = list(
/mob/living/simple_animal/slime/metal,
/mob/living/simple_animal/slime/gold,
/mob/living/simple_animal/slime/sapphire,
/mob/living/simple_animal/slime/sapphire
)
/mob/living/simple_animal/slime/gold/Weaken(amount)
power_charge = between(0, power_charge + amount, 10)
return
/mob/living/simple_animal/slime/gold/Stun(amount)
power_charge = between(0, power_charge + amount, 10)
return
/mob/living/simple_animal/slime/gold/get_description_interaction() // So it doesn't say to use a baton on them.
return list()
// Tier 5
/mob/living/simple_animal/slime/oil
desc = "This slime is explosive and volatile. Smoking near it is probably a bad idea."
color = "#333333"
slime_color = "oil"
shiny = TRUE
coretype = /obj/item/slime_extract/oil
description_info = "If this slime suffers damage from a fire or heat based source, or if it is caught inside \
an explosion, it will explode. Rabid oil slimes will charge at enemies, then suicide-bomb themselves. \
Bomb suits can protect from the explosion."
slime_mutation = list(
/mob/living/simple_animal/slime/oil,
/mob/living/simple_animal/slime/oil,
/mob/living/simple_animal/slime/red,
/mob/living/simple_animal/slime/red
)
/mob/living/simple_animal/slime/oil/proc/explode()
if(stat != DEAD)
// explosion(src.loc, 1, 2, 4)
explosion(src.loc, 0, 2, 4) // A bit weaker since the suicide charger tended to gib the poor sod being targeted.
if(src) // Delete ourselves if the explosion didn't do it.
qdel(src)
/mob/living/simple_animal/slime/oil/post_attack(var/mob/living/L, var/intent = I_HURT)
if(!rabid)
return ..()
if(intent == I_HURT || intent == I_GRAB)
say(pick("Sacrifice...!", "Sssss...", "Boom...!"))
sleep(2 SECOND)
log_and_message_admins("[src] has suicide-bombed themselves while trying to kill \the [L].")
explode()
/mob/living/simple_animal/slime/oil/ex_act(severity)
log_and_message_admins("[src] exploded due to a chain reaction with another explosion.")
explode()
/mob/living/simple_animal/slime/oil/fire_act(datum/gas_mixture/air, temperature, volume)
log_and_message_admins("[src] exploded due to exposure to fire.")
explode()
/mob/living/simple_animal/slime/oil/bullet_act(var/obj/item/projectile/P, var/def_zone)
if(P.damage_type && P.damage_type == BURN && P.damage) // Most bullets won't trigger the explosion, as a mercy towards Security.
log_and_message_admins("[src] exploded due to bring hit by a burning projectile[P.firer ? " by [key_name(P.firer)]" : ""].")
explode()
else
..()
/mob/living/simple_animal/slime/oil/attackby(var/obj/item/weapon/W, var/mob/user)
if(istype(W) && W.force && W.damtype == BURN)
log_and_message_admins("[src] exploded due to being hit with a burning weapon ([W]) by [key_name(user)].")
explode()
else
..()
/mob/living/simple_animal/slime/sapphire
desc = "This slime seems a bit brighter than the rest, both figuratively and literally."
color = "#2398FF"
slime_color = "sapphire"
shiny = TRUE
glows = TRUE
coretype = /obj/item/slime_extract/sapphire
optimal_combat = TRUE // Lift combat AI restrictions to look smarter.
run_at_them = FALSE // Use fancy A* pathing.
astar_adjacent_proc = /turf/proc/TurfsWithAccess // Normal slimes don't care about cardinals (because BYOND) so smart slimes shouldn't as well.
move_to_delay = 3 // A* chasing is slightly slower in terms of movement speed than regular pathing so reducing this hopefully makes up for that.
description_info = "This slime uses more robust tactics when fighting and won't hold back, so it is dangerous to be alone \
with one if hostile, and especially dangerous if they outnumber you."
slime_mutation = list(
/mob/living/simple_animal/slime/sapphire,
/mob/living/simple_animal/slime/sapphire,
/mob/living/simple_animal/slime/gold,
/mob/living/simple_animal/slime/gold
)
/mob/living/simple_animal/slime/emerald
desc = "This slime is faster than usual, even more so than the red slimes."
color = "#22FF22"
shiny = TRUE
glows = TRUE
slime_color = "emerald"
coretype = /obj/item/slime_extract/emerald
description_info = "This slime will make everything around it, and itself, faster for a few seconds, if close by."
move_to_delay = 2
slime_mutation = list(
/mob/living/simple_animal/slime/green,
/mob/living/simple_animal/slime/green,
/mob/living/simple_animal/slime/emerald,
/mob/living/simple_animal/slime/emerald
)
/mob/living/simple_animal/slime/emerald/Life()
if(stat != DEAD)
zoom_aura()
..()
/mob/living/simple_animal/slime/emerald/proc/zoom_aura()
for(var/mob/living/L in view(src, 2))
if(L.stat == DEAD || L == target_mob)
continue
L.add_modifier(/datum/modifier/technomancer/haste, 5 SECONDS, src)
/mob/living/simple_animal/slime/light_pink
desc = "This slime seems a lot more peaceful than the others."
color = "#FF8888"
slime_color = "light pink"
coretype = /obj/item/slime_extract/light_pink
description_info = "This slime is effectively always disciplined initially."
obedience = 5
discipline = 5
slime_mutation = list(
/mob/living/simple_animal/slime/pink,
/mob/living/simple_animal/slime/pink,
/mob/living/simple_animal/slime/light_pink,
/mob/living/simple_animal/slime/light_pink
)
// Special
/mob/living/simple_animal/slime/rainbow
desc = "This slime changes colors constantly."
color = null // Only slime subtype that uses a different icon_state.
slime_color = "rainbow"
coretype = /obj/item/slime_extract/rainbow
icon_state_override = "rainbow"
unity = TRUE
description_info = "This slime is considered to be the same color as all other slime colors at the same time for the purposes of \
other slimes being friendly to them, and therefore will never be harmed by another slime. \
Attacking this slime will provoke the wrath of all slimes within range."
slime_mutation = list(
/mob/living/simple_animal/slime/rainbow,
/mob/living/simple_animal/slime/rainbow,
/mob/living/simple_animal/slime/rainbow,
/mob/living/simple_animal/slime/rainbow
)
/mob/living/simple_animal/slime/rainbow/New()
unify()
..()
// The RD's pet slime.
/mob/living/simple_animal/slime/rainbow/kendrick
name = "Kendrick"
desc = "The Research Director's pet slime. It shifts colors constantly."
rainbow_core_candidate = FALSE
/mob/living/simple_animal/slime/rainbow/kendrick/New()
pacify()
..()