diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 13f774d25d..d3bf0a4e00 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -78455,6 +78455,7 @@ /turf/open/floor/engine, /area/science/xenobiology) "dbq" = ( +/mob/living/simple_animal/hostile/retaliate/goose/vomit, /turf/open/floor/wood{ icon_state = "wood-broken6" }, diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 7e4f54c8b4..3d15f887bd 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -54387,6 +54387,10 @@ }, /turf/open/floor/plating, /area/maintenance/department/cargo) +"ggg" = ( +/mob/living/simple_animal/hostile/retaliate/goose/vomit, +/turf/open/floor/wood, +/area/maintenance/department/crew_quarters/dorms) "gih" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 @@ -99275,7 +99279,7 @@ cBk jhD cBo alQ -alb +ggg cBw noC aiS diff --git a/code/game/sound.dm b/code/game/sound.dm index 5503c6103d..e7562476a8 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -182,6 +182,8 @@ soundin = pick('sound/voice/beepsky/god.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/beepsky/secureday.ogg', 'sound/voice/beepsky/radio.ogg', 'sound/voice/beepsky/insult.ogg', 'sound/voice/beepsky/creep.ogg') if("honkbot_e") soundin = pick('sound/items/bikehorn.ogg', 'sound/items/AirHorn2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/items/AirHorn.ogg', 'sound/effects/reee.ogg', 'sound/items/WEEOO1.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/beepsky/creep.ogg','sound/magic/Fireball.ogg' ,'sound/effects/pray.ogg', 'sound/voice/hiss1.ogg','sound/machines/buzz-sigh.ogg', 'sound/machines/ping.ogg', 'sound/weapons/flashbang.ogg', 'sound/weapons/bladeslice.ogg') + if("goose") + soundin = pick('sound/creatures/goose1.ogg', 'sound/creatures/goose2.ogg', 'sound/creatures/goose3.ogg', 'sound/creatures/goose4.ogg') //START OF CIT CHANGES - adds random vore sounds if ("struggle_sound") soundin = pick( 'sound/vore/pred/struggle_01.ogg','sound/vore/pred/struggle_02.ogg','sound/vore/pred/struggle_03.ogg', diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 7110ff4405..f3d50729d1 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -452,16 +452,21 @@ /turf/AllowDrop() return TRUE -/turf/proc/add_vomit_floor(mob/living/carbon/M, toxvomit = NONE) +/turf/proc/add_vomit_floor(mob/living/M, toxvomit = NONE) + var/obj/effect/decal/cleanable/vomit/V = new /obj/effect/decal/cleanable/vomit(src, M.get_static_viruses()) - // If the vomit combined, apply toxicity and reagents to the old vomit + //if the vomit combined, apply toxicity and reagents to the old vomit if (QDELETED(V)) V = locate() in src // Make toxins and blazaam vomit look different if(toxvomit == VOMIT_PURPLE) V.icon_state = "vomitpurp_[pick(1,4)]" - else if(toxvomit == VOMIT_TOXIC) + else if (toxvomit == VOMIT_TOXIC) V.icon_state = "vomittox_[pick(1,4)]" + if (iscarbon(M)) + var/mob/living/carbon/C = M + if(C.reagents) + clear_reagents_to_vomit_pool(C,V) /proc/clear_reagents_to_vomit_pool(mob/living/carbon/M, obj/effect/decal/cleanable/vomit/V) M.reagents.trans_to(V, M.reagents.total_volume / 10) @@ -474,4 +479,4 @@ //Whatever happens after high temperature fire dies out or thermite reaction works. //Should return new turf /turf/proc/Melt() - return ScrapeAway() \ No newline at end of file + return ScrapeAway() diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 1087f1ebb5..86a9c21f10 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -2230,6 +2230,20 @@ contains = list(/mob/living/simple_animal/hostile/retaliate/goat) crate_name = "goat crate" +/datum/supply_pack/critter/goose + name = "Goose Crate" + desc = "Angry and violent birds. Evil, evil creatures." + cost = 2500 + contains = list(/mob/living/simple_animal/hostile/retaliate/goose) + crate_name = "goose crate" + +/datum/supply_pack/critter/goose/vomit + name = "Vomit Goose Crate" + desc = "Angry and violent birds. Evil, evil creatures. This one pukes!" + cost = 5000 + contains = list(/mob/living/simple_animal/hostile/retaliate/goose/vomit/cargo) + crate_name = "vomit goose crate" + /datum/supply_pack/critter/monkey name = "Monkey Cube Crate" desc = "Stop monkeying around! Contains seven monkey cubes. Just add water!" diff --git a/code/modules/mob/living/simple_animal/hostile/goose.dm b/code/modules/mob/living/simple_animal/hostile/goose.dm new file mode 100644 index 0000000000..50b8261c79 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/goose.dm @@ -0,0 +1,173 @@ +#define GOOSE_SATIATED 50 + +/mob/living/simple_animal/hostile/retaliate/goose + name = "goose" + desc = "It's loose" + icon_state = "goose" // sprites by cogwerks from goonstation, used with permission + icon_living = "goose" + icon_dead = "goose_dead" + mob_biotypes = list(MOB_ORGANIC, MOB_BEAST) + speak_chance = 0 + turns_per_move = 5 + butcher_results = list(/obj/item/reagent_containers/food/snacks/meat = 2) + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + emote_taunt = list("hisses") + taunt_chance = 30 + speed = 0 + maxHealth = 25 + health = 25 + harm_intent_damage = 5 + melee_damage_lower = 5 + melee_damage_upper = 5 + attacktext = "pecks" + attack_sound = "goose" + speak_emote = list("honks") + faction = list("neutral") + attack_same = TRUE + gold_core_spawnable = HOSTILE_SPAWN + var/random_retaliate = TRUE + var/icon_vomit_start = "vomit_start" + var/icon_vomit = "vomit" + var/icon_vomit_end = "vomit_end" + +/mob/living/simple_animal/hostile/retaliate/goose/handle_automated_movement() + . = ..() + if(prob(5) && random_retaliate == TRUE) + Retaliate() + +/mob/living/simple_animal/hostile/retaliate/goose/vomit + name = "Birdboat" + real_name = "Birdboat" + desc = "It's a sick-looking goose, probably ate too much maintenance trash. Best not to move it around too much." + gender = MALE + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + gold_core_spawnable = NO_SPAWN + random_retaliate = FALSE + var/vomiting = FALSE + var/vomitCoefficient = 1 + var/vomitTimeBonus = 0 + var/datum/action/cooldown/vomit/goosevomit + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/cargo + name = "Sickly Goose" + real_name = "Sickly Goose" + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/Initialize() + . = ..() + goosevomit = new + goosevomit.Grant(src) + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/Destroy() + QDEL_NULL(goosevomit) + return ..() + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/examine(user) + . = ..() + . += "Somehow, it still looks hungry." + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/attacked_by(obj/item/O, mob/user) + . = ..() + feed(O) + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/feed(obj/item/O) + var/obj/item/reagent_containers/food/tasty = O + if(!istype(O)) + return + if (contents.len > GOOSE_SATIATED) + visible_message("[src] looks too full to eat \the [tasty]!") + return + if (tasty.foodtype & GROSS) + visible_message("[src] hungrily gobbles up \the [tasty]!") + tasty.forceMove(src) + playsound(src,'sound/items/eatfood.ogg', 70, 1) + vomitCoefficient += 3 + vomitTimeBonus += 2 + else + visible_message("[src] refuses to eat \the [tasty].") + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit() + var/turf/T = get_turf(src) + var/obj/item/reagent_containers/food/consumed = locate() in contents //Barf out a single food item from our guts + if (prob(50) && consumed) + barf_food(consumed) + else + playsound(T, 'sound/effects/splat.ogg', 50, 1) + T.add_vomit_floor(src) + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/barf_food(var/atom/A, var/hard = FALSE) + if(!istype(A, /obj/item/reagent_containers/food)) + return + var/turf/currentTurf = get_turf(src) + var/obj/item/reagent_containers/food/consumed = A + consumed.forceMove(currentTurf) + var/destination = get_edge_target_turf(currentTurf, pick(GLOB.alldirs)) //Pick a random direction to toss them in + var/throwRange = hard ? rand(2,8) : 1 + consumed.safe_throw_at(destination, throwRange, 2) //Thow the food at a random tile 1 spot away + sleep(2) + if (QDELETED(src) || QDELETED(consumed)) + return + currentTurf = get_turf(consumed) + currentTurf.add_vomit_floor(src) + playsound(currentTurf, 'sound/effects/splat.ogg', 50, 1) + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit_prestart(duration) + flick("vomit_start",src) + addtimer(CALLBACK(src, .proc/vomit_start, duration), 13) //13 is the length of the vomit_start animation in gooseloose.dmi + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit_start(duration) + vomiting = TRUE + icon_state = "vomit" + vomit() + addtimer(CALLBACK(src, .proc/vomit_preend), duration) + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit_preend() + for (var/obj/item/consumed in contents) //Get rid of any food left in the poor thing + barf_food(consumed, TRUE) + sleep(1) + if (QDELETED(src)) + return + vomit_end() + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/proc/vomit_end() + flick("vomit_end",src) + vomiting = FALSE + icon_state = initial(icon_state) + +/mob/living/simple_animal/hostile/retaliate/goose/vomit/Moved(oldLoc, dir) + . = ..() + if(vomiting) + vomit() // its supposed to keep vomiting if you move + return + var/turf/currentTurf = get_turf(src) + while (currentTurf == get_turf(src)) + var/obj/item/reagent_containers/food/tasty = locate() in currentTurf + if (tasty) + feed(tasty) + stoplag(20) + if(prob(vomitCoefficient * 0.2)) + vomit_prestart(vomitTimeBonus + 25) + vomitCoefficient = 1 + vomitTimeBonus = 0 + +/datum/action/cooldown/vomit + name = "Vomit" + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "vomit" + icon_icon = 'icons/mob/animal.dmi' + cooldown_time = 250 + +/datum/action/cooldown/vomit/Trigger() + if(!..()) + return FALSE + if(!istype(owner, /mob/living/simple_animal/hostile/retaliate/goose/vomit)) + return FALSE + var/mob/living/simple_animal/hostile/retaliate/goose/vomit/vomit = owner + if(!vomit.vomiting) + vomit.vomit_prestart(vomit.vomitTimeBonus + 25) + vomit.vomitCoefficient = 1 + vomit.vomitTimeBonus = 0 + return TRUE diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 2a85f8a422..e9343c7ed2 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/sound/creatures/goose1.ogg b/sound/creatures/goose1.ogg new file mode 100644 index 0000000000..3d605ad622 Binary files /dev/null and b/sound/creatures/goose1.ogg differ diff --git a/sound/creatures/goose2.ogg b/sound/creatures/goose2.ogg new file mode 100644 index 0000000000..735faba791 Binary files /dev/null and b/sound/creatures/goose2.ogg differ diff --git a/sound/creatures/goose3.ogg b/sound/creatures/goose3.ogg new file mode 100644 index 0000000000..1aeec77369 Binary files /dev/null and b/sound/creatures/goose3.ogg differ diff --git a/sound/creatures/goose4.ogg b/sound/creatures/goose4.ogg new file mode 100644 index 0000000000..699f143bd3 Binary files /dev/null and b/sound/creatures/goose4.ogg differ diff --git a/tgstation.dme b/tgstation.dme index cceeb1f915..9929e4b2df 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2192,6 +2192,7 @@ #include "code\modules\mob\living\simple_animal\hostile\eyeballs.dm" #include "code\modules\mob\living\simple_animal\hostile\faithless.dm" #include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm" +#include "code\modules\mob\living\simple_animal\hostile\goose.dm" #include "code\modules\mob\living\simple_animal\hostile\headcrab.dm" #include "code\modules\mob\living\simple_animal\hostile\hivebot.dm" #include "code\modules\mob\living\simple_animal\hostile\hostile.dm"