/obj/critter/livingobj name = "" desc = "" icon_state = "livingobj" density = 0 health = 10 aggressive = 0 defensive = 0 wanderer = 1 opensdoors = 0 atkcarbon = 0 atksilicon = 0 generic = 0 butcherable = 1 //Because "toolbox meat" would be hilarious atk_text = "slams into" atk_brute_amt = 2 crit_chance = 0 chase_text = "leaps at" var/stunprob = 0 layer = 5 var/obj/original_object = null CritterAttack(var/mob/M) playsound(src.loc, "sound/impact_sounds/Generic_Hit_1.ogg", 50, 1, -1) ..() attack_hand(mob/user as mob) if (src.alive && (user.a_intent != INTENT_HARM)) src.visible_message("[user] pets [src]!") return ..() CritterDeath() src.visible_message("[src] stops moving!") animate_float(src, 1, 5) playsound(src.loc, "sound/effects/suck.ogg", 40, 1, -1, 0.6) SPAWN_DBG (100) //Give time for people to butcher it if they want. if (!src.disposed && src.loc && original_object) original_object.loc = src.loc original_object = null qdel(src) return ..() ChaseAttack(mob/M) ..() if (prob(stunprob)) M.changeStatus("weakened", 2 SECONDS) //playsound(src.loc, "sound/impact_sounds/Generic_Hit_1.ogg", 50, 1, -1) disposing() if (original_object) original_object.dispose() original_object = null ..() /obj/critter/spore name = "plasma spore" desc = "A barely intelligent colony of organisms. Very volatile." icon_state = "spore" density = 1 health = 1 aggressive = 0 defensive = 0 wanderer = 1 opensdoors = 0 atkcarbon = 0 atksilicon = 0 firevuln = 2 brutevuln = 2 flying = 1 CritterDeath() src.visible_message("[src] ruptures and explodes!") src.alive = 0 var/turf/T = get_turf(src.loc) if(T) T.hotspot_expose(700,125) explosion(src, T, -1, -1, 2, 3) qdel (src) ex_act(severity) CritterDeath() bullet_act(flag, A as obj) CritterDeath() /obj/critter/mimic name = "mechanical toolbox" desc = null icon_state = "mimic_blue1" health = 20 aggressive = 1 defensive = 1 wanderer = 0 atkcarbon = 1 atksilicon = 1 brutevuln = 0.5 seekrange = 1 angertext = "suddenly comes to life and lunges at" death_text = "%src% flops closed, dead!" chase_text = "hurls itself at" atk_brute_amt = 3 crit_brute_amt = 6 var/toolbox_style = "blue" var/list/toolbox_list = list("blue", "red", "yellow", "green") var/switcharoo = 10 // set to 0 for mimics that always are mimics and never toolboxes New() ..() src.toolbox_style = pick(src.toolbox_list) src.update_icon() if (prob(src.switcharoo)) switch (src.toolbox_style) if ("blue") new /obj/item/storage/toolbox/mechanical(src.loc) if ("red") new /obj/item/storage/toolbox/emergency(src.loc) if ("yellow") new /obj/item/storage/toolbox/electrical(src.loc) if ("green") if (prob(1)) new /obj/item/storage/toolbox/memetic(src.loc) else new /obj/item/storage/toolbox/artistic(src.loc) qdel(src) ai_think() ..() if (src.alive) switch (task) if ("thinking") src.update_icon() if ("chasing") src.update_icon() if ("attacking") src.update_icon() ChaseAttack(mob/M) ..() if (prob(33)) M.changeStatus("weakened", 4 SECONDS) CritterAttack(mob/M) ..() proc/update_icon() if (!src.toolbox_style) src.toolbox_style = pick(src.toolbox_list) src.dead_state = "mimic_[src.toolbox_style]1-dead" switch (src.task) if ("thinking") src.icon_state = "mimic_[src.toolbox_style]1" if (src.toolbox_style == "blue") src.name = "mechanical toolbox" src.desc = "A metal container designed to hold various tools. This variety holds standard construction tools." if (src.toolbox_style == "red") src.name = "emergency toolbox" src.desc = "A metal container designed to hold various tools. This variety holds supplies required for emergencies." if (src.toolbox_style == "yellow") src.name = "electrical toolbox" src.desc = "A metal container designed to hold various tools. This variety holds electrical supplies." if (src.toolbox_style == "green") src.name = "artistic toolbox" src.desc = "It almost hurts to look at that, it's all out of focus." if ("chasing") src.icon_state = "mimic_[src.toolbox_style]2" src.name = "mimic" src.desc = "Oh shit, that's no toolbox at all!" if ("attacking") src.icon_state = "mimic_[src.toolbox_style]2" src.name = "mimic" src.desc = "Oh shit, that's no toolbox at all!" /* /obj/critter/mimic_old name = "mechanical toolbox" desc = null icon_state = "mimic1" health = 20 aggressive = 1 defensive = 1 wanderer = 0 atkcarbon = 1 atksilicon = 1 brutevuln = 0.5 seekrange = 1 angertext = "suddenly comes to life and lunges at" death_text = "%src% crumbles to pieces!" ai_think() ..() if (src.alive) switch(task) if("thinking") src.icon_state = "mimic1" src.name = "mechanical toolbox" if("chasing") src.icon_state = "mimic2" src.name = "mimic" if("attacking") src.icon_state = "mimic2" src.name = "mimic" ChaseAttack(mob/M) src.visible_message("[src] hurls itself at [M]!") if (prob(33)) M.weakened += rand(3,6) CritterAttack(mob/M) src.attacking = 1 src.visible_message("[src] bites [src.target]!") random_brute_damage(src.target, rand(2,4)) SPAWN_DBG(2.5 SECONDS) src.attacking = 0 */ /obj/critter/wraithskeleton name = "skeleton" desc = "It looks rather crumbly." icon = 'icons/mob/human_decomp.dmi' icon_state = "decomp4" health = 1 aggressive = 1 defensive = 1 wanderer = 1 atkcarbon = 1 atksilicon = 1 brutevuln = 1 seekrange = 7 skinresult = /obj/item/material_piece/bone max_skins = 2 death_text = "%src% vaporizes instantly!" chase_text = "knocks down" atk_text = "beats" atk_brute_amt = 6 crit_chance = 0 ChaseAttack(mob/M) if (prob(75)) ..() M.changeStatus("weakened", 4 SECONDS) else src.visible_message("[src] tries to knock down [M]!") CritterAttack(mob/M) ..() CritterDeath() ..() particleMaster.SpawnSystem(new /datum/particleSystem/localSmoke("#000000", 5, locate(x, y, z))) qdel(src) /obj/critter/mimic2 name = "mechanical toolbox" desc = null icon_state = "mimic1" health = 20 aggressive = 1 defensive = 1 wanderer = 0 atkcarbon = 1 atksilicon = 1 brutevuln = 0.5 seekrange = 1 angertext = "suddenly comes to life and lunges at" var/objname = "mechanical toolbox" //name when in disguise generic = 0 death_text = "%src% crumbles to pieces!" chase_text = "hurls itself at" atk_brute_amt = 3 crit_brute_amt = 6 ai_think() ..() if (src.alive) switch(task) if("thinking") src.overlays = null src.name = objname if("chasing") src.overlays += image("icon" = 'icons/misc/critter.dmi', "icon_state" = "mimicface", "layer" = FLOAT_LAYER) src.name = "mimic" if("attacking") src.overlays += image("icon" = 'icons/misc/critter.dmi', "icon_state" = "mimicface", "layer" = FLOAT_LAYER) src.name = "mimic" ChaseAttack(mob/M) ..() if (prob(33)) M.changeStatus("weakened", 4 SECONDS) CritterAttack(mob/M) ..() /obj/critter/spirit name = "spirit" desc = null invisibility = 10 icon_state = "spirit" health = 10 aggressive = 1 defensive = 1 wanderer = 0 atkcarbon = 1 atksilicon = 1 brutevuln = 0.5 opensdoors = 1 seekrange = 5 density = 0 angertext = "suddenly materializes and lunges at" flying = 1 generic = 0 death_text = "%src% dissipates!" chase_text = "hurls itself at" atk_text = "attacks" atk_brute_amt = 3 crit_chance = 0 ai_think() ..() if (src.alive) switch(task) if("thinking") src.invisibility = 10 if("chasing") src.invisibility = 0 if("attacking") src.invisibility = 0 seek_target() src.anchored = 0 for (var/mob/living/C in hearers(src.seekrange,src)) if (src.target) src.task = "chasing" break if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue if (iscarbon(C) && !src.atkcarbon) continue if (issilicon(C) && !src.atksilicon) continue if (C.health < 0) continue if (C in src.friends) continue if (isvampire(C)) continue if (C.name == src.attacker) src.attack = 1 if (iscarbon(C) && src.atkcarbon) src.attack = 1 if (issilicon(C) && src.atksilicon) src.attack = 1 if (src.attack) src.target = C src.oldtarget_name = C.name src.visible_message("[src] [src.angertext] [C.name]!") src.task = "chasing" break else continue ChaseAttack(mob/M) ..() if (prob(30)) M.changeStatus("weakened", 3 SECONDS) CritterAttack(mob/M) ..() CritterDeath() if (!src.alive) return ..() new /obj/item/reagent_containers/food/snacks/ectoplasm(src.loc) qdel(src) bullet_act(var/obj/projectile/P) if (istype(P, /datum/projectile/energy_bolt_antighost)) src.CritterDeath() return else ..() CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if (istype(mover, /obj/projectile)) var/obj/projectile/proj = mover if (istype(proj.proj_data, /datum/projectile/energy_bolt_antighost)) return 0 return 1 /obj/critter/spacebee name = "space wasp" desc = "A wasp in space." icon_state = "spacebee" density = 1 health = 10 aggressive = 1 defensive = 1 wanderer = 1 opensdoors = 0 atkcarbon = 1 atksilicon = 1 firevuln = 1 brutevuln = 1 angertext = "buzzes at" butcherable = 1 flags = NOSPLASH | OPENCONTAINER flying = 1 //var/neurotoxin = 2 chase_text = "stings" CritterDeath() ..() src.reagents.add_reagent("toxin", 50, null) src.reagents.add_reagent("histamine", 50, null) return seek_target() src.anchored = 0 for (var/mob/living/C in hearers(src.seekrange,src)) if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue if (iscarbon(C) && !src.atkcarbon) continue if (issilicon(C) && !src.atksilicon) continue if (C.job == "Botanist") continue if (C.health < 0) continue if (C in src.friends) continue if (iscarbon(C) && src.atkcarbon) src.attack = 1 if (issilicon(C) && src.atksilicon) src.attack = 1 if (src.attack) src.target = C src.oldtarget_name = C.name src.visible_message("[src] charges at [C.name]!") src.task = "chasing" break else continue ChaseAttack(mob/M) ..() if (M.reagents) M.reagents.add_reagent("histamine", 12) M.reagents.add_reagent("toxin", 2) /obj/item/reagent_containers/food/snacks/ingredient/egg/critter/wasp name = "space wasp egg" critter_type = /obj/critter/spacebee /obj/critter/magiczombie name = "skeleton" desc = "Clak clak, motherfucker." icon_state = "skeleton" dead_state = "skeleton-dead" density = 1 health = 20 // too strong aggressive = 1 defensive = 0 wanderer = 1 opensdoors = 1 atkcarbon = 1 atksilicon = 1 atcritter = 1 firevuln = 0.25 brutevuln = 0.5 chase_text = "bashes" var/pixel_y_inc = 0 skinresult = /obj/item/material_piece/bone max_skins = 2 var/revivalChance = 0 // Chance to revive when killed, out of 100. Wizard spell will set to 100, defaults to 0 because skeletons appear in telesci/other sources var/revivalDecrement = 16 // Decreases revival chance each successful revival. Set to 0 and revivalChance=100 for a permanently reviving skeleton New() ..() playsound(src.loc, "sound/items/Scissor.ogg", 50, 0) Move() playsound(src.loc, "sound/impact_sounds/Crystal_Hit_1.ogg", 50, 0) ..() attackby(obj/item/W as obj, mob/living/user as mob) ..() if (!src.alive) return if (istype(W, /obj/item/clothing/head)) if (pixel_y_inc > 20) return var/image/I = image('icons/mob/head.dmi', src, W.icon_state) I.pixel_y = pixel_y_inc src.overlays += I pixel_y_inc += 3 seek_target() if (!src.alive) return var/mob/living/Cc for (var/mob/living/C in hearers(src.seekrange,src)) if (iswizard(C)) continue //do not attack our master if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue if (iscarbon(C) && !src.atkcarbon) continue if (issilicon(C) && !src.atksilicon) continue if (isdead(C)) continue if (iscarbon(C) && src.atkcarbon) src.attack = 1 if (issilicon(C) && src.atksilicon) src.attack = 1 Cc = C if (src.attack) src.target = Cc src.oldtarget_name = Cc.name src.visible_message("[src] charges towards [Cc.name]!") playsound(src.loc, "sound/items/Scissor.ogg", 50, 0) src.task = "chasing" return proc/CustomizeMagZom(var/NM, var/is_monkey) src.name = "[capitalize(NM)]'s skeleton" src.desc = "A horrible skeleton, raised from the corpse of [NM] by a wizard." src.revivalChance = 100 if (is_monkey) icon = 'icons/mob/monkey.dmi' return ChaseAttack(mob/M) if (!src.alive) return ..() playsound(M.loc, "punch", 25, 1, -1) random_brute_damage(M, rand(5,10)) if(prob(15)) // too mean before M.visible_message("[M] staggers!") M.changeStatus("stunned", 2 SECONDS) M.changeStatus("weakened", 2 SECONDS) CritterAttack(mob/M) if (!src.alive) return src.attacking = 1 if (ishuman(M)) var/mob/living/carbon/human/H = M H.was_harmed(src) if(!M.stat) M.visible_message("[src] pummels [src.target] mercilessly!") playsound(src.loc, "sound/impact_sounds/Generic_Hit_1.ogg", 50, 1, -1) if(prob(10)) // lowered probability slightly M.visible_message("[M] staggers!") M.changeStatus("stunned", 2 SECONDS) M.changeStatus("weakened", 2 SECONDS) random_brute_damage(M, rand(5,10)) else M.visible_message("[src] hits [src.target] with a bone!") playsound(src.loc, "punch", 30, 1, -2) random_brute_damage(M, rand(10,15)) SPAWN_DBG(1 SECOND) src.attacking = 0 CritterDeath(mob/M) if (!src.alive) return ..() if (rand(100) <= revivalChance) src.revivalChance -= revivalDecrement SPAWN_DBG(rand(400,800)) src.alive = 1 src.set_density(1) src.health = initial(src.health) src.icon_state = initial(src.icon_state) for(var/mob/O in viewers(src, null)) O.show_message("[src] re-assembles and is ready to fight once more!") return /obj/item/reagent_containers/food/snacks/ingredient/egg/critter/skeleton name = "skeleton egg" desc = "Uh. What?" critter_type = /obj/critter/magiczombie warm_count = 5 critter_reagent = "ash" /obj/critter/golem name = "Golem" desc = "An elemental being, crafted by local artisans using traditional techniques." icon_state = "golem" density = 1 health = 25 aggressive = 1 defensive = 0 wanderer = 1 opensdoors = 1 atkcarbon = 1 atksilicon = 1 atcritter = 0 // don't bother! firevuln = 0.25 brutevuln = 0.5 generic = 0 atk_text = "bashes against" atk_brute_amt = 7 var/reagent_id = null New() ..() var/datum/reagents/R = new/datum/reagents(1000) reagents = R R.my_atom = src SPAWN_DBG(4 SECONDS) if(!reagents.total_volume) if (all_functional_reagent_ids.len > 0) src.reagent_id = pick(all_functional_reagent_ids) else src.reagent_id = "water" R.add_reagent(src.reagent_id, 10) var/oldcolor = src.reagents.get_master_color() var/icon/I = new /icon('icons/misc/critter.dmi',"golem") I.Blend(oldcolor, ICON_ADD) src.icon = I src.name = "[capitalize(src.reagents.get_master_reagent_name())]-Golem" return seek_target() src.anchored = 0 var/mob/living/Cc for (var/mob/living/C in hearers(src.seekrange,src)) if (C.ckey == null) continue //do not attack non-threats ie. NPC monkeys and AFK players if (iswizard(C)) continue //do not attack our master var/mob/living/carbon/human/H = C if (istype(C) && (H.traitHolder.hasTrait("training_chaplain"))) continue if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue if (iscarbon(C) && !src.atkcarbon) continue if (issilicon(C) && !src.atksilicon) continue if (isdead(C)) continue if (iscarbon(C) && src.atkcarbon) src.attack = 1 if (issilicon(C) && src.atksilicon) src.attack = 1 Cc = C if (src.attack) src.target = Cc src.oldtarget_name = Cc.name src.visible_message("[src] charges at [Cc.name]!") src.task = "chasing" return proc/CustomizeGolem(var/datum/reagents/CR) //customise it with the reagents in a container for(var/current_id in CR.reagent_list) var/datum/reagent/R = CR.reagent_list[current_id] src.reagents.add_reagent(current_id, min(R.volume * 5, 50)) var/oldcolor = src.reagents.get_master_color() var/icon/I = new /icon('icons/misc/critter.dmi',"golem") I.Blend(oldcolor, ICON_ADD) src.icon = I src.name = "[capitalize(src.reagents.get_master_reagent_name())]-Golem" src.desc = "An elemental entity composed of [src.reagents.get_master_reagent_name()], conjured by a wizard." return CritterAttack(mob/M) var/mob/living/carbon/human/H = M if (istype(M) && (H.traitHolder.hasTrait("training_chaplain"))) return ..() playsound(src.loc, "sound/impact_sounds/Generic_Hit_1.ogg", 50, 1, -1) if(M.reagents) if(src.reagents && src.reagents.total_volume) src.reagents.reaction(M, TOUCH) reagents.trans_to(M, 5) CritterDeath() if (!src.alive) return ..() src.visible_message("[src] bursts into a puff of smoke!") var/datum/chemical_reaction/smoke/thesmoke = new thesmoke.on_reaction(src.reagents, 12) invisibility = 100 SPAWN_DBG(5 SECONDS) qdel(src) /obj/critter/townguard name = "Town Guard" desc = "An angry man dressed in medieval armor." icon_state = "townguard" density = 1 health = 100 aggressive = 1 defensive = 0 wanderer = 1 opensdoors = 1 atkcarbon = 1 atksilicon = 1 atcritter = 1 firevuln = 0.75 brutevuln = 0.5 death_text = "%src% seizes up and falls limp, his eyes dead and lifeless..." chase_text = "tackles" var/sword_damage_max = 12 var/sword_damage_min = 6 passive sword_damage_max = 0 sword_damage_min = 0 seek_target() src.anchored = 0 for (var/mob/living/C in hearers(src.seekrange,src)) if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue if (iscarbon(C) && !src.atkcarbon) continue if (issilicon(C) && !src.atksilicon) continue if (C.health < 0) continue if (iscarbon(C) && src.atkcarbon) src.attack = 1 if (issilicon(C) && src.atksilicon) src.attack = 1 if (src.attack) src.target = C src.oldtarget_name = C.name src.visible_message("[src] points at [C.name]!") for(var/mob/O in hearers(src, null)) O.show_message("[src] says, \"HALT!\"", 2) playsound(src.loc, "sound/voice/guard_halt.ogg", 50, 0) src.task = "chasing" return else continue if(!src.atcritter) return for (var/obj/critter/C in view(src.seekrange,src)) if (!C.alive) continue if (C.health < 0) continue if (!istype(C, /obj/critter/townguard)) src.attack = 1 if (src.attack) src.target = C src.oldtarget_name = C.name src.visible_message("[src] points at [C.name]!") for(var/mob/O in hearers(src, null)) O.show_message("[src] says, \"HALT!\"", 2) playsound(src.loc, "sound/voice/guard_halt.ogg", 50, 0) src.task = "chasing" return else continue ChaseAttack(mob/M) if(iscarbon(M) && prob(15)) ..() playsound(src.loc, "sound/impact_sounds/Generic_Shove_1.ogg", 50, 1, -1) random_brute_damage(M, rand(0,3)) M.changeStatus("stunned", 2 SECONDS) M.changeStatus("weakened", 2 SECONDS) else src.visible_message("[src] tries to knock down [src.target] but misses!", 1) CritterAttack(mob/M) for(var/mob/O in viewers(src, null)) O.show_message("[src] says, \"HALT!\"", 2) playsound(src.loc, "sound/voice/guard_halt.ogg", 50, 0) src.attacking = 1 if(istype(M,/obj/critter)) var/obj/critter/C = M for(var/mob/O in hearers(src, null)) O.show_message("[src] says, \"HALT!\"", 2) playsound(C.loc, "swing_hit", 50, 1, -1) C.health -= 6 if(C.health <= 0) C.CritterDeath() SPAWN_DBG(2.5 SECONDS) src.attacking = 0 return if (M.health > 40 && !M.getStatusDuration("weakened")) src.visible_message("[src] attacks [src.target] with his sword!") playsound(M.loc, "swing_hit", 50, 1, -1) var/to_deal = rand(sword_damage_min,sword_damage_max) random_brute_damage(M, to_deal) if(iscarbon(M)) if(to_deal > (((sword_damage_max-sword_damage_min)/2)+sword_damage_min) && prob(50)) src.visible_message("[src] knocks down [M]!") M:changeStatus("weakened", 80) SPAWN_DBG(2.5 SECONDS) src.attacking = 0 else src.visible_message("[src] kicks [src.target]!") playsound(src.loc, "swing_hit", 50, 1, -1) random_brute_damage(src.target, rand(4,8)) SPAWN_DBG(2.5 SECONDS) src.attacking = 0 if (ishuman(M)) var/mob/living/carbon/human/H = M H.was_harmed(src) return ai_think() if (prob(20)) if (src.target) for(var/mob/O in viewers(src, null)) O.show_message("[src] says, \"HALT!\"", 2) playsound(src.loc, "sound/voice/guard_halt.ogg", 50, 0) return ..() /obj/item/reagent_containers/food/snacks/ingredient/egg/critter/townguard name = "\improper Town Guard egg" desc = "This is not how humans reproduce. They do not lay eggs. What the hell is this?" critter_type = /obj/critter/townguard warm_count = 75 /obj/item/reagent_containers/food/snacks/ingredient/egg/critter/townguard/passive critter_type = /obj/critter/townguard/passive /obj/critter/bloodling name = "Bloodling" desc = "A force of pure sorrow and evil." icon_state = "bling" density = 1 health = 20 aggressive = 1 defensive = 0 wanderer = 1 opensdoors = 1 atkcarbon = 1 atksilicon = 0 atcritter = 0 firevuln = 0 brutevuln = 0 seekrange = 5 invisibility = 1 flying = 1 generic = 0 seek_target() src.anchored = 0 for (var/mob/living/C in hearers(src.seekrange,src)) if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue if (iscarbon(C) && !src.atkcarbon) continue if (issilicon(C) && !src.atksilicon) continue if (C.health < 0) continue if (iscarbon(C) && src.atkcarbon) src.attack = 1 if (issilicon(C) && src.atksilicon) src.attack = 1 if (src.attack) src.target = C src.oldtarget_name = C.name src.task = "chasing" return else continue ChaseAttack(mob/M) src.attacking = 1 if (narrator_mode) playsound(src.loc, 'sound/vox/ghost.ogg', 50, 1, -1) else playsound(src.loc, 'sound/effects/ghost.ogg', 50, 1, -1) if(iscarbon(M) && prob(50)) if(M.see_invisible < 2) boutput(M, "You are forced to the ground by an unseen being!") else boutput(M, "You are forced to the ground by the Bloodling!") random_brute_damage(M, rand(0,3)) M.changeStatus("stunned", 2 SECONDS) M.changeStatus("weakened", 2 SECONDS) src.attacking = 0 return CritterAttack(mob/M) playsound(src.loc, "sound/effects/ghost2.ogg", 50, 1, -1) attacking = 1 if(iscarbon(M)) if(prob(50)) random_brute_damage(M, rand(3,7)) boutput(M, "You feel blood getting drawn out through your skin!") else boutput(M, "You feel uncomfortable.") SPAWN_DBG(5 DECI SECONDS) attacking = 0 attackby(obj/item/W as obj, mob/living/user as mob) if (!src.alive) return else if(!W.reagents) boutput(user, "Hitting it with [W] is ineffective!") return if(W.reagents.has_reagent("water_holy")) boutput(user, "[src] screams!") CritterDeath() return else boutput(user, "Hitting it with [W] is ineffective!") return ai_think() if(!locate(/obj/decal/cleanable/blood) in src.loc) playsound(src.loc, "sound/impact_sounds/Slimy_Splat_1.ogg", 50, 1, -1) make_cleanable( /obj/decal/cleanable/blood,loc) return ..() /obj/critter/blobman name = "mutant" desc = "Some sort of horrific, pulsating blob of flesh." icon_state = "blobman" density = 1 health = 15 aggressive = 1 defensive = 0 wanderer = 1 opensdoors = 1 atkcarbon = 1 atksilicon = 1 atcritter = 1 firevuln = 0.75 brutevuln = 0.5 death_text = "%src% collapses into viscera." atk_text = "flails against" atk_brute_amt = 6 crit_text = "flails heavily against" crit_brute_amt = 12 chase_text = "headbutts" CritterAttack(mob/M) ..() playsound(src.loc, "sound/impact_sounds/Generic_Hit_1.ogg", 50, 1, -1) ChaseAttack(mob/M) ..() if(iscarbon(M)) if (prob(5)) M.changeStatus("stunned", 2 SECONDS) random_brute_damage(M, rand(2,5)) //A terrible post-human cloud of murder. /obj/critter/aberration name = "transposed particle field" desc = "A cloud of particles transposed by some manner of dangerous science, echoing some mannerisms of their previous configuration. In layman's terms, a goddamned science ghost." icon_state = "aberration" density = 1 health = 2 aggressive = 1 defensive = 1 wanderer = 1 opensdoors = 1 atkcarbon = 1 atksilicon = 1 atcritter = 1 firevuln = 0.01 brutevuln = 0.25 flying = 1 generic = 0 death_text = "%src% dissipates!" CritterDeath() ..() qdel(src) CritterAttack(mob/M) src.attacking = 1 src.visible_message("The [src.name] starts to envelop [M]!") var/lastloc = M.loc SPAWN_DBG(6 SECONDS) if (get_dist(src, M) <= 1 && ((M.loc == lastloc))) if(isliving(M)) logTheThing("combat", M, null, "was enveloped by [src] (obj) at [log_loc(src)].") // Some logging for instakill critters would be nice (Convair880). M.ghostize() if (iscarbon(M)) for(var/obj/item/W in M) if (isitem(W)) M.u_equip(W) if (W) W.set_loc(M.loc) W.dropped(M) W.layer = initial(W.layer) src.visible_message("The [src.name] completely envelops [M]!") playsound(src.loc, "sound/impact_sounds/Slimy_Hit_4.ogg", 50, 1) qdel(M) src.attacking = 0 attack_hand(var/mob/user as mob) if (src.alive) boutput(user, "Your hand passes right through! It's so cold...") return attackby(obj/item/W as obj, mob/living/user as mob) if (!src.alive) return else if (istype(W, /obj/item/baton)) var/obj/item/baton/B = W if (B.can_stun(1, 1, user) == 1) user.visible_message("[user] shocks the [src.name] with [B]!", "While your baton passes through, the [src.name] appears damaged!") B.process_charges(-1, user) src.health-- if (src.health <= 0) src.CritterDeath() return boutput(user, "[W] passes right through!") return seek_target() src.anchored = 0 for (var/mob/living/C in range(src.seekrange,src)) if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue if (iscarbon(C) && !src.atkcarbon) continue if (issilicon(C) && !src.atksilicon) continue if (ishuman(C) && istype(C:head, /obj/item/clothing/head/void_crown)) continue if (C.health < 0) continue if (iscarbon(C) && src.atkcarbon) src.attack = 1 if (issilicon(C) && src.atksilicon) src.attack = 1 if (src.attack) src.target = C src.oldtarget_name = C.name src.task = "chasing" return else continue bullet_act(var/obj/projectile/P) var/damage = 0 damage = round((P.power*(1-P.proj_data.ks_ratio)), 1.0) if(P.proj_data.damage_type == D_ENERGY) src.health -= damage else return if (src.health <= 0) src.CritterDeath() ChaseAttack(mob/M) return /obj/critter/ancient_thing name = "???" desc = "What the hell is that?" icon_state = "ancientrobot" invisibility = 10 health = 30 firevuln = 0 brutevuln = 0.5 aggressive = 1 defensive = 1 wanderer = 0 opensdoors = 1 seekrange = 5 density = 1 var/boredom_countdown = 0 CritterDeath() src.visible_message("[src] fades away.") src.alive = 0 walk_to(src,0) flick("ancientrobot-disappear",src) src.invisibility = 10 critters -= src src.dispose() seek_target() src.anchored = 0 if (src.target) src.task = "chasing" return for (var/mob/living/carbon/C in view(src.seekrange,src)) if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue if (C.stat || C.health < 0) continue src.boredom_countdown = rand(5,10) src.target = C src.oldtarget_name = C.name src.task = "chasing" src.appear() break attackby(obj/item/W as obj, mob/living/user as mob) if (!src.alive) ..() return switch(W.damtype) if("fire") src.health -= W.force * src.firevuln if("brute") src.health -= W.force * src.brutevuln if (src.alive && src.health <= 0) src.CritterDeath() src.boredom_countdown = rand(5,10) src.target = user src.oldtarget_name = user.name src.task = "chasing" attack_hand(var/mob/user as mob) if (!src.alive) ..() return if (user.a_intent == "harm") src.health -= rand(1,2) * src.brutevuln for(var/mob/O in viewers(src, null)) O.show_message("[user] punches [src]!", 1) playsound(src.loc, "punch", 50, 1) if (src.alive && src.health <= 0) src.CritterDeath() src.boredom_countdown = rand(5,10) src.target = user src.oldtarget_name = user.name src.task = "chasing" else src.visible_message("[user] pets [src]!
For some reason! Not like that's weird or anything!
", 1) ChaseAttack(mob/M) return CritterAttack(mob/M) src.attacking = 1 if (boredom_countdown-- > 0) src.visible_message("[src] [pick("measures", "gently pulls at", "examines", "pokes", "gently prods", "feels")] [src.target]'s [pick("head","neck","shoulders","right arm", "left arm","left leg","right leg")]!") if (prob(50)) boutput(src.target, "You feel [pick("very ",null,"rather ","fairly ","remarkably ")]uncomfortable.") else var/mob/living/doomedMob = src.target if (!istype(doomedMob)) return src.visible_message("In a whirling flurry of tendrils, [src] rends down [src.target]! Holy shit!") logTheThing("combat", M, null, "was gibbed by [src] at [log_loc(src)].") // Some logging for instakill critters would be nice (Convair880). playsound(src.loc, "sound/impact_sounds/Flesh_Break_1.ogg", 50, 1) doomedMob.ghostize() new /obj/decal/skeleton(doomedMob.loc) doomedMob.gib() src.target = null SPAWN_DBG(4 SECONDS) src.attacking = 0 proc/appear() if (!invisibility || (src.icon_state != "ancientrobot")) return src.name = pick("something","weird thing","odd thing","whatchamacallit","thing","something weird","old thing") src.icon_state = "ancientrobot-appear" src.invisibility = 0 SPAWN_DBG(1.2 SECONDS) src.icon_state = "ancientrobot" return /obj/critter/crunched name = "transposed scientist" desc = "A fellow who seems to have been shunted between dimensions. Not a good state to be in." icon_state = "crunched" health = 10 brutevuln = 0.5 firevuln = 0 aggressive = 1 generic = 0 attack_hand(var/mob/user as mob) if (user.a_intent == "help") return ..() ChaseAttack(mob/M) return CritterAttack(mob/M) if (!ismob(M)) return src.attacking = 1 if (M.lying) src.speak( pick("No! Get up! Please, get up!", "Not again! Not again! I need you!", "Please! Please get up! Please!", "I don't want to be alone again!") ) src.visible_message("[src] shakes [M] trying to wake them up!") boutput(M, "It burns!") M.TakeDamage("chest", 0, rand(5,15)) else src.speak( pick("Please! Help! I need help!", "Please...help me!", "Are you real? You're real! YOU'RE REAL", "Everything hurts! Everything hurts!", "Please, make the pain stop! MAKE IT STOP!") ) src.visible_message("[src] grabs at [M]'s arm!") boutput(M, "It burns!") M.TakeDamage("chest", 0, rand(5,15)) if (ishuman(M)) var/mob/living/carbon/human/H = M H.was_harmed(src) SPAWN_DBG(6 SECONDS) src.attacking = 0 ai_think() if(task == "thinking" || task == "wandering") if (prob(5)) src.speak( pick("Cut the power! It's about to go critical, cut the power!","I warned them. I warned them the system wasn't ready.","Shut it down!","It hurts, oh God, oh God.") ) else if (prob(5)) src.speak( pick("Please...help...it hurts...please", "I'm...sick...help","It went wrong. It all went wrong.","I didn't mean for this to happen!", "I see everything twice!") ) return ..() CritterDeath() speak( pick("There...is...nothing...","It's dark. Oh god, oh god, it's dark.","Thank you.","Oh wow. Oh wow. Oh wow.") ) src.icon_state = "crunched-dead" src.alive = 0 SPAWN_DBG(1.5 SECONDS) qdel(src) seek_target() src.anchored = 0 if (src.target) src.task = "chasing" return for (var/mob/living/carbon/C in view(src.seekrange,src)) if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue if (C.stat || C.health < 0) continue src.target = C src.oldtarget_name = C.name src.task = "chasing" src.speak( pick("Hey..you! Help! Help me please!","I need..a doctor...","Someone...new? Help me...please.","Are you real?") ) break proc/speak(var/message) if (!message) return var/fontSize = 1 var/fontIncreasing = 1 var/fontSizeMax = 3 var/fontSizeMin = -3 var/messageLen = length(message) var/processedMessage = "" for (var/i = 1, i <= messageLen, i++) processedMessage += "[copytext(message, i, i+1)]" if (fontIncreasing) fontSize = min(fontSize+1, fontSizeMax) if (fontSize >= fontSizeMax) fontIncreasing = 0 else fontSize = max(fontSize-1, fontSizeMin) if (fontSize <= fontSizeMin) fontIncreasing = 1 src.visible_message("[src.name] says, \"[processedMessage]\"") return