mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
What you wear and on what chair you sit on can now influence fishing difficulty (#86646)
## About The Pull Request A foreword, I had to refactor a few bits of shitcode my past self added first. For context, the "gone fishing" and "actively fishing" traits only had one source, which is the fishing challenge itself, ad there was no way to access the challenge from outside its code, except for a few weakrefs which were being used as sources for the aforementioned traits (the shitcode in a nutshell). There were also a few signals that I didn't like because they were being sent to the harder-to-access challenge datum rather than the user. So I scrapped the traits for a couple signals to send to the user, then added a global list as a mean to easily access the challenge datum, and lastly changed the code to accomodate the titled feature (and allow the challenge to recalculate its difficulty DURING the minigame phase) Moving on to the actual feature: I've added a component that can be added to objects on which mobs can be buckled to or items. When equipped in the right slots or buckled to, the object will adjust the difficulty of current and future fishing challenges by a certain amount (more often than not positive, but there're many exceptions) as long as the object isn't equipped or the user is unbuckled. I've been having some fun adding component to a ton of clothes in the game as well as chairs. Way too many objects to enumerate, so I'll give you the general idea: - each carp-themed article provides a slight positive modifier (easier) - some (not all) doctor-related garbs provide a marginal positive modifier each (fish doctor jokes) - floortile camo clothes have positive modifiers - Tuxedo, laceups, gowns provide negative modifier (more difficult) - utility garbs such as bio/bomb/rad hoods and suits are quite bad. Riot armor too. - boxing gloves are very, very bad. Insulated gloves and haul gauntlets are also very bad, to a lesser degree. - **tackle** gloves are good. (pun intended) - wizard garbs are good, because wizards are good at casting. (also a pun) - magboots slightly bad. Space suits bad. - Blindfolds and welding protection are also bad. Gas masks marginally bad. - Pirate attire is nice to have. (I just vibed a little on this one) - plastic chairs are quite versatile because they can be carried around, but the mime chair is the best, followed by ratvarian chairs. - Fishing toolboxes, analyzers and the fish catalog are a plus, because they can be held. - And the fishing hat, obviously (not as great as you'd think) Some of these may be subject to change depending on what people say. ## Why It's Good For The Game A hundred lines of fishing challenge code made ever-so-slightly less awful, and a way to modify fishing diffculty beside skills and bait. ## Changelog 🆑 add: Your current clothes and what chair you sit on can now influence the difficulty of fishing minigames. Having a bare minimum of fishing skill will let you distinguish which objects can help and which won't, so keep an eye out. Holding fishing toolboxes, fish analyzers or fish catalogs can also help. /🆑
This commit is contained in:
@@ -41,7 +41,7 @@
|
||||
|
||||
register_item_context()
|
||||
update_appearance()
|
||||
|
||||
AddComponent(/datum/component/adjust_fishing_difficulty, -3, ITEM_SLOT_HANDS)
|
||||
|
||||
/obj/item/fish_analyzer/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
custom_price = PAYCHECK_CREW * 2
|
||||
starting_content = "Lot of fish stuff" //book wrappers could use cleaning so this is not necessary
|
||||
|
||||
/obj/item/book/manual/fish_catalog/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/adjust_fishing_difficulty, -4, ITEM_SLOT_HANDS)
|
||||
|
||||
/obj/item/book/manual/fish_catalog/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
|
||||
@@ -53,6 +53,10 @@
|
||||
else
|
||||
long_jump_chance *= master.difficulty
|
||||
|
||||
/datum/fish_movement/proc/reset_difficulty_values()
|
||||
short_jump_chance = initial(short_jump_chance)
|
||||
long_jump_chance = initial(long_jump_chance)
|
||||
|
||||
///The main proc, called by minigame every SSfishing tick while it's in the 'active' phase.
|
||||
/datum/fish_movement/proc/move_fish(seconds_per_tick)
|
||||
times_fired++
|
||||
@@ -190,6 +194,12 @@
|
||||
plunging_speed += round(plunging_speed * master.difficulty * 0.03)
|
||||
fish_idle_velocity += plunging_speed //so it can be safely subtracted if the fish starts at the bottom.
|
||||
|
||||
/datum/fish_movement/plunger/reset_difficulty_values()
|
||||
. = ..()
|
||||
if(is_plunging)
|
||||
fish_idle_velocity -= plunging_speed
|
||||
plunging_speed = initial(plunging_speed)
|
||||
|
||||
/datum/fish_movement/plunger/move_fish(seconds_per_tick)
|
||||
var/fish_area = FISHING_MINIGAME_AREA - master.fish_height
|
||||
if(is_plunging)
|
||||
|
||||
@@ -288,6 +288,8 @@
|
||||
inhand_icon_state = "artistic_toolbox"
|
||||
material_flags = NONE
|
||||
custom_price = PAYCHECK_CREW * 3
|
||||
///How much holding this affects fishing difficulty
|
||||
var/fishing_modifier = -2
|
||||
|
||||
/obj/item/storage/toolbox/fishing/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -296,6 +298,7 @@
|
||||
/obj/item/fishing_rod,
|
||||
))
|
||||
atom_storage.exception_hold = exception_cache
|
||||
AddComponent(/datum/component/adjust_fishing_difficulty, -2, ITEM_SLOT_HANDS)
|
||||
|
||||
/obj/item/storage/toolbox/fishing/PopulateContents()
|
||||
new /obj/item/bait_can/worm(src)
|
||||
@@ -326,6 +329,7 @@
|
||||
desc = "Contains EVERYTHING (almost) you need for your fishing trip."
|
||||
icon_state = "gold"
|
||||
inhand_icon_state = "toolbox_gold"
|
||||
fishing_modifier = -7
|
||||
|
||||
/obj/item/storage/toolbox/fishing/master/PopulateContents()
|
||||
new /obj/item/fishing_rod/telescopic/master(src)
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
///The standard pixel height of the fish (minus a pixel on each direction for the sake of a better looking sprite)
|
||||
#define MINIGAME_FISH_HEIGHT 4
|
||||
|
||||
GLOBAL_LIST_EMPTY(fishing_challenges_by_user)
|
||||
|
||||
/datum/fishing_challenge
|
||||
/// When the ui minigame phase started
|
||||
var/start_time
|
||||
@@ -120,8 +122,10 @@
|
||||
RegisterSignal(comp.fish_source, COMSIG_FISHING_SOURCE_INTERRUPT_CHALLENGE, PROC_REF(interrupt_challenge))
|
||||
comp.fish_source.RegisterSignal(src, COMSIG_FISHING_CHALLENGE_ROLL_REWARD, TYPE_PROC_REF(/datum/fish_source, roll_reward_minigame))
|
||||
comp.fish_source.RegisterSignal(src, COMSIG_FISHING_CHALLENGE_GET_DIFFICULTY, TYPE_PROC_REF(/datum/fish_source, calculate_difficulty_minigame))
|
||||
comp.fish_source.RegisterSignal(src, COMSIG_FISHING_CHALLENGE_COMPLETED, TYPE_PROC_REF(/datum/fish_source, on_challenge_completed))
|
||||
comp.fish_source.RegisterSignal(user, COMSIG_MOB_COMPLETE_FISHING, TYPE_PROC_REF(/datum/fish_source, on_challenge_completed))
|
||||
background = comp.fish_source.background
|
||||
SEND_SIGNAL(user, COMSIG_MOB_BEGIN_FISHING, src)
|
||||
GLOB.fishing_challenges_by_user[user] = src
|
||||
|
||||
/// Enable special parameters
|
||||
if(rod.line)
|
||||
@@ -148,6 +152,7 @@
|
||||
completion_loss += user.mind?.get_skill_modifier(/datum/skill/fishing, SKILL_VALUE_MODIFIER)/5
|
||||
|
||||
/datum/fishing_challenge/Destroy(force)
|
||||
GLOB.fishing_challenges_by_user -= user
|
||||
if(!completed)
|
||||
complete(win = FALSE)
|
||||
if(fishing_line)
|
||||
@@ -192,7 +197,6 @@
|
||||
active_effects = bitfield_to_list(special_effects & FISHING_MINIGAME_ACTIVE_EFFECTS)
|
||||
// If fishing line breaks los / rod gets dropped / deleted
|
||||
RegisterSignal(used_rod, COMSIG_ITEM_ATTACK_SELF, PROC_REF(on_attack_self))
|
||||
ADD_TRAIT(user, TRAIT_GONE_FISHING, WEAKREF(src))
|
||||
user.add_mood_event("fishing", /datum/mood_event/fishing)
|
||||
RegisterSignal(user, COMSIG_MOB_CLICKON, PROC_REF(handle_click))
|
||||
start_baiting_phase()
|
||||
@@ -308,8 +312,6 @@
|
||||
if(phase == MINIGAME_PHASE)
|
||||
remove_minigame_hud()
|
||||
if(!QDELETED(user))
|
||||
UnregisterSignal(user, SIGNAL_REMOVETRAIT(TRAIT_GONE_FISHING))
|
||||
user.remove_traits(list(TRAIT_GONE_FISHING, TRAIT_ACTIVELY_FISHING), WEAKREF(src))
|
||||
if(start_time)
|
||||
var/seconds_spent = (world.time - start_time) * 0.1
|
||||
if(!(special_effects & FISHING_MINIGAME_RULE_NO_EXP))
|
||||
@@ -319,7 +321,7 @@
|
||||
if(win)
|
||||
if(reward_path != FISHING_DUD)
|
||||
playsound(location, 'sound/effects/bigsplash.ogg', 100)
|
||||
SEND_SIGNAL(src, COMSIG_FISHING_CHALLENGE_COMPLETED, user, win)
|
||||
SEND_SIGNAL(user, COMSIG_MOB_COMPLETE_FISHING, src, win)
|
||||
if(!QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
@@ -419,16 +421,41 @@
|
||||
var/damage = CEILING((world.time - start_time)/10 * FISH_DAMAGE_PER_SECOND, 1)
|
||||
reward.adjust_health(reward.health - damage)
|
||||
|
||||
///Get the difficulty and other variables, than start the minigame
|
||||
/datum/fishing_challenge/proc/start_minigame_phase(auto_reel = FALSE)
|
||||
/datum/fishing_challenge/proc/get_difficulty()
|
||||
var/list/difficulty_holder = list(0)
|
||||
SEND_SIGNAL(src, COMSIG_FISHING_CHALLENGE_GET_DIFFICULTY, reward_path, used_rod, user, difficulty_holder)
|
||||
difficulty = difficulty_holder[1]
|
||||
//If you manage to be so well-equipped and skilled to completely crush the difficulty, just skip to the reward.
|
||||
if(difficulty <= 0)
|
||||
complete(TRUE)
|
||||
return
|
||||
return FALSE
|
||||
difficulty = clamp(round(difficulty), FISHING_MINIMUM_DIFFICULTY, 100)
|
||||
return TRUE
|
||||
|
||||
/datum/fishing_challenge/proc/update_difficulty()
|
||||
if(phase != MINIGAME_PHASE)
|
||||
return
|
||||
var/old_difficulty = difficulty
|
||||
//early return if the difficulty is the same or we crush the minigame all the way to 0 difficulty
|
||||
if(!get_difficulty() || difficulty == old_difficulty)
|
||||
return
|
||||
bait_height = initial(bait_height)
|
||||
experience_multiplier -= difficulty * FISHING_SKILL_DIFFIULTY_EXP_MULT
|
||||
mover.reset_difficulty_values()
|
||||
adjust_to_difficulty()
|
||||
|
||||
/datum/fishing_challenge/proc/adjust_to_difficulty()
|
||||
mover.adjust_to_difficulty()
|
||||
bait_height -= round(difficulty * BAIT_HEIGHT_DIFFICULTY_MALUS)
|
||||
bait_pixel_height = round(MINIGAME_BAIT_HEIGHT * (bait_height/initial(bait_height)), 1)
|
||||
experience_multiplier += difficulty * FISHING_SKILL_DIFFIULTY_EXP_MULT
|
||||
fishing_hud.hud_bait.adjust_to_difficulty(src)
|
||||
|
||||
///Get the difficulty and other variables, than start the minigame
|
||||
/datum/fishing_challenge/proc/start_minigame_phase(auto_reel = FALSE)
|
||||
SEND_SIGNAL(user, COMSIG_MOB_BEGIN_FISHING_MINIGAME, src)
|
||||
if(!get_difficulty()) //we totalized 0 or less difficulty, instant win.
|
||||
return
|
||||
|
||||
if(difficulty > FISHING_DEFAULT_DIFFICULTY)
|
||||
completion -= MAX_FISH_COMPLETION_MALUS * (difficulty * 0.01)
|
||||
@@ -449,11 +476,6 @@
|
||||
else
|
||||
mover = new /datum/fish_movement(src)
|
||||
|
||||
mover.adjust_to_difficulty()
|
||||
|
||||
bait_height -= round(difficulty * BAIT_HEIGHT_DIFFICULTY_MALUS)
|
||||
bait_pixel_height = round(MINIGAME_BAIT_HEIGHT * (bait_height/initial(bait_height)), 1)
|
||||
|
||||
if(auto_reel)
|
||||
completion *= 1.3
|
||||
else
|
||||
@@ -471,11 +493,14 @@
|
||||
fish_position = rand(0, (FISHING_MINIGAME_AREA - fish_height) * 0.8)
|
||||
var/diff_dist = 100 + difficulty
|
||||
bait_position = clamp(round(fish_position + rand(-diff_dist, diff_dist) - bait_height * 0.5), 0, FISHING_MINIGAME_AREA - bait_height)
|
||||
|
||||
if(!prepare_minigame_hud())
|
||||
get_stack_trace("couldn't prepare minigame hud for a fishing challenge.") //just to be sure. This shouldn't happen.
|
||||
qdel(src)
|
||||
return
|
||||
ADD_TRAIT(user, TRAIT_ACTIVELY_FISHING, WEAKREF(src))
|
||||
|
||||
adjust_to_difficulty()
|
||||
|
||||
phase = MINIGAME_PHASE
|
||||
deltimer(next_phase_timer)
|
||||
if((FISHING_MINIGAME_RULE_KILL in special_effects) && ispath(reward_path,/obj/item/fish))
|
||||
@@ -483,7 +508,6 @@
|
||||
var/wait_time = (initial(fish.health) / FISH_DAMAGE_PER_SECOND) SECONDS
|
||||
addtimer(CALLBACK(src, PROC_REF(win_anyway)), wait_time, TIMER_DELETE_ME)
|
||||
start_time = world.time
|
||||
experience_multiplier += difficulty * FISHING_SKILL_DIFFIULTY_EXP_MULT
|
||||
|
||||
///Throws a stack with prefixed text.
|
||||
/datum/fishing_challenge/proc/get_stack_trace(init_text)
|
||||
@@ -709,18 +733,24 @@
|
||||
icon = 'icons/hud/fishing_hud.dmi'
|
||||
icon_state = "bait"
|
||||
vis_flags = VIS_INHERIT_ID
|
||||
///The stored value we used to squish the bar based on the difficulty
|
||||
var/current_vertical_transform
|
||||
|
||||
/atom/movable/screen/hud_bait/Initialize(mapload, datum/hud/hud_owner, datum/fishing_challenge/challenge)
|
||||
. = ..()
|
||||
if(!challenge || challenge.bait_pixel_height == MINIGAME_BAIT_HEIGHT)
|
||||
return
|
||||
var/static/icon_height
|
||||
if(!icon_height)
|
||||
var/list/icon_dimensions = get_icon_dimensions(icon)
|
||||
icon_height = icon_dimensions["height"]
|
||||
var/height_percent_diff = challenge.bait_pixel_height/MINIGAME_BAIT_HEIGHT
|
||||
transform = transform.Scale(1, height_percent_diff)
|
||||
pixel_z = -icon_height * (1 - height_percent_diff) * 0.5
|
||||
adjust_to_difficulty(challenge)
|
||||
|
||||
/atom/movable/screen/hud_bait/proc/adjust_to_difficulty(datum/fishing_challenge/challenge)
|
||||
if(current_vertical_transform)
|
||||
transform = transform.Scale(1, 1/current_vertical_transform)
|
||||
pixel_z = 0
|
||||
var/list/icon_dimensions = get_icon_dimensions(icon)
|
||||
var/icon_height = icon_dimensions["height"]
|
||||
current_vertical_transform = challenge.bait_pixel_height/MINIGAME_BAIT_HEIGHT
|
||||
transform = transform.Scale(1, current_vertical_transform)
|
||||
pixel_z = -icon_height * (1 - current_vertical_transform) * 0.5
|
||||
|
||||
/atom/movable/screen/hud_fish
|
||||
icon = 'icons/hud/fishing_hud.dmi'
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
|
||||
/obj/item/fishing_rod/add_item_context(obj/item/source, list/context, atom/target, mob/living/user)
|
||||
. = ..()
|
||||
var/gone_fishing = HAS_TRAIT(user, TRAIT_GONE_FISHING)
|
||||
var/gone_fishing = GLOB.fishing_challenges_by_user[user]
|
||||
if(currently_hooked || gone_fishing)
|
||||
context[SCREENTIP_CONTEXT_LMB] = (gone_fishing && spin_frequency) ? "Spin" : "Reel in"
|
||||
if(!gone_fishing)
|
||||
@@ -411,7 +411,7 @@
|
||||
|
||||
/// Ideally this will be replaced with generic slotted storage datum + display
|
||||
/obj/item/fishing_rod/proc/use_slot(slot, mob/user, obj/item/new_item)
|
||||
if(fishing_line || HAS_TRAIT(user, TRAIT_GONE_FISHING))
|
||||
if(fishing_line || GLOB.fishing_challenges_by_user[user])
|
||||
return
|
||||
var/obj/item/current_item
|
||||
switch(slot)
|
||||
@@ -545,7 +545,7 @@
|
||||
if(HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE))
|
||||
return
|
||||
//the fishing minigame uses the attack_self signal to let the user end it early without having to drop the rod.
|
||||
if(HAS_TRAIT(user, TRAIT_GONE_FISHING))
|
||||
if(GLOB.fishing_challenges_by_user[user])
|
||||
return COMPONENT_BLOCK_TRANSFORM
|
||||
|
||||
///Gives feedback to the user, makes it show up inhand, toggles whether it can be used for fishing.
|
||||
|
||||
@@ -222,21 +222,21 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
SEND_SIGNAL(src, COMSIG_FISHING_SOURCE_INTERRUPT_CHALLENGE, reason)
|
||||
|
||||
/**
|
||||
* Proc called when the COMSIG_FISHING_CHALLENGE_COMPLETED signal is sent.
|
||||
* Proc called when the COMSIG_MOB_COMPLETE_FISHING signal is sent.
|
||||
* Check if we've succeeded. If so, write into memory and dispense the reward.
|
||||
*/
|
||||
/datum/fish_source/proc/on_challenge_completed(datum/fishing_challenge/source, mob/user, success)
|
||||
/datum/fish_source/proc/on_challenge_completed(mob/user, datum/fishing_challenge/challenge, success)
|
||||
SIGNAL_HANDLER
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
UnregisterSignal(user, COMSIG_MOB_COMPLETE_FISHING)
|
||||
if(!success)
|
||||
return
|
||||
var/obj/item/fish/caught = source.reward_path
|
||||
user.add_mob_memory(/datum/memory/caught_fish, protagonist = user, deuteragonist = initial(caught.name))
|
||||
var/turf/fishing_spot = get_turf(source.float)
|
||||
var/atom/movable/reward = dispense_reward(source.reward_path, user, fishing_spot)
|
||||
if(source.used_rod)
|
||||
SEND_SIGNAL(source.used_rod, COMSIG_FISHING_ROD_CAUGHT_FISH, reward, user)
|
||||
source.used_rod.consume_bait(reward)
|
||||
var/turf/fishing_spot = get_turf(challenge.float)
|
||||
var/atom/movable/reward = dispense_reward(challenge.reward_path, user, fishing_spot)
|
||||
if(reward)
|
||||
user.add_mob_memory(/datum/memory/caught_fish, protagonist = user, deuteragonist = reward.name)
|
||||
SEND_SIGNAL(challenge.used_rod, COMSIG_FISHING_ROD_CAUGHT_FISH, reward, user)
|
||||
challenge.used_rod.consume_bait(reward)
|
||||
|
||||
/// Gives out the reward if possible
|
||||
/datum/fish_source/proc/dispense_reward(reward_path, mob/fisherman, turf/fishing_spot)
|
||||
|
||||
Reference in New Issue
Block a user