Skip to content

Commit

Permalink
Fishing UI resprite and bugfixes (#89267)
Browse files Browse the repository at this point in the history
## About The Pull Request

Fishing UI has received a major glowup:

https://github.com/user-attachments/assets/e255822c-9c2c-4e09-843d-20ea70f470f5

All fishing rods now have unique frames (with material rods' frames'
colors being based on their material), and most fishing sources now have
unique backgrounds. Completion bar now uses alpha filters, making it
much smoother, and bait bar is assembled from thin lines, which allows
us to avoid stretching it when we need to resize the bar.

Fixed experiments not unlinking after being completed, resulting in
infinitely stacking examine lines on advanced fishing rods.

Fish death messages now use more fitting span_warning.

Removed devious SS_POST_FIRE_TIMING from the fishing SS, as it made
sometimes the fishing SS only fire every ***two*** ticks instead of
every tick, despite passing 0.05s (1 tick) into its process() calls -
this flag only makes sense on heavy and costly subsystems, not on a
subsystem dedicated mostly to fishing minigames. This is required as now
instead of directly assigning coordinates (why???) fishing UI uses
animate() to control the bait bar and fish icons, making it much
smoother.

Also gave blue dough its own bait overlay and mansus rift its own portal
icon because why not.

## Why It's Good For The Game

Fishing UI didn't look very nice, and removing the subsystem flag makes
the game smoother.

## Changelog
:cl:
qol: Fishing minigame should be smoother now
fix: Fixed infinitely stacking examine lines on advanced fishing rods
image: Resprited fishing UI
image: Blue doughballs now have their own fishing rod overlay
image: Resprited mansus rift fishing portal overlay
/:cl:
  • Loading branch information
SmArtKar authored and Iajret committed Jan 30, 2025
1 parent 50e361b commit 51fdad3
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 37 deletions.
2 changes: 1 addition & 1 deletion code/controllers/subsystem/processing/fishing.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/// subsystem for the fishing minigame processing.
PROCESSING_SUBSYSTEM_DEF(fishing)
name = "Fishing"
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING
flags = SS_BACKGROUND
wait = 0.05 SECONDS // If you raise it to 0.1 SECONDS, you better also modify [datum/fish_movement/move_fish()]
///A list of cached fish icons
var/list/cached_fish_icons
Expand Down
1 change: 1 addition & 0 deletions code/game/objects/items/food/bait.dm
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
/obj/item/food/bait/doughball/synthetic
name = "synthetic doughball"
icon_state = "doughball_blue"
rod_overlay_icon_state = "dough_blue_overlay"
preserved_food = TRUE
show_on_wiki = FALSE //It's an abstract item.

Expand Down
1 change: 1 addition & 0 deletions code/modules/clothing/gloves/special.dm
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@
name = "athletics fishing gloves"
icon = /obj/item/clothing/gloves/fishing::icon
icon_state = /obj/item/clothing/gloves/fishing::icon_state
frame_state = "frame_athletic"
line = null
bait = null
ui_description = "A pair of gloves to fish without a fishing rod while training your athletics."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@
*/
/datum/component/experiment_handler/proc/link_experiment(datum/experiment/experiment)
if (can_select_experiment(experiment))
unlink_experiment()
selected_experiment = experiment
selected_experiment.on_selected(src)

Expand Down
2 changes: 1 addition & 1 deletion code/modules/fishing/fish/_fish.dm
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@
REMOVE_TRAIT(src, TRAIT_UNCOMPOSTABLE, INNATE_TRAIT)
stop_flopping()
if(!silent)
var/message = span_notice(replacetext(death_text, "%SRC", "[src]"))
var/message = span_warning(replacetext(death_text, "%SRC", "[src]"))
if(loc && HAS_TRAIT(loc, TRAIT_IS_AQUARIUM))
loc.visible_message(message)
else
Expand Down
71 changes: 42 additions & 29 deletions code/modules/fishing/fishing_minigame.dm
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,21 @@
/// The multiplier of how much the difficulty negatively impacts the bait height
#define BAIT_HEIGHT_DIFFICULTY_MALUS 1.3

///Defines to know how the bait is moving on the minigame slider.
/// Defines to know how the bait is moving on the minigame slider.
#define REELING_STATE_IDLE 0
#define REELING_STATE_UP 1
#define REELING_STATE_DOWN 2

///The pixel height of the minigame bar
/// The pixel height of the minigame bar
#define MINIGAME_SLIDER_HEIGHT 76
///The standard pixel height of the bait
/// The standard pixel height of the bait
#define MINIGAME_BAIT_HEIGHT 27
///The standard pixel height of the fish (minus a pixel on each direction for the sake of a better looking sprite)
/// How many pixels bottom and top parts of the bait take up
#define MINIGAME_BAIT_TOP_AND_BOTTOM_HEIGHT 6
/// 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
/// Pixel height of the completion bar
#define MINIGAME_COMPLETION_BAR_HEIGHT 80

GLOBAL_LIST_EMPTY(fishing_challenges_by_user)

Expand Down Expand Up @@ -640,7 +644,7 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)
mover.move_fish(seconds_per_tick)
move_bait(seconds_per_tick)
if(!QDELETED(fishing_hud))
update_visuals()
update_visuals(seconds_per_tick)

///The proc that handles fancy effects like flipping the hud or skewing movement
/datum/fishing_challenge/proc/select_active_effect()
Expand Down Expand Up @@ -759,20 +763,19 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)
return (fish_position + fish_height >= bait_position) && (bait_position + bait_height >= fish_position)

///update the vertical pixel position of both fish and bait, and the icon state of the completion bar
/datum/fishing_challenge/proc/update_visuals()
var/bait_offset_mult = bait_position/FISHING_MINIGAME_AREA
fishing_hud.hud_bait.pixel_y = round(MINIGAME_SLIDER_HEIGHT * bait_offset_mult, 1)
var/fish_offset_mult = fish_position/FISHING_MINIGAME_AREA
fishing_hud.hud_fish.pixel_y = round(MINIGAME_SLIDER_HEIGHT * fish_offset_mult, 1)
fishing_hud.hud_completion.icon_state = "completion_[FLOOR(completion, 5)]"
/datum/fishing_challenge/proc/update_visuals(seconds_per_tick)
var/bait_offset_mult = bait_position / FISHING_MINIGAME_AREA
animate(fishing_hud.hud_bait, pixel_y = MINIGAME_SLIDER_HEIGHT * bait_offset_mult, time = seconds_per_tick SECONDS)
var/fish_offset_mult = fish_position / FISHING_MINIGAME_AREA
animate(fishing_hud.hud_fish, pixel_y = MINIGAME_SLIDER_HEIGHT * fish_offset_mult, time = seconds_per_tick SECONDS)
fishing_hud.hud_completion.update_state(completion, seconds_per_tick)

///The screen object which bait, fish, and completion bar are visually attached to.
/atom/movable/screen/fishing_hud
icon = 'icons/hud/fishing_hud.dmi'
screen_loc = "CENTER+1:8,CENTER:2"
name = "fishing minigame"
appearance_flags = APPEARANCE_UI|KEEP_TOGETHER
alpha = 230
///The fish as shown in the minigame
var/atom/movable/screen/hud_fish/hud_fish
///The bait as shown in the minigame
Expand All @@ -783,12 +786,13 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)
///Initialize bait, fish and completion bar and add them to the visual appearance of this screen object.
/atom/movable/screen/fishing_hud/proc/prepare_minigame(datum/fishing_challenge/challenge)
icon_state = challenge.background
add_overlay("frame")
add_overlay(challenge.used_rod?.get_frame(challenge) || "frame_wood")
hud_bait = new(null, null, challenge)
hud_fish = new(null, null, challenge)
hud_completion = new(null, null, challenge)
hud_completion = new(null, null)
vis_contents += list(hud_bait, hud_fish, hud_completion)
challenge.user.client.screen += src
challenge.update_visuals(0) // Set all states to their initial positions so they don't jump around when the game starts
master_ref = WEAKREF(challenge)

/atom/movable/screen/fishing_hud/Destroy()
Expand All @@ -802,26 +806,31 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)

/atom/movable/screen/hud_bait
icon = 'icons/hud/fishing_hud.dmi'
icon_state = "bait"
icon_state = "bait_bottom"
vis_flags = VIS_INHERIT_ID
///The stored value we used to squish the bar based on the difficulty
var/current_vertical_transform
var/cur_height = MINIGAME_BAIT_HEIGHT

/atom/movable/screen/hud_bait/Initialize(mapload, datum/hud/hud_owner, datum/fishing_challenge/challenge)
. = ..()
if(!challenge || challenge.bait_pixel_height == MINIGAME_BAIT_HEIGHT)
update_icon()
return

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
cur_height = challenge.bait_pixel_height
update_icon()

/atom/movable/screen/hud_bait/update_overlays()
. = ..()
var/mutable_appearance/bait_top = mutable_appearance(icon, "bait_top")
bait_top.pixel_y += cur_height - MINIGAME_BAIT_TOP_AND_BOTTOM_HEIGHT
. += bait_top
for (var/i in 1 to (cur_height - MINIGAME_BAIT_TOP_AND_BOTTOM_HEIGHT))
var/mutable_appearance/bair_bar = mutable_appearance(icon, "bair_bar")
bair_bar.pixel_y += i
. += bair_bar

/atom/movable/screen/hud_fish
icon = 'icons/hud/fishing_hud.dmi'
Expand All @@ -835,13 +844,15 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)

/atom/movable/screen/hud_completion
icon = 'icons/hud/fishing_hud.dmi'
icon_state = "completion_0"
icon_state = "completion_overlay"
vis_flags = VIS_INHERIT_ID

/atom/movable/screen/hud_completion/Initialize(mapload, datum/hud/hud_owner, datum/fishing_challenge/challenge)
/atom/movable/screen/hud_completion/Initialize(mapload, datum/hud/hud_owner)
. = ..()
if(challenge)
icon_state = "completion_[FLOOR(challenge.completion, 5)]"
add_filter("completion_mask", 1, alpha_mask_filter(icon = icon(icon, "completion_overlay")))

/atom/movable/screen/hud_completion/proc/update_state(completion, seconds_per_tick)
animate(get_filter("completion_mask"), y = -MINIGAME_COMPLETION_BAR_HEIGHT * (1 - completion * 0.01), time = seconds_per_tick SECONDS)

/// The visual that appears over the fishing spot
/obj/effect/fishing_float
Expand Down Expand Up @@ -888,6 +899,8 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user)
#undef MINIGAME_SLIDER_HEIGHT
#undef MINIGAME_BAIT_HEIGHT
#undef MINIGAME_FISH_HEIGHT
#undef MINIGAME_BAIT_TOP_AND_BOTTOM_HEIGHT
#undef MINIGAME_COMPLETION_BAR_HEIGHT

#undef BAIT_HEIGHT_DIFFICULTY_MALUS

Expand Down
20 changes: 18 additions & 2 deletions code/modules/fishing/fishing_rod.dm
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,15 @@
/// The default color for the reel overlay if no line is equipped.
var/default_line_color = "gray"

///Is this currently being used by the profound fisher component?
/// Is this currently being used by the profound fisher component?
var/internal = FALSE

///The name of the icon state of the reel overlay
/// The name of the icon state of the reel overlay
var/reel_overlay = "reel_overlay"

/// Icon state of the frame overlay this rod uses for the minigame
var/frame_state = "frame_wood"

/**
* A list with two keys delimiting the spinning interval in which a mouse click has to be pressed while fishing.
* Inherited from baits, passed down to the minigame lure.
Expand Down Expand Up @@ -663,6 +666,9 @@
if(slot)
SEND_SIGNAL(gone, COMSIG_ITEM_FISHING_ROD_UNSLOTTED, src, slot)

/obj/item/fishing_rod/proc/get_frame(datum/fishing_challenge/challenge)
return mutable_appearance('icons/hud/fishing_hud.dmi', frame_state)

///Found in the fishing toolbox (the hook and line are separate items)
/obj/item/fishing_rod/unslotted
hook = null
Expand All @@ -681,6 +687,7 @@
icon_state = "fishing_rod_bone"
reel_overlay = "reel_bone"
default_line_color = "red"
frame_state = "frame_bone"
line = null //sinew line (usable to fish in lava) not included
hook = /obj/item/fishing_hook/bone

Expand All @@ -695,6 +702,7 @@
ui_description = "A collapsible fishing rod that can fit within a backpack."
wiki_description = "<b>It has to be bought from Cargo</b>."
reel_overlay = "reel_telescopic"
frame_state = "frame_telescopic"
completion_speed_mult = 1.1
bait_speed_mult = 1.1
deceleration_mult = 1.1
Expand Down Expand Up @@ -764,6 +772,7 @@
wiki_description = null
icon_state = "fishing_rod_master"
reel_overlay = "reel_master"
frame_state = "frame_master"
active_force = 13 //It's that sturdy
cast_range = 5
line = /obj/item/fishing_line/bouncy
Expand All @@ -783,6 +792,7 @@
wiki_description = "<b>It requires the Advanced Fishing Technology Node to be researched to be printed.</b>"
icon_state = "fishing_rod_science"
reel_overlay = "reel_science"
frame_state = "frame_science"
bait = /obj/item/food/bait/doughball/synthetic/unconsumable
completion_speed_mult = 1.1
bait_speed_mult = 1.1
Expand Down Expand Up @@ -819,6 +829,7 @@
desc = "A custom fishing rod from your local autolathe."
icon_state = "fishing_rod_material"
reel_overlay = "reel_material"
frame_state = "frame_material"
ui_description = "An autolathe-printable fishing rod made of some material."
wiki_description = "Different materials can have different effects. They also catch fish made of the same material used to print the rod."
material_flags = MATERIAL_EFFECTS|MATERIAL_AFFECT_STATISTICS|MATERIAL_COLOR|MATERIAL_ADD_PREFIX
Expand All @@ -831,6 +842,11 @@
. = ..()
name = "fishing rod" //so it doesn't reset to "material fishing rod"

/obj/item/fishing_rod/material/get_frame(datum/fishing_challenge/challenge)
var/mutable_appearance/frame = ..()
frame.color = color
return frame

#undef ROD_SLOT_BAIT
#undef ROD_SLOT_LINE
#undef ROD_SLOT_HOOK
Expand Down
19 changes: 15 additions & 4 deletions code/modules/fishing/sources/source_types.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
overlay_state = "portal_beach"

/datum/fish_source/ice_fishing
background = "background_ice"
catalog_description = "Ice-covered water"
radial_state = "ice"
overlay_state = "portal_ocean"
Expand Down Expand Up @@ -147,7 +148,7 @@
REMOVE_TRAIT(spot.parent, TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION, INNATE_TRAIT)

/datum/fish_source/portal/chasm
background = "background_lavaland"
background = "background_chasm"
fish_table = list(
FISHING_DUD = 5,
/obj/item/fish/chasm_crab = 10,
Expand Down Expand Up @@ -195,6 +196,7 @@
REMOVE_TRAIT(spot.parent, TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION, INNATE_TRAIT)

/datum/fish_source/portal/hyperspace
background = "background_space"
fish_table = list(
FISHING_DUD = 5,
/obj/item/fish/starfish = 6,
Expand Down Expand Up @@ -317,7 +319,7 @@

/datum/fish_source/chasm
catalog_description = "Chasm depths"
background = "background_lavaland"
background = "background_chasm"
radial_state = "ground_hole"
overlay_state = "portal_chasm"
fish_table = list(
Expand Down Expand Up @@ -370,6 +372,7 @@
return "You'll need reinforced fishing line to fish in there."

/datum/fish_source/lavaland/icemoon
background = "background_plasma"
catalog_description = "Liquid plasma vents"
radial_state = "plasma"
fish_table = list(
Expand All @@ -395,6 +398,7 @@
overlay_state = "portal_plasma"

/datum/fish_source/moisture_trap
background = "background_dank"
catalog_description = "Moisture trap basins"
radial_state = "garbage"
overlay_state = "portal_river" // placeholder
Expand All @@ -406,6 +410,7 @@
fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 20

/datum/fish_source/toilet
background = "background_dank"
catalog_description = "Station toilets"
radial_state = "toilet"
duds = list("ewww... nothing", "it was nothing", "it was toilet paper", "it was flushed away", "the hook is empty", "where's the damn money?!")
Expand Down Expand Up @@ -470,6 +475,7 @@
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)

/datum/fish_source/oil_well
background = "background_oil_well"
catalog_description = "Oil wells"
radial_state = "oil"
overlay_state = "portal_chasm" //close enough to pitch black
Expand All @@ -494,6 +500,7 @@
fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 25

/datum/fish_source/hydro_tray
background = "background_tray"
catalog_description = "Hydroponics trays"
radial_state = "hydro"
overlay_state = "portal_tray"
Expand Down Expand Up @@ -604,6 +611,7 @@
return new picked_path(spawn_location)

/datum/fish_source/carp_rift
background = "background_carp_rift"
catalog_description = "Space Dragon Rifts"
radial_state = "carp"
overlay_state = "portal_rift"
Expand All @@ -627,6 +635,7 @@
fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 28

/datum/fish_source/deepfryer
background = "background_lavaland"
catalog_description = "Deep Fryers"
radial_state = "fryer"
overlay_state = "portal_fry" // literally resprited lava. better than nothing
Expand Down Expand Up @@ -773,6 +782,7 @@
fish_source_flags = FISH_SOURCE_FLAG_EXPLOSIVE_MALUS

/datum/fish_source/vending
background = "background_chasm"
catalog_description = "Vending Machines"
radial_state = "vending"
overlay_state = "portal_randomizer"
Expand Down Expand Up @@ -943,9 +953,10 @@
return reward

/datum/fish_source/dimensional_rift
catalog_description = null //it's a secret (sorta, I know you're reading this)
background = "background_mansus"
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
overlay_state = "portal_mansus"
fish_table = list(
FISHING_INFLUENCE = 6,
FISHING_RANDOM_ARM = 3,
Expand Down
Binary file modified icons/hud/fishing_hud.dmi
Binary file not shown.
Binary file modified icons/obj/fishing.dmi
Binary file not shown.

0 comments on commit 51fdad3

Please sign in to comment.