Rift Fishing (#88619)
## About The Pull Request Adds rift fishing to the game.  Drained and undrained influences can be fished in, the latter only by heretics. Fishing in an undrained influence shows a bobber floating over nothing to other people, so don't be stupid! The loot pool includes the following: - Knowledge. Great for heretics, bad for crew. Only actually gives knowledge if fished up in an unopened rift, opening it. One of each heretic potion type. - A wild Fire Shark, hostile to all. - One of each heretic potion, and two flasks of eldritch essence. - Several new fish:  In order: 1. Chrystarfish Cosmostarfishe that snuck into the bluespace compartment of a shuttle engine. Teleports around when eaten. Can be cut into bluespace crystals. Very pointy. 2. Flumpulus Probably not an actual fish. Contains flumpuline, which is in many ways an upgrade to oculine. Except for it occasionally popping your eyes out and replacing them with fungus. It also gets flattened if you land on it, cushioning your fall.  3. Gullion This fish can be cut into two diamonds, and needs no mate to reproduce, making it an excellent way to replenish the station's diamond supply! However, it needs silicon in the fish tank to survive. 4. Walro-Dolphish Weird, amphibious creature. Amazing weapon - high damage, strong piercing wounds, decent block chances. However, it will bite you if you hold it for too long, so be careful! More fish are planned to be added. The PR was split in two to reduce review complexity as the latter half of the fish were increasingly convoluted. Any fishing rod will do for fishing, but heretics are now able to infuse their fishing rod with a grasp:  Infusing the rod will temporarily improve its fishing modifier and give it a unique trait that lets heretics gather 2 influence, rather than 1, from a fished-up rift. If crew fish up a glimpse of the Mansus, they will recieve the same effects as if they examined the rift, and a curse hand will shoot out at them. influences cannot be bombed for fish. ## Why It's Good For The Game Rifts are _extremely_ close to basically just being eldritch pools of liquid that some heretic spilled over the station. It's always stuck out like a sore thumb that we can't fish in them, but now we _can_. (Also, someone needs to PR fishing in a bucket for clowns and mimes.) Fishing in a rift is just one of those things you see some random, innocent assistant do while doing an errand, passively enhancing the round with the sheer ridiculousness of it. Coming back, it's likely you'll see them running from a wild Fire Shark they unwisely dug up from messing with eldritch influences. For Heretics, this is for the most part actively a worse alternative than just doing things normally. But sometimes you don't want to be optimal. Infusing their fishing rod is almost entirely an amusing twist on the blade infusion that blade path has, and they can even infuse other people's rods - make fish not war. Ghommie gave me the fish sprites, and I interpreted them the silliest and most interesting ways I could think of. > Chrystarfish Bluespace's technobabble has finally reached fish. Much like the Gullion, the intention here was primarily some additional, risky way to procure some amount of bluespace crystals and dust that doesn't depend on Mining to do their job, either for the station or for your own stupid plans. (Obviously mining is still the best way to get it, but it's not healthy for the game for them to be the ONLY way to do so!) >Flumpulus  Imagine taking a pill of 'Super oculine!' and suddenly your eyes pop out and are replaced with fungeyes. 10/10 >Gullion Diamonds are extremely scarce on the station and the only way to get more is by mining. I thought adding some rare, restricted way of getting more would be fun for the game, and encourage fish breeding. Parthenogenesis may be a bit much admittedly, but let's just see what happens > Walro-Dolphish The name for this thing kinda sucks. I like the idea of an amphibious fish-weapon like the pikes that actually kinda just hates being wielded around like a stick. It's also piercing to differentiate.  ## Changelog 🆑 Carlarc, Ghommie add: Adds rift fishing to the game. Includes new wacky fish! add: Drained and undrained influences can be fished in, the latter only by heretics. Fishing in an undrained influence shows a bobber floating over nothing to other people, so don't be stupid! add: influences cannot be bombed for fish. add: Heretics can now infuse their fishing rod, and fish for knowledge. /🆑 --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
@@ -4,6 +4,8 @@
|
||||
#define FISHING_RANDOM_SEED "Random seed"
|
||||
///Used in the surgery fishing spot to define a random organ reward
|
||||
#define FISHING_RANDOM_ORGAN "Random organ"
|
||||
///Used in the dimensional rift fishing spot to define influence gain
|
||||
#define FISHING_INFLUENCE "Influence"
|
||||
|
||||
// Baseline fishing difficulty levels
|
||||
#define FISHING_DEFAULT_DIFFICULTY 15
|
||||
@@ -272,6 +274,8 @@
|
||||
#define FISH_SOURCE_FLAG_NO_BLUESPACE_ROD (1<<1)
|
||||
/// When examined by someone with enough fishing skill, this will also display fish that doesn't have FISH_FLAG_SHOW_IN_CATALOG
|
||||
#define FISH_SOURCE_FLAG_IGNORE_HIDDEN_ON_CATALOG (1<<2)
|
||||
/// This fish source will not spawn fish on explosions
|
||||
#define FISH_SOURCE_FLAG_EXPLOSIVE_NONE (1<<3)
|
||||
|
||||
/**
|
||||
* A macro to ensure the wikimedia filenames of fish icons are unique, especially since there're a couple fish that have
|
||||
|
||||
@@ -806,6 +806,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_ROD_ATTRACT_SHINY_LOVERS "rod_attract_shiny_lovers"
|
||||
/// This rod can be used to fish on lava
|
||||
#define TRAIT_ROD_LAVA_USABLE "rod_lava_usable"
|
||||
/// This rod was infused by a heretic, making it awesome and improving influence gain
|
||||
#define TRAIT_ROD_MANSUS_INFUSED "rod_infused"
|
||||
/// Stuff that can go inside fish cases and aquariums
|
||||
#define TRAIT_AQUARIUM_CONTENT "aquarium_content"
|
||||
/// If the item can be used as a bit.
|
||||
@@ -1030,6 +1032,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
///fish traits
|
||||
#define TRAIT_FISH_STASIS "fish_stasis"
|
||||
#define TRAIT_FISH_FLOPPING "fish_flopping"
|
||||
#define TRAIT_RESIST_PSYCHIC "resist_psychic"
|
||||
#define TRAIT_RESIST_EMULSIFY "resist_emulsify"
|
||||
#define TRAIT_FISH_SELF_REPRODUCE "fish_self_reproduce"
|
||||
#define TRAIT_FISH_NO_MATING "fish_no_mating"
|
||||
|
||||
@@ -667,6 +667,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_FISH_QUICK_GROWTH" = TRAIT_FISH_QUICK_GROWTH,
|
||||
"TRAIT_FISH_TOXIN_IMMUNE" = TRAIT_FISH_TOXIN_IMMUNE,
|
||||
"TRAIT_RESIST_EMULSIFY" = TRAIT_RESIST_EMULSIFY,
|
||||
"TRAIT_RESIST_PSYCHIC" = TRAIT_RESIST_PSYCHIC,
|
||||
"TRAIT_FISH_WELL_COOKED" = TRAIT_FISH_WELL_COOKED,
|
||||
"TRAIT_YUCKY_FISH" = TRAIT_YUCKY_FISH,
|
||||
),
|
||||
@@ -675,6 +676,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_ROD_IGNORE_ENVIRONMENT" = TRAIT_ROD_IGNORE_ENVIRONMENT,
|
||||
"TRAIT_ROD_LAVA_USABLE" = TRAIT_ROD_LAVA_USABLE,
|
||||
"TRAIT_ROD_REMOVE_FISHING_DUD" = TRAIT_ROD_REMOVE_FISHING_DUD,
|
||||
"TRAIT_ROD_MANSUS_INFUSED" = TRAIT_ROD_MANSUS_INFUSED,
|
||||
),
|
||||
/obj/item/integrated_circuit = list(
|
||||
"TRAIT_CIRCUIT_UI_OPEN" = TRAIT_CIRCUIT_UI_OPEN,
|
||||
|
||||
@@ -379,6 +379,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
|
||||
"TRAIT_ROD_IGNORE_ENVIRONMENT" = TRAIT_ROD_IGNORE_ENVIRONMENT,
|
||||
"TRAIT_ROD_LAVA_USABLE" = TRAIT_ROD_LAVA_USABLE,
|
||||
"TRAIT_ROD_REMOVE_FISHING_DUD" = TRAIT_ROD_REMOVE_FISHING_DUD,
|
||||
"TRAIT_ROD_MANSUS_INFUSED" = TRAIT_ROD_MANSUS_INFUSED,
|
||||
),
|
||||
/obj/item/organ/liver = list(
|
||||
"TRAIT_BALLMER_SCIENTIST" = TRAIT_BALLMER_SCIENTIST,
|
||||
|
||||
@@ -187,6 +187,7 @@
|
||||
damagetype = STAMINA,
|
||||
)
|
||||
to_chat(victim, span_userdanger("[weapon] embedded in your [limb.plaintext_zone] jostles and stings!"))
|
||||
embed_data.jostle_callback?.Invoke(victim, weapon, embed_data)
|
||||
|
||||
|
||||
/// Called when then item randomly falls out of a carbon. This handles the damage and descriptors, then calls safe_remove()
|
||||
|
||||
@@ -6,37 +6,42 @@
|
||||
*
|
||||
* It's an element that squishes things. After the duration passes, it reverses the transformation it squished with, taking into account if they are a different orientation than they started (read: rotationally-fluid)
|
||||
*
|
||||
* Normal squishes apply vertically, as if the target is being squished from above, but you can set reverse to TRUE if you want to squish them from the sides, like if they pancake into a wall from the East or West
|
||||
* Normal squishes apply vertically, as if the target is being squished from above, but you can set horizontal_squish to TRUE if you want to squish them from the sides, like if they pancake into a wall from the East or West
|
||||
*/
|
||||
/datum/element/squish
|
||||
element_flags = ELEMENT_DETACH_ON_HOST_DESTROY
|
||||
|
||||
/datum/element/squish/Attach(datum/target, duration=20 SECONDS, reverse=FALSE)
|
||||
/datum/element/squish/Attach(atom/target, duration=20 SECONDS, horizontal_squish=FALSE)
|
||||
. = ..()
|
||||
if(!iscarbon(target))
|
||||
|
||||
if(!isatom(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
|
||||
var/mob/living/carbon/C = target
|
||||
var/was_lying = C.body_position == LYING_DOWN
|
||||
addtimer(CALLBACK(src, PROC_REF(Detach), C, was_lying, reverse), duration)
|
||||
var/was_lying = FALSE
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/carboniucus = target
|
||||
was_lying = carboniucus.body_position == LYING_DOWN
|
||||
addtimer(CALLBACK(src, PROC_REF(Detach), target, was_lying, horizontal_squish), duration)
|
||||
|
||||
if(reverse)
|
||||
C.transform = C.transform.Scale(SHORT, TALL)
|
||||
if(horizontal_squish)
|
||||
target.transform = target.transform.Scale(SHORT, TALL)
|
||||
else
|
||||
C.transform = C.transform.Scale(TALL, SHORT)
|
||||
target.transform = target.transform.Scale(TALL, SHORT)
|
||||
|
||||
/datum/element/squish/Detach(mob/living/carbon/C, was_lying, reverse)
|
||||
/datum/element/squish/Detach(atom/target, was_lying, horizontal_squish)
|
||||
. = ..()
|
||||
if(istype(C))
|
||||
var/is_lying = C.body_position == LYING_DOWN
|
||||
var/is_lying = FALSE
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/carboniucus = target
|
||||
is_lying = carboniucus.body_position == LYING_DOWN
|
||||
|
||||
if(reverse)
|
||||
is_lying = !is_lying
|
||||
if(horizontal_squish)
|
||||
is_lying = !is_lying
|
||||
|
||||
if(was_lying == is_lying)
|
||||
C.transform = C.transform.Scale(SHORT, TALL)
|
||||
else
|
||||
C.transform = C.transform.Scale(TALL, SHORT)
|
||||
if(was_lying == is_lying)
|
||||
target.transform = target.transform.Scale(SHORT, TALL)
|
||||
else
|
||||
target.transform = target.transform.Scale(TALL, SHORT)
|
||||
|
||||
#undef SHORT
|
||||
#undef TALL
|
||||
|
||||
@@ -35,6 +35,8 @@ GLOBAL_LIST_INIT(embed_by_type, generate_embed_type_cache())
|
||||
var/jostle_chance = 5
|
||||
/// Coefficient of multiplication for the damage the item does while
|
||||
var/jostle_pain_mult = 1
|
||||
/// Call this proc on jostling, if it exists!
|
||||
var/datum/callback/jostle_callback
|
||||
/// This percentage of all pain will be dealt as stam damage rather than brute (0-1)
|
||||
var/pain_stam_pct = 0
|
||||
|
||||
@@ -51,5 +53,6 @@ GLOBAL_LIST_INIT(embed_by_type, generate_embed_type_cache())
|
||||
data.ignore_throwspeed_threshold = !isnull(ignore_throwspeed_threshold) ? ignore_throwspeed_threshold : src.ignore_throwspeed_threshold
|
||||
data.jostle_chance = !isnull(jostle_chance) ? jostle_chance : src.jostle_chance
|
||||
data.jostle_pain_mult = !isnull(jostle_pain_mult) ? jostle_pain_mult : src.jostle_pain_mult
|
||||
data.jostle_callback = !isnull(jostle_callback) ? jostle_callback : src.jostle_callback
|
||||
data.pain_stam_pct = !isnull(pain_stam_pct) ? pain_stam_pct : src.pain_stam_pct
|
||||
return data
|
||||
|
||||
@@ -122,9 +122,14 @@
|
||||
|
||||
/datum/mood_event/heretics
|
||||
description = "THE HIGHER I RISE, THE MORE I SEE."
|
||||
mood_change = 10 //maybe being a cultist isnt that bad after all
|
||||
mood_change = 10 //maybe being a heretic isnt that bad after all
|
||||
hidden = TRUE
|
||||
|
||||
/datum/mood_event/rift_fishing
|
||||
description = "THE MORE I FISH, THE HIGHER I RISE."
|
||||
mood_change = 7
|
||||
timeout = 5 MINUTES
|
||||
|
||||
/datum/mood_event/family_heirloom
|
||||
description = "My family heirloom is safe with me."
|
||||
mood_change = 1
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
/obj/effect/visible_heretic_influence/Initialize(mapload)
|
||||
. = ..()
|
||||
addtimer(CALLBACK(src, PROC_REF(show_presence)), 15 SECONDS)
|
||||
AddComponent(/datum/component/fishing_spot, GLOB.preset_fish_sources[/datum/fish_source/dimensional_rift])
|
||||
|
||||
var/image/silicon_image = image('icons/effects/eldritch.dmi', src, null, OBJ_LAYER)
|
||||
silicon_image.override = TRUE
|
||||
@@ -175,6 +176,7 @@
|
||||
|
||||
AddElement(/datum/element/block_turf_fingerprints)
|
||||
AddComponent(/datum/component/redirect_attack_hand_from_turf, interact_check = CALLBACK(src, PROC_REF(verify_user_can_see)))
|
||||
AddComponent(/datum/component/fishing_spot, GLOB.preset_fish_sources[/datum/fish_source/dimensional_rift])
|
||||
|
||||
/obj/effect/heretic_influence/proc/verify_user_can_see(mob/user)
|
||||
return (user.mind in GLOB.reality_smash_track.tracked_heretics)
|
||||
|
||||
@@ -109,9 +109,10 @@
|
||||
bloodiest_wound.adjust_blood_flow(-0.5 * seconds_between_ticks)
|
||||
|
||||
/// Torment the target with a frightening hand
|
||||
/proc/fire_curse_hand(mob/living/carbon/victim)
|
||||
/proc/fire_curse_hand(mob/living/carbon/victim, turf/forced_turf)
|
||||
var/grab_dir = turn(victim.dir, pick(-90, 90, 180, 180)) // Not in front, favour behind
|
||||
var/turf/spawn_turf = get_ranged_target_turf(victim, grab_dir, 8)
|
||||
spawn_turf = forced_turf ? forced_turf : spawn_turf
|
||||
if (isnull(spawn_turf))
|
||||
return
|
||||
new /obj/effect/temp_visual/dir_setting/curse/grasp_portal(spawn_turf, victim.dir)
|
||||
|
||||
@@ -25,6 +25,39 @@ GLOBAL_LIST_INIT(heretic_start_knowledge, initialize_starting_knowledge())
|
||||
cost = 0
|
||||
is_starting_knowledge = TRUE
|
||||
|
||||
// Heretics can enhance their fishing rods to fish better - fishing content.
|
||||
// Lasts until succesfully fishing something up.
|
||||
/datum/heretic_knowledge/spell/basic/on_gain(mob/user, datum/antagonist/heretic/our_heretic)
|
||||
..()
|
||||
RegisterSignal(user, COMSIG_TOUCH_HANDLESS_CAST, PROC_REF(on_grasp_cast))
|
||||
|
||||
/datum/heretic_knowledge/spell/basic/proc/on_grasp_cast(mob/living/carbon/cast_on, datum/action/cooldown/spell/touch/touch_spell)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
// Not a grasp, we dont want this to activate with say star or mending touch.
|
||||
if(!istype(touch_spell, action_to_add))
|
||||
return NONE
|
||||
|
||||
var/obj/item/fishing_rod/held_rod = cast_on.get_active_held_item()
|
||||
if(!istype(held_rod, /obj/item/fishing_rod) || HAS_TRAIT(held_rod, TRAIT_ROD_MANSUS_INFUSED))
|
||||
return NONE
|
||||
|
||||
INVOKE_ASYNC(cast_on, TYPE_PROC_REF(/atom/movable, say), message = "R'CH T'H F'SH!", forced = "fishing rod infusion invocation")
|
||||
playsound(cast_on, /datum/action/cooldown/spell/touch/mansus_grasp::sound, 15)
|
||||
cast_on.visible_message(span_notice("[cast_on] snaps [cast_on.p_their()] fingers next to [held_rod], covering it in a burst of purple flames!"))
|
||||
|
||||
ADD_TRAIT(held_rod, TRAIT_ROD_MANSUS_INFUSED, REF(held_rod))
|
||||
held_rod.difficulty_modifier -= 20
|
||||
RegisterSignal(held_rod, COMSIG_FISHING_ROD_CAUGHT_FISH, PROC_REF(unfuse))
|
||||
held_rod.add_filter("mansus_infusion", 2, list("type" = "outline", "color" = COLOR_VOID_PURPLE, "size" = 1))
|
||||
return COMPONENT_CAST_HANDLESS
|
||||
|
||||
/datum/heretic_knowledge/spell/basic/proc/unfuse(obj/item/fishing_rod/item, reward, mob/user)
|
||||
if(reward == FISHING_INFLUENCE || prob(35))
|
||||
item.remove_filter("mansus_infusion")
|
||||
REMOVE_TRAIT(item, TRAIT_ROD_MANSUS_INFUSED, REF(item))
|
||||
item.difficulty_modifier += 20
|
||||
|
||||
/**
|
||||
* The Living Heart heretic knowledge.
|
||||
*
|
||||
|
||||
@@ -386,6 +386,9 @@
|
||||
bites_amount++
|
||||
var/bites_to_finish = weight / FISH_WEIGHT_BITE_DIVISOR
|
||||
adjust_health(health - (initial(health) / bites_to_finish) * 3)
|
||||
flinch_on_eat(eater, feeder)
|
||||
|
||||
/obj/item/fish/proc/flinch_on_eat(mob/living/eater, mob/living/feeder)
|
||||
if(status == FISH_ALIVE && prob(50) && feeder.is_holding(src) && feeder.dropItemToGround(src))
|
||||
to_chat(feeder, span_warning("[src] slips out of your hands in pain!"))
|
||||
var/turf/target_turf = get_ranged_target_turf(get_turf(src), pick(GLOB.alldirs), 2)
|
||||
@@ -927,6 +930,9 @@
|
||||
stop_flopping()
|
||||
|
||||
/obj/item/fish/process(seconds_per_tick)
|
||||
do_fish_process(seconds_per_tick)
|
||||
|
||||
/obj/item/fish/proc/do_fish_process(seconds_per_tick)
|
||||
if(HAS_TRAIT(src, TRAIT_FISH_STASIS) || status != FISH_ALIVE)
|
||||
return
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits())
|
||||
|
||||
/// Proc used by both the predator and necrophage traits.
|
||||
/datum/fish_trait/proc/eat_fish(obj/item/fish/predator, obj/item/fish/prey)
|
||||
var/message = prey.status == FISH_DEAD ? "[src] eats [prey]'s carcass." : "[src] hunts down and eats [prey]."
|
||||
var/message = prey.status == FISH_DEAD ? "[predator] eats [prey]'s carcass." : "[predator] hunts down and eats [prey]."
|
||||
predator.loc.visible_message(span_warning(message))
|
||||
SEND_SIGNAL(prey, COMSIG_FISH_EATEN_BY_OTHER_FISH, predator)
|
||||
qdel(prey)
|
||||
@@ -286,11 +286,13 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits())
|
||||
/datum/fish_trait/emulsijack
|
||||
name = "Emulsifier"
|
||||
catalog_description = "This fish emits an invisible toxin that emulsifies other fish for it to feed on."
|
||||
var/list/resistance_traits = list(TRAIT_RESIST_EMULSIFY, TRAIT_FISH_TOXIN_IMMUNE)
|
||||
var/trait_to_add = TRAIT_RESIST_EMULSIFY
|
||||
|
||||
/datum/fish_trait/emulsijack/apply_to_fish(obj/item/fish/fish)
|
||||
. = ..()
|
||||
RegisterSignal(fish, COMSIG_FISH_LIFE, PROC_REF(emulsify))
|
||||
ADD_TRAIT(fish, TRAIT_RESIST_EMULSIFY, FISH_TRAIT_DATUM)
|
||||
ADD_TRAIT(fish, trait_to_add, FISH_TRAIT_DATUM)
|
||||
|
||||
/datum/fish_trait/emulsijack/proc/emulsify(obj/item/fish/source, seconds_per_tick)
|
||||
SIGNAL_HANDLER
|
||||
@@ -298,8 +300,9 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits())
|
||||
return
|
||||
var/emulsified = FALSE
|
||||
for(var/obj/item/fish/victim in source.loc)
|
||||
if(HAS_TRAIT(victim, TRAIT_RESIST_EMULSIFY) || HAS_TRAIT(victim, TRAIT_FISH_TOXIN_IMMUNE)) //no team killing
|
||||
continue
|
||||
for(var/trait in resistance_traits)
|
||||
if(HAS_TRAIT(victim, trait))
|
||||
continue
|
||||
victim.adjust_health(victim.health - 3 * seconds_per_tick) //the victim may heal a bit but this will quickly kill
|
||||
emulsified = TRUE
|
||||
if(emulsified)
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
grind_results = list(/datum/reagent/bluespace = 10)
|
||||
fillet_type = null
|
||||
fish_traits = list(/datum/fish_trait/antigrav, /datum/fish_trait/mixotroph)
|
||||
compatible_types = list(/obj/item/fish/starfish/chrystarfish)
|
||||
beauty = FISH_BEAUTY_GREAT
|
||||
|
||||
/obj/item/fish/starfish/Initialize(mapload, apply_qualities = TRUE)
|
||||
@@ -97,8 +98,11 @@
|
||||
|
||||
/obj/item/fish/starfish/update_overlays()
|
||||
. = ..()
|
||||
. += add_emissive()
|
||||
|
||||
/obj/item/fish/starfish/proc/add_emissive()
|
||||
if(status == FISH_ALIVE)
|
||||
. += emissive_appearance(icon, "starfish_emissive", src)
|
||||
return emissive_appearance(icon, "starfish_emissive", src)
|
||||
|
||||
///It spins, and dimly glows in the dark.
|
||||
/obj/item/fish/starfish/flop_animation()
|
||||
|
||||
@@ -0,0 +1,395 @@
|
||||
/obj/item/fish/starfish/chrystarfish
|
||||
name = "chrystarfish"
|
||||
fish_id = "chrystarfish"
|
||||
desc = "This is what happens when a cosmostarfish sneaks into the bluespace compartment of a hyperspace engine. Very pointy and damaging - leading cause of spaceship explosions in 2554."
|
||||
icon = 'icons/obj/aquarium/rift.dmi'
|
||||
dedicated_in_aquarium_icon = 'icons/obj/aquarium/rift.dmi'
|
||||
icon_state = "chrystarfish"
|
||||
force = 12
|
||||
sharpness = SHARP_POINTY
|
||||
wound_bonus = -10
|
||||
bare_wound_bonus = 15
|
||||
armour_penetration = 6
|
||||
demolition_mod = 1.2
|
||||
throwforce = 11
|
||||
throw_range = 8
|
||||
throw_speed = 4
|
||||
embed_type = /datum/embed_data/chrystarfish
|
||||
attack_verb_continuous = list("stabs", "jabs")
|
||||
attack_verb_simple = list("stab", "jab")
|
||||
hitsound = SFX_SHATTER
|
||||
pickup_sound = 'sound/items/handling/materials/glass_pick_up.ogg'
|
||||
drop_sound = 'sound/items/handling/materials/glass_drop.ogg'
|
||||
|
||||
sprite_width = 7
|
||||
sprite_height = 9
|
||||
|
||||
average_size = 40
|
||||
average_weight = 1500
|
||||
food = /datum/reagent/bluespace
|
||||
feeding_frequency = 10 MINUTES
|
||||
health = 50
|
||||
death_text = "%SRC splinters apart into shards!"
|
||||
random_case_rarity = FISH_RARITY_GOOD_LUCK_FINDING_THIS
|
||||
fillet_type = /obj/item/stack/ore/bluespace_crystal
|
||||
num_fillets = 3
|
||||
stable_population = 3
|
||||
compatible_types = list(/obj/item/fish/starfish)
|
||||
fish_traits = list(/datum/fish_trait/antigrav)
|
||||
beauty = FISH_BEAUTY_EXCELLENT
|
||||
fish_movement_type = /datum/fish_movement/accelerando
|
||||
fishing_difficulty_modifier = 15
|
||||
favorite_bait = list(/obj/item/stack/ore/bluespace_crystal)
|
||||
// something something bluespace
|
||||
electrogenesis_power = 9 MEGA JOULES
|
||||
|
||||
// Basically a ninja star that's highly likely to embed and teleports you around if you don't stop to remove it. However it doesn't deal that much damage!
|
||||
/datum/embed_data/chrystarfish
|
||||
pain_mult = 1
|
||||
embed_chance = 85
|
||||
fall_chance = 3
|
||||
pain_chance = 9
|
||||
impact_pain_mult = 1
|
||||
remove_pain_mult = 2
|
||||
rip_time = 1.5 SECONDS
|
||||
ignore_throwspeed_threshold = TRUE // basically shaped like a shuriken
|
||||
jostle_chance = 15
|
||||
jostle_pain_mult = 1
|
||||
// about to be set!
|
||||
jostle_callback = null
|
||||
|
||||
/datum/embed_data/chrystarfish/New()
|
||||
..()
|
||||
jostle_callback = CALLBACK(src, PROC_REF(teleport))
|
||||
|
||||
/datum/embed_data/chrystarfish/proc/teleport(mob/victim, atom/embed_parent, datum/embed_data/real_data)
|
||||
do_teleport(victim, get_turf(victim), 3, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
|
||||
victim.visible_message(span_danger("[victim] teleports as [embed_parent] jostles inside [victim.p_them()]!"))
|
||||
|
||||
/obj/item/fish/starfish/chrystarfish/set_status(new_status, silent)
|
||||
. = ..()
|
||||
if(new_status == FISH_DEAD)
|
||||
new fillet_type(get_turf(src))
|
||||
playsound(src, SFX_SHATTER, 50)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/fish/starfish/chrystarfish/add_emissive()
|
||||
return
|
||||
|
||||
/obj/item/fish/starfish/chrystarfish/get_base_edible_reagents_to_add()
|
||||
var/list/return_list = ..()
|
||||
return_list[/datum/reagent/bluespace] = 5
|
||||
return return_list
|
||||
|
||||
/obj/item/fish/starfish/chrystarfish/flinch_on_eat(mob/living/eater, mob/living/feeder)
|
||||
if(status != FISH_ALIVE)
|
||||
return
|
||||
to_chat(feeder, span_warning("[src] slips out of the spacetime in pain!"))
|
||||
|
||||
var/tp_range = 6 * clamp(weight/average_weight, 3, 9) // usually 6, plus or minus fish weight
|
||||
// teleports itself if on a turf otherwise its container - whatever it is
|
||||
do_teleport(isturf(loc) ? src : loc, get_turf(feeder), tp_range, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
|
||||
|
||||
/obj/item/fish/starfish/chrystarfish/suicide_act(mob/living/user)
|
||||
visible_message(span_suicide("[user] swallows [src] whole! It looks like they're trying to commit suicide!"))
|
||||
forceMove(user)
|
||||
// *everything*
|
||||
for(var/obj/thing in user.get_contents())
|
||||
if(QDELETED(thing) || istype(thing, /obj/item/bodypart/chest))
|
||||
continue // don't want a gib
|
||||
stoplag(0.1 SECONDS)
|
||||
playsound(src, 'sound/effects/phasein.ogg', 15, TRUE)
|
||||
do_teleport(thing, get_turf(user), 2, asoundin = null, channel = TELEPORT_CHANNEL_BLUESPACE)
|
||||
qdel(src)
|
||||
return MANUAL_SUICIDE
|
||||
|
||||
// Prevents the first 2 messages from spamming on each patience update.
|
||||
#define PATIENCE_FLINCH "PATIENCE_FLINCH"
|
||||
#define PATIENCE_UNCOMFY "PATIENCE_UNCOMFY"
|
||||
|
||||
/obj/item/fish/dolphish
|
||||
name = "walro-dolphish"
|
||||
fish_id = "walro-dolphish"
|
||||
desc = "Strange bloodthirsty apex predator from beyond. A powerful weapon, but it -hates- being held."
|
||||
icon = 'icons/obj/aquarium/wide.dmi'
|
||||
dedicated_in_aquarium_icon = 'icons/obj/aquarium/rift.dmi'
|
||||
icon_state = "dolphish"
|
||||
lefthand_file = 'icons/mob/inhands/fish_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/fish_righthand.dmi'
|
||||
force = 19
|
||||
sharpness = SHARP_POINTY
|
||||
wound_bonus = -5
|
||||
bare_wound_bonus = 20
|
||||
armour_penetration = 12
|
||||
block_chance = 33
|
||||
throwforce = 7
|
||||
throw_range = 4
|
||||
attack_verb_continuous = list("bites", "impales", "rams")
|
||||
attack_verb_simple = list("bite", "impale", "ram")
|
||||
hitsound = 'sound/items/weapons/bladeslice.ogg'
|
||||
block_sound = 'sound/items/weapons/parry.ogg'
|
||||
drop_sound = 'sound/mobs/non-humanoids/fish/fish_drop1.ogg'
|
||||
pickup_sound = SFX_FISH_PICKUP
|
||||
sound_vary = TRUE
|
||||
|
||||
base_pixel_x = -16
|
||||
pixel_x = -16
|
||||
sprite_width = 13
|
||||
sprite_height = 9
|
||||
|
||||
required_fluid_type = AQUARIUM_FLUID_AIR
|
||||
required_temperature_min = BODYTEMP_COLD_DAMAGE_LIMIT // you mean just like a human? that's odd...
|
||||
required_temperature_max = BODYTEMP_HEAT_DAMAGE_LIMIT
|
||||
food = /datum/reagent/blood
|
||||
health = 600 // apex predator
|
||||
random_case_rarity = FISH_RARITY_GOOD_LUCK_FINDING_THIS
|
||||
fillet_type = /obj/item/food/fishmeat/fish_tail
|
||||
num_fillets = 1
|
||||
stable_population = 3
|
||||
fish_traits = list(/datum/fish_trait/wary, /datum/fish_trait/carnivore, /datum/fish_trait/necrophage, /datum/fish_trait/predator, /datum/fish_trait/territorial, /datum/fish_trait/stinger)
|
||||
fish_movement_type = /datum/fish_movement/choppy
|
||||
fishing_difficulty_modifier = 30
|
||||
favorite_bait = list()
|
||||
disliked_bait = list()
|
||||
average_size = 150
|
||||
average_weight = 2750
|
||||
weight_size_deviation = 0.5
|
||||
safe_air_limits = list(
|
||||
/datum/gas/oxygen = list(12, 100),
|
||||
/datum/gas/nitrogen,
|
||||
/datum/gas/carbon_dioxide = list(0, 10),
|
||||
)
|
||||
min_pressure = HAZARD_LOW_PRESSURE
|
||||
max_pressure = HAZARD_HIGH_PRESSURE
|
||||
beauty = FISH_BEAUTY_GREAT
|
||||
/// Maximum patience for below var.
|
||||
var/max_patience = 20
|
||||
/// Counter of how much patience the fish currently has before it attacks its wielder.
|
||||
var/patience = 20
|
||||
/// Ensures the last warning fx isn't repeated
|
||||
var/last_effect
|
||||
|
||||
/obj/item/fish/dolphish/get_force_rank()
|
||||
var/multiplier = 1
|
||||
switch(w_class)
|
||||
if(WEIGHT_CLASS_TINY)
|
||||
multiplier = 0.35
|
||||
if(WEIGHT_CLASS_SMALL)
|
||||
multiplier = 0.5
|
||||
if(WEIGHT_CLASS_NORMAL)
|
||||
multiplier = 0.75
|
||||
// bulky is avergae
|
||||
if(WEIGHT_CLASS_HUGE)
|
||||
multiplier = 1.15
|
||||
if(WEIGHT_CLASS_GIGANTIC)
|
||||
multiplier = 1.35
|
||||
|
||||
if(status == FISH_DEAD)
|
||||
multiplier -= 0.35 // huge nerf if dead
|
||||
|
||||
force *= multiplier
|
||||
attack_speed *= multiplier
|
||||
demolition_mod *= multiplier
|
||||
block_chance *= multiplier
|
||||
armour_penetration *= multiplier
|
||||
wound_bonus *= multiplier
|
||||
bare_wound_bonus *= multiplier
|
||||
|
||||
/obj/item/fish/dolphish/do_fish_process(seconds_per_tick)
|
||||
. = ..()
|
||||
var/patience_reduction = 1
|
||||
|
||||
var/turf/onturf = get_turf(loc)
|
||||
//gas check
|
||||
var/datum/gas_mixture/turf_gasmix = onturf.return_air()
|
||||
// likes water, gets sleepy, gets very sleepy
|
||||
if(turf_gasmix.gases[/datum/gas/water_vapor] && turf_gasmix.gases[/datum/gas/water_vapor][MOLES] >= 5)
|
||||
patience_reduction *= 0.5
|
||||
if(turf_gasmix.gases[/datum/gas/nitrous_oxide] && turf_gasmix.gases[/datum/gas/nitrous_oxide][MOLES] >= 5)
|
||||
patience_reduction *= 0.25
|
||||
if(turf_gasmix.gases[/datum/gas/healium] && turf_gasmix.gases[/datum/gas/healium][MOLES] >= 5)
|
||||
patience_reduction *= 0.1
|
||||
|
||||
if(!ismob(loc))
|
||||
// dividing by the multiplier nets us an increasing value. happy dolphish gain patience quicker
|
||||
var/patience_bonus = (1 / patience_reduction)
|
||||
patience = clamp(patience + patience_bonus * seconds_per_tick, 0, max_patience)
|
||||
return
|
||||
|
||||
var/mob/living/moc = loc
|
||||
if(moc.mob_biotypes & MOB_AQUATIC)
|
||||
patience_reduction *= 0.6
|
||||
if(HAS_TRAIT(moc, TRAIT_IS_WET))
|
||||
patience_reduction *= 0.6
|
||||
|
||||
patience = clamp(patience - (patience_reduction * seconds_per_tick), 0, max_patience)
|
||||
|
||||
switch(patience)
|
||||
if(0)
|
||||
// No check, we always want sharky to bite jerky on 0
|
||||
moc.visible_message(span_bolddanger("[src] bites directly into [moc] and squirms away from [moc.p_their()] grasp!"), span_userdanger("[src] sinks its fangs into you!!"))
|
||||
moc.apply_damage(force, BRUTE, moc.get_active_hand(), wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness, attacking_item = src)
|
||||
forceMove(moc.drop_location())
|
||||
moc.painful_scream()
|
||||
patience = max_patience
|
||||
playsound(src, hitsound, 45)
|
||||
if(1 to 10)
|
||||
// No check, final warning as they struggle, also funny.
|
||||
visible_message(span_bolddanger("[src] thrashes against [moc]'s grasp!"))
|
||||
moc.shake_up_animation()
|
||||
if(10 to 15)
|
||||
if(last_effect == PATIENCE_FLINCH)
|
||||
return
|
||||
visible_message(span_danger("[src] flinches away from [moc]!"))
|
||||
moc.shake_up_animation()
|
||||
last_effect = PATIENCE_FLINCH
|
||||
if(15 to 20)
|
||||
if(last_effect == PATIENCE_UNCOMFY)
|
||||
return
|
||||
visible_message(span_notice("[src] seems uncomfortable in [moc]'s grasp."))
|
||||
last_effect = PATIENCE_UNCOMFY
|
||||
|
||||
return
|
||||
|
||||
#undef PATIENCE_FLINCH
|
||||
#undef PATIENCE_UNCOMFY
|
||||
|
||||
/obj/item/fish/flumpulus
|
||||
name = "flumpulus"
|
||||
fish_id = "flumpulus"
|
||||
desc = "You can hardly even guess as to how this possibly counts as a fish. Inexplicably, you get the feeling that it could serve as a fantastic way to cushion a fall."
|
||||
icon = 'icons/obj/aquarium/rift.dmi'
|
||||
dedicated_in_aquarium_icon = 'icons/obj/aquarium/rift.dmi'
|
||||
icon_state = "flumpulus"
|
||||
lefthand_file = 'icons/mob/inhands/fish_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/fish_righthand.dmi'
|
||||
attack_verb_continuous = list("splats", "splorts")
|
||||
attack_verb_simple = list("splat", "splort")
|
||||
|
||||
sprite_width = 10
|
||||
sprite_height = 9
|
||||
|
||||
required_fluid_type = AQUARIUM_FLUID_AIR
|
||||
required_temperature_min = 0
|
||||
required_temperature_max = INFINITY
|
||||
food = /datum/reagent/consumable/nutriment/fat
|
||||
random_case_rarity = FISH_RARITY_GOOD_LUCK_FINDING_THIS
|
||||
fillet_type = /obj/item/food/meat/slab/human/mutant/slime
|
||||
num_fillets = 2
|
||||
stable_population = 2
|
||||
fish_traits = list()
|
||||
fish_movement_type = /datum/fish_movement/slow
|
||||
fishing_difficulty_modifier = 22
|
||||
favorite_bait = list()
|
||||
disliked_bait = list()
|
||||
// twice as big, half as heavy
|
||||
average_size = 100
|
||||
average_weight = 500
|
||||
material_weight_mult = 1
|
||||
weight_size_deviation = 0.6
|
||||
safe_air_limits = list(
|
||||
/datum/gas/nitrogen,
|
||||
)
|
||||
min_pressure = 0
|
||||
max_pressure = HAZARD_HIGH_PRESSURE
|
||||
beauty = FISH_BEAUTY_UGLY
|
||||
|
||||
/obj/item/fish/flumpulus/suicide_act(mob/living/user)
|
||||
visible_message(span_suicide("[user] swallows [src] whole! It looks like they're trying to commit suicide!"))
|
||||
forceMove(user)
|
||||
. = MANUAL_SUICIDE
|
||||
for(var/i in 1 to rand(5, 15))
|
||||
addtimer(CALLBACK(src, PROC_REF(flump_attack), user), 0.4 SECONDS * i)
|
||||
|
||||
/obj/item/fish/flumpulus/proc/flump_attack(mob/living/user)
|
||||
var/obj/item/organ/eyes/eyes = user.get_organ_slot(ORGAN_SLOT_EYES)
|
||||
var/obj/item/organ/eyes/new_eyes = pick(list(/obj/item/organ/eyes/snail, /obj/item/organ/eyes/night_vision/mushroom))
|
||||
new_eyes = new new_eyes(user)
|
||||
new_eyes.Insert(user)
|
||||
playsound(user, 'sound/effects/cartoon_sfx/cartoon_pop.ogg', 50, TRUE)
|
||||
user.visible_message("[user]'s [eyes ? eyes : "eye holes"] suddenly sprout stalks and turn into [new_eyes]!")
|
||||
ASYNC
|
||||
user.emote("scream")
|
||||
sleep(5 SECONDS)
|
||||
if(!QDELETED(eyes))
|
||||
eyes.visible_message(span_danger("[eyes] rapidly turn to dust."))
|
||||
eyes.dust()
|
||||
|
||||
/obj/item/fish/flumpulus/get_base_edible_reagents_to_add()
|
||||
var/list/return_list = ..()
|
||||
//return_list[/datum/reagent/flumpulus_extract] = 10
|
||||
return_list[/datum/reagent/medicine/oculine/flumpuline] = 10
|
||||
return return_list
|
||||
|
||||
/obj/item/fish/flumpulus/intercept_zImpact(list/falling_movables, levels)
|
||||
. = ..()
|
||||
if(status == FISH_DEAD)
|
||||
return .
|
||||
|
||||
for(var/mob/living/fallen_mob in falling_movables)
|
||||
visible_message(span_danger("[src] flattens like a pancake as [fallen_mob] lands on top of it!"))
|
||||
adjust_health(initial(health) * 0.1) // very durable
|
||||
AddElement(/datum/element/squish, 15 SECONDS)
|
||||
fallen_mob.Paralyze(0.5 SECONDS)
|
||||
playsound(src, 'sound/effects/cartoon_sfx/cartoon_splat.ogg', 75)
|
||||
|
||||
return FALL_INTERCEPTED | FALL_NO_MESSAGE
|
||||
|
||||
/obj/item/fish/gullion
|
||||
name = "gullion"
|
||||
fish_id = "gullion"
|
||||
desc = "This crystalline fish is actually one of only two known silicon-based lifeforms.\
|
||||
It avoids death via oxygen-silicate reactions by organically shielding its exterior, allowing the thick scales to calcify into quartz and diamond, at the cost of rendering the fish functionally blind. \
|
||||
How xenomorphs manage is a complete mystery bordering on bullshit."
|
||||
icon = 'icons/obj/aquarium/rift.dmi'
|
||||
dedicated_in_aquarium_icon = 'icons/obj/aquarium/rift.dmi'
|
||||
icon_state = "gullion"
|
||||
lefthand_file = 'icons/mob/inhands/fish_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/fish_righthand.dmi'
|
||||
attack_verb_continuous = list("stabs", "jabs")
|
||||
attack_verb_simple = list("stab", "jab")
|
||||
hitsound = SFX_DEFAULT_FISH_SLAP
|
||||
pickup_sound = 'sound/items/handling/materials/glass_pick_up.ogg'
|
||||
drop_sound = 'sound/items/handling/materials/glass_drop.ogg'
|
||||
sprite_width = 7
|
||||
sprite_height = 5
|
||||
|
||||
food = /datum/reagent/silicon
|
||||
feeding_frequency = 30 SECONDS
|
||||
health = 160
|
||||
death_text = "%SRC calcifies."
|
||||
random_case_rarity = FISH_RARITY_GOOD_LUCK_FINDING_THIS
|
||||
fillet_type = /obj/item/stack/sheet/mineral/diamond
|
||||
num_fillets = 2
|
||||
stable_population = 3
|
||||
fish_traits = list(/datum/fish_trait/heavy, /datum/fish_trait/parthenogenesis) // this thing is a diamond farm
|
||||
beauty = FISH_BEAUTY_EXCELLENT
|
||||
fish_movement_type = /datum/fish_movement/slow
|
||||
favorite_bait = list(/obj/item/stack/sheet/mineral/diamond)
|
||||
fishing_difficulty_modifier = 22
|
||||
average_size = 30
|
||||
average_weight = 2000
|
||||
weight_size_deviation = 0.3
|
||||
safe_air_limits = list(
|
||||
/datum/gas/oxygen = list(0, 2), // does NOT like oxygen
|
||||
/datum/gas/water_vapor,
|
||||
)
|
||||
required_fluid_type = AQUARIUM_FLUID_SULPHWATEVER
|
||||
required_temperature_min = 0
|
||||
required_temperature_max = BODYTEMP_HEAT_DAMAGE_LIMIT
|
||||
min_pressure = HAZARD_LOW_PRESSURE
|
||||
max_pressure = WARNING_HIGH_PRESSURE
|
||||
|
||||
/obj/item/fish/gullion/suicide_act(mob/living/user)
|
||||
visible_message(span_suicide("[user] swallows [src] whole! It looks like they're trying to commit suicide!"))
|
||||
forceMove(user)
|
||||
var/datum/gas_mixture/environment = user.loc.return_air()
|
||||
var/oxygen_in_air = check_gases(environment.gases, list(/datum/gas/oxygen))
|
||||
if(!oxygen_in_air || (status == FISH_DEAD))
|
||||
visible_message(span_suicide("[user] chokes and dies! (Wait, from the fish or from lack of air?)"))
|
||||
return OXYLOSS
|
||||
|
||||
user.petrify(statue_timer = INFINITY)
|
||||
visible_message(span_suicide("[user]'s skin turns into quartz upon contact with the oxygen in the air!'"))
|
||||
qdel(src)
|
||||
return MANUAL_SUICIDE
|
||||
@@ -132,6 +132,13 @@
|
||||
. += "" //add a new line
|
||||
. += span_notice("Thanks to your fishing skills, you can examine it again for more in-depth information.")
|
||||
return
|
||||
if(HAS_TRAIT(src, TRAIT_ROD_MANSUS_INFUSED))
|
||||
if(IS_HERETIC(user))
|
||||
. += span_purple("This rod has been <b>infused</b> by a heretic, improving its ability to catch glimpses of the Mansus. And fish.")
|
||||
else
|
||||
. += span_purple("It's glowing an eerie purple...")
|
||||
else if(IS_HERETIC(user))
|
||||
. += span_purple("As a Heretic, you can infuse this fishing rod with your <b>Mansus Grasp</b> by activating the spell while wielding it, to enhance its fishing power.")
|
||||
|
||||
/obj/item/fishing_rod/examine_more(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -504,6 +504,8 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
|
||||
/datum/fish_source/proc/spawn_reward_from_explosion(atom/location, severity)
|
||||
SIGNAL_HANDLER
|
||||
if(fish_source_flags & FISH_SOURCE_FLAG_EXPLOSIVE_NONE)
|
||||
return
|
||||
var/multiplier = 1
|
||||
if(fish_source_flags & FISH_SOURCE_FLAG_EXPLOSIVE_MALUS)
|
||||
if(explosive_fishing_score <= 0)
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
radial_name = "Chasm"
|
||||
overlay_state = "portal_chasm"
|
||||
radial_state = "ground_hole"
|
||||
fish_source_flags = FISH_SOURCE_FLAG_EXPLOSIVE_NONE
|
||||
|
||||
/datum/fish_source/portal/ocean
|
||||
fish_table = list(
|
||||
@@ -295,7 +296,7 @@
|
||||
mover.long_jump_velocity_limit += rand(-100, 100)
|
||||
|
||||
///Cherry on top, fish caught from the randomizer portal also have (almost completely) random traits
|
||||
/datum/fish_source/portal/random/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot)
|
||||
/datum/fish_source/portal/random/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot, obj/item/fishing_rod/used_rod)
|
||||
if(!ispath(reward_path, /obj/item/fish))
|
||||
return ..()
|
||||
|
||||
@@ -342,9 +343,6 @@
|
||||
|
||||
return rod.hook.chasm_detritus_type
|
||||
|
||||
/datum/fish_source/chasm/spawn_reward_from_explosion(atom/location, severity)
|
||||
return //Spawned content would immediately fall back into the chasm, so it wouldn't matter.
|
||||
|
||||
/datum/fish_source/lavaland
|
||||
catalog_description = "Lava vents"
|
||||
background = "background_lavaland"
|
||||
@@ -582,7 +580,7 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/fish_source/hydro_tray/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot)
|
||||
/datum/fish_source/hydro_tray/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot, obj/item/fishing_rod/used_rod)
|
||||
if(reward_path != FISHING_RANDOM_SEED)
|
||||
var/mob/living/created_reward = ..()
|
||||
if(istype(created_reward))
|
||||
@@ -662,7 +660,7 @@
|
||||
//The range for waiting is also a bit narrower, so it cannot take as few as 3 seconds or as many as 25 to snatch an organ.
|
||||
wait_time_range = list(6 SECONDS, 12 SECONDS)
|
||||
|
||||
/datum/fish_source/surgery/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot)
|
||||
/datum/fish_source/surgery/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot, obj/item/fishing_rod/used_rod)
|
||||
if(istype(fishing_spot, /obj/machinery/fishing_portal_generator))
|
||||
var/obj/machinery/fishing_portal_generator/portal = fishing_spot
|
||||
fishing_spot = portal.current_linked_atom
|
||||
@@ -707,7 +705,7 @@
|
||||
fish_table = list(
|
||||
FISHING_DUD = 10,
|
||||
)
|
||||
fish_source_flags = FISH_SOURCE_FLAG_NO_BLUESPACE_ROD|FISH_SOURCE_FLAG_IGNORE_HIDDEN_ON_CATALOG
|
||||
fish_source_flags = FISH_SOURCE_FLAG_NO_BLUESPACE_ROD|FISH_SOURCE_FLAG_IGNORE_HIDDEN_ON_CATALOG|FISH_SOURCE_FLAG_EXPLOSIVE_NONE
|
||||
fishing_difficulty = FISHING_EASY_DIFFICULTY + 5
|
||||
|
||||
#undef RANDOM_AQUARIUM_FISH
|
||||
@@ -725,9 +723,6 @@
|
||||
return fish_table
|
||||
return table
|
||||
|
||||
/datum/fish_source/aquarium/spawn_reward_from_explosion(atom/location, severity)
|
||||
return //If the aquarium breaks, all fish are released anyway.
|
||||
|
||||
/datum/fish_source/aquarium/generate_wiki_contents(datum/autowiki/fish_sources/wiki)
|
||||
var/list/data = list()
|
||||
|
||||
@@ -775,3 +770,77 @@
|
||||
)
|
||||
fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 20
|
||||
fish_source_flags = FISH_SOURCE_FLAG_EXPLOSIVE_MALUS
|
||||
|
||||
/datum/fish_source/dimensional_rift
|
||||
catalog_description = null //it's a secret (sorta, I know you're reading this)
|
||||
radial_state = "cursed" // placeholder
|
||||
overlay_state = "portal_rift_2" // yeah good luck adaptin the rift sprite to this template. recolored randomizer's the best you're getting
|
||||
fish_table = list(
|
||||
FISHING_INFLUENCE = 6,
|
||||
/obj/item/fish/starfish/chrystarfish = 7,
|
||||
/obj/item/fish/dolphish = 7,
|
||||
/obj/item/fish/flumpulus = 7,
|
||||
/obj/item/fish/gullion = 7,
|
||||
/mob/living/basic/heretic_summon/fire_shark/wild = 3,
|
||||
/obj/item/eldritch_potion/crucible_soul = 1,
|
||||
/obj/item/eldritch_potion/duskndawn = 1,
|
||||
/obj/item/eldritch_potion/wounded = 1,
|
||||
/obj/item/reagent_containers/cup/beaker/eldritch = 2,
|
||||
)
|
||||
fish_counts = list(
|
||||
/mob/living/basic/heretic_summon/fire_shark/wild = 3,
|
||||
/obj/item/eldritch_potion/crucible_soul = 1,
|
||||
/obj/item/eldritch_potion/duskndawn = 1,
|
||||
/obj/item/eldritch_potion/wounded = 1,
|
||||
/obj/item/reagent_containers/cup/beaker/eldritch = 2,
|
||||
)
|
||||
fish_count_regen = list(
|
||||
/mob/living/basic/heretic_summon/fire_shark/wild = 3 MINUTES,
|
||||
/obj/item/eldritch_potion/crucible_soul = 5 MINUTES,
|
||||
/obj/item/eldritch_potion/duskndawn = 5 MINUTES,
|
||||
/obj/item/eldritch_potion/wounded = 5 MINUTES,
|
||||
/obj/item/reagent_containers/cup/beaker/eldritch = 2.5 MINUTES,
|
||||
)
|
||||
fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 35
|
||||
fish_source_flags = FISH_SOURCE_FLAG_EXPLOSIVE_NONE
|
||||
|
||||
/datum/fish_source/dimensional_rift/on_challenge_completed(mob/user, datum/fishing_challenge/challenge, success)
|
||||
. = ..()
|
||||
|
||||
if(challenge.reward_path != FISHING_INFLUENCE)
|
||||
return
|
||||
var/mob/living/carbon/human/human_user
|
||||
if(ishuman(user))
|
||||
human_user = user
|
||||
|
||||
user.visible_message(span_danger("[user] reels [user.p_their()] [challenge.used_rod] in, catching.. nothing?"), span_notice("You catch.. a glimpse into the workings of the Mansus itself!"))
|
||||
// Heretics that fish in the rift gain knowledge.
|
||||
if(IS_HERETIC(user))
|
||||
human_user?.add_mood_event("rift fishing", /datum/mood_event/rift_fishing)
|
||||
var/obj/effect/heretic_influence/fishfluence = challenge.location
|
||||
// But only if it's an open rift
|
||||
if(!istype(fishfluence))
|
||||
to_chat(user, span_notice("You glimpse something fairly uninteresting."))
|
||||
return
|
||||
fishfluence.after_drain(user)
|
||||
var/datum/antagonist/heretic/heretic_datum = GET_HERETIC(user)
|
||||
if(heretic_datum)
|
||||
heretic_datum.knowledge_points++
|
||||
to_chat(user, "[span_hear("You hear a whisper...")] [span_hypnophrase("THE HIGHER I RISE, THE MORE I FISH.")]")
|
||||
// They can also gain an extra influence point if they infused their rod.
|
||||
if(HAS_TRAIT(challenge.used_rod, TRAIT_ROD_MANSUS_INFUSED))
|
||||
heretic_datum.knowledge_points++
|
||||
to_chat(user, span_boldnotice("Your infused rod improves your knowledge gain!"))
|
||||
return
|
||||
|
||||
// Non-heretics instead go crazy
|
||||
human_user?.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10, 190)
|
||||
human_user?.add_mood_event("gates_of_mansus", /datum/mood_event/gates_of_mansus)
|
||||
// Hand fires at them from the location
|
||||
fire_curse_hand(user, get_turf(challenge.location))
|
||||
|
||||
// Handled above
|
||||
/datum/fish_source/dimensional_rift/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot)
|
||||
if(reward_path != FISHING_INFLUENCE)
|
||||
return ..()
|
||||
return
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
mob_size = MOB_SIZE_TINY
|
||||
speak_emote = list("screams")
|
||||
basic_mob_flags = DEL_ON_DEATH
|
||||
ai_controller = /datum/ai_controller/basic_controller/simple_hostile_obstacles
|
||||
|
||||
/mob/living/basic/heretic_summon/fire_shark/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -32,3 +33,6 @@
|
||||
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
|
||||
ADD_TRAIT(src, TRAIT_FREE_HYPERSPACE_MOVEMENT, INNATE_TRAIT)
|
||||
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
|
||||
|
||||
/mob/living/basic/heretic_summon/fire_shark/wild
|
||||
faction = list(FACTION_HOSTILE)
|
||||
|
||||
@@ -78,6 +78,8 @@ GLOBAL_LIST_EMPTY(features_by_species)
|
||||
var/obj/item/organ/heart/mutantheart = /obj/item/organ/heart
|
||||
///Replaces default lungs with a different organ
|
||||
var/obj/item/organ/lungs/mutantlungs = /obj/item/organ/lungs
|
||||
/// Smoker lungs for the quirk, overriden by certain species
|
||||
var/obj/item/organ/lungs/smoker_lungs = /obj/item/organ/lungs/smoker_lungs
|
||||
///Replaces default eyes with a different organ
|
||||
var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes
|
||||
///Replaces default ears with a different organ
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
id = SPECIES_ETHEREAL
|
||||
meat = /obj/item/food/meat/slab/human/mutant/ethereal
|
||||
mutantlungs = /obj/item/organ/lungs/ethereal
|
||||
smoker_lungs = /obj/item/organ/lungs/ethereal/ethereal_smoker
|
||||
mutantstomach = /obj/item/organ/stomach/ethereal
|
||||
mutanttongue = /obj/item/organ/tongue/ethereal
|
||||
mutantheart = /obj/item/organ/heart/ethereal
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
inherent_biotypes = MOB_HUMANOID|MOB_MINERAL
|
||||
inherent_respiration_type = RESPIRATION_PLASMA
|
||||
mutantlungs = /obj/item/organ/lungs/plasmaman
|
||||
smoker_lungs = /obj/item/organ/lungs/plasmaman/plasmaman_smoker
|
||||
mutanttongue = /obj/item/organ/tongue/bone/plasmaman
|
||||
mutantliver = /obj/item/organ/liver/bone/plasmaman
|
||||
mutantstomach = /obj/item/organ/stomach/bone/plasmaman
|
||||
|
||||
@@ -73,15 +73,22 @@
|
||||
#define DUST_ANIMATION_TIME 1.3 SECONDS
|
||||
|
||||
/**
|
||||
* This is the proc for turning a mob into ash.
|
||||
* This is the proc for turning an atom into ash.
|
||||
* Dusting robots does not eject the MMI, so it's a bit more powerful than gib()
|
||||
*
|
||||
* Arguments:
|
||||
* Arguments: (Only used for mobs)
|
||||
* * just_ash - If TRUE, ash will spawn where the mob was, as opposed to remains
|
||||
* * drop_items - Should the mob drop their items before dusting?
|
||||
* * force - Should this mob be FORCABLY dusted?
|
||||
*/
|
||||
/mob/living/proc/dust(just_ash, drop_items, force)
|
||||
/atom/movable/proc/dust(just_ash, drop_items, force)
|
||||
dust_animation()
|
||||
// since this is sometimes called in the middle of movement, allow half a second for movement to finish, ghosting to happen and animation to play.
|
||||
// Looks much nicer and doesn't cause multiple runtimes.
|
||||
QDEL_IN(src, DUST_ANIMATION_TIME)
|
||||
|
||||
/mob/living/dust(just_ash, drop_items, force)
|
||||
..()
|
||||
if(body_position == STANDING_UP)
|
||||
// keep us upright so the animation fits.
|
||||
ADD_TRAIT(src, TRAIT_FORCED_STANDING, TRAIT_GENERIC)
|
||||
@@ -93,10 +100,8 @@
|
||||
if(buckled)
|
||||
buckled.unbuckle_mob(src, force = TRUE)
|
||||
|
||||
dust_animation()
|
||||
addtimer(CALLBACK(src, PROC_REF(spawn_dust), just_ash), DUST_ANIMATION_TIME - 0.3 SECONDS)
|
||||
ghostize()
|
||||
QDEL_IN(src, DUST_ANIMATION_TIME) // since this is sometimes called in the middle of movement, allow half a second for movement to finish, ghosting to happen and animation to play. Looks much nicer and doesn't cause multiple runtimes.
|
||||
|
||||
/// Animates turning into dust.
|
||||
/// Does not delete src afterwards, BUT it will become invisible (and grey), so ensure you handle that yourself
|
||||
|
||||
@@ -3008,3 +3008,8 @@ GLOBAL_LIST_EMPTY(fire_appearances)
|
||||
/mob/living/proc/check_hit_limb_zone_name(hit_zone)
|
||||
if(has_limbs)
|
||||
return hit_zone
|
||||
|
||||
/mob/living/proc/painful_scream(force = FALSE)
|
||||
if(HAS_TRAIT(src, TRAIT_ANALGESIA) && !force)
|
||||
return
|
||||
INVOKE_ASYNC(src, PROC_REF(emote), "scream")
|
||||
|
||||
@@ -759,6 +759,63 @@
|
||||
if(affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags))
|
||||
. = UPDATE_MOB_HEALTH
|
||||
|
||||
/datum/reagent/medicine/oculine/flumpuline
|
||||
name = "Flumpuline"
|
||||
description = "Often confused for, or sold as, Oculine or a variation thereof. Slowly transmogrifies the eyes of the patient into grotesque stalks - but you'll never need glasses again."
|
||||
color = "#6c596d"
|
||||
metabolization_rate = 0.1 * REAGENTS_METABOLISM
|
||||
overdose_threshold = 5
|
||||
taste_description = "fungus"
|
||||
purity = 1
|
||||
ph = 0.01
|
||||
chemical_flags = REAGENT_DEAD_PROCESS|REAGENT_IGNORE_STASIS|REAGENT_NO_RANDOM_RECIPE|REAGENT_CAN_BE_SYNTHESIZED
|
||||
inverse_chem = /datum/reagent/inverse
|
||||
inverse_chem_val = 0
|
||||
var/static/list/eye_types = list(/obj/item/organ/eyes/snail, /obj/item/organ/eyes/night_vision/mushroom)
|
||||
|
||||
/datum/reagent/medicine/oculine/flumpuline/improve_eyesight(mob/living/carbon/affected_mob, obj/item/organ/eyes/eyes)
|
||||
delta_light = 200 //2x better than pure oculine
|
||||
eyes.lighting_cutoff += delta_light
|
||||
affected_mob.update_sight()
|
||||
|
||||
/datum/reagent/medicine/oculine/flumpuline/restore_eyesight(mob/living/carbon/affected_mob, obj/item/organ/eyes/eyes)
|
||||
eyes.lighting_cutoff -= delta_light
|
||||
affected_mob.update_sight()
|
||||
|
||||
/datum/reagent/medicine/oculine/flumpuline/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
|
||||
. = ..()
|
||||
var/obj/item/organ/eyes/eyes = affected_mob.get_organ_slot(ORGAN_SLOT_EYES)
|
||||
// if no eyes or inorganic do nothing. we let already changed eyes go because funny
|
||||
if(!eyes || !IS_ORGANIC_ORGAN(eyes))
|
||||
return .
|
||||
|
||||
if(!prob(2))
|
||||
return .
|
||||
|
||||
flump_eyes(affected_mob, eyes)
|
||||
|
||||
// Overdose causes constant eye popping
|
||||
/datum/reagent/medicine/oculine/flumpuline/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired)
|
||||
. = ..()
|
||||
if(!prob(25))
|
||||
return
|
||||
var/obj/item/organ/eyes/eyes = affected_mob.get_organ_slot(ORGAN_SLOT_EYES)
|
||||
|
||||
flump_eyes(affected_mob, eyes)
|
||||
|
||||
/datum/reagent/medicine/oculine/flumpuline/proc/flump_eyes(mob/affected_mob, obj/eyes)
|
||||
var/obj/item/organ/eyes/new_eyes = pick(eye_types)
|
||||
new_eyes = new new_eyes(affected_mob)
|
||||
new_eyes.Insert(affected_mob)
|
||||
playsound(affected_mob, 'sound/effects/cartoon_sfx/cartoon_pop.ogg', 50, TRUE)
|
||||
affected_mob.visible_message("[affected_mob]'s [eyes ? eyes : "eye holes"] suddenly sprout stalks and turn into [new_eyes]!")
|
||||
ASYNC
|
||||
affected_mob.emote("scream")
|
||||
sleep(5 SECONDS)
|
||||
if(!QDELETED(eyes))
|
||||
eyes.visible_message(span_danger("[eyes] rapidly turn to dust."))
|
||||
eyes.dust()
|
||||
|
||||
/datum/reagent/medicine/inacusiate
|
||||
name = "Inacusiate"
|
||||
description = "Rapidly repairs damage to the patient's ears to cure deafness, assuming the source of said deafness isn't from genetic mutations, chronic deafness, or a total defecit of ears." //by "chronic" deafness, we mean people with the "deaf" quirk
|
||||
|
||||
@@ -153,9 +153,9 @@
|
||||
return ..() | SPELL_NO_FEEDBACK | SPELL_NO_IMMEDIATE_COOLDOWN
|
||||
|
||||
/datum/action/cooldown/spell/touch/cast(mob/living/carbon/cast_on)
|
||||
if(SEND_SIGNAL(cast_on, COMSIG_TOUCH_HANDLESS_CAST) & COMPONENT_CAST_HANDLESS)
|
||||
if(SEND_SIGNAL(cast_on, COMSIG_TOUCH_HANDLESS_CAST, src) & COMPONENT_CAST_HANDLESS)
|
||||
StartCooldown()
|
||||
return ..()
|
||||
return
|
||||
|
||||
if(!QDELETED(attached_hand) && (attached_hand in cast_on.held_items))
|
||||
remove_hand(cast_on, reset_cooldown_after = TRUE)
|
||||
|
||||
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 29 KiB |
@@ -4234,6 +4234,7 @@
|
||||
#include "code\modules\fishing\fish\types\freshwater.dm"
|
||||
#include "code\modules\fishing\fish\types\holographic.dm"
|
||||
#include "code\modules\fishing\fish\types\mining.dm"
|
||||
#include "code\modules\fishing\fish\types\rift.dm"
|
||||
#include "code\modules\fishing\fish\types\ruins.dm"
|
||||
#include "code\modules\fishing\fish\types\saltwater.dm"
|
||||
#include "code\modules\fishing\fish\types\station.dm"
|
||||
|
||||