diff --git a/code/modules/events/cat_surgeon.dm b/code/modules/events/cat_surgeon.dm new file mode 100644 index 0000000000..d968e5e1f8 --- /dev/null +++ b/code/modules/events/cat_surgeon.dm @@ -0,0 +1,22 @@ +/datum/round_event_control/cat_surgeon + name = "Cat Surgeon" + typepath = /datum/round_event/cat_surgeon + max_occurrences = 1 + weight = 10 + + +/datum/round_event/cat_surgeon/start() + var/list/spawn_locs = list() + for(var/X in GLOB.xeno_spawn) + spawn_locs += X + + if(!spawn_locs.len) + message_admins("No valid spawn locations found, aborting...") + return MAP_ERROR + + var/turf/T = get_turf(pick(spawn_locs)) + var/mob/living/simple_animal/hostile/cat_butcherer/S = new(T) + playsound(S, 'sound/misc/catscream.ogg', 50, 1, -1) + message_admins("A cat surgeon has been spawned at [COORD(T)][ADMIN_JMP(T)]") + log_game("A cat surgeon has been spawned at [COORD(T)]") + return SUCCESSFUL_SPAWN diff --git a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm index d85f75cbbd..6950c6409f 100644 --- a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm +++ b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm @@ -6,37 +6,108 @@ icon_living = "cat_butcher" icon_dead = "syndicate_dead" icon_gib = "syndicate_gib" + projectiletype = /obj/item/projectile/bullet/dart/catranq + projectilesound = 'sound/items/syringeproj.ogg' + ranged = 1 + ranged_message = "fires the syringe gun at" + ranged_cooldown_time = 30 speak_chance = 0 turns_per_move = 5 + response_help_continuous = "pokes" + response_harm_continuous = "hits" speed = 0 stat_attack = UNCONSCIOUS robust_searching = 1 maxHealth = 100 health = 100 - harm_intent_damage = 5 melee_damage_lower = 15 melee_damage_upper = 15 attack_verb_continuous = "slashes at" - attack_verb_simple = "slash at" attack_sound = 'sound/weapons/circsawhit.ogg' a_intent = INTENT_HARM - mob_biotypes = MOB_ORGANIC|MOB_HUMANOID - loot = list(/obj/effect/mob_spawn/human/corpse/cat_butcher, /obj/item/circular_saw) + mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID) + loot = list(/obj/effect/mob_spawn/human/corpse/cat_butcher, /obj/item/circular_saw, /obj/item/gun/syringe) atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 faction = list("hostile") check_friendly_fire = 1 status_flags = CANPUSH - del_on_death = 1 + del_on_death = TRUE + var/impatience = 0 + rapid_melee = 2 //this lets him attack nearly as fast as a normal player, instead of half as fast as one. Without this, due to mood differences, a greytider in melee can actually facetank and beat him to death with only fists + dodging = TRUE + +/mob/living/simple_animal/hostile/cat_butcherer/Life() + . = ..() + if(prob(10) && health <= maxHealth && !target) //heal himself when not in combat + var/healamount = min(maxHealth-health, 20) + visible_message("[src] medicates themself.", "You medicate yourself.") + health += healamount + +/mob/living/simple_animal/hostile/cat_butcherer/CanAttack(atom/the_target) + if(iscarbon(target)) + var/mob/living/carbon/human/C = target + if(C.getorgan(/obj/item/organ/ears/cat) && C.getorgan(/obj/item/organ/tail/cat) && C.has_trauma_type(/datum/brain_trauma/severe/pacifism))//he wont attack his creations + if(C.stat && !istype(C.dna.species, /datum/species/ipc))//unless they need healing + return ..() + else + return FALSE + return ..() /mob/living/simple_animal/hostile/cat_butcherer/AttackingTarget() - . = ..() - if(. && prob(35) && iscarbon(target)) + if(iscarbon(target)) var/mob/living/carbon/human/L = target - var/obj/item/organ/tail/cat/tail = L.getorgan(/obj/item/organ/tail/cat) - if(!QDELETED(tail)) - visible_message("[src] severs [L]'s tail in one swift swipe!", "You sever [L]'s tail in one swift swipe.") - tail.Remove() - var/obj/item/organ/tail/cat/dropped_tail = new(target.drop_location()) - dropped_tail.color = L.hair_color - return 1 + if(!L.getorgan(/obj/item/organ/ears/cat) && L.stat) //target doesnt have cat ears + if(L.getorgan(/obj/item/organ/ears)) //slice off the old ears + var/obj/item/organ/ears/ears = L.getorgan(/obj/item/organ/ears) + visible_message("[src] slices off [L]'s ears!", "You slice [L]'s ears off.") + ears.Remove(L) + ears.forceMove(get_turf(L)) + else //implant new ears + visible_message("[src] attaches a pair of cat ears to [L]!", "You attach a pair of cat ears to [L].") + var/obj/item/organ/ears/cat/newears = new + newears.Insert(L, drop_if_replaced = FALSE) + return + else if(!L.getorgan(/obj/item/organ/tail/cat) && L.stat) + if(L.getorgan(/obj/item/organ/tail)) //cut off the tail if they have one already + var/obj/item/organ/tail/tail = L.getorgan(/obj/item/organ/tail) + visible_message("[src] severs [L]'s tail in one swift swipe!", "You sever [L]'s tail in one swift swipe.") + tail.Remove(L) + tail.forceMove(get_turf(L)) + else //put a cat tail on + visible_message("[src] attaches a cat tail to [L]!", "You attach a tail to [L].") + var/obj/item/organ/tail/cat/newtail = new + newtail.Insert(L, drop_if_replaced = FALSE) + return + else if(!L.has_trauma_type(/datum/brain_trauma/severe/pacifism) && L.getorgan(/obj/item/organ/ears/cat) && L.getorgan(/obj/item/organ/tail/cat)) //still does damage. This also lacks a Stat check- felinids beware. + visible_message("[src] drills a hole in [L]'s skull!", "You pacify [L]. Another successful creation.") + if(L.stat == CONSCIOUS) + L.emote("scream") + L.gain_trauma(/datum/brain_trauma/severe/pacifism, TRAUMA_RESILIENCE_BASIC) + say("Such a GOOD KITTY!!") + if(L.mind && maxHealth <= 300) //if he robusts a tider, he becomes stronger + maxHealth += 20 + adjustHealth(-(maxHealth)) //he heals whenever he finishes + else if(L.stat) //quickly heal them up and move on to our next target! + visible_message("[src] injects [L] with an unknown medicine!", "You inject [L] with medicine.") + L.SetSleeping(0, FALSE) + L.SetUnconscious(0, FALSE) + L.adjustOxyLoss(-50)// do CPR first + if(L.blood_volume <= 500) //bandage them up and give em some blood if they're bleeding + L.blood_volume += 30 + L.bleedsuppress = 0 + if(L.getBruteLoss() >= 50)// first, did we beat them into crit? if so, heal that + var/healing = min(L.getBruteLoss(), 120) + L.adjustBruteLoss(-healing) + L.bleedsuppress = 0 //bandage their ass + return + else if(L.getFireLoss() >= 50) // are they still down from other damage? fix it, but not as fast as the burns + var/healing = min(L.getFireLoss(), 50) + L.adjustFireLoss(-healing) + impatience += 50 + if(prob(impatience)) + FindTarget()//so we don't focus on some unconscious dude when we could get our eyes on the prize + impatience = 0 + say("Bah!!") + return + return ..() diff --git a/code/modules/projectiles/projectile/bullets/dart_syringe.dm b/code/modules/projectiles/projectile/bullets/dart_syringe.dm index 25809cc7ca..bc2a7c40fb 100644 --- a/code/modules/projectiles/projectile/bullets/dart_syringe.dm +++ b/code/modules/projectiles/projectile/bullets/dart_syringe.dm @@ -38,6 +38,10 @@ reagents.add_reagent(/datum/reagent/foaming_agent, 5) reagents.add_reagent(/datum/reagent/toxin/acid, 5) +/obj/item/projectile/bullet/dart/catranq/Initialize() + . = ..() + reagents.add_reagent(/datum/reagent/fermi/furranium, 5) // Turns out I don't even need to give this guy actual tranquilizer chems. + /obj/item/projectile/bullet/dart/syringe name = "syringe" icon_state = "syringeproj" diff --git a/sound/misc/catscream.ogg b/sound/misc/catscream.ogg new file mode 100644 index 0000000000..831767730e Binary files /dev/null and b/sound/misc/catscream.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 8c9d6cd621..bf6cf98d56 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2074,6 +2074,7 @@ #include "code\modules\events\bureaucratic_error.dm" #include "code\modules\events\camerafailure.dm" #include "code\modules\events\carp_migration.dm" +#include "code\modules\events\cat_surgeon.dm" #include "code\modules\events\communications_blackout.dm" #include "code\modules\events\devil.dm" #include "code\modules\events\disease_outbreak.dm"