mirror of
https://github.com/Skyrat-SS13/Skyrat-tg.git
synced 2026-08-27 23:09:53 +01:00
* Refactored the fish case and examining fish. New bluespace fish case to fit large fish inside a backpack. (#85271) ## About The Pull Request I've refactored the FISH_SAFE_STORAGE trait into an element, mainly because there were a few problems with how it worked: It wasn't stopping hunger from raising, ditto with the breeding wait, and it offered no healing whatsoever, which I find kind of a bummer. The new element will keep the fish from getting any hungrier or ready to reproduce and will heal them up to 65% of their base health. Also, I've added a new bluespace fish case as a techweb design, found along with other stuff in the advanced fishing node, though if you want I can move it to a bluespace node. This should make it possible to reasonably store and carry around larger fish. Examining a fish will no longer give out readings on weight and size if you haven't at least attempted fishing once (you can get to novice level in less than a minute). While examining a fish with apprentice level or higher will also give readings on the general conditions of the fish (is it starving? drowning? has it lost a considerable chunk of health?). The fishing skillchip also gives you these traits. I've also converted two fish variables into traits, because fish have waaaay too many variables. and gave some topdown shading to the pre-existing fishbox sprite. ## Why It's Good For The Game ## Changelog 🆑 add: Added a bluespace fish case to the advanced fishing node. balance: Fish cases will keep a fish from getting hungrier or ready to reproduce, while also healing it up to 65% health. balance: Examining a fish with zero fishing skill whatsoever won't give a reading on its size and weight. Conversely, examining one with the skill leveled two times will give general information on if it's starving, sick, hungry, or dead. /🆑 * Refactored the fish case and examining fish. New bluespace fish case to fit large fish inside a backpack. --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
273 lines
10 KiB
Plaintext
273 lines
10 KiB
Plaintext
/obj/structure/toilet
|
|
name = "toilet"
|
|
desc = "The HT-451, a torque rotation-based, waste disposal unit for small matter. This one seems remarkably clean."
|
|
icon = 'icons/obj/watercloset.dmi'
|
|
icon_state = "toilet00" //The first number represents if the toilet lid is up, the second is if the cistern is open.
|
|
base_icon_state = "toilet"
|
|
density = FALSE
|
|
anchored = TRUE
|
|
|
|
///Boolean if whether the toilet is currently flushing.
|
|
var/flushing = FALSE
|
|
///Boolean if the toilet seat is up.
|
|
var/cover_open = FALSE
|
|
///Boolean if the cistern is up, allowing items to be put in/out.
|
|
var/cistern_open = FALSE
|
|
///The combined weight of all items in the cistern put together.
|
|
var/w_items = 0
|
|
///Reference to the mob being given a swirlie.
|
|
var/mob/living/swirlie
|
|
///The type of material used to build the toilet.
|
|
var/buildstacktype = /obj/item/stack/sheet/iron
|
|
///How much of the buildstacktype is needed to construct the toilet.
|
|
var/buildstackamount = 1
|
|
///Lazylist of items in the cistern.
|
|
var/list/cistern_items
|
|
///Lazylist of fish in the toilet, not to be mixed with the items in the cistern. Max of 3
|
|
var/list/fishes
|
|
///Static toilet water overlay given to toilets that are facing a direction we can see the water in.
|
|
var/static/mutable_appearance/toilet_water_overlay
|
|
|
|
/obj/structure/toilet/Initialize(mapload)
|
|
. = ..()
|
|
if(isnull(toilet_water_overlay))
|
|
toilet_water_overlay = mutable_appearance(icon, "[base_icon_state]-water")
|
|
cover_open = round(rand(0, 1))
|
|
update_appearance(UPDATE_ICON)
|
|
if(mapload && SSmapping.level_trait(z, ZTRAIT_STATION))
|
|
AddElement(/datum/element/lazy_fishing_spot, /datum/fish_source/toilet)
|
|
AddElement(/datum/element/fish_safe_storage)
|
|
register_context()
|
|
|
|
/obj/structure/toilet/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
|
. = ..()
|
|
if(user.pulling && isliving(user.pulling))
|
|
context[SCREENTIP_CONTEXT_LMB] = "Give Swirlie"
|
|
else if(cover_open && istype(held_item, /obj/item/fish))
|
|
context[SCREENTIP_CONTEXT_LMB] = "Insert Fish"
|
|
else if(cover_open && LAZYLEN(fishes))
|
|
context[SCREENTIP_CONTEXT_LMB] = "Grab Fish"
|
|
else if(cistern_open)
|
|
if(isnull(held_item))
|
|
context[SCREENTIP_CONTEXT_LMB] = "Check Cistern"
|
|
else
|
|
context[SCREENTIP_CONTEXT_LMB] = "Insert Item"
|
|
context[SCREENTIP_CONTEXT_RMB] = "Flush"
|
|
context[SCREENTIP_CONTEXT_ALT_LMB] = "[cover_open ? "Close" : "Open"] Lid"
|
|
return CONTEXTUAL_SCREENTIP_SET
|
|
|
|
/obj/structure/toilet/examine(mob/user)
|
|
. = ..()
|
|
if(cover_open && LAZYLEN(fishes))
|
|
. += span_notice("You can see fish in the toilet, you can probably take one out.")
|
|
|
|
/obj/structure/toilet/examine_more(mob/user)
|
|
. = ..()
|
|
if(cistern_open && LAZYLEN(cistern_items))
|
|
. += span_notice("You can see [cistern_items.len] items inside of the cistern.")
|
|
|
|
/obj/structure/toilet/Destroy(force)
|
|
. = ..()
|
|
QDEL_LAZYLIST(fishes)
|
|
QDEL_LAZYLIST(cistern_items)
|
|
|
|
/obj/structure/toilet/Exited(atom/movable/gone, direction)
|
|
. = ..()
|
|
if(gone in cistern_items)
|
|
LAZYREMOVE(cistern_items, gone)
|
|
return
|
|
if(gone in fishes)
|
|
LAZYREMOVE(fishes, gone)
|
|
return
|
|
|
|
/obj/structure/toilet/attack_hand(mob/living/user, list/modifiers)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
|
|
if(swirlie)
|
|
user.changeNext_move(CLICK_CD_MELEE)
|
|
playsound(src.loc, SFX_SWING_HIT, 25, TRUE)
|
|
swirlie.visible_message(span_danger("[user] slams the toilet seat onto [swirlie]'s head!"), span_userdanger("[user] slams the toilet seat onto your head!"), span_hear("You hear reverberating porcelain."))
|
|
log_combat(user, swirlie, "swirlied (brute)")
|
|
swirlie.adjustBruteLoss(5)
|
|
return
|
|
|
|
if(user.pulling && isliving(user.pulling))
|
|
user.changeNext_move(CLICK_CD_MELEE)
|
|
var/mob/living/grabbed_mob = user.pulling
|
|
if(user.grab_state < GRAB_AGGRESSIVE)
|
|
to_chat(user, span_warning("You need a tighter grip!"))
|
|
return
|
|
if(grabbed_mob.loc != get_turf(src))
|
|
to_chat(user, span_warning("[grabbed_mob] needs to be on [src]!"))
|
|
return
|
|
if(swirlie)
|
|
return
|
|
if(cover_open)
|
|
grabbed_mob.visible_message(span_danger("[user] starts to give [grabbed_mob] a swirlie!"), span_userdanger("[user] starts to give you a swirlie..."))
|
|
swirlie = grabbed_mob
|
|
var/was_alive = (swirlie.stat != DEAD)
|
|
if(!do_after(user, 3 SECONDS, target = src, timed_action_flags = IGNORE_HELD_ITEM))
|
|
swirlie = null
|
|
return
|
|
grabbed_mob.visible_message(span_danger("[user] gives [grabbed_mob] a swirlie!"), span_userdanger("[user] gives you a swirlie!"), span_hear("You hear a toilet flushing."))
|
|
if(iscarbon(grabbed_mob))
|
|
var/mob/living/carbon/carbon_grabbed = grabbed_mob
|
|
if(!carbon_grabbed.internal)
|
|
log_combat(user, carbon_grabbed, "swirlied (oxy)")
|
|
carbon_grabbed.adjustOxyLoss(5)
|
|
else
|
|
log_combat(user, grabbed_mob, "swirlied (oxy)")
|
|
grabbed_mob.adjustOxyLoss(5)
|
|
if(was_alive && swirlie.stat == DEAD && swirlie.client)
|
|
swirlie.client.give_award(/datum/award/achievement/misc/swirlie, swirlie) // just like space high school all over again!
|
|
swirlie = null
|
|
else
|
|
playsound(src.loc, 'sound/effects/bang.ogg', 25, TRUE)
|
|
grabbed_mob.visible_message(span_danger("[user] slams [grabbed_mob.name] into [src]!"), span_userdanger("[user] slams you into [src]!"))
|
|
log_combat(user, grabbed_mob, "toilet slammed")
|
|
grabbed_mob.adjustBruteLoss(5)
|
|
return
|
|
|
|
if(cistern_open && !cover_open && user.CanReach(src))
|
|
if(!LAZYLEN(cistern_items))
|
|
to_chat(user, span_notice("The cistern is empty."))
|
|
return
|
|
var/obj/item/random_cistern_item = pick(cistern_items)
|
|
if(ishuman(user))
|
|
user.put_in_hands(random_cistern_item)
|
|
else
|
|
random_cistern_item.forceMove(drop_location())
|
|
to_chat(user, span_notice("You find [random_cistern_item] in the cistern."))
|
|
w_items -= random_cistern_item.w_class
|
|
return
|
|
|
|
if(!flushing && LAZYLEN(fishes) && cover_open)
|
|
var/obj/item/random_fish = pick(fishes)
|
|
if(ishuman(user))
|
|
user.put_in_hands(random_fish)
|
|
else
|
|
random_fish.forceMove(drop_location())
|
|
to_chat(user, span_notice("You take [random_fish] out of the toilet, poor thing."))
|
|
|
|
/obj/structure/toilet/click_alt(mob/living/user)
|
|
if(flushing)
|
|
return CLICK_ACTION_BLOCKING
|
|
cover_open = !cover_open
|
|
update_appearance(UPDATE_ICON)
|
|
return CLICK_ACTION_SUCCESS
|
|
|
|
/obj/structure/toilet/attack_hand_secondary(mob/user, list/modifiers)
|
|
. = ..()
|
|
if(flushing)
|
|
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
|
flushing = TRUE
|
|
playsound(src, 'sound/machines/toilet_flush.ogg', cover_open ? 40 : 20, TRUE)
|
|
if(cover_open && (dir & SOUTH))
|
|
update_appearance(UPDATE_OVERLAYS)
|
|
flick_overlay_view(mutable_appearance(icon, "[base_icon_state]-water-flick"), 3 SECONDS)
|
|
addtimer(CALLBACK(src, PROC_REF(end_flushing)), 4 SECONDS)
|
|
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
|
|
|
/obj/structure/toilet/update_icon_state()
|
|
icon_state = "[base_icon_state][cover_open][cistern_open]"
|
|
return ..()
|
|
|
|
/obj/structure/toilet/update_overlays()
|
|
. = ..()
|
|
if(!flushing && cover_open && (dir & SOUTH))
|
|
. += toilet_water_overlay
|
|
|
|
/obj/structure/toilet/atom_deconstruct(dissambled = TRUE)
|
|
for(var/obj/toilet_item in cistern_items)
|
|
toilet_item.forceMove(drop_location())
|
|
if(buildstacktype)
|
|
new buildstacktype(loc,buildstackamount)
|
|
else
|
|
for(var/datum/material/M as anything in custom_materials)
|
|
new M.sheet_type(loc, FLOOR(custom_materials[M] / SHEET_MATERIAL_AMOUNT, 1))
|
|
|
|
/obj/structure/toilet/attackby(obj/item/attacking_item, mob/living/user, params)
|
|
add_fingerprint(user)
|
|
if(cover_open && istype(attacking_item, /obj/item/fish))
|
|
if(fishes >= 3)
|
|
to_chat(user, span_warning("There's too many fishes, flush them down first."))
|
|
return
|
|
if(!user.transferItemToLoc(attacking_item, src))
|
|
to_chat(user, span_warning("\The [attacking_item] is stuck to your hand!"))
|
|
return
|
|
var/obj/item/fish/the_fish = attacking_item
|
|
if(the_fish.status == FISH_DEAD)
|
|
to_chat(user, span_warning("You place [attacking_item] into [src], may it rest in peace."))
|
|
else
|
|
to_chat(user, span_notice("You place [attacking_item] into [src], hopefully no one will miss it!"))
|
|
LAZYADD(fishes, attacking_item)
|
|
return
|
|
|
|
if(cistern_open && !user.combat_mode)
|
|
if(attacking_item.w_class > WEIGHT_CLASS_NORMAL)
|
|
to_chat(user, span_warning("[attacking_item] does not fit!"))
|
|
return
|
|
if(w_items + attacking_item.w_class > WEIGHT_CLASS_HUGE)
|
|
to_chat(user, span_warning("The cistern is full!"))
|
|
return
|
|
if(!user.transferItemToLoc(attacking_item, src))
|
|
to_chat(user, span_warning("\The [attacking_item] is stuck to your hand, you cannot put it in the cistern!"))
|
|
return
|
|
LAZYADD(cistern_items, attacking_item)
|
|
w_items += attacking_item.w_class
|
|
to_chat(user, span_notice("You carefully place [attacking_item] into the cistern."))
|
|
return
|
|
|
|
if(is_reagent_container(attacking_item) && !user.combat_mode)
|
|
if (!cover_open)
|
|
return
|
|
if(istype(attacking_item, /obj/item/food/monkeycube))
|
|
var/obj/item/food/monkeycube/cube = attacking_item
|
|
cube.Expand()
|
|
return
|
|
var/obj/item/reagent_containers/RG = attacking_item
|
|
RG.reagents.add_reagent(/datum/reagent/water, min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this))
|
|
to_chat(user, span_notice("You fill [RG] from [src]. Gross."))
|
|
return ..()
|
|
|
|
/obj/structure/toilet/crowbar_act(mob/living/user, obj/item/tool)
|
|
to_chat(user, span_notice("You start to [cistern_open ? "replace the lid on" : "lift the lid off"] the cistern..."))
|
|
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, TRUE)
|
|
if(tool.use_tool(src, user, 30))
|
|
user.visible_message(
|
|
span_notice("[user] [cistern_open ? "replaces the lid on" : "lifts the lid off"] the cistern!"),
|
|
span_notice("You [cistern_open ? "replace the lid on" : "lift the lid off"] the cistern!"),
|
|
span_hear("You hear grinding porcelain."))
|
|
cistern_open = !cistern_open
|
|
update_appearance(UPDATE_ICON_STATE)
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/structure/toilet/wrench_act(mob/living/user, obj/item/tool)
|
|
tool.play_tool_sound(src)
|
|
deconstruct()
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
///Ends the flushing animation and updates overlays if necessary
|
|
/obj/structure/toilet/proc/end_flushing()
|
|
flushing = FALSE
|
|
if(cover_open && (dir & SOUTH))
|
|
update_appearance(UPDATE_OVERLAYS)
|
|
QDEL_LAZYLIST(fishes)
|
|
|
|
/obj/structure/toilet/greyscale
|
|
material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
|
buildstacktype = null
|
|
|
|
/obj/structure/toilet/secret
|
|
var/secret_type = null
|
|
|
|
/obj/structure/toilet/secret/Initialize(mapload)
|
|
. = ..()
|
|
if(secret_type)
|
|
var/obj/item/secret = new secret_type(src)
|
|
secret.desc += " It's a secret!"
|
|
w_items += secret.w_class
|
|
LAZYADD(cistern_items, secret)
|