From 82f7e5d4b4d80d393e38b14c7b7f86589c2e6b79 Mon Sep 17 00:00:00 2001 From: Meghan-Rossi <56671765+Meghan-Rossi@users.noreply.github.com> Date: Thu, 14 Nov 2019 19:19:44 +0000 Subject: [PATCH] Remove unused simple_animal files -moves corpse.dm from code\modules\mob\living\simple_animal to code\modules\mob\dead -deletes folder code\modules\mob\living\simple_animal since none of the other files in it are even included in the dme (we use simple_mob instead) --- .../{living/simple_animal => dead}/corpse.dm | 338 ++-- .../mob/living/simple_animal/aliens/alien.dm | 142 -- .../living/simple_animal/aliens/creature.dm | 78 - .../mob/living/simple_animal/aliens/drone.dm | 286 --- .../living/simple_animal/aliens/faithless.dm | 84 - .../living/simple_animal/aliens/hivebot.dm | 241 --- .../mob/living/simple_animal/aliens/mimic.dm | 201 -- .../mob/living/simple_animal/aliens/shade.dm | 61 - .../mob/living/simple_animal/aliens/statue.dm | 457 ----- .../mob/living/simple_animal/animals/bat.dm | 85 - .../mob/living/simple_animal/animals/bear.dm | 141 -- .../mob/living/simple_animal/animals/carp.dm | 93 - .../mob/living/simple_animal/animals/cat.dm | 193 -- .../mob/living/simple_animal/animals/corgi.dm | 231 --- .../mob/living/simple_animal/animals/crab.dm | 87 - .../simple_animal/animals/farm_animals.dm | 292 --- .../mob/living/simple_animal/animals/fish.dm | 80 - .../simple_animal/animals/giant_spider.dm | 580 ------ .../mob/living/simple_animal/animals/goose.dm | 59 - .../living/simple_animal/animals/lizard.dm | 24 - .../simple_animal/animals/miscellaneous.dm | 21 - .../mob/living/simple_animal/animals/mouse.dm | 137 -- .../living/simple_animal/animals/parrot.dm | 768 -------- .../living/simple_animal/animals/penguin.dm | 27 - .../animals/sif_wildlife/diyaab.dm | 29 - .../animals/sif_wildlife/savik.dm | 36 - .../animals/sif_wildlife/shantak.dm | 29 - .../mob/living/simple_animal/animals/slime.dm | 70 - .../living/simple_animal/animals/spiderbot.dm | 302 --- .../living/simple_animal/animals/tomato.dm | 24 - .../mob/living/simple_animal/animals/tree.dm | 60 - .../mob/living/simple_animal/animals/worm.dm | 199 -- .../mob/living/simple_animal/borer/borer.dm | 213 -- .../simple_animal/borer/borer_captive.dm | 57 - .../simple_animal/borer/borer_powers.dm | 337 ---- .../mob/living/simple_animal/borer/say.dm | 40 - .../living/simple_animal/humanoids/clown.dm | 49 - .../simple_animal/humanoids/mechamobs.dm | 123 -- .../living/simple_animal/humanoids/pirate.dm | 72 - .../living/simple_animal/humanoids/russian.dm | 68 - .../simple_animal/humanoids/syndicate.dm | 265 --- .../mob/living/simple_animal/simple_animal.dm | 1732 ----------------- .../mob/living/simple_animal/simple_hud.dm | 311 --- .../mob/living/simple_animal/slime/ai.dm | 91 - .../mob/living/simple_animal/slime/combat.dm | 277 --- .../mob/living/simple_animal/slime/death.dm | 27 - .../mob/living/simple_animal/slime/life.dm | 183 -- .../mob/living/simple_animal/slime/slime.dm | 470 ----- .../living/simple_animal/slime/subtypes.dm | 748 ------- polaris.dme | 2 +- 50 files changed, 170 insertions(+), 10350 deletions(-) rename code/modules/mob/{living/simple_animal => dead}/corpse.dm (96%) delete mode 100644 code/modules/mob/living/simple_animal/aliens/alien.dm delete mode 100644 code/modules/mob/living/simple_animal/aliens/creature.dm delete mode 100644 code/modules/mob/living/simple_animal/aliens/drone.dm delete mode 100644 code/modules/mob/living/simple_animal/aliens/faithless.dm delete mode 100644 code/modules/mob/living/simple_animal/aliens/hivebot.dm delete mode 100644 code/modules/mob/living/simple_animal/aliens/mimic.dm delete mode 100644 code/modules/mob/living/simple_animal/aliens/shade.dm delete mode 100644 code/modules/mob/living/simple_animal/aliens/statue.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/bat.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/bear.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/carp.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/cat.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/corgi.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/crab.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/farm_animals.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/fish.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/giant_spider.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/goose.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/lizard.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/miscellaneous.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/mouse.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/parrot.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/penguin.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/sif_wildlife/diyaab.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/sif_wildlife/savik.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/sif_wildlife/shantak.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/slime.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/spiderbot.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/tomato.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/tree.dm delete mode 100644 code/modules/mob/living/simple_animal/animals/worm.dm delete mode 100644 code/modules/mob/living/simple_animal/borer/borer.dm delete mode 100644 code/modules/mob/living/simple_animal/borer/borer_captive.dm delete mode 100644 code/modules/mob/living/simple_animal/borer/borer_powers.dm delete mode 100644 code/modules/mob/living/simple_animal/borer/say.dm delete mode 100644 code/modules/mob/living/simple_animal/humanoids/clown.dm delete mode 100644 code/modules/mob/living/simple_animal/humanoids/mechamobs.dm delete mode 100644 code/modules/mob/living/simple_animal/humanoids/pirate.dm delete mode 100644 code/modules/mob/living/simple_animal/humanoids/russian.dm delete mode 100644 code/modules/mob/living/simple_animal/humanoids/syndicate.dm delete mode 100644 code/modules/mob/living/simple_animal/simple_animal.dm delete mode 100644 code/modules/mob/living/simple_animal/simple_hud.dm delete mode 100644 code/modules/mob/living/simple_animal/slime/ai.dm delete mode 100644 code/modules/mob/living/simple_animal/slime/combat.dm delete mode 100644 code/modules/mob/living/simple_animal/slime/death.dm delete mode 100644 code/modules/mob/living/simple_animal/slime/life.dm delete mode 100644 code/modules/mob/living/simple_animal/slime/slime.dm delete mode 100644 code/modules/mob/living/simple_animal/slime/subtypes.dm diff --git a/code/modules/mob/living/simple_animal/corpse.dm b/code/modules/mob/dead/corpse.dm similarity index 96% rename from code/modules/mob/living/simple_animal/corpse.dm rename to code/modules/mob/dead/corpse.dm index 62b2c43fe8..81a51214a7 100644 --- a/code/modules/mob/living/simple_animal/corpse.dm +++ b/code/modules/mob/dead/corpse.dm @@ -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 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/aliens/alien.dm b/code/modules/mob/living/simple_animal/aliens/alien.dm deleted file mode 100644 index 3dba09330a..0000000000 --- a/code/modules/mob/living/simple_animal/aliens/alien.dm +++ /dev/null @@ -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) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/aliens/creature.dm b/code/modules/mob/living/simple_animal/aliens/creature.dm deleted file mode 100644 index 20840e66db..0000000000 --- a/code/modules/mob/living/simple_animal/aliens/creature.dm +++ /dev/null @@ -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() diff --git a/code/modules/mob/living/simple_animal/aliens/drone.dm b/code/modules/mob/living/simple_animal/aliens/drone.dm deleted file mode 100644 index e51dfd82a7..0000000000 --- a/code/modules/mob/living/simple_animal/aliens/drone.dm +++ /dev/null @@ -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("\icon[src] [src] shudders and shakes as some of it's damaged systems come back online.") - 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("\icon[src] [src] retracts several targetting vanes, and dulls it's running lights.") - hostile = 0 - else - src.visible_message("\icon[src] [src] suddenly lights up, and additional targetting vanes slide into place.") - 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("\icon[src] [src] suddenly shuts down!") - else - src.visible_message("\icon[src] [src] suddenly lies still and quiet.") - disabled = rand(150, 600) - walk(src,0) - - if(exploding && prob(20)) - if(prob(50)) - src.visible_message("\icon[src] [src] begins to spark and shake violenty!") - else - src.visible_message("\icon[src] [src] sparks and shakes like it's about to explode!") - 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\the [src] knocks down \the [L]!") - -/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() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/aliens/hivebot.dm b/code/modules/mob/living/simple_animal/aliens/hivebot.dm deleted file mode 100644 index 876f5927a2..0000000000 --- a/code/modules/mob/living/simple_animal/aliens/hivebot.dm +++ /dev/null @@ -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("[src] 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("The [src] warps in!") - playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1) - - warpbots() - icon_state = "def_radar" - visible_message("The [src] turns on!") - 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 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/aliens/mimic.dm b/code/modules/mob/living/simple_animal/aliens/mimic.dm deleted file mode 100644 index 2dc3a4afe7..0000000000 --- a/code/modules/mob/living/simple_animal/aliens/mimic.dm +++ /dev/null @@ -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("[src] 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("\the [src] knocks down \the [L]!") - -// -// 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("\the [src] knocks down \the [L]!") diff --git a/code/modules/mob/living/simple_animal/aliens/shade.dm b/code/modules/mob/living/simple_animal/aliens/shade.dm deleted file mode 100644 index c1c2f1dc01..0000000000 --- a/code/modules/mob/living/simple_animal/aliens/shade.dm +++ /dev/null @@ -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("[src] lets out a contented sigh as their form unwinds.") - - ghostize() - qdel(src) - return diff --git a/code/modules/mob/living/simple_animal/aliens/statue.dm b/code/modules/mob/living/simple_animal/aliens/statue.dm deleted file mode 100644 index f80181bdb0..0000000000 --- a/code/modules/mob/living/simple_animal/aliens/statue.dm +++ /dev/null @@ -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, "You cannot move, there are eyes on you!") - 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("[user] tries to banish [src] with [O]!") - if(do_after(user, 15, src)) - if(banishable) - visible_message("[src] crumbles into dust!") - gib() - else - visible_message("[src] is too strong to be banished!") - 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, "You cannot move, there are eyes on you!") - 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("Your eyes feel very heavy.", "You blink suddenly!", "Your eyes close involuntarily!")) - 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, "You cannot attack, there are eyes on you!") - 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 = "You glare your eyes." - 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 = "You glare your eyes." - 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, "You rub the slab in hopes a wandering spirit wishes to inhabit it. [src] starts to sparkle!") - 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("[src] fades. Maybe it will spark another time.") - -/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, "You are \a [S], brought into existence on [station_name()] by [user]! Obey all their orders.") - S.mind.assigned_role = "The Statue" - visible_message("The slab suddenly takes the shape of a humanoid!") - 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("The slab suddenly takes the shape of a humanoid!") - S.creator = user - qdel(src) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/bat.dm b/code/modules/mob/living/simple_animal/animals/bat.dm deleted file mode 100644 index 680091010e..0000000000 --- a/code/modules/mob/living/simple_animal/animals/bat.dm +++ /dev/null @@ -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("\the [src] scares \the [L]!") - -/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() diff --git a/code/modules/mob/living/simple_animal/animals/bear.dm b/code/modules/mob/living/simple_animal/animals/bear.dm deleted file mode 100644 index e399419602..0000000000 --- a/code/modules/mob/living/simple_animal/animals/bear.dm +++ /dev/null @@ -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 - ..() diff --git a/code/modules/mob/living/simple_animal/animals/carp.dm b/code/modules/mob/living/simple_animal/animals/carp.dm deleted file mode 100644 index 7e7ae92876..0000000000 --- a/code/modules/mob/living/simple_animal/animals/carp.dm +++ /dev/null @@ -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("\the [src] knocks down \the [L]!") - diff --git a/code/modules/mob/living/simple_animal/animals/cat.dm b/code/modules/mob/living/simple_animal/animals/cat.dm deleted file mode 100644 index 140deb0b24..0000000000 --- a/code/modules/mob/living/simple_animal/animals/cat.dm +++ /dev/null @@ -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 << "[src] ignores you." - 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) - ..() diff --git a/code/modules/mob/living/simple_animal/animals/corgi.dm b/code/modules/mob/living/simple_animal/animals/corgi.dm deleted file mode 100644 index 6cc1f80523..0000000000 --- a/code/modules/mob/living/simple_animal/animals/corgi.dm +++ /dev/null @@ -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("[user] baps [name] on the nose with the rolled up [O]") - 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 << "You can't fit this on [src]" - 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, "[src] already has a cute bow!") - 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" diff --git a/code/modules/mob/living/simple_animal/animals/crab.dm b/code/modules/mob/living/simple_animal/animals/crab.dm deleted file mode 100644 index c369aa375a..0000000000 --- a/code/modules/mob/living/simple_animal/animals/crab.dm +++ /dev/null @@ -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") diff --git a/code/modules/mob/living/simple_animal/animals/farm_animals.dm b/code/modules/mob/living/simple_animal/animals/farm_animals.dm deleted file mode 100644 index 534bbf6000..0000000000 --- a/code/modules/mob/living/simple_animal/animals/farm_animals.dm +++ /dev/null @@ -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("[src] gets an evil-looking gleam in their eye.") - -/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("[user] milks [src] using \the [O].") - var/transfered = udder.trans_id_to(G, "milk", rand(5,10)) - if(G.reagents.total_volume >= G.volume) - user << "The [O] is full." - if(!transfered) - user << "The udder is dry. Wait a bit longer..." - 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("[user] milks [src] using \the [O].") - var/transfered = udder.trans_id_to(G, "milk", rand(5,10)) - if(G.reagents.total_volume >= G.volume) - user << "The [O] is full." - if(!transfered) - user << "The udder is dry. Wait a bit longer..." - 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("[M] tips over [src].","You tip over [src].") - 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("[user] feeds [O] to [name]! It clucks happily.","You feed [O] to [name]! It clucks happily.") - user.drop_item() - qdel(O) - eggsleft += rand(1, 4) - else - user << "[name] doesn't seem hungry!" - 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) diff --git a/code/modules/mob/living/simple_animal/animals/fish.dm b/code/modules/mob/living/simple_animal/animals/fish.dm deleted file mode 100644 index 547b095bfd..0000000000 --- a/code/modules/mob/living/simple_animal/animals/fish.dm +++ /dev/null @@ -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" diff --git a/code/modules/mob/living/simple_animal/animals/giant_spider.dm b/code/modules/mob/living/simple_animal/animals/giant_spider.dm deleted file mode 100644 index 587edeb0f8..0000000000 --- a/code/modules/mob/living/simple_animal/animals/giant_spider.dm +++ /dev/null @@ -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("\The [src]'s abdomen splits as it rolls over, spiderlings crawling from the wound.") - 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 bad 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("\The [src]'s body begins to rupture!") - spawn(rand(1,5)) - if(src && !exploded) - visible_message("\The [src]'s body detonates!") - 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, "You feel a tiny prick.") - 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, "\The [src] injects something into your [O.name]!") - -/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("\The [src] throws a layer of web at \the [L]!") - 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("\The [src] begins to secrete a sticky substance.") - 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("\The [src] begins to lay a cluster of eggs.") - 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("\The [src] begins to secrete a sticky substance around \the [cocoon_target].") - 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("\The [src] sticks a proboscis into \the [cocoon_target] and sucks a viscous substance out.") - 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 diff --git a/code/modules/mob/living/simple_animal/animals/goose.dm b/code/modules/mob/living/simple_animal/animals/goose.dm deleted file mode 100644 index 7ac8dfd45d..0000000000 --- a/code/modules/mob/living/simple_animal/animals/goose.dm +++ /dev/null @@ -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 diff --git a/code/modules/mob/living/simple_animal/animals/lizard.dm b/code/modules/mob/living/simple_animal/animals/lizard.dm deleted file mode 100644 index 3cceeb4da4..0000000000 --- a/code/modules/mob/living/simple_animal/animals/lizard.dm +++ /dev/null @@ -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") diff --git a/code/modules/mob/living/simple_animal/animals/miscellaneous.dm b/code/modules/mob/living/simple_animal/animals/miscellaneous.dm deleted file mode 100644 index 29bb7a3da3..0000000000 --- a/code/modules/mob/living/simple_animal/animals/miscellaneous.dm +++ /dev/null @@ -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" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/mouse.dm b/code/modules/mob/living/simple_animal/animals/mouse.dm deleted file mode 100644 index 370001a7ca..0000000000 --- a/code/modules/mob/living/simple_animal/animals/mouse.dm +++ /dev/null @@ -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("\icon[src] Squeek!") - 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 diff --git a/code/modules/mob/living/simple_animal/animals/parrot.dm b/code/modules/mob/living/simple_animal/animals/parrot.dm deleted file mode 100644 index 42796c8cee..0000000000 --- a/code/modules/mob/living/simple_animal/animals/parrot.dm +++ /dev/null @@ -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 = "
Inventory of [name]

" - if(ears) - dat += "
Headset: [ears] (Remove)" - else - dat += "
Headset: Nothing" - - 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, "There is nothing to remove from its [remove_from].") - 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, "You have nothing in your hand to put on its [add_to].") - return - switch(add_to) - if("ears") - if(ears) - to_chat(usr, "It's already wearing something.") - 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, "This object won't fit.") - 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]!", "You grab the [held_item]!", "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, "You are already holding the [held_item]") - 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]!", "You grab the [held_item]!", "You hear the sounds of wings flapping furiously.") - return held_item - - to_chat(src, "There is nothing of interest to take.") - 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, "You are already holding the [held_item]") - 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!", "You snag the [held_item] out of [C]'s hand!", "You hear the sounds of wings flapping furiously.") - return held_item - - to_chat(src, "There is nothing of interest to take.") - 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, "You have nothing to drop!") - 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, "There is no perch nearby to sit on.") - 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 diff --git a/code/modules/mob/living/simple_animal/animals/penguin.dm b/code/modules/mob/living/simple_animal/animals/penguin.dm deleted file mode 100644 index da7c9c4328..0000000000 --- a/code/modules/mob/living/simple_animal/animals/penguin.dm +++ /dev/null @@ -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 diff --git a/code/modules/mob/living/simple_animal/animals/sif_wildlife/diyaab.dm b/code/modules/mob/living/simple_animal/animals/sif_wildlife/diyaab.dm deleted file mode 100644 index 86b2a261e7..0000000000 --- a/code/modules/mob/living/simple_animal/animals/sif_wildlife/diyaab.dm +++ /dev/null @@ -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") \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/sif_wildlife/savik.dm b/code/modules/mob/living/simple_animal/animals/sif_wildlife/savik.dm deleted file mode 100644 index b451901b60..0000000000 --- a/code/modules/mob/living/simple_animal/animals/sif_wildlife/savik.dm +++ /dev/null @@ -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) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/sif_wildlife/shantak.dm b/code/modules/mob/living/simple_animal/animals/sif_wildlife/shantak.dm deleted file mode 100644 index 999916bbe6..0000000000 --- a/code/modules/mob/living/simple_animal/animals/sif_wildlife/shantak.dm +++ /dev/null @@ -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") \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/slime.dm b/code/modules/mob/living/simple_animal/animals/slime.dm deleted file mode 100644 index 0449146a7e..0000000000 --- a/code/modules/mob/living/simple_animal/animals/slime.dm +++ /dev/null @@ -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) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/spiderbot.dm b/code/modules/mob/living/simple_animal/animals/spiderbot.dm deleted file mode 100644 index 5aa5f50e94..0000000000 --- a/code/modules/mob/living/simple_animal/animals/spiderbot.dm +++ /dev/null @@ -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 << "There's already a brain in [src]!" - return - if(!B.brainmob) - user << "Sticking an empty MMI into the frame would sort of defeat the purpose." - 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 << "[O] is completely unresponsive; there's no point." - return - - if(B.brainmob.stat == DEAD) - user << "[O] is dead. Sticking it into the frame would sort of defeat the purpose." - return - - if(jobban_isbanned(B.brainmob, "Cyborg")) - user << "\The [O] does not seem to fit." - return - - user << "You install \the [O] in \the [src]!" - - 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("\The [user] has spot-welded some of the damage to \the [src]!") - else - user << "\The [src] is undamaged!" - else - user << "You need more welding fuel for this task!" - return - else if(istype(O, /obj/item/weapon/card/id)||istype(O, /obj/item/device/pda)) - if (!mmi) - user << "There's no reason to swipe your ID - \the [src] has no brain to remove." - 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 << "You swipe your access card and pop the brain out of \the [src]." - eject_brain() - if(held_item) - held_item.forceMove(src.loc) - held_item = null - return 1 - else - user << "You swipe your card with no effect." - 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 << "[src] is already overloaded - better run." - return 0 - else - user << "You short out the security protocols and overload [src]'s cell, priming it to explode in a short time." - spawn(100) - to_chat(src, "Your cell seems to be outputting a lot of power...") - spawn(200) - to_chat(src, "Internal heat sensors are spiking! Something is badly wrong with your cell!") - 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("\The [src] makes an odd warbling noise, fizzles, and explodes!") - 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 << "You have nothing to drop!" - return 0 - - if(istype(held_item, /obj/item/weapon/grenade)) - visible_message("\The [src] launches \the [held_item]!", \ - "You launch \the [held_item]!", \ - "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("\The [src] drops \the [held_item].", \ - "You drop \the [held_item].", \ - "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, "You are already holding \the [held_item]") - 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("\The [src] scoops up \the [held_item].", \ - "You grab \the [held_item].", \ - "You hear a skittering noise and a clink.") - return held_item - to_chat(src, "\The [selection] is too far away.") - return 0 - - to_chat(src, "There is nothing of interest to take.") - 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 diff --git a/code/modules/mob/living/simple_animal/animals/tomato.dm b/code/modules/mob/living/simple_animal/animals/tomato.dm deleted file mode 100644 index 711922eeb0..0000000000 --- a/code/modules/mob/living/simple_animal/animals/tomato.dm +++ /dev/null @@ -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 diff --git a/code/modules/mob/living/simple_animal/animals/tree.dm b/code/modules/mob/living/simple_animal/animals/tree.dm deleted file mode 100644 index 09c8451811..0000000000 --- a/code/modules/mob/living/simple_animal/animals/tree.dm +++ /dev/null @@ -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("\the [src] knocks down \the [L]!") - -/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) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/worm.dm b/code/modules/mob/living/simple_animal/animals/worm.dm deleted file mode 100644 index da30dbf8fd..0000000000 --- a/code/modules/mob/living/simple_animal/animals/worm.dm +++ /dev/null @@ -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 diff --git a/code/modules/mob/living/simple_animal/borer/borer.dm b/code/modules/mob/living/simple_animal/borer/borer.dm deleted file mode 100644 index 8b28544b9e..0000000000 --- a/code/modules/mob/living/simple_animal/borer/borer.dm +++ /dev/null @@ -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 << "You feel the soporific flow of sugar in your host's blood, lulling you into docility." - else - to_chat(src, "You feel the soporific flow of sugar in your host's blood, lulling you into docility.") - docile = 1 - else - if(docile) - if(controlling) - host << "You shake off your lethargy as the sugar leaves your host's blood." - else - to_chat(src, "You shake off your lethargy as the sugar leaves your host's blood.") - docile = 0 - - if(chemicals < 250) - chemicals++ - if(controlling) - - if(docile) - host << "You are feeling far too docile to continue controlling your host..." - 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, "You are a cortical borer! 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 say, to other borers with say :x, and use your Abilities tab to access powers.") - -/mob/living/simple_mob/animal/borer/cannot_use_vents() - return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/borer/borer_captive.dm b/code/modules/mob/living/simple_animal/borer/borer_captive.dm deleted file mode 100644 index c7088bc715..0000000000 --- a/code/modules/mob/living/simple_animal/borer/borer_captive.dm +++ /dev/null @@ -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, "You cannot speak in IC (muted).") - 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 << "You begin doggedly resisting the parasite's control (this will take approximately sixty seconds)." - B.host << "You feel the captive mind of [src] begin to resist your control." - - spawn(rand(200,250)+B.host.brainloss) - if(!B || !B.controlling) return - - B.host.adjustBrainLoss(rand(0.1,0.5)) - H << "With an immense exertion of will, you regain control of your body!" - B.host << "You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you." - B.detatch() - verbs -= /mob/living/carbon/proc/release_control - verbs -= /mob/living/carbon/proc/punish_host - verbs -= /mob/living/carbon/proc/spawn_larvae - - return - - ..() diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_animal/borer/borer_powers.dm deleted file mode 100644 index d5575f78e7..0000000000 --- a/code/modules/mob/living/simple_animal/borer/borer_powers.dm +++ /dev/null @@ -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, "You are feeling far too docile to do that.") - 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 << "Something slimy wiggles out of your ear and plops to the ground!" - host << "As though waking from a dream, you shake off the insidious mind control of the brain worm. Your thoughts are your own again." - - 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, "You are feeling far too docile to do that.") - return - - - to_chat(src, "It only takes a few moments to render the dead host brain down into a nutrient-rich slurry...") - 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, "You settle into the empty brainpan and begin to expand, fusing inextricably with the dead flesh of [H].") - - 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, "You are feeling far too docile to do that.") - 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, "You squirt a measure of [chem] from your reservoirs into [host]'s bloodstream.") - 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, "You focus your psychic lance on [M] and freeze their limbs with a wave of terrible dread.") - M << "You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing." - 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, "You are feeling far too docile to do that.") - 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, "You plunge your probosci deep into the cortex of the host brain, interfacing directly with their nervous system.") - host << "You feel a strange shifting sensation behind your eyes as an alien consciousness displaces yours." - 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 diff --git a/code/modules/mob/living/simple_animal/borer/say.dm b/code/modules/mob/living/simple_animal/borer/say.dm deleted file mode 100644 index 41229d9bd2..0000000000 --- a/code/modules/mob/living/simple_animal/borer/say.dm +++ /dev/null @@ -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, "You cannot speak in IC (muted).") - 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]\"" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/humanoids/clown.dm b/code/modules/mob/living/simple_animal/humanoids/clown.dm deleted file mode 100644 index d94fa47c77..0000000000 --- a/code/modules/mob/living/simple_animal/humanoids/clown.dm +++ /dev/null @@ -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") diff --git a/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm b/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm deleted file mode 100644 index 1bc4b985a4..0000000000 --- a/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm +++ /dev/null @@ -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" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/humanoids/pirate.dm b/code/modules/mob/living/simple_animal/humanoids/pirate.dm deleted file mode 100644 index a02e4382bb..0000000000 --- a/code/modules/mob/living/simple_animal/humanoids/pirate.dm +++ /dev/null @@ -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 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/humanoids/russian.dm b/code/modules/mob/living/simple_animal/humanoids/russian.dm deleted file mode 100644 index d02c36de5a..0000000000 --- a/code/modules/mob/living/simple_animal/humanoids/russian.dm +++ /dev/null @@ -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 diff --git a/code/modules/mob/living/simple_animal/humanoids/syndicate.dm b/code/modules/mob/living/simple_animal/humanoids/syndicate.dm deleted file mode 100644 index 9a11178e66..0000000000 --- a/code/modules/mob/living/simple_animal/humanoids/syndicate.dm +++ /dev/null @@ -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("\The [src] blocks \the [O] with its shield!") - if(user) - react_to_attack(user) - return - else - ..() - else - usr << "This weapon is ineffective, it does no damage." - visible_message("\The [user] gently taps [src] with \the [O].") - -/mob/living/simple_animal/hostile/syndicate/melee/bullet_act(var/obj/item/projectile/Proj) - if(!Proj) return - if(prob(35)) - visible_message("[src] blocks [Proj] with its shield!") - 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) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm deleted file mode 100644 index 741f32f3fd..0000000000 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ /dev/null @@ -1,1732 +0,0 @@ -#define ai_log(M,V) if(debug_ai) ai_log_output(M,V) - -//Talky things -#define try_say_list(L) if(L.len) say(pick(L)) - -/mob/living/simple_animal - name = "animal" - desc = "" - icon = 'icons/mob/animal.dmi' - health = 20 - maxHealth = 20 - - mob_bump_flag = SIMPLE_ANIMAL - mob_swap_flags = MONKEY|SLIME|HUMAN - mob_push_flags = MONKEY|SLIME|HUMAN - - var/tt_desc = "Uncataloged Life Form" //Tooltip description - - //Settings for played mobs - var/show_stat_health = 1 // Does the percentage health show in the stat panel for the mob - var/ai_inactive = 0 // Set to 1 to turn off most AI actions - var/has_hands = 0 // Set to 1 to enable the use of hands and the hands hud - var/humanoid_hands = 0 // Can a player in this mob use things like guns or AI cards? - var/hand_form = "hands" // Used in IsHumanoidToolUser. 'Your X are not fit-'. - var/list/hud_gears // Slots to show on the hud (typically none) - var/ui_icons // Icon file path to use for the HUD, otherwise generic icons are used - var/r_hand_sprite // If they have hands, - var/l_hand_sprite // they could use some icons. - var/player_msg // Message to print to players about 'how' to play this mob on login. - - //Mob icon/appearance settings - var/icon_living = "" // The iconstate if we're alive, required - var/icon_dead = "" // The iconstate if we're dead, required - var/icon_gib = "generic_gib" // The iconstate for being gibbed, optional. Defaults to a generic gib animation. - var/icon_rest = null // The iconstate for resting, optional - var/image/modifier_overlay = null // Holds overlays from modifiers. - attack_icon = 'icons/effects/effects.dmi' //Just the default, played like the weapon attack anim - attack_icon_state = "slash" //Just the default - - //Mob talking settings - universal_speak = 0 // Can all mobs in the entire universe understand this one? - var/has_langs = list(LANGUAGE_GALCOM)// Text name of their language if they speak something other than galcom. They speak the first one. - var/speak_chance = 0 // Probability that I talk (this is 'X in 200' chance since even 1/100 is pretty noisy) - var/reacts = 0 // Reacts to some things being said - var/list/speak = list() // Things I might say if I talk - var/list/emote_hear = list() // Hearable emotes I might perform - var/list/emote_see = list() // Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps - var/list/say_understood = list()// List of things to say when accepting an order - var/list/say_cannot = list() // List of things to say when they cannot comply - var/list/say_maybe_target = list()// List of things to say when they spot something barely - var/list/say_got_target = list()// List of things to say when they engage a target - var/list/reactions = list() // List of "string" = "reaction" and things they hear will be searched for string. - - //Mob movement settings - var/wander = 1 // Does the mob wander around when idle? - var/wander_distance = 3 // How far the mob will wander before going home (assuming they are allowed to do that) - var/returns_home = 0 // Mob knows how to return to wherever it started - var/turns_per_move = 1 // How many life() cycles to wait between each wander mov? - var/stop_when_pulled = 1 // When set to 1 this stops the animal from moving when someone is pulling it. - var/follow_dist = 2 // Distance the mob tries to follow a friend - var/obstacles = list() // Things this mob refuses to move through - var/speed = 0 // Higher speed is slower, negative speed is faster. - var/obj/item/weapon/card/id/myid// An ID card if they have one to give them access to stuff. - var/turf/home_turf // Set when they spawned, they try to come back here sometimes. - - //Mob interaction - var/response_help = "tries to help" // If clicked on help intent - var/response_disarm = "tries to disarm" // If clicked on disarm intent - var/response_harm = "tries to hurt" // If clicked on harm intent - var/harm_intent_damage = 3 // How much an unarmed harm click does to this mob. - var/meat_amount = 0 // How much meat to drop from this mob when butchered - var/obj/meat_type // The meat object to drop - var/list/loot_list = list() // The list of lootable objects to drop, with "/path = prob%" structure - var/recruitable = 0 // Mob can be bossed around - var/recruit_cmd_str = "Hey," // The thing you prefix commands with when bossing them around - var/intelligence_level = SA_ANIMAL// How 'smart' the mob is ICly, used to deliniate between animal, robot, and humanoid SAs. - - //Mob environment settings - var/minbodytemp = 250 // Minimum "okay" temperature in kelvin - var/maxbodytemp = 350 // Maximum of above - var/heat_damage_per_tick = 3 // Amount of damage applied if animal's body temperature is higher than maxbodytemp - var/cold_damage_per_tick = 2 // Same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp - var/fire_alert = 0 // 0 = fine, 1 = hot, 2 = cold - - var/min_oxy = 5 // Oxygen in moles, minimum, 0 is 'no minimum' - var/max_oxy = 0 // Oxygen in moles, maximum, 0 is 'no maximum' - var/min_tox = 0 // Phoron min - var/max_tox = 1 // Phoron max - var/min_co2 = 0 // CO2 min - var/max_co2 = 5 // CO2 max - var/min_n2 = 0 // N2 min - var/max_n2 = 0 // N2 max - var/unsuitable_atoms_damage = 2 // This damage is taken when atmos doesn't fit all the requirements above - - //Hostility settings - var/hostile = 0 // Do I even attack? - var/retaliate = 0 // I respond to damage against specific targets. - var/view_range = 7 // Scan for targets in this range. - var/specific_targets = 0 // Only use Found() targets, ignore others. - var/investigates = 0 // Do I investigate if I saw someone briefly? - var/attack_same = 0 // Do I attack members of my own faction? - var/cooperative = 0 // Do I ask allies to help me? - var/assist_distance = 25 // Radius in which I'll ask my comrades for help. - var/supernatural = 0 // If the mob is supernatural (used in null-rod stuff for banishing?) - var/grab_resist = 75 // Chance of me resisting a grab attempt. - var/taser_kill = 1 // Is the mob weak to tasers - - //Attack ranged settings - var/ranged = 0 // Do I attack at range? - var/shoot_range = 7 // How far away do I start shooting from? - var/rapid = 0 // Three-round-burst fire mode - var/firing_lines = 0 // Avoids shooting allies - var/projectiletype // The projectiles I shoot - var/projectilesound // The sound I make when I do it - var/casingtype // What to make the hugely laggy casings pile out of - - //Mob melee settings - var/melee_damage_lower = 2 // Lower bound of randomized melee damage - var/melee_damage_upper = 6 // Upper bound of randomized melee damage - var/list/attacktext = list("attacked") // "You are [attacktext] by the mob!" - var/list/friendly = list("nuzzles") // "The mob [friendly] the person." - var/attack_sound = null // Sound to play when I attack - var/environment_smash = 0 // How much environment damage do I do when I hit stuff? - var/melee_miss_chance = 15 // percent chance to miss a melee attack. - var/melee_attack_minDelay = 5 // How long between attacks at least - var/melee_attack_maxDelay = 10 // How long between attacks at most - var/attack_armor_type = "melee" // What armor does this check? - var/attack_armor_pen = 0 // How much armor pen this attack has. - var/attack_sharp = 0 // Is the attack sharp? - var/attack_edge = 0 // Does the attack have an edge? - - //Special attacks - var/spattack_prob = 0 // Chance of the mob doing a special attack (0 for never) - var/spattack_min_range = 0 // Min range to perform the special attacks from - var/spattack_max_range = 0 // Max range to perform special attacks from - - //Attack movement settings - var/run_at_them = 1 // Don't use A* pathfinding, use walk_to - var/move_to_delay = 4 // Delay for the automated movement (deciseconds) - var/destroy_surroundings = 1 // Should I smash things to get to my target? - var/astar_adjacent_proc = /turf/proc/CardinalTurfsWithAccess // Proc to use when A* pathfinding. Default makes them bound to cardinals. - - //Damage resistances - var/shock_resistance = 0 // Siemens modifier, directly subtracted from 1. Value of 0.4 means 0.6 siemens on shocks. - var/resistance = 0 // Damage reduction for all types - var/list/armor = list( // Values for normal getarmor() checks - "melee" = 0, - "bullet" = 0, - "laser" = 0, - "energy" = 0, - "bomb" = 0, - "bio" = 100, - "rad" = 100) - - //Scary debug things - var/debug_ai = 0 // Logging level for this mob (1,2,3) - var/path_display = 0 // Will display the path in green when pathing - var/path_icon = 'icons/misc/debug_group.dmi' // What icon to use for the overlay - var/path_icon_state = "red" // What state to use for the overlay - var/icon/path_overlay // A reference to restart - - ////// These are used for inter-proc communications so don't edit them manually ////// - var/stance = STANCE_IDLE // Used to determine behavior - var/stop_automated_movement = 0 // Use this to temporarely stop random movement or to if you write special movement code for animals. - var/lifes_since_move = 0 // A counter for how many life() cycles since move - var/shuttletarget = null // Shuttle's here, time to get to it - var/enroute = 0 // If the shuttle is en-route - var/purge = 0 // A counter used for null-rod stuff - var/mob/living/target_mob // Who I'm trying to attack - var/mob/living/follow_mob // Who I'm recruited by - var/mob/living/list/friends = list() // People who are immune to my wrath, for now - var/mob/living/simple_animal/list/faction_friends = list() // Other simple mobs I am friends with - var/turf/list/walk_list = list()// List of turfs to walk through to get somewhere - var/astarpathing = 0 // Am I currently pathing to somewhere? - var/stance_changed = 0 // When our stance last changed (world.time) - var/last_target_time = 0 // When we last set our target, to prevent juggles - var/last_follow_time = 0 // When did we last get asked to follow someone? - var/last_helpask_time = 0 // When did we last call for help? - var/follow_until_time = 0 // Give up following when we reach this time (0 = never) - var/annoyed = 0 // Do people keep distract-kiting us? - ////// ////// ////// - -/mob/living/simple_animal/New() - ..() - verbs -= /mob/verb/observe - home_turf = get_turf(src) - path_overlay = new(path_icon,path_icon_state) - move_to_delay = max(2,move_to_delay) //Protection against people coding things incorrectly and A* pathing 100% of the time - maxHealth = health - - for(var/L in has_langs) - languages |= all_languages[L] - if(languages.len) - default_language = languages[1] - - if(cooperative) - var/mob/living/simple_animal/first_friend - for(var/mob/living/simple_animal/M in living_mob_list) - if(M.faction == src.faction) - first_friend = M - break - if(first_friend) - faction_friends = first_friend.faction_friends - faction_friends |= src - else - faction_friends |= src - -/mob/living/simple_animal/Destroy() - home_turf = null - path_overlay = null - default_language = null - target_mob = null - follow_mob = null - if(myid) - qdel(myid) - myid = null - - if(faction_friends.len) //This list is shared amongst the faction - faction_friends -= src - - friends.Cut() //This one is not - walk_list.Cut() - languages.Cut() - return ..() - -//Client attached -/mob/living/simple_animal/Login() - . = ..() - ai_inactive = 1 - handle_stance(STANCE_IDLE) - LoseTarget() - to_chat(src,"Mob AI disabled while you are controlling the mob.
You are \the [src]. [player_msg]") - -//Client detatched -/mob/living/simple_animal/Logout() - spawn(15 SECONDS) //15 seconds to get back into the mob before it goes wild - if(src && !src.client) - ai_inactive = initial(ai_inactive) //So if they never have an AI, they stay that way. - ..() - -//For debug purposes! -/mob/living/simple_animal/proc/ai_log_output(var/msg = "missing message", var/ver = 1) - if(ver <= debug_ai) - log_debug("SA-AI: ([src]:[x],[y],[z])(@[world.time]): [msg] ") - -//Should we be dead? -/mob/living/simple_animal/updatehealth() - health = getMaxHealth() - getToxLoss() - getFireLoss() - getBruteLoss() - - //Alive, becoming dead - if((stat < DEAD) && (health <= 0)) - death() - - //Overhealth - if(health > getMaxHealth()) - health = getMaxHealth() - - //Update our hud if we have one - if(healths) - if(stat != DEAD) - var/heal_per = (health / getMaxHealth()) * 100 - switch(heal_per) - if(100 to INFINITY) - healths.icon_state = "health0" - if(80 to 100) - healths.icon_state = "health1" - if(60 to 80) - healths.icon_state = "health2" - if(40 to 60) - healths.icon_state = "health3" - if(20 to 40) - healths.icon_state = "health4" - if(0 to 20) - healths.icon_state = "health5" - else - healths.icon_state = "health6" - else - healths.icon_state = "health7" - - //Updates the nutrition while we're here - if(nutrition_icon) - var/food_per = (nutrition / initial(nutrition)) * 100 - switch(food_per) - if(90 to INFINITY) - nutrition_icon.icon_state = "nutrition0" - if(75 to 90) - nutrition_icon.icon_state = "nutrition1" - if(50 to 75) - nutrition_icon.icon_state = "nutrition2" - if(25 to 50) - nutrition_icon.icon_state = "nutrition3" - if(0 to 25) - nutrition_icon.icon_state = "nutrition4" - -/mob/living/simple_animal/update_icon() - . = ..() - var/mutable_appearance/ma = new(src) - ma.layer = layer - ma.plane = plane - - ma.overlays = list(modifier_overlay) - - //Awake and normal - if((stat == CONSCIOUS) && (!icon_rest || !resting || !incapacitated(INCAPACITATION_DISABLED) )) - ma.icon_state = icon_living - - //Dead - else if(stat >= DEAD) - ma.icon_state = icon_dead - - //Resting or KO'd - else if(((stat == UNCONSCIOUS) || resting || incapacitated(INCAPACITATION_DISABLED) ) && icon_rest) - ma.icon_state = icon_rest - - //Backup - else - ma.icon_state = initial(icon_state) - - if(has_hands) - if(r_hand_sprite) - ma.overlays += r_hand_sprite - if(l_hand_sprite) - ma.overlays += l_hand_sprite - - appearance = ma - -// If your simple mob's update_icon() call calls overlays.Cut(), this needs to be called after this, or manually apply modifier_overly to overlays. -/mob/living/simple_animal/update_modifier_visuals() - var/image/effects = null - if(modifier_overlay) - overlays -= modifier_overlay - modifier_overlay.overlays.Cut() - effects = modifier_overlay - else - effects = new() - - for(var/datum/modifier/M in modifiers) - if(M.mob_overlay_state) - var/image/I = image("icon" = 'icons/mob/modifier_effects.dmi', "icon_state" = M.mob_overlay_state) - I.appearance_flags = RESET_COLOR // So colored mobs don't affect the overlay. - effects.overlays += I - - modifier_overlay = effects - overlays += modifier_overlay - - -/mob/living/simple_animal/Life() - ..() - - //Health - updatehealth() - if(stat >= DEAD) - return 0 - - handle_stunned() - handle_weakened() - handle_paralysed() - handle_supernatural() - handle_atmos() //Atmos - - ai_log("Life() - stance=[stance] ai_inactive=[ai_inactive]", 4) - - //AI Actions - if(!ai_inactive) - //Stanceyness - handle_stance() - - //Movement - if(!stop_automated_movement && wander && !anchored) //Allowed to move? - handle_wander_movement() - - //Speaking - if(speak_chance && stance == STANCE_IDLE) // Allowed to chatter? - handle_idle_speaking() - - //Resisting out buckles - if(stance != STANCE_IDLE && incapacitated(INCAPACITATION_BUCKLED_PARTIALLY)) - handle_resist() - - //Resisting out of closets - if(istype(loc,/obj/structure/closet)) - var/obj/structure/closet/C = loc - if(C.sealed) - handle_resist() - else - C.open() - - return 1 - -// Resists out of things. -// Sometimes there are times you want SAs to be buckled to something, so override this for when that is needed. -/mob/living/simple_animal/proc/handle_resist() - resist() - -// Peforms the random walk wandering -/mob/living/simple_animal/proc/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. - Move(get_step(src,moving_to)) - lifes_since_move = 0 - -// Handles random chatter, called from Life() when stance = STANCE_IDLE -/mob/living/simple_animal/proc/handle_idle_speaking() - if(rand(0,200) < speak_chance) - if(speak && speak.len) - if((emote_hear && emote_hear.len) || (emote_see && emote_see.len)) - var/length = speak.len - if(emote_hear && emote_hear.len) - length += emote_hear.len - if(emote_see && emote_see.len) - length += emote_see.len - var/randomValue = rand(1,length) - if(randomValue <= speak.len) - try_say_list(speak) - else - randomValue -= speak.len - if(emote_see && randomValue <= emote_see.len) - visible_emote("[pick(emote_see)].") - else - audible_emote("[pick(emote_hear)].") - else - try_say_list(speak) - else - if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len)) - visible_emote("[pick(emote_see)].") - if((emote_hear && emote_hear.len) && !(emote_see && emote_see.len)) - audible_emote("[pick(emote_hear)].") - if((emote_hear && emote_hear.len) && (emote_see && emote_see.len)) - var/length = emote_hear.len + emote_see.len - var/pick = rand(1,length) - if(pick <= emote_see.len) - visible_emote("[pick(emote_see)].") - else - audible_emote("[pick(emote_hear)].") - -// Handle interacting with and taking damage from atmos -// TODO - Refactor this to use handle_environment() like a good /mob/living -/mob/living/simple_animal/proc/handle_atmos() - var/atmos_unsuitable = 0 - - var/atom/A = src.loc - - if(istype(A,/turf)) - var/turf/T = A - - var/datum/gas_mixture/Environment = T.return_air() - - if(Environment) - - if( abs(Environment.temperature - bodytemperature) > 40 ) - bodytemperature += ((Environment.temperature - bodytemperature) / 5) - - if(min_oxy) - if(Environment.gas["oxygen"] < min_oxy) - atmos_unsuitable = 1 - if(max_oxy) - if(Environment.gas["oxygen"] > max_oxy) - atmos_unsuitable = 1 - if(min_tox) - if(Environment.gas["phoron"] < min_tox) - atmos_unsuitable = 2 - if(max_tox) - if(Environment.gas["phoron"] > max_tox) - atmos_unsuitable = 2 - if(min_n2) - if(Environment.gas["nitrogen"] < min_n2) - atmos_unsuitable = 1 - if(max_n2) - if(Environment.gas["nitrogen"] > max_n2) - atmos_unsuitable = 1 - if(min_co2) - if(Environment.gas["carbon_dioxide"] < min_co2) - atmos_unsuitable = 1 - if(max_co2) - if(Environment.gas["carbon_dioxide"] > max_co2) - atmos_unsuitable = 1 - - //Atmos effect - if(bodytemperature < minbodytemp) - fire_alert = 2 - adjustBruteLoss(cold_damage_per_tick) - if(fire) - fire.icon_state = "fire1" - else if(bodytemperature > maxbodytemp) - fire_alert = 1 - adjustBruteLoss(heat_damage_per_tick) - if(fire) - fire.icon_state = "fire2" - else - fire_alert = 0 - if(fire) - fire.icon_state = "fire0" - - if(atmos_unsuitable) - adjustBruteLoss(unsuitable_atoms_damage) - if(oxygen) - oxygen.icon_state = "oxy1" - else if(oxygen) - if(oxygen) - oxygen.icon_state = "oxy0" - -// For setting the stance WITHOUT processing it -/mob/living/simple_animal/proc/set_stance(var/new_stance) - stance = new_stance - stance_changed = world.time - ai_log("set_stance() changing to [new_stance]",2) - -// For proccessing the current stance, or setting and processing a new one -/mob/living/simple_animal/proc/handle_stance(var/new_stance) - if(ai_inactive) - stance = STANCE_IDLE - return - - if(new_stance) - set_stance(new_stance) - - switch(stance) - if(STANCE_IDLE) - target_mob = null - a_intent = I_HELP - annoyed = max(0,annoyed--) - - //Yes I'm breaking this into two if()'s for ease of reading - //If we ARE ALLOWED TO - if(returns_home && home_turf && !astarpathing && (world.time - stance_changed) > 10 SECONDS) - if(get_dist(src,home_turf) > wander_distance) - move_to_delay = initial(move_to_delay)*2 //Walk back. - GoHome() - else - stop_automated_movement = 0 - - //Search for targets while idle - if(hostile || specific_targets) - FindTarget() - if(STANCE_FOLLOW) - annoyed = 15 - FollowTarget() - if(follow_until_time && world.time > follow_until_time) - LoseFollow() - return - if(hostile || specific_targets) - FindTarget() - if(STANCE_ATTACK) - annoyed = 50 - a_intent = I_HURT - RequestHelp() - MoveToTarget() - if(STANCE_ATTACKING) - annoyed = 50 - AttackTarget() - -/mob/living/simple_animal/proc/handle_supernatural() - if(purge) - purge -= 1 - -/mob/living/simple_animal/gib() - ..(icon_gib,1,icon) // we need to specify where the gib animation is stored - -/mob/living/simple_animal/emote(var/act, var/type, var/desc) - if(act) - ..(act, type, desc) - -/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj) - ai_log("bullet_act() I was shot by: [Proj.firer]",2) - - //Projectiles with bonus SA damage - if(!Proj.nodamage) - if(!Proj.SA_vulnerability || Proj.SA_vulnerability == intelligence_level) - Proj.damage += Proj.SA_bonus_damage - - . = ..() - - if(Proj.firer) - react_to_attack(Proj.firer) - -// When someone clicks us with an empty hand -/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M as mob) - ..() - - switch(M.a_intent) - - if(I_HELP) - if (health > 0) - M.visible_message("[M] [response_help] \the [src].") - - if(I_DISARM) - M.visible_message("[M] [response_disarm] \the [src].") - M.do_attack_animation(src) - //TODO: Push the mob away or something - - if(I_GRAB) - if (M == src) - return - if (!(status_flags & CANPUSH)) - return - if(!incapacitated(INCAPACITATION_ALL) && (stance != STANCE_IDLE) && prob(grab_resist)) - M.visible_message("[M] tries to grab [src] but fails!") - return - - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src) - - M.put_in_active_hand(G) - - G.synch() - G.affecting = src - LAssailant = M - - M.visible_message("[M] has grabbed [src] passively!") - M.do_attack_animation(src) - ai_log("attack_hand() I was grabbed by: [M]",2) - react_to_attack(M) - - if(I_HURT) - var/armor = run_armor_check(def_zone = null, attack_flag = "melee") - apply_damage(damage = harm_intent_damage, damagetype = BURN, def_zone = null, blocked = armor, blocked = resistance, used_weapon = null, sharp = FALSE, edge = FALSE) - M.visible_message("[M] [response_harm] \the [src]!") - M.do_attack_animation(src) - ai_log("attack_hand() I was hit by: [M]",2) - react_to_attack(M) - - return - -// When somoene clicks us with an item in hand -/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user) - if(istype(O, /obj/item/stack/medical)) - if(stat != DEAD) - var/obj/item/stack/medical/MED = O - if(health < getMaxHealth()) - if(MED.amount >= 1) - adjustBruteLoss(-MED.heal_brute) - MED.amount -= 1 - if(MED.amount <= 0) - qdel(MED) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("[user] applies the [MED] on [src].") - else - var/datum/gender/T = gender_datums[src.get_visible_gender()] - user << "\The [src] is dead, medical items won't bring [T.him] back to life." // the gender lookup is somewhat overkill, but it functions identically to the obsolete gender macros and future-proofs this code - if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead. - if(istype(O, /obj/item/weapon/material/knife) || istype(O, /obj/item/weapon/material/knife/butch)) - harvest(user) - else - ai_log("attackby() I was weapon'd by: [user]",2) - if(O.force) - react_to_attack(user) - - return ..() - -/mob/living/simple_animal/hit_with_weapon(obj/item/O, mob/living/user, var/effective_force, var/hit_zone) - - //Animals can't be stunned(?) - if(O.damtype == HALLOSS) - effective_force = 0 - if(supernatural && istype(O,/obj/item/weapon/nullrod)) - effective_force *= 2 - purge = 3 - if(O.force <= resistance) - to_chat(user,"This weapon is ineffective, it does no damage.") - return 2 - - ai_log("hit_with_weapon() I was h_w_weapon'd by: [user]",2) - react_to_attack(user) - - . = ..() - -// When someone throws something at us -/mob/living/simple_animal/hitby(atom/movable/AM) - ..() - if(AM.thrower) - react_to_attack(AM.thrower) - -//SA vs SA basically -/mob/living/simple_animal/attack_generic(var/mob/attacker) - if(attacker) - react_to_attack(attacker) - return ..() - -/mob/living/simple_animal/movement_delay() - var/tally = 0 //Incase I need to add stuff other than "speed" later - - tally = speed - - if(force_max_speed) - return -3 - - for(var/datum/modifier/M in modifiers) - if(!isnull(M.haste) && M.haste == TRUE) - return -3 - if(!isnull(M.slowdown)) - tally += M.slowdown - - if(purge)//Purged creatures will move more slowly. The more time before their purge stops, the slower they'll move. - if(tally <= 0) - tally = 1 - tally *= purge - - if(m_intent == "walk") - tally *= 1.5 - - return tally+config.animal_delay - -/mob/living/simple_animal/Stat() - ..() - - if(statpanel("Status") && show_stat_health) - stat(null, "Health: [round((health / getMaxHealth()) * 100)]%") - -/mob/living/simple_animal/lay_down() - ..() - if(resting && icon_rest) - icon_state = icon_rest - else - icon_state = icon_living - update_icon() - -/mob/living/simple_animal/death(gibbed, deathmessage = "dies!") - density = 0 //We don't block even if we did before - walk(src, 0) //We stop any background-processing walks - resting = 0 //We can rest in peace later. - - if(faction_friends.len) - faction_friends -= src - - if(loot_list.len) //Drop any loot - for(var/path in loot_list) - if(prob(loot_list[path])) - new path(get_turf(src)) - - spawn(3) //We'll update our icon in a sec - update_icon() - - return ..(gibbed,deathmessage) - -/mob/living/simple_animal/ex_act(severity) - if(!blinded) - flash_eyes() - var/armor = run_armor_check(def_zone = null, attack_flag = "bomb") - var/bombdam = 500 - switch (severity) - if (1.0) - bombdam = 500 - if (2.0) - bombdam = 60 - if (3.0) - bombdam = 30 - - apply_damage(damage = bombdam, damagetype = BRUTE, def_zone = null, blocked = armor, blocked = resistance, used_weapon = null, sharp = FALSE, edge = FALSE) - - if(bombdam > maxHealth) - gib() - -// Check target_mob if worthy of attack (i.e. check if they are dead or empty mecha) -/mob/living/simple_animal/proc/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) - return 1 - if (istype(target_mob,/obj/mecha)) - var/obj/mecha/M = target_mob - if (M.occupant) - return 1 - ai_log("SA_attackable([target_mob]): no",3) - return 0 - -/mob/living/simple_animal/say(var/message,var/datum/language/language) - var/verb = "says" - if(speak_emote.len) - verb = pick(speak_emote) - - message = sanitize(message) - - ..(message, null, verb) - -/mob/living/simple_animal/get_speech_ending(verb, var/ending) - return verb - -/mob/living/simple_animal/put_in_hands(var/obj/item/W) // No hands. - if(has_hands) - put_in_active_hand(W) - return 1 - W.forceMove(get_turf(src)) - return 1 - -// Harvest an animal's delicious byproducts -/mob/living/simple_animal/proc/harvest(var/mob/user) - var/actual_meat_amount = max(1,(meat_amount/2)) - if(meat_type && actual_meat_amount>0 && (stat == DEAD)) - for(var/i=0;i[user] chops up \the [src]!") - new/obj/effect/decal/cleanable/blood/splatter(get_turf(src)) - qdel(src) - else - user.visible_message("[user] butchers \the [src] messily!") - gib() - -/mob/living/simple_animal/handle_fire() - return -/mob/living/simple_animal/update_fire() - return -/mob/living/simple_animal/IgniteMob() - return -/mob/living/simple_animal/ExtinguishMob() - return - -//We got hit! Consider hitting them back! -/mob/living/simple_animal/proc/react_to_attack(var/mob/living/M) - if(ai_inactive || stat || M == target_mob) return //Not if we're dead or already hitting them - if(M in friends || M.faction == faction) return //I'll overlook it THIS time... - ai_log("react_to_attack([M])",1) - if(retaliate && set_target(M, 1)) - handle_stance(STANCE_ATTACK) - return M - - return 0 - -/mob/living/simple_animal/proc/set_target(var/mob/M, forced = 0) - ai_log("SetTarget([M])",2) - if(!M || (world.time - last_target_time < 5 SECONDS) && target_mob) - ai_log("SetTarget() can't set it again so soon",3) - return 0 - - var/turf/seen = get_turf(M) - - if(investigates && (annoyed < 10)) - try_say_list(say_maybe_target) - face_atom(seen) - annoyed += 14 - sleep(1 SECOND) //For realism - - if(forced || (M in ListTargets(view_range))) - try_say_list(say_got_target) - target_mob = M - last_target_time = world.time - return M - else if(investigates) - spawn(1) - WanderTowards(seen) - - return 0 - -// Set a follow target, with optional time for how long to follow them. -/mob/living/simple_animal/proc/set_follow(var/mob/M, var/follow_for = 0) - ai_log("SetFollow([M]) for=[follow_for]",2) - if(!M || (world.time - last_target_time < 4 SECONDS) && follow_mob) - ai_log("SetFollow() can't set it again so soon",3) - return 0 - - follow_mob = M - last_follow_time = world.time - follow_until_time = !follow_for ? 0 : world.time + follow_for - return 1 - -//Scan surroundings for a valid target -/mob/living/simple_animal/proc/FindTarget() - var/atom/T = null - for(var/atom/A in ListTargets(view_range)) - - if(A == src) - continue - - var/atom/F = Found(A) - if(F) - T = F - break - else if(specific_targets) - return 0 - - if(isliving(A)) - var/mob/living/L = A - if(L.faction == src.faction && !attack_same) - continue - else if(L in friends) - continue - else if(L.alpha <= EFFECTIVE_INVIS) - continue - else if(!SA_attackable(L)) - continue - else if(!special_target_check(L)) - continue - else - T = L - break - - else if(istype(A, /obj/mecha)) // Our line of sight stuff was already done in ListTargets(). - var/obj/mecha/M = A - if(!SA_attackable(M)) - continue - else if(!special_target_check(M)) - continue - if((M.occupant.faction != src.faction) || attack_same) - T = M - break - - //You found one! - if(T) - ai_log("FindTarget() found [T]!",1) - if(set_target(T)) - handle_stance(STANCE_ATTACK) - - return T - -//Used for special targeting or reactions -/mob/living/simple_animal/proc/Found(var/atom/A) - return - -// Used for somewhat special targeting, but not to the extent of using Found() -/mob/living/simple_animal/proc/special_target_check(var/atom/A) - return TRUE - -//Requesting help from like-minded individuals -/mob/living/simple_animal/proc/RequestHelp() - if(!cooperative || ((world.time - last_helpask_time) < 10 SECONDS)) - return - - ai_log("RequestHelp() to [faction_friends.len] friends",2) - last_helpask_time = world.time - for(var/mob/living/simple_animal/F in faction_friends) - if(F == src) continue - if(get_dist(src,F) <= F.assist_distance) - spawn(0) - if(F) //They could have died by now and some mobs delete themselves on death - ai_log("RequestHelp() to [F]",3) - F.HelpRequested(src) - -//Someone wants help? -/mob/living/simple_animal/proc/HelpRequested(var/mob/living/simple_animal/F) - if(target_mob || stat) - ai_log("HelpRequested() by [F] but we're busy/dead",2) - return - if(get_dist(src,F) <= follow_dist) - ai_log("HelpRequested() by [F] but we're already here",2) - return - if(get_dist(src,F) <= view_range) - ai_log("HelpRequested() by [F] and within targetshare range",2) - if(F.target_mob && set_target(F.target_mob)) - handle_stance(STANCE_ATTACK) - return - - if(set_follow(F, 10 SECONDS)) - handle_stance(STANCE_FOLLOW) - -// Can be used to conditionally do a ranged or melee attack. -// Note that the SA must be able to do an attack at the specified range or else it may get trapped in a loop of switching -// between STANCE_ATTACK and STANCE_ATTACKING, due to being told by MoveToTarget() that they're in range but being told by AttackTarget() that they're not. -/mob/living/simple_animal/proc/ClosestDistance() - return ranged ? shoot_range - 1 : 1 // Shoot range -1 just because we don't want to constantly get kited - -//Move to a target (or near if we're ranged) -/mob/living/simple_animal/proc/MoveToTarget() - if(incapacitated(INCAPACITATION_DISABLED)) - ai_log("MoveToTarget() Bailing because we're disabled",2) - return - - //If we were chasing someone and we can't anymore, give up. - if(!target_mob || !SA_attackable(target_mob)) - ai_log("MoveToTarget() Losing target at top",2) - LoseTarget() - return - - //Don't wander - stop_automated_movement = 1 - move_to_delay = initial(move_to_delay) - - //We recompute our path every time we're called if we can still see them - if(target_mob in ListTargets(view_range)) - - //Recompute the path if we were using one since we can still see them. - if(astarpathing) - ForgetPath() - - //Find out where we're getting to - var/get_to = ClosestDistance() - var/distance = get_dist(src,target_mob) - ai_log("MoveToTarget() [src] get_to: [get_to] distance: [distance]",2) - - //We're here! - if(distance <= get_to) - ai_log("MoveToTarget() [src] attack range",2) - handle_stance(STANCE_ATTACKING) - return - - //We're just setting out, making a new path, or we can't path with A* - if(!walk_list.len) - ai_log("SA: MoveToTarget() pathing to [target_mob]",2) - - //GetPath failed for whatever reason, just smash into things towards them - if(run_at_them || !GetPath(get_turf(target_mob),get_to)) - - //We try the built-in way to stay close - walk_to(src, target_mob, get_to, move_to_delay) - ai_log("MoveToTarget() walk_to([src],[target_mob],[get_to],[move_to_delay])",3) - - //Break shit in their direction! LEME SMAHSH - var/dir_to_mob = get_dir(src,target_mob) - face_atom(target_mob) - DestroySurroundings(dir_to_mob) - ai_log("MoveToTarget() DestroySurroundings([get_dir(src,target_mob)])",3) - - //We have a path! We aren't already pathing it! - if(!astarpathing && walk_list.len) - ai_log("MoveToTarget() going to start a path",2) - spawn(1) - - //Do the path! - var/result = WalkPath(target_thing = target_mob, target_dist = get_to) - ai_log("MoveToTarget() WalkPath r:[result]",2) - - //WalkPath failed, either interrupted for recalc, or something else - if(!result) - return - - //WalkPath either got close enough or we ran out of path - else - spawn(1) - ai_log("MoveToTarget() resetting",2) - MoveToTarget() - - //We can't see them, and we don't have a path we're trying to follow to find them - else if(!astarpathing) - ai_log("MoveToTarget() Losing target at bottom",2) - LoseTarget() //Just forget it. - -//Follow a target (and don't attempt to murder it horribly) -/mob/living/simple_animal/proc/FollowTarget() - ai_log("FollowTarget() [follow_mob]",1) - stop_automated_movement = 1 - //If we were chasing someone and we can't anymore, give up. - if(!follow_mob || follow_mob.stat) - ai_log("FollowTarget() Losing follow at top",2) - LoseFollow() - return - - if(incapacitated(INCAPACITATION_DISABLED)) - ai_log("FollowTarget() Bailing because we're disabled",2) - LoseFollow() - return - - if((get_dist(src,follow_mob) <= follow_dist)) - ai_log("FollowTarget() Already at target",2) - return - - move_to_delay = initial(move_to_delay) - var/start_distance = get_dist(src,follow_mob) - - //Bad pathing - if(run_at_them) - walk_to(src, follow_mob, follow_dist, move_to_delay) - ai_log("FollowTarget() walk_to([src],[target_mob],2,[move_to_delay])",3) - spawn(3 SECONDS) - if(src && follow_mob && (stance == STANCE_FOLLOW) && (get_dist(src,follow_mob) >= start_distance)) - ai_log("FollowTarget() walk_to not making headway, giving up",3) - LoseFollow() - - //Good pathing - else - GetPath(get_turf(follow_mob),follow_dist) - if(!astarpathing && walk_list.len) - spawn(1) - ai_log("FollowTarget() A* path getting underway",2) - //Do the path! - var/result = WalkPath(target_thing = follow_mob, target_dist = follow_dist) - ai_log("FollowTarget() WalkPath r:[result]",3) - - else - ai_log("FollowTarget() GetPath can't path, giving up",3) - LoseFollow() - -//Just try one time to go look at something. Don't really focus much on it. -/mob/living/simple_animal/proc/WanderTowards(var/turf/T) - if(!T) return - ai_log("WanderTowards() [T.x],[T.y]",1) - - stop_automated_movement = 1 - GetPath(T,1) - - if(run_at_them || !walk_list.len) - ai_log("WanderTowards() walk_to getting underway",2) - walk_to(src, T, 1, move_to_delay) - else - if(!astarpathing) - spawn(1) - ai_log("WanderTowards() A* path getting underway",2) - WalkPath(target_thing = T, target_dist = 1) - -//A* now, try to a path to a target -/mob/living/simple_animal/proc/GetPath(var/turf/target,var/get_to = 1,var/max_distance = world.view*6) - ai_log("GetPath([target],[get_to],[max_distance])",2) - ForgetPath() - var/list/new_path = AStar(get_turf(loc), target, astar_adjacent_proc, /turf/proc/Distance, min_target_dist = get_to, max_node_depth = max_distance, id = myid, exclude = obstacles) - - if(new_path && new_path.len) - walk_list = new_path - if(path_display) - for(var/turf/T in walk_list) - T.overlays |= path_overlay - else - return 0 - - return walk_list.len - -//Walk along our A* path, target_thing allows us to stop early if we're nearby -/mob/living/simple_animal/proc/WalkPath(var/atom/target_thing, var/target_dist = 1, var/proc/steps_callback = null, var/every_steps = 4) - ai_log("WalkPath() (steps:[walk_list.len])",2) - if(!walk_list || !walk_list.len) - return - - astarpathing = 1 - var/step_count = 0 - var/failed_steps = 0 - while(1) - //We're supposed to stop - if(!astarpathing || incapacitated(INCAPACITATION_DISABLED)) - astarpathing = 0 - ai_log("WalkPath() was interrupted",2) - return 0 - //Finished the path - if(!walk_list.len) - astarpathing = 0 - ai_log("WalkPath() exited naturally",2) - return 1 - if(failed_steps >= 3) - astarpathing = 0 - ai_log("WalkPath() failed too many steps",2) - return 0 - - //Take a step - if(!MoveOnce()) - ai_log("WalkPath() failed a step",3) - failed_steps++ - else - ai_log("WalkPath() took a step",3) - failed_steps = 0 - step_count++ - - //If we have a particular target we care about, look for them - if(target_thing && (get_dist(src,target_thing) <= target_dist)) - ai_log("WalkPath() returning due to proximity",2) - return target_thing - - //If we have a callback - if(steps_callback && (step_count >= every_steps)) - ai_log("WalkPath() doing callback",3) - call(steps_callback)() - - //And wait for the time to our next step - sleep(move_to_delay) - -//Take one step along a path -/mob/living/simple_animal/proc/MoveOnce() - if(!walk_list.len) - return - - if(path_display) - var/turf/T = src.walk_list[1] - T.overlays -= path_overlay - - step_towards(src, src.walk_list[1]) - if(src.loc != src.walk_list[1]) - ai_log("MoveOnce() step_towards returning 0",3) - return 0 - else - walk_list -= src.walk_list[1] - ai_log("MoveOnce() step_towards returning 1",3) - return 1 - -//Forget the path entirely -/mob/living/simple_animal/proc/ForgetPath() - ai_log("ForgetPath()",2) - if(path_display) - for(var/turf/T in walk_list) - T.overlays -= path_overlay - astarpathing = 0 - walk_list.Cut() - -//Giving up on moving -/mob/living/simple_animal/proc/GiveUpMoving() - ai_log("GiveUpMoving()",1) - ForgetPath() - walk(src, 0) - stop_automated_movement = 0 - -//Return home, all-in-one proc (though does target scan and drop out if they see one) -/mob/living/simple_animal/proc/GoHome() - if(!home_turf) return - if(astarpathing) ForgetPath() - ai_log("GoHome()",1) - var/close_enough = 2 - var/look_in = 50 - if(GetPath(home_turf,close_enough,look_in)) - stop_automated_movement = 1 - spawn(1) - if(WalkPath()) //If we made it without interruption - ai_log("GoHome() got home",2) - GiveUpMoving() //Go back to wandering - -//Get into attack mode on a target -/mob/living/simple_animal/proc/AttackTarget() - stop_automated_movement = 1 - if(incapacitated(INCAPACITATION_DISABLED)) - ai_log("AttackTarget() Bailing because we're disabled",2) - LoseTarget() - return 0 - if(!target_mob || !SA_attackable(target_mob) || (target_mob.alpha <= EFFECTIVE_INVIS)) //if the target went invisible, you can't follow it - LoseTarget() - return 0 - if(!(target_mob in ListTargets(view_range))) - LostTarget() - return 0 - - ai_log("AttackTarget() vs. [target_mob]",1) - var/distance = get_dist(src, target_mob) - face_atom(target_mob) - - //Hadoooooken! - if(prob(spattack_prob) && (distance >= spattack_min_range) && (distance <= spattack_max_range)) - ai_log("AttackTarget() special",3) - if(SpecialAtkTarget()) //Might not succeed/be allowed, do something else. - return 1 - //AAAAH! - if(distance <= 1) - ai_log("AttackTarget() melee",3) - PunchTarget() - return 1 - //Open fire! - else if(ranged && (distance <= shoot_range)) - ai_log("AttackTarget() ranged",3) - ShootTarget(target_mob) - return 1 - //They ran away! - else - ai_log("AttackTarget() out of range!",3) - stoplag(1) // Unfortunately this is needed to protect from ClosestDistance() sometimes not updating fast enough to prevent an infinite loop. - handle_stance(STANCE_ATTACK) - return 0 - -//Attack the target in melee -/mob/living/simple_animal/proc/PunchTarget() - if(!Adjacent(target_mob)) - return - if(!canClick()) - return - setClickCooldown(get_attack_speed()) -// if(!client) -// sleep(rand(melee_attack_minDelay, melee_attack_maxDelay)) - if(isliving(target_mob)) - var/mob/living/L = target_mob - - if(prob(melee_miss_chance)) - add_attack_logs(src,L,"Animal-attacked (miss)", admin_notify = FALSE) - visible_message("[src] misses [L]!") - do_attack_animation(src) - return L - else - DoPunch(L) - return L - if(istype(target_mob,/obj/mecha)) - var/obj/mecha/M = target_mob - DoPunch(M) - return M - -// This is the actual act of 'punching'. Override for special behaviour. -/mob/living/simple_animal/proc/DoPunch(var/atom/A) - if(!Adjacent(A) && !istype(A, /obj/structure/window) && !istype(A, /obj/machinery/door/window)) // They could've moved in the meantime. But a Window probably wouldn't have. This allows player simple-mobs to attack windows. - 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 - if(H.check_shields(damage = damage_to_do, damage_source = src, attacker = src, def_zone = null, attack_text = "the attack")) - return FALSE - - 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 - -//The actual top-level ranged attack proc -/mob/living/simple_animal/proc/ShootTarget() - if(!canClick()) - return FALSE - - setClickCooldown(get_attack_speed()) - - var/target = target_mob - var/tturf = get_turf(target) - - if((firing_lines && !client) && !CheckFiringLine(tturf)) - step_rand(src) - face_atom(tturf) - return FALSE - - visible_message("[src] fires at [target]!") - if(rapid) - spawn(1) - Shoot(target, src.loc, src) - if(casingtype) - new casingtype(get_turf(src)) - spawn(4) - Shoot(target, src.loc, src) - if(casingtype) - new casingtype(get_turf(src)) - spawn(6) - Shoot(target, src.loc, src) - if(casingtype) - new casingtype(get_turf(src)) - else - Shoot(target, src.loc, src) - if(casingtype) - new casingtype - - return TRUE - -//Check firing lines for faction_friends (if we're not cooperative, we don't care) -/mob/living/simple_animal/proc/CheckFiringLine(var/turf/tturf) - if(!tturf) return - - var/turf/list/crosses = list() - var/this_turf = get_turf(src) - - while(this_turf != tturf) - this_turf = get_step(this_turf,get_dir(this_turf,tturf)) - crosses += this_turf - - for(var/mob/living/FF in faction_friends) - if(FF.loc in crosses) - return 0 - - for(var/mob/living/F in friends) - if(F.loc in crosses) - return 0 - - return 1 - -//Special attacks, like grenades or blinding spit or whatever -/mob/living/simple_animal/proc/SpecialAtkTarget() - return 0 - -//Shoot a bullet at someone -/mob/living/simple_animal/proc/Shoot(atom/target, atom/start, mob/user, var/bullet = 0) - if(target == start) - return - - var/obj/item/projectile/A = new projectiletype(user.loc) - playsound(user, projectilesound, 100, 1) - if(!A) return - -// if (!istype(target, /turf)) -// qdel(A) -// return - A.old_style_target(target) - A.fire() - -//We can't see the target -/mob/living/simple_animal/proc/LoseTarget() - ai_log("LoseTarget() [target_mob]",2) - target_mob = null - handle_stance(STANCE_IDLE) - GiveUpMoving() - -//Target is no longer valid (?) -/mob/living/simple_animal/proc/LostTarget() - handle_stance(STANCE_IDLE) - GiveUpMoving() - -//Forget a follow mode -/mob/living/simple_animal/proc/LoseFollow() - ai_log("LoseFollow() [target_mob]",2) - stop_automated_movement = 0 - follow_mob = null - handle_stance(STANCE_IDLE) - GiveUpMoving() - -// Makes the simple mob stop everything. Useful for when it get stunned. -/mob/living/simple_animal/proc/Disable() - ai_log("Disable() [target_mob]",2) - spawn(0) - LoseTarget() - LoseFollow() - -/mob/living/simple_animal/Stun(amount) - if(amount > 0) - Disable() - ..(amount) - -/mob/living/simple_animal/AdjustStunned(amount) - if(amount > 0) - Disable() - ..(amount) - -/mob/living/simple_animal/Weaken(amount) - if(amount > 0) - Disable() - ..(amount) - -/mob/living/simple_animal/AdjustWeakened(amount) - if(amount > 0) - Disable() - ..(amount) - -/mob/living/simple_animal/Paralyse(amount) - if(amount > 0) - Disable() - ..(amount) - -/mob/living/simple_animal/AdjustParalysis(amount) - if(amount > 0) - Disable() - ..(amount) - -//Find me some targets -/mob/living/simple_animal/proc/ListTargets(var/dist = view_range) - var/list/L = hearers(src, dist) - - for(var/obj/mecha/M in mechas_list) - if ((M.z == src.z) && (get_dist(src, M) <= dist) && (isInSight(src,M))) - L += M - - return L - -//Break through windows/other things -/mob/living/simple_animal/proc/DestroySurroundings(var/direction) - if(!direction) - direction = pick(cardinal) //FLAIL WILDLY - - var/turf/problem_turf = get_step(src, direction) - - ai_log("DestroySurroundings([direction])",3) - 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 - - for(var/obj/structure/window/obstacle in problem_turf) - if(obstacle.dir == reverse_dir[dir]) // So that windows get smashed in the right order - ai_log("DestroySurroundings() directional window hit",3) - obstacle.attack_generic(src, damage_to_do, pick(attacktext)) - return - else if(obstacle.is_fulltile()) - ai_log("DestroySurroundings() full tile window hit",3) - obstacle.attack_generic(src, damage_to_do, pick(attacktext)) - return - - var/obj/structure/obstacle = locate(/obj/structure, problem_turf) - if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille)) - ai_log("DestroySurroundings() generic structure hit [obstacle]",3) - obstacle.attack_generic(src, damage_to_do, pick(attacktext)) - return - - for(var/obj/machinery/door/baddoor in problem_turf) //Required since firelocks take up the same turf - if(baddoor.density) - ai_log("DestroySurroundings() door hit [baddoor]",3) - baddoor.attack_generic(src, damage_to_do, pick(attacktext)) - return - -//Check for shuttle bumrush -/mob/living/simple_animal/proc/check_horde() - return 0 - if(emergency_shuttle.shuttle.location) - if(!enroute && !target_mob) //The shuttle docked, all monsters rush for the escape hallway - if(!shuttletarget && escape_list.len) //Make sure we didn't already assign it a target, and that there are targets to pick - shuttletarget = pick(escape_list) //Pick a shuttle target - enroute = 1 - stop_automated_movement = 1 - spawn() - if(!src.stat) - horde() - - if(get_dist(src, shuttletarget) <= 2) //The monster reached the escape hallway - enroute = 0 - stop_automated_movement = 0 - -//Shuttle bumrush -/mob/living/simple_animal/proc/horde() - var/turf/T = get_step_to(src, shuttletarget) - for(var/atom/A in T) - if(istype(A,/obj/machinery/door/airlock)) - var/obj/machinery/door/airlock/D = A - D.open(1) - else if(istype(A,/obj/structure/simple_door)) - var/obj/structure/simple_door/D = A - if(D.density) - D.Open() - else if(istype(A,/obj/structure/cult/pylon)) - A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper)) - else if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille)) - A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper)) - Move(T) - FindTarget() - if(!target_mob || enroute) - spawn(10) - if(!src.stat) - horde() - -//Touches a wire, etc -/mob/living/simple_animal/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null) - shock_damage *= max(siemens_coeff - shock_resistance, 0) - if (shock_damage < 1) - return 0 - - apply_damage(damage = shock_damage, damagetype = BURN, def_zone = null, blocked = null, blocked = resistance, used_weapon = null, sharp = FALSE, edge = FALSE) - playsound(loc, "sparks", 50, 1, -1) - - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, loc) - s.start() - -//Shot with taser/stunvolver -/mob/living/simple_animal/stun_effect_act(var/stun_amount, var/agony_amount, var/def_zone, var/used_weapon=null) - if(taser_kill) - var/stunDam = 0 - var/agonyDam = 0 - var/armor = run_armor_check(def_zone = null, attack_flag = "energy") - - if(stun_amount) - stunDam += stun_amount * 0.5 - apply_damage(damage = stunDam, damagetype = BURN, def_zone = null, blocked = armor, blocked = resistance, used_weapon = used_weapon, sharp = FALSE, edge = FALSE) - - if(agony_amount) - agonyDam += agony_amount * 0.5 - apply_damage(damage = agonyDam, damagetype = BURN, def_zone = null, blocked = armor, blocked = resistance, used_weapon = used_weapon, sharp = FALSE, edge = FALSE) - -/mob/living/simple_animal/emp_act(severity) - if(!isSynthetic()) - return - switch(severity) - if(1) - adjustFireLoss(rand(15, 25)) - if(2) - adjustFireLoss(rand(10, 18)) - if(3) - adjustFireLoss(rand(5, 12)) - if(4) - adjustFireLoss(rand(1, 6)) - -/mob/living/simple_animal/getarmor(def_zone, attack_flag) - var/armorval = armor[attack_flag] - if(!armorval) - return 0 - else - return armorval -/* -// Force it to target something -/mob/living/simple_animal/proc/taunt(var/mob/living/new_target, var/forced = FALSE) - if(intelligence_level == SA_HUMANOID && !forced) - return - set_target(new_target) -*/ -/mob/living/simple_animal/is_sentient() - return intelligence_level != SA_PLANT && intelligence_level != SA_ROBOTIC - -// Hand procs for player-controlled SA's -/mob/living/simple_animal/swap_hand() - src.hand = !( src.hand ) - if(hud_used.l_hand_hud_object && hud_used.r_hand_hud_object) - if(hand) //This being 1 means the left hand is in use - hud_used.l_hand_hud_object.icon_state = "l_hand_active" - hud_used.r_hand_hud_object.icon_state = "r_hand_inactive" - else - hud_used.l_hand_hud_object.icon_state = "l_hand_inactive" - hud_used.r_hand_hud_object.icon_state = "r_hand_active" - return -/* -/mob/living/simple_animal/put_in_active_hand(var/obj/item/I) - if(!has_hands || !istype(I)) - return -*/ -//Puts the item into our active hand if possible. returns 1 on success. -/mob/living/simple_animal/put_in_active_hand(var/obj/item/W) - if(!has_hands) - return FALSE - return (hand ? put_in_l_hand(W) : put_in_r_hand(W)) - -/mob/living/simple_animal/put_in_l_hand(var/obj/item/W) - if(!..() || l_hand) - return 0 - W.forceMove(src) - l_hand = W - W.equipped(src,slot_l_hand) - W.add_fingerprint(src) - update_inv_l_hand() - return TRUE - -/mob/living/simple_animal/put_in_r_hand(var/obj/item/W) - if(!..() || r_hand) - return 0 - W.forceMove(src) - r_hand = W - W.equipped(src,slot_r_hand) - W.add_fingerprint(src) - update_inv_r_hand() - return TRUE - -/mob/living/simple_animal/update_inv_r_hand() - if(QDESTROYING(src)) - return - - if(r_hand) - r_hand.screen_loc = ui_rhand //TODO - - //determine icon state to use - var/t_state - if(r_hand.item_state_slots && r_hand.item_state_slots[slot_r_hand_str]) - t_state = r_hand.item_state_slots[slot_r_hand_str] - else if(r_hand.item_state) - t_state = r_hand.item_state - else - t_state = r_hand.icon_state - - //determine icon to use - var/icon/t_icon - if(r_hand.item_icons && (slot_r_hand_str in r_hand.item_icons)) - t_icon = r_hand.item_icons[slot_r_hand_str] - else if(r_hand.icon_override) - t_state += "_r" - t_icon = r_hand.icon_override - else - t_icon = INV_R_HAND_DEF_ICON - - //apply color - var/image/standing = image(icon = t_icon, icon_state = t_state) - standing.color = r_hand.color - - r_hand_sprite = standing - - else - r_hand_sprite = null - - update_icon() - -/mob/living/simple_animal/update_inv_l_hand() - if(QDESTROYING(src)) - return - - if(l_hand) - l_hand.screen_loc = ui_lhand //TODO - - //determine icon state to use - var/t_state - if(l_hand.item_state_slots && l_hand.item_state_slots[slot_l_hand_str]) - t_state = l_hand.item_state_slots[slot_l_hand_str] - else if(l_hand.item_state) - t_state = l_hand.item_state - else - t_state = l_hand.icon_state - - //determine icon to use - var/icon/t_icon - if(l_hand.item_icons && (slot_l_hand_str in l_hand.item_icons)) - t_icon = l_hand.item_icons[slot_l_hand_str] - else if(l_hand.icon_override) - t_state += "_l" - t_icon = l_hand.icon_override - else - t_icon = INV_L_HAND_DEF_ICON - - //apply color - var/image/standing = image(icon = t_icon, icon_state = t_state) - standing.color = l_hand.color - - l_hand_sprite = standing - - else - l_hand_sprite = null - - update_icon() - -//Can insert extra huds into the hud holder here. -/mob/living/simple_animal/proc/extra_huds(var/datum/hud/hud,var/icon/ui_style,var/list/hud_elements) - return - -//If they can or cannot use tools/machines/etc -/mob/living/simple_animal/IsAdvancedToolUser() - return has_hands - -/mob/living/simple_animal/proc/IsHumanoidToolUser(var/atom/tool) - if(!humanoid_hands) - var/display_name = null - if(tool) - display_name = tool - else - display_name = "object" - to_chat(src, "Your [hand_form] are not fit for use of \the [display_name].") - return humanoid_hands - -/mob/living/simple_animal/drop_from_inventory(var/obj/item/W, var/atom/target = null) - . = ..(W, target) - if(!target) - target = src.loc - if(.) - W.forceMove(src.loc) - -//Commands, reactions, etc -/mob/living/simple_animal/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(!ai_inactive && reacts && speaker && (message in reactions) && (!hostile || isliving(speaker)) && say_understands(speaker,language)) - var/mob/living/L = speaker - if(L.faction == faction) - spawn(10) - face_atom(speaker) - say(reactions[message]) - -//Just some subpaths for easy searching -/mob/living/simple_animal/hostile - faction = "not yours" - hostile = 1 - retaliate = 1 - stop_when_pulled = 0 - destroy_surroundings = 1 - -/mob/living/simple_animal/retaliate - retaliate = 1 - destroy_surroundings = 1 - -/mob/living/simple_animal/get_nametag_desc(mob/user) - return "[tt_desc]" diff --git a/code/modules/mob/living/simple_animal/simple_hud.dm b/code/modules/mob/living/simple_animal/simple_hud.dm deleted file mode 100644 index 5da7e8a696..0000000000 --- a/code/modules/mob/living/simple_animal/simple_hud.dm +++ /dev/null @@ -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 diff --git a/code/modules/mob/living/simple_animal/slime/ai.dm b/code/modules/mob/living/simple_animal/slime/ai.dm deleted file mode 100644 index 3a8718c997..0000000000 --- a/code/modules/mob/living/simple_animal/slime/ai.dm +++ /dev/null @@ -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 - ..() diff --git a/code/modules/mob/living/simple_animal/slime/combat.dm b/code/modules/mob/living/simple_animal/slime/combat.dm deleted file mode 100644 index d13e81cd30..0000000000 --- a/code/modules/mob/living/simple_animal/slime/combat.dm +++ /dev/null @@ -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("\The [src] latches onto [victim]!", - "\The [src] latches onto you!") - -/mob/living/simple_animal/slime/proc/stop_consumption() - if(!victim) - return - victim.unbuckle_mob() - victim.visible_message("\The [src] slides off of [victim]!", - "\The [src] slides off of you!") - 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, "[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")]...") - 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("[src] gently pokes [L]!", - "[src] gently pokes you!") - 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("[src] has shocked [L]!", "[src] has shocked you!") - 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("[src] has pounced at [L]!", "[src] has pounced at you!") - 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("[src] has tried to pounce at [L]!", "[src] has tried to pounce at you!") - 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("\The [user]'s [W] passes right through [src]!") - 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("[M] attempts to wrestle \the [name] off!") - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - - else - visible_message(" [M] manages to wrestle \the [name] off!") - 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, "\The [source] shocks you, and it charges you.") diff --git a/code/modules/mob/living/simple_animal/slime/death.dm b/code/modules/mob/living/simple_animal/slime/death.dm deleted file mode 100644 index 622b12a859..0000000000 --- a/code/modules/mob/living/simple_animal/slime/death.dm +++ /dev/null @@ -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 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm deleted file mode 100644 index 691b880574..0000000000 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ /dev/null @@ -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, "You are starving!") - -/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) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm deleted file mode 100644 index 2b5d44ded9..0000000000 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ /dev/null @@ -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("\The [src] enrages!") - -// 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, "I must be conscious to do this...") - return - - if(docile) - to_chat(src, "I have been pacified. I cannot evolve...") - return - - if(!is_adult) - if(amount_grown >= 10) - make_adult() - else - to_chat(src, "I am not ready to evolve yet...") - else - to_chat(src, "I have already evolved...") - -/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, "I must be conscious to do this...") - return - - if(docile) - to_chat(src, "I have been pacified. I cannot reproduce...") - 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, "It is too cramped here to reproduce...") - 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, "I am not ready to reproduce yet...") - else - to_chat(src, "I am not old enough to reproduce yet...") - -// 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, "\The [new_hat] isn't a hat.") - return - if(hat) - to_chat(user, "\The [src] is already wearing \a [hat].") - return - else - user.drop_item(new_hat) - hat = new_hat - new_hat.forceMove(src) - to_chat(user, "You place \a [new_hat] on \the [src]. How adorable!") - update_icon() - return - -/mob/living/simple_animal/slime/proc/remove_hat(var/mob/living/user) - if(!hat) - to_chat(user, "\The [src] doesn't have a hat to remove.") - else - hat.forceMove(get_turf(src)) - user.put_in_hands(hat) - to_chat(user, "You take away \the [src]'s [hat.name]. How mean.") - 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") - diff --git a/code/modules/mob/living/simple_animal/slime/subtypes.dm b/code/modules/mob/living/simple_animal/slime/subtypes.dm deleted file mode 100644 index 75f33cdcef..0000000000 --- a/code/modules/mob/living/simple_animal/slime/subtypes.dm +++ /dev/null @@ -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("\The [src] erupts in an inferno!") - 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("\The [src] reflects \the [P]!") - - // 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, "There's nothing to teleport to.") - return FALSE - - if(world.time < last_tele + tele_cooldown) - to_chat(src, "You can't teleport right now, wait a few seconds.") - 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, "There wasn't an unoccupied spot to teleport to.") - 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("\The [src] vanishes!") - s1.start() - - forceMove(target_turf) - playsound(target_turf, 'sound/effects/phasein.ogg', 50, 1) - to_chat(src, "You teleport to \the [target_turf].") - - target_turf.visible_message("\The [src] appears!") - 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("\The [src] sends \the [L] flying with the impact!") - 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 = "Twinkling spores of goo surround you. It makes you feel healthier." - on_expired_text = "The spores of goo have faded, although you feel much healthier than before." - 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() - ..() \ No newline at end of file diff --git a/polaris.dme b/polaris.dme index e2ea7c5fb4..b1b773a612 100644 --- a/polaris.dme +++ b/polaris.dme @@ -1857,6 +1857,7 @@ #include "code\modules\mob\_modifiers\traits.dm" #include "code\modules\mob\_modifiers\traits_phobias.dm" #include "code\modules\mob\_modifiers\unholy.dm" +#include "code\modules\mob\dead\corpse.dm" #include "code\modules\mob\dead\death.dm" #include "code\modules\mob\dead\observer\login.dm" #include "code\modules\mob\dead\observer\logout.dm" @@ -2053,7 +2054,6 @@ #include "code\modules\mob\living\silicon\robot\subtypes\gravekeeper.dm" #include "code\modules\mob\living\silicon\robot\subtypes\lost_drone.dm" #include "code\modules\mob\living\silicon\robot\subtypes\syndicate.dm" -#include "code\modules\mob\living\simple_animal\corpse.dm" #include "code\modules\mob\living\simple_mob\appearance.dm" #include "code\modules\mob\living\simple_mob\combat.dm" #include "code\modules\mob\living\simple_mob\defense.dm"