diff --git a/code/__DEFINES/achievements.dm b/code/__DEFINES/achievements.dm index 4f1cf4b746a..a6dccb5e226 100644 --- a/code/__DEFINES/achievements.dm +++ b/code/__DEFINES/achievements.dm @@ -58,6 +58,7 @@ #define MEDAL_SISYPHUS "Sisyphus" #define MEDAL_ARCHMAGE "Archmage" #define MEDAL_CIGARETTES "Cigarettes" +#define MEDAL_SHARKDRAGON "Sharkdragon" #define MEDAL_THEORETICAL_LIMITS "All Within Theoretical Limits" //Skill medal hub IDs diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 774b89cdb0e..2a04228cbab 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -965,6 +965,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai ///A trait for mechs that were created through the normal construction process, and not spawned by map or other effects. #define TRAIT_MECHA_CREATED_NORMALLY "trait_mecha_created_normally" +/// Stops a movable from being removed from the mob it's in by the content_barfer component. +#define TRAIT_NOT_BARFABLE "not_barfable" + ///fish traits #define TRAIT_FISH_STASIS "fish_stasis" #define TRAIT_FISH_FLOPPING "fish_flopping" diff --git a/code/_globalvars/phobias.dm b/code/_globalvars/phobias.dm index 131e530ce82..e112d376adf 100644 --- a/code/_globalvars/phobias.dm +++ b/code/_globalvars/phobias.dm @@ -69,6 +69,7 @@ GLOBAL_LIST_INIT(phobia_mobs, list( )), "carps" = typecacheof(list( /mob/living/basic/carp, + /mob/living/basic/space_dragon, )), "conspiracies" = typecacheof(list( /mob/living/basic/drone, @@ -247,6 +248,7 @@ GLOBAL_LIST_INIT(phobia_objs, list( /obj/item/clothing/mask/gas/carp, /obj/item/cigarette/carp, /obj/item/clothing/under/suit/carpskin, + /obj/item/fish/baby_carp, /obj/item/food/cubancarp, /obj/item/food/fishmeat/carp, /obj/item/grenade/clusterbuster/spawner_spesscarp, diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 4b7dbf769be..6cd4e326d04 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -57,11 +57,13 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_MOVE_PHASING" = TRAIT_MOVE_PHASING, "TRAIT_MOVE_UPSIDE_DOWN" = TRAIT_MOVE_UPSIDE_DOWN, "TRAIT_MOVE_VENTCRAWLING" = TRAIT_MOVE_VENTCRAWLING, - "TRAIT_NOT_ENGRAVABLE" = TRAIT_NOT_ENGRAVABLE, + "TRAIT_MOVE_UPSIDE_DOWN" = TRAIT_MOVE_UPSIDE_DOWN, "TRAIT_NO_FLOATING_ANIM" = TRAIT_NO_FLOATING_ANIM, "TRAIT_NO_MANIFEST_CONTENTS_ERROR" = TRAIT_NO_MANIFEST_CONTENTS_ERROR, "TRAIT_NO_MISSING_ITEM_ERROR" = TRAIT_NO_MISSING_ITEM_ERROR, "TRAIT_NO_THROW_HITPUSH" = TRAIT_NO_THROW_HITPUSH, + "TRAIT_NOT_BARFABLE" = TRAIT_NOT_BARFABLE, + "TRAIT_NOT_ENGRAVABLE" = TRAIT_NOT_ENGRAVABLE, "TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT" = TRAIT_ODD_CUSTOMIZABLE_FOOD_INGREDIENT, "TRAIT_ON_HIT_EFFECT" = TRAIT_ON_HIT_EFFECT, "TRAIT_RUNECHAT_HIDDEN" = TRAIT_RUNECHAT_HIDDEN, diff --git a/code/datums/achievements/misc_achievements.dm b/code/datums/achievements/misc_achievements.dm index bd1719783e1..4e37400d51d 100644 --- a/code/datums/achievements/misc_achievements.dm +++ b/code/datums/achievements/misc_achievements.dm @@ -234,7 +234,13 @@ icon_state = "sisyphus" /datum/award/achievement/misc/cigarettes - name = "Unhealthy snacks" + name = "Unhealthy Snacks" desc = "You were curious to taste it. And then another. You must have more!" database_id = MEDAL_CIGARETTES icon_state = "cigarettes" + +/datum/award/achievement/misc/sharkdragon + name = "You're What You Eat" + desc = "Nutritionists often recommend a balanced and varied diet. However that clearly isn't the case for some creatures." + database_id = MEDAL_SHARKDRAGON + icon_state = "dragon_plus_fish" diff --git a/code/datums/components/profound_fisher.dm b/code/datums/components/profound_fisher.dm index 61f6543bd12..9638af4a8f2 100644 --- a/code/datums/components/profound_fisher.dm +++ b/code/datums/components/profound_fisher.dm @@ -9,6 +9,7 @@ return COMPONENT_INCOMPATIBLE src.our_rod = our_rod || new(parent) src.our_rod.internal = TRUE + ADD_TRAIT(src.our_rod, TRAIT_NOT_BARFABLE, REF(src)) RegisterSignal(src.our_rod, COMSIG_QDELETING, PROC_REF(on_rod_qdel)) if(!isgloves) @@ -43,6 +44,7 @@ /datum/component/profound_fisher/Destroy() our_rod.internal = FALSE UnregisterSignal(our_rod, COMSIG_QDELETING) + REMOVE_TRAIT(our_rod, TRAIT_NOT_BARFABLE, REF(src)) our_rod = null return ..() diff --git a/code/datums/elements/content_barfer.dm b/code/datums/elements/content_barfer.dm index e30294bc08a..533a88503e2 100644 --- a/code/datums/elements/content_barfer.dm +++ b/code/datums/elements/content_barfer.dm @@ -20,7 +20,9 @@ /datum/element/content_barfer/proc/barf_contents(mob/living/target) SIGNAL_HANDLER - for(var/atom/movable/barfed_out in target) + for(var/atom/movable/barfed_out as anything in target) + if(HAS_TRAIT(barfed_out, TRAIT_NOT_BARFABLE)) + continue barfed_out.forceMove(target.loc) if(prob(90)) step(barfed_out, pick(GLOB.alldirs)) diff --git a/code/game/objects/items/dehy_carp.dm b/code/game/objects/items/dehy_carp.dm index 88a3a98a5bb..e863f09ecde 100644 --- a/code/game/objects/items/dehy_carp.dm +++ b/code/game/objects/items/dehy_carp.dm @@ -71,3 +71,6 @@ UnregisterSignal(owner, COMSIG_QDELETING) owner = null + +/obj/item/toy/plush/carpplushie/dehy_carp/peaceful + mobtype = /mob/living/basic/carp/passive diff --git a/code/game/objects/items/food/meatdish.dm b/code/game/objects/items/food/meatdish.dm index 9bda586b269..770b6f8bf31 100644 --- a/code/game/objects/items/food/meatdish.dm +++ b/code/game/objects/items/food/meatdish.dm @@ -88,6 +88,13 @@ cell_line = null starting_reagent_purity = 0.3 +///carp fillet, but without the toxin. Used by baby carps (fish item), which have a trait that handles the toxin already. +/obj/item/food/fishmeat/carp/no_tox + +/obj/item/food/fishmeat/carp/no_tox/Initialize(mapload) + food_reagents -= /datum/reagent/toxin/carpotoxin + return ..() + /obj/item/food/fishmeat/moonfish name = "moonfish fillet" desc = "A fillet of moonfish." diff --git a/code/modules/antagonists/space_dragon/carp_rift.dm b/code/modules/antagonists/space_dragon/carp_rift.dm index 6038c5e6820..6299bde9275 100644 --- a/code/modules/antagonists/space_dragon/carp_rift.dm +++ b/code/modules/antagonists/space_dragon/carp_rift.dm @@ -111,6 +111,8 @@ healing_color = COLOR_BLUE, \ ) + AddComponent(/datum/component/fishing_spot, /datum/fish_source/carp_rift) + gravity_aura = new( /* host = */src, /* range = */15, diff --git a/code/modules/antagonists/space_dragon/space_dragon.dm b/code/modules/antagonists/space_dragon/space_dragon.dm index 090c8f66dc8..74b0c60a872 100644 --- a/code/modules/antagonists/space_dragon/space_dragon.dm +++ b/code/modules/antagonists/space_dragon/space_dragon.dm @@ -112,7 +112,7 @@ var/icon/icon = icon('icons/mob/nonhuman-player/spacedragon.dmi', "spacedragon") icon.Blend(COLOR_STRONG_VIOLET, ICON_MULTIPLY) - icon.Blend(icon('icons/mob/nonhuman-player/spacedragon.dmi', "overlay_base"), ICON_OVERLAY) + icon.Blend(icon('icons/mob/nonhuman-player/spacedragon.dmi', "spacedragon_overlay_base"), ICON_OVERLAY) icon.Crop(10, 9, 54, 53) icon.Scale(ANTAGONIST_PREVIEW_ICON_SIZE, ANTAGONIST_PREVIEW_ICON_SIZE) diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index d88129a7c43..539f7c9a0b9 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -1304,6 +1304,10 @@ /obj/item/fish/proc/undo_petted() fish_flags &= ~FISH_FLAG_PETTED +/obj/item/fish/update_atom_colour() + . = ..() + aquarium_vc_color = color || initial(aquarium_vc_color) + /// Returns random fish, using random_case_rarity probabilities. /proc/random_fish_type(required_fluid) var/static/probability_table diff --git a/code/modules/fishing/fish/fish_traits.dm b/code/modules/fishing/fish/fish_traits.dm index c9ab3325af3..b0eec9d58f2 100644 --- a/code/modules/fishing/fish/fish_traits.dm +++ b/code/modules/fishing/fish/fish_traits.dm @@ -427,6 +427,8 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) catalog_description = "This fish contains toxins. Feeding it to predatory fishes or people is not recommended." diff_traits_inheritability = 25 reagents_to_add = list(/datum/reagent/toxin/tetrodotoxin = 1) + ///The amount of venom injected if the fish has a stinger is multiplied by this value. + var/venom_mult = 1 /datum/fish_trait/toxic/apply_to_fish(obj/item/fish/fish) . = ..() @@ -438,13 +440,13 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) SIGNAL_HANDLER if(!HAS_TRAIT(source, TRAIT_FISH_STINGER)) return - add_venom(source, /datum/reagent/toxin/tetrodotoxin, new_weight, mult = source.status == FISH_DEAD ? 0.1 : 0.25) + add_venom(source, reagents_to_add[1], new_weight, mult = (source.status == FISH_DEAD ? 0.1 : 0.25) * venom_mult) /datum/fish_trait/toxic/proc/on_status_change(obj/item/fish/source) SIGNAL_HANDLER if(!HAS_TRAIT(source, TRAIT_FISH_STINGER)) return - change_venom_on_death(source, /datum/reagent/toxin/tetrodotoxin, 0.25, 0.1) + change_venom_on_death(source, reagents_to_add[1], 0.25 * venom_mult, 0.1 * venom_mult) /datum/fish_trait/toxic/proc/on_eaten(obj/item/fish/source, obj/item/fish/predator) if(HAS_TRAIT(predator, TRAIT_FISH_TOXIN_IMMUNE)) @@ -463,7 +465,14 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) /datum/fish_trait/toxic/apply_to_mob(mob/living/basic/mob) . = ..() - mob.AddElement(/datum/element/venomous, /datum/reagent/toxin/tetrodotoxin, 0.5 * mob.mob_size) + mob.AddElement(/datum/element/venomous, reagents_to_add[1], 0.5 * mob.mob_size * venom_mult) + +/datum/fish_trait/toxic/carpotoxin + name = "Carpotoxic" + catalog_description = "This fish contains carpotoxin. Definitely not safe for consumption." + diff_traits_inheritability = 50 + reagents_to_add = list(/datum/reagent/toxin/carpotoxin = 4) + venom_mult = 6 /datum/fish_trait/toxin_immunity name = "Toxin Immunity" diff --git a/code/modules/fishing/fish/types/air_space.dm b/code/modules/fishing/fish/types/air_space.dm index dda3794ff4e..177ae9c6e0e 100644 --- a/code/modules/fishing/fish/types/air_space.dm +++ b/code/modules/fishing/fish/types/air_space.dm @@ -99,3 +99,85 @@ ///It spins, and dimly glows in the dark. /obj/item/fish/starfish/flop_animation() DO_FLOATING_ANIM(src) + +/obj/item/fish/baby_carp + name = "baby space carp" + desc = "A juvenile spawn of the dreaded space carp. Don't let the innocent looks fool you, they're aggressive little bastards." + icon_state = "baby_carp" + sprite_height = 3 + sprite_width = 5 + average_size = 35 + average_weight = 550 + stable_population = 7 + required_fluid_type = AQUARIUM_FLUID_ANY_WATER + random_case_rarity = FISH_RARITY_VERY_RARE + required_temperature_min = 0 + required_temperature_max = MIN_AQUARIUM_TEMP+200 + safe_air_limits = null + fillet_type = /obj/item/food/fishmeat/carp/no_tox + fish_traits = list( + /datum/fish_trait/carnivore, + /datum/fish_trait/aggressive, + /datum/fish_trait/predator, + /datum/fish_trait/necrophage, + /datum/fish_trait/no_mating, + /datum/fish_trait/toxic/carpotoxin, + ) + favorite_bait = list( + list( + FISH_BAIT_TYPE = FISH_BAIT_FOODTYPE, + FISH_BAIT_VALUE = MEAT, + ), + ) + disliked_bait = list( + list( + FISH_BAIT_TYPE = FISH_BAIT_FOODTYPE, + FISH_BAIT_VALUE = GRAIN|DAIRY, + ), + ) + beauty = FISH_BEAUTY_GREAT + +/obj/item/fish/baby_carp/Initialize(mapload, apply_qualities = TRUE) + color = pick_weight(GLOB.carp_colors) + . = ..() + RegisterSignal(src, COMSIG_FISH_BEFORE_GROWING, PROC_REF(growth_checks)) + RegisterSignal(src, COMSIG_FISH_FINISH_GROWING, PROC_REF(on_growth)) + update_appearance(UPDATE_OVERLAYS) + +/obj/item/fish/baby_carp/update_overlays() + . = ..() + var/mutable_appearance/eyes = mutable_appearance(icon, "baby_carp_eyes") + if(status == FISH_DEAD) + eyes.icon_state += "_dead" + else + eyes.appearance_flags = RESET_COLOR + . += eyes + +///Determines the speed at which the carp grows based on how big it's +/obj/item/fish/baby_carp/update_size_and_weight(new_size = average_size, new_weight = average_weight) + . = ..() + var/growth_rate = 4.5 MINUTES + growth_rate *= clamp(size/average_size, 0.5, 2) + growth_rate *= clamp(weight/average_weight, 0.5, 2) + + AddComponent(/datum/component/fish_growth, /mob/living/basic/carp/advanced, growth_rate) + +/obj/item/fish/baby_carp/proc/growth_checks(datum/source, seconds_per_tick) + SIGNAL_HANDLER + var/hunger = CLAMP01((world.time - last_feeding) / feeding_frequency) + if(health <= initial(health) * 0.6 || hunger >= 0.6) //if too hurt or hungry, don't grow. + return COMPONENT_DONT_GROW + + if(!isaquarium(loc)) + return + + var/obj/structure/aquarium/aquarium = loc + if(!aquarium.reproduction_and_growth) //the aquarium has breeding disabled + return COMPONENT_DONT_GROW + if(length(aquarium.get_fishes()) > AQUARIUM_MAX_BREEDING_POPULATION * 0.5) //check if there's enough room to maturate. + return COMPONENT_DONT_GROW + +/obj/item/fish/baby_carp/proc/on_growth(datum/source, mob/living/basic/carp/result) + SIGNAL_HANDLER + //yes, this means that if we use a spraycan on the fish, the resulting space carp will be of spraycan color + result.set_greyscale(colors = list(color)) diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index 38455068ce2..c2db0a43fc9 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -41,6 +41,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) /obj/item/fish/stingray = FISH_ICON_WEAPON, /obj/item/fish/swordfish = FISH_ICON_WEAPON, /obj/item/fish/zipzap = FISH_ICON_ELECTRIC, + /obj/item/knife/carp = FISH_ICON_WEAPON, /obj/item/seeds/grass = FISH_ICON_SEED, /obj/item/seeds/random = FISH_ICON_SEED, /obj/item/storage/wallet = FISH_ICON_COIN, diff --git a/code/modules/fishing/sources/source_types.dm b/code/modules/fishing/sources/source_types.dm index 06d508ffcab..56c1cb8e325 100644 --- a/code/modules/fishing/sources/source_types.dm +++ b/code/modules/fishing/sources/source_types.dm @@ -193,6 +193,7 @@ fish_table = list( // FISHING_DUD = 5, BUBBERSTATION CHANGE: NO DUDS. HOLY SHIT. /obj/item/fish/starfish = 6, + /obj/item/fish/baby_carp = 6, /obj/item/stack/ore/bluespace_crystal = 2, /mob/living/basic/carp = 2, ) @@ -580,6 +581,25 @@ var/picked_path = pick(seeds_to_draw_from) return new picked_path(get_turf(fishing_spot)) +/datum/fish_source/carp_rift + catalog_description = "Space Dragon Rifts" + radial_state = "carp" + fish_table = list( + FISHING_DUD = 3, + /obj/item/fish/baby_carp = 5, + /mob/living/basic/carp = 1, + /mob/living/basic/carp/passive = 1, + /mob/living/basic/carp/mega = 1, + /obj/item/clothing/head/fedora/carpskin = 1, + /obj/item/toy/plush/carpplushie = 1, + /obj/item/toy/plush/carpplushie/dehy_carp/peaceful = 1, + /obj/item/knife/carp = 1, + ) + fish_counts = list( + /mob/living/basic/carp/mega = 2, + ) + fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 18 + /datum/fish_source/deepfryer catalog_description = "Deep Fryers" radial_state = "fryer" diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp.dm b/code/modules/mob/living/basic/space_fauna/carp/carp.dm index 3461f5b104e..f1c12cc3ce9 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp.dm @@ -96,6 +96,7 @@ AddComponent(/datum/component/aggro_emote, emote_list = string_list(list("gnashes"))) AddComponent(/datum/component/regenerator, outline_colour = regenerate_colour) + AddComponent(/datum/component/profound_fisher) if (tamer) tamed(tamer, feedback = FALSE) befriend(tamer) diff --git a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm index f672e60ee29..b1acd8f9631 100644 --- a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm +++ b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm @@ -62,6 +62,11 @@ /// Our wing flap action var/datum/action/cooldown/mob_cooldown/wing_buffet/buffet + ///Are currently sharkified or a plain space dragon? + var/shark_form = FALSE + ///The amount of fish (weight) the space dragon has to eat to be sharkified and receive a cheevo for it. + var/fish_left = 15000 // 30 fish with a weight of 500. + /mob/living/basic/space_dragon/Initialize(mapload) . = ..() add_traits(list(TRAIT_SPACEWALK, TRAIT_FREE_HYPERSPACE_MOVEMENT, TRAIT_NO_FLOATING_ANIM, TRAIT_HEALS_FROM_CARP_RIFTS), INNATE_TRAIT) @@ -70,6 +75,7 @@ AddElement(/datum/element/wall_tearer, tear_time = 4 SECONDS, reinforced_multiplier = 3, do_after_key = DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION) AddElement(/datum/element/door_pryer, pry_time = 4 SECONDS, interaction_key = DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION) AddComponent(/datum/component/seethrough_mob) + AddComponent(/datum/component/profound_fisher, new /obj/item/fishing_rod/mob_fisher/dragon(src)) RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attack)) RegisterSignal(src, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_changed)) RegisterSignal(src, COMSIG_ATOM_PRE_EX_ACT, PROC_REF(on_exploded)) @@ -89,9 +95,33 @@ . = ..() if(!isnull(chosen_colour)) return + if(client.get_award_status(/datum/award/achievement/misc/sharkdragon)) + if(tgui_alert(src, "Shall you take the dragon form or the shark form?","Shark Form Unlocked", list("Dragon","Shark")) == "Shark") + sharkify() rename_dragon() select_colour() +/mob/living/basic/space_dragon/mind_initialize() + . = ..() + if(shark_form && mind.get_skill_level(/datum/skill/fishing) < SKILL_LEVEL_APPRENTICE) + mind.set_level(/datum/skill/fishing, SKILL_LEVEL_APPRENTICE, TRUE) + +/mob/living/basic/space_dragon/proc/sharkify() + if(shark_form) + return + pixel_z -= 3 + base_pixel_z -= 3 + do_jitter_animation(150) + shark_form = TRUE + desc = "A piscine mutation of the fearsome leviathan whose flight defies modern physics. Said to be the other ultimate stage in the life cycle of the Space Carp." + icon_state = icon_state == icon_living ? "sharkdragon" : "sharkdragon_dead" + icon_living = "sharkdragon" + icon_dead = "sharkdragon_dead" + if(mind && mind.get_skill_level(/datum/skill/fishing) < SKILL_LEVEL_APPRENTICE) + mind.set_level(/datum/skill/fishing, SKILL_LEVEL_APPRENTICE, TRUE) + client?.give_award(/datum/award/achievement/misc/sharkdragon, src) + update_appearance() + /// Allows the space dragon to pick a funny name /mob/living/basic/space_dragon/proc/rename_dragon() var/chosen_name = sanitize_name(reject_bad_text(tgui_input_text(src, "What would you like your name to be?", "Choose Your Name", real_name, MAX_NAME_LEN))) @@ -125,9 +155,9 @@ icon_state = icon_living return if (HAS_TRAIT(src, TRAIT_WING_BUFFET_TIRED)) - icon_state = "spacedragon_gust_2" + icon_state = "[icon_living]_gust_2" return - icon_state = "spacedragon_gust" + icon_state = "[icon_living]_gust" /mob/living/basic/space_dragon/update_overlays() . = ..() @@ -139,7 +169,7 @@ else if (HAS_TRAIT(src, TRAIT_WING_BUFFET)) overlay_state = "overlay_gust" - var/mutable_appearance/overlay = mutable_appearance(icon, overlay_state) + var/mutable_appearance/overlay = mutable_appearance(icon, "[icon_living]_[overlay_state]") overlay.appearance_flags = RESET_COLOR . += overlay @@ -157,6 +187,8 @@ if (DOING_INTERACTION(source, DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION)) balloon_alert(source, "busy!") return COMPONENT_HOSTILE_NO_ATTACK + if(isfish(target)) + INVOKE_ASYNC(src, PROC_REF(try_eat), target) if (!isliving(target)) return var/mob/living/living_target = target @@ -166,14 +198,23 @@ return COMPONENT_HOSTILE_NO_ATTACK /// Try putting something inside us -/mob/living/basic/space_dragon/proc/try_eat(mob/living/food) +/mob/living/basic/space_dragon/proc/try_eat(atom/movable/food) balloon_alert(src, "swallowing...") if (do_after(src, 3 SECONDS, target = food)) - eat(food) + if(isliving(food)) + eat(food) + else if(isfish(food)) + eat_fish(food) /// Succeed in putting something inside us /mob/living/basic/space_dragon/proc/eat(mob/living/food) - adjust_health(-food.maxHealth * 0.25) + var/health_recovered = food.maxHealth * 0.25 + if(shark_form) + if(istype(food, /mob/living/basic/carp)) + health_recovered *= 1.75 // plus 7.5 points when eating advanced space carps (from the rift) + else + health_recovered *= 0.75 // minus 7.5 points when eating a human for example. + adjust_health(round(-health_recovered, 1)) if (QDELETED(food) || food.loc == src) return FALSE playsound(src, 'sound/effects/magic/demon_attack1.ogg', 60, TRUE) @@ -182,6 +223,43 @@ food.forceMove(src) return TRUE +/mob/living/basic/space_dragon/proc/eat_fish(obj/item/fish/fish) + //a standard fish weights about 500 units on average, rarely exceeds 2000 units, the amount healed is less than a one fiftyth of our total on average. + var/health_recovered = fish.weight * 0.014 + if(shark_form) + health_recovered *= 2 + else + fish_left -= fish.weight + if(fish_left <= 0) + addtimer(CALLBACK(src, PROC_REF(begin_sharkify)), 2 SECONDS) + fish_left = initial(fish_left) //prevent begin_sharkify from being called again by eating another fish. + adjust_health(round(-health_recovered, 1)) + playsound(src, 'sound/effects/magic/demon_attack1.ogg', 40, TRUE) + visible_message(span_boldwarning("[src] swallows [fish] whole!")) + if(HAS_TRAIT(fish, TRAIT_YUCKY_FISH)) + balloon_alert(src, "disgusting!") + to_chat(src, span_warning("that [fish.name] tasted awful, you feel like you're about to throw up...")) + addtimer(CALLBACK(src, PROC_REF(barf_contents)), 3 SECONDS) + qdel(fish) + +/mob/living/basic/space_dragon/proc/begin_sharkify() + do_jitter_animation(300) + addtimer(CALLBACK(src, PROC_REF(sharkify)), 1.2 SECONDS) + visible_message(span_warning("[src] begins mutating!")) + +/mob/living/basic/space_dragon/proc/barf_contents() + if(stat == DEAD) + return + new /obj/effect/decal/cleanable/vomit(loc) + playsound(src, 'sound/effects/splat.ogg', vol = 50, vary = TRUE) + visible_message(span_danger("[src] vomits up everything it ate so far!")) + for(var/atom/movable/eaten in src) + if(HAS_TRAIT(eaten, TRAIT_NOT_BARFABLE)) + continue + eaten.forceMove(eaten.loc) + if(prob(90)) + step(eaten, pick(GLOB.alldirs)) + /mob/living/basic/space_dragon/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs) . = ..() if (isliving(arrived)) @@ -230,5 +308,10 @@ . = ..() mind.add_antag_datum(/datum/antagonist/space_dragon) +/// The internal fishing rod of our space dragon +/obj/item/fishing_rod/mob_fisher/dragon + difficulty_modifier = -14 + hook = /obj/item/fishing_hook/jaws + #undef REJECT_DARK_COLOUR_THRESHOLD #undef DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION diff --git a/icons/hud/radial_fishing.dmi b/icons/hud/radial_fishing.dmi index 90b2b17c83a..d77d9064882 100644 Binary files a/icons/hud/radial_fishing.dmi and b/icons/hud/radial_fishing.dmi differ diff --git a/icons/mob/nonhuman-player/spacedragon.dmi b/icons/mob/nonhuman-player/spacedragon.dmi index a1f3d4d782b..a453b4441e3 100644 Binary files a/icons/mob/nonhuman-player/spacedragon.dmi and b/icons/mob/nonhuman-player/spacedragon.dmi differ diff --git a/icons/obj/aquarium/fish.dmi b/icons/obj/aquarium/fish.dmi index eec60317b0e..deabb8c7a36 100644 Binary files a/icons/obj/aquarium/fish.dmi and b/icons/obj/aquarium/fish.dmi differ diff --git a/icons/ui/achievements/achievements.dmi b/icons/ui/achievements/achievements.dmi index 740759467e0..8f6b9e1f42a 100644 Binary files a/icons/ui/achievements/achievements.dmi and b/icons/ui/achievements/achievements.dmi differ