mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-10 07:41:16 +01:00
21b4095dfd
Upstream 04/17/2026 fixes https://github.com/Bubberstation/Bubberstation/issues/5549 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com> Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Rhials <28870487+Rhials@users.noreply.github.com> Co-authored-by: rageguy505 <54517726+rageguy505@users.noreply.github.com> Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Co-authored-by: Aliceee2ch <160794176+Aliceee2ch@users.noreply.github.com> Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com> Co-authored-by: Tsar-Salat <62388554+Tsar-Salat@users.noreply.github.com> Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Co-authored-by: Maxipat <108554989+Maxipat112@users.noreply.github.com> Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com> Co-authored-by: SimplyLogan <47579821+loganuk@users.noreply.github.com> Co-authored-by: loganuk <fakeemail123@aol.com> Co-authored-by: Leland Kemble <70413276+lelandkemble@users.noreply.github.com> Co-authored-by: FalloutFalcon <86381784+FalloutFalcon@users.noreply.github.com> Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com> Co-authored-by: Lucy <lucy@absolucy.moe> Co-authored-by: siliconOpossum <138069572+siliconOpossum@users.noreply.github.com> Co-authored-by: Isratosh <Isratosh@hotmail.com> Co-authored-by: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com> Co-authored-by: Neocloudy <88008002+Neocloudy@users.noreply.github.com> Co-authored-by: Alexander V. <volas@ya.ru> Co-authored-by: ElGitificador <168473461+ElGitificador@users.noreply.github.com> Co-authored-by: Twaticus <46540570+Twaticus@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Tim <timothymtorres@gmail.com> Co-authored-by: Iamgoofball <iamgoofball@gmail.com> Co-authored-by: Layzu666 <121319428+Layzu666@users.noreply.github.com> Co-authored-by: Arturlang <24881678+Arturlang@users.noreply.github.com> Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com> Co-authored-by: mrmanlikesbt <99309552+mrmanlikesbt@users.noreply.github.com> Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Co-authored-by: John F. Kennedy <54908920+MacaroniCritter@users.noreply.github.com> Co-authored-by: Cursor <102828457+theselfish@users.noreply.github.com> Co-authored-by: Josh <josh.adam.powell@gmail.com> Co-authored-by: Josh Powell <josh.powell@softwire.com> Co-authored-by: Yobrocharlie <Charliemiller5617@gmail.com> Co-authored-by: Hardly3D <66234359+Hardly3D@users.noreply.github.com> Co-authored-by: shayoki <96078776+shayoki@users.noreply.github.com> Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
212 lines
7.9 KiB
Plaintext
212 lines
7.9 KiB
Plaintext
/obj/item/wallframe/fish
|
|
name = "fish mount"
|
|
desc = "The frame of a mount for trophy fish, to show off your proudest catch."
|
|
icon = 'icons/obj/wallmounts.dmi'
|
|
icon_state = "fish_mount_item"
|
|
result_path = /obj/structure/fish_mount
|
|
custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 2)
|
|
pixel_shift = 31
|
|
///Reference to the persistent_id of the mount this was spawned from.
|
|
var/persistence_id
|
|
|
|
/obj/item/wallframe/fish/after_attach(obj/structure/fish_mount/mount)
|
|
. = ..()
|
|
mount.persistence_id = persistence_id
|
|
|
|
///A wallmounted structure on which a fish can be attached to be used as room decoration.
|
|
/obj/structure/fish_mount
|
|
name = "fish mount"
|
|
desc = "A mount for trophy fish, to show off your proudest catch."
|
|
icon = 'icons/obj/wallmounts.dmi'
|
|
icon_state = "fish_mount"
|
|
anchored = TRUE
|
|
opacity = FALSE
|
|
density = FALSE
|
|
layer = SIGN_LAYER
|
|
max_integrity = 100
|
|
custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT)
|
|
armor_type = /datum/armor/structure_sign
|
|
resistance_flags = FLAMMABLE
|
|
/// The instance of the fish mounted on this.
|
|
var/obj/item/fish/mounted_fish
|
|
/// The identifier for mounts that carry the trophy between rounds.
|
|
var/persistence_id
|
|
/// Trophies from persistence have a good chance to be dusted if removal is attempted, though rarely it pays off.
|
|
var/persistence_loaded_fish = FALSE
|
|
|
|
/obj/structure/fish_mount/Initialize(mapload)
|
|
. = ..()
|
|
//Mounted fish shouldn't flop. It should also show size and weight to everyone.
|
|
add_traits(list(TRAIT_STOP_FISH_FLOPPING, TRAIT_EXAMINE_FISH), INNATE_TRAIT)
|
|
if(mapload)
|
|
find_and_mount_on_atom()
|
|
if(!persistence_id)
|
|
return
|
|
if(SSfishing.initialized)
|
|
load_trophy_fish()
|
|
else
|
|
RegisterSignal(SSfishing, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(load_trophy_fish))
|
|
|
|
/obj/structure/fish_mount/Destroy(force)
|
|
QDEL_NULL(mounted_fish)
|
|
return ..()
|
|
|
|
/obj/structure/fish_mount/proc/load_trophy_fish(datum/source)
|
|
SIGNAL_HANDLER
|
|
SSpersistence.load_trophy_fish(src)
|
|
UnregisterSignal(SSfishing, COMSIG_SUBSYSTEM_POST_INITIALIZE)
|
|
if(!mounted_fish)
|
|
add_first_fish()
|
|
|
|
/obj/structure/fish_mount/screwdriver_act(mob/living/user, obj/item/item)
|
|
. = ..()
|
|
balloon_alert(user, "removing mount...")
|
|
if(!item.use_tool(src, user, 3 SECONDS, volume = 50))
|
|
return ITEM_INTERACT_BLOCKING
|
|
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
|
|
balloon_alert_to_viewers("fish mount removed")
|
|
deconstruct()
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/structure/fish_mount/proc/add_first_fish()
|
|
var/list/valid_picks = subtypesof(/obj/item/fish) - typesof(/obj/item/fish/holo) - /obj/item/fish/starfish/chrystarfish // chrystarfish immediately shatters when placed
|
|
var/obj/item/fish/fish_path = pick(valid_picks)
|
|
if(fish_path.fish_id_redirect_path)
|
|
fish_path = fish_path.fish_id_redirect_path
|
|
var/fluff_name = pick("John Trasen III", "a nameless intern", "Pun Pun", AQUARIUM_COMPANY, "Unknown", "Central Command")
|
|
add_fish(new fish_path(loc), from_persistence = TRUE, catcher = fluff_name)
|
|
mounted_fish.randomize_size_and_weight()
|
|
mounted_fish.set_status(FISH_DEAD)
|
|
SSpersistence.save_trophy_fish(src)
|
|
|
|
/obj/structure/fish_mount/atom_deconstruct(disassembled = TRUE)
|
|
. = ..()
|
|
if(disassembled)
|
|
var/obj/item/wallframe/fish/frame = new (loc)
|
|
frame.persistence_id = persistence_id
|
|
mounted_fish?.forceMove(loc)
|
|
|
|
/obj/structure/fish_mount/item_interaction(mob/living/user, obj/item/item, list/modifiers)
|
|
if(!isfish(item) || user.combat_mode)
|
|
return ..()
|
|
if(mounted_fish)
|
|
balloon_alert(user, "remove other fish first!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
if(item.flags_1 & HOLOGRAM_1)
|
|
balloon_alert(user, "fish not mountable!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
balloon_alert(user, "mounting fish...")
|
|
if(!do_after(user, 3 SECONDS, src) || mounted_fish)
|
|
return ITEM_INTERACT_BLOCKING
|
|
add_fish(item, catcher = user.name)
|
|
balloon_alert_to_viewers("fish mounted")
|
|
playsound(loc, 'sound/machines/click.ogg', 30, TRUE)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/structure/fish_mount/IsContainedAtomAccessible(atom/contained, atom/movable/user)
|
|
return TRUE
|
|
|
|
/obj/structure/fish_mount/proc/add_fish(obj/item/fish/fish, from_persistence = FALSE, catcher)
|
|
if(QDELETED(src)) // don't ever try to add a fish to one of these that's already been deleted - and get rid of the one that was created
|
|
qdel(fish)
|
|
return
|
|
if(QDELETED(fish)) // no adding deleted fishies either
|
|
return
|
|
if(mounted_fish)
|
|
mounted_fish.forceMove(loc)
|
|
fish.forceMove(src)
|
|
vis_contents += fish
|
|
fish.vis_flags |= (VIS_INHERIT_PLANE|VIS_INHERIT_LAYER)
|
|
fish.interaction_flags_item &= ~INTERACT_ITEM_ATTACK_HAND_PICKUP
|
|
fish.obj_flags &= ~UNIQUE_RENAME
|
|
fish.remove_fillet_type()
|
|
fish.anchored = TRUE
|
|
mounted_fish = fish
|
|
|
|
if(!fish.catcher_name)
|
|
fish.catcher_name = catcher
|
|
if(!fish.catch_date)
|
|
fish.catch_date = "[time2text(world.realtime, "Day, Month DD", NO_TIMEZONE)], [CURRENT_STATION_YEAR]"
|
|
|
|
AddElement(/datum/element/beauty, get_fish_beauty())
|
|
RegisterSignals(fish, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW), PROC_REF(on_fish_attack_hand))
|
|
if(from_persistence)
|
|
persistence_loaded_fish = TRUE
|
|
fish.add_traits(list(TRAIT_NO_FISHING_ACHIEVEMENT, TRAIT_FISH_LOW_PRICE), INNATE_TRAIT)
|
|
else if(persistence_id)
|
|
SSpersistence.save_trophy_fish(src)
|
|
|
|
/obj/structure/fish_mount/proc/get_fish_beauty()
|
|
var/beauty = 100 + mounted_fish.beauty * 1.2
|
|
var/datum/material/main_material = mounted_fish.get_master_material()
|
|
if(main_material)
|
|
beauty += main_material.get_property(MATERIAL_BEAUTY) * mounted_fish.weight
|
|
return round(beauty)
|
|
|
|
/obj/structure/fish_mount/proc/on_fish_attack_hand(datum/source, mob/living/user)
|
|
SIGNAL_HANDLER
|
|
INVOKE_ASYNC(src, PROC_REF(remove_fish), user)
|
|
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
|
|
|
/obj/structure/fish_mount/attack_hand_secondary(mob/living/user, list/modifiers)
|
|
. = ..()
|
|
if(!mounted_fish)
|
|
balloon_alert(user, "no fish mounted!")
|
|
else
|
|
remove_fish(user)
|
|
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
|
|
|
/obj/structure/fish_mount/proc/remove_fish(mob/living/user)
|
|
balloon_alert(user, "removing fish...")
|
|
if(!do_after(user, (persistence_loaded_fish ? 6 : 3) SECONDS, src) || !mounted_fish)
|
|
return
|
|
|
|
var/obj/item/fish/fish_reference = mounted_fish
|
|
if(persistence_loaded_fish)
|
|
roll_for_safe_removal(user)
|
|
|
|
if(QDELETED(fish_reference))
|
|
var/ash_type = /obj/effect/decal/cleanable/ash
|
|
if(fish_reference.w_class >= WEIGHT_CLASS_BULKY)
|
|
ash_type = /obj/effect/decal/cleanable/ash/large
|
|
new ash_type(loc)
|
|
visible_message("[fish_reference] turns into dust as [fish_reference.p_theyre()] removed from [src].")
|
|
else
|
|
user.put_in_hands(mounted_fish)
|
|
balloon_alert_to_viewers("fish removed")
|
|
|
|
/obj/structure/fish_mount/Exited(atom/movable/gone)
|
|
if(gone != mounted_fish)
|
|
return ..()
|
|
RemoveElement(/datum/element/beauty, get_fish_beauty())
|
|
if(!QDELETED(mounted_fish) && (!persistence_loaded_fish || roll_for_safe_removal()))
|
|
UnregisterSignal(mounted_fish, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW))
|
|
mounted_fish.vis_flags &= ~(VIS_INHERIT_PLANE|VIS_INHERIT_LAYER)
|
|
mounted_fish.interaction_flags_item |= INTERACT_ITEM_ATTACK_HAND_PICKUP
|
|
mounted_fish.obj_flags |= UNIQUE_RENAME
|
|
mounted_fish.add_fillet_type()
|
|
mounted_fish.anchored = FALSE
|
|
persistence_loaded_fish = FALSE
|
|
mounted_fish = null
|
|
return ..()
|
|
|
|
/obj/structure/fish_mount/proc/roll_for_safe_removal(mob/living/user)
|
|
if(isnull(mounted_fish))
|
|
return FALSE
|
|
|
|
///the base success rate is calculated considering the item inventory size and the heaviness of the fish.
|
|
var/success_prob = 100/(mounted_fish.w_class + GET_FISH_WEIGHT_RANK(mounted_fish.weight))
|
|
var/fishing_prowess = user?.mind?.get_skill_level(/datum/skill/fishing)
|
|
success_prob += fishing_prowess * 4 // up to 28% fixed bonus chance to safely retrieve the trophy depending on skill.
|
|
if(!prob(success_prob))
|
|
qdel(mounted_fish)
|
|
return FALSE
|
|
|
|
persistence_loaded_fish = FALSE //this way we don't roll again on Exited()
|
|
return TRUE
|
|
|
|
/obj/structure/fish_mount/bar
|
|
persistence_id = "Bar"
|
|
|
|
MAPPING_DIRECTIONAL_HELPERS(/obj/structure/fish_mount/bar, /obj/item/wallframe/fish::pixel_shift)
|