From 4e167856aa04033a1f307906bb359da6e4ff3201 Mon Sep 17 00:00:00 2001
From: SkyratBot <59378654+SkyratBot@users.noreply.github.com>
Date: Wed, 21 Aug 2024 08:51:26 +0200
Subject: [PATCH] [MIRROR] Adds a treasure chest to the ocean/beach fishing
spot. (#29398)
* Adds a treasure chest to the ocean/beach fishing spot. (#85276)
## About The Pull Request
This PR adds a treasure chest that can be fished from the ocean if
you're lucky enough (or have enough explosives or lobstrosities to do it
for you). The treasure chest is basically a mystery box (like the ones
from the deathmatch) with a couple catches; the treasure chest can be
opened up to 18 times in total before breaking down, however, it can
only be opened up to 3 times per spaceman, encouraging the player to
share it with others.
Here the possible loot by the by:
- A toolbox containing a master fishing rod, all the hooks and reels,
fish feed, an experi-scanner, an aquarium kit and a can of super baits
- A box containing a lazarus injector, a cup and a bottle of strange
reagent which you can use to revive fish now
- A circuit board for a pre-emagged fishing portal generator
- A master fishing rod
- A can of super fishing baits
- A fish case containing Tiziran fish
- A fish case containing Syndicate fish
- An old, yet fairly strong cutlass
- An old laser gun which fires only 5 shots before running out
- A crank laser musket
- A smoothbore disabler
- A surplus bolt action rifle
- A ration pack
- A can of squid ink
- A bottle of aged rum that forces you to switch to the piratespeak
language
- A money bag with some doubloons inside
- A piratespeak manual
- Pirate armored coat
- Pirate armored hat
- A pre-loaded cannon
- Four trash cannon balls
- Four cannon balls
## Why It's Good For The Game
Mystery boxes are fun, from the little fanfare they play to the
potential loot they can give, and I had an old treasure chest I had
sprited for fun years ago around so I've come up with an entertaining
idea. If you think the loot list is a bit too hot, I can cool it down a
bit.
Also yeah, I wanted to make fish revivable with strange reagent, since
you can already do it with lazarus injectors even though using a lazarus
injector for this would be a severe waste of mining points.
## Changelog
:cl:
add: Added a treasure chest you can rarely fish from the ocean/beach,
with loot being a mix of fishing and piratey stuff.
add: You can revive fish with strange reagent now.
/:cl:
* Adds a treasure chest to the ocean/beach fishing spot.
---------
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
---
_maps/RandomZLevels/TheBeach.dmm | 94 +++++++++++------
code/__DEFINES/language.dm | 1 +
code/game/area/areas/away_content.dm | 10 --
.../objects/effects/spawners/random/exotic.dm | 3 +-
.../effects/spawners/random/food_or_drink.dm | 1 +
.../machines/machine_circuitboards.dm | 4 +
code/game/objects/items/food/bait.dm | 10 +-
code/game/objects/items/weaponry.dm | 8 ++
.../game/objects/structures/cannons/cannon.dm | 12 +++
code/game/objects/structures/mystery_box.dm | 97 +++++++++++++++---
.../awaymissions/mission_code/Beach.dm | 19 ++++
code/modules/fishing/aquarium/aquarium_kit.dm | 1 +
code/modules/fishing/bait.dm | 38 ++++++-
code/modules/fishing/fish/_fish.dm | 14 +++
code/modules/fishing/fishing_equipment.dm | 48 ++++++++-
.../modules/fishing/fishing_portal_machine.dm | 4 +
code/modules/fishing/sources/source_types.dm | 2 +
code/modules/language/_language_manuals.dm | 8 ++
code/modules/mob_spawn/corpses/mob_corpses.dm | 10 ++
.../reagents/drinks/alcohol_reagents.dm | 21 ++++
.../reagent_containers/cups/bottle.dm | 5 +
.../reagent_containers/cups/glassbottle.dm | 6 ++
icons/obj/drinks/bottles.dmi | Bin 24653 -> 28099 bytes
icons/obj/fishing.dmi | Bin 15986 -> 17843 bytes
icons/obj/service/library.dmi | Bin 23649 -> 23853 bytes
icons/obj/storage/box.dmi | Bin 13353 -> 13478 bytes
icons/obj/storage/crates.dmi | Bin 40173 -> 41444 bytes
icons/obj/weapons/cannons.dmi | Bin 2516 -> 2563 bytes
tgstation.dme | 1 +
29 files changed, 348 insertions(+), 69 deletions(-)
create mode 100644 code/modules/awaymissions/mission_code/Beach.dm
diff --git a/_maps/RandomZLevels/TheBeach.dmm b/_maps/RandomZLevels/TheBeach.dmm
index bc12d30d77b..1abeb5c67e6 100644
--- a/_maps/RandomZLevels/TheBeach.dmm
+++ b/_maps/RandomZLevels/TheBeach.dmm
@@ -278,16 +278,6 @@
/obj/structure/musician/piano,
/turf/open/floor/wood,
/area/awaymission/beach)
-"dx" = (
-/obj/structure/sign/directions/dorms/directional/north{
- pixel_y = 35
- },
-/obj/structure/sign/directions/medical/directional/north{
- pixel_y = 29
- },
-/obj/machinery/computer/slot_machine,
-/turf/open/floor/wood/large,
-/area/awaymission/beach)
"dL" = (
/obj/machinery/door/airlock/public/glass{
name = "Locker Room"
@@ -365,6 +355,10 @@
},
/turf/open/floor/iron/white/textured_large,
/area/awaymission/beach)
+"fc" = (
+/obj/item/broken_bottle,
+/turf/open/misc/beach/sand,
+/area/awaymission/beach)
"fd" = (
/obj/structure/table/bronze,
/obj/structure/desk_bell{
@@ -989,12 +983,6 @@
/obj/structure/table/glass,
/turf/open/floor/iron/dark/diagonal,
/area/awaymission/beach)
-"mu" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/mapping_helpers/broken_floor,
-/obj/effect/landmark/awaystart/beach,
-/turf/open/floor/plating,
-/area/awaymission/beach)
"mG" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -1084,6 +1072,16 @@
/obj/structure/table/glass,
/turf/open/floor/wood/large,
/area/awaymission/beach)
+"nu" = (
+/obj/structure/sign/directions/dorms/directional/north{
+ pixel_y = 35
+ },
+/obj/structure/sign/directions/medical/directional/north{
+ pixel_y = 29
+ },
+/obj/machinery/computer/slot_machine,
+/turf/open/floor/wood/large,
+/area/awaymission/beach)
"nC" = (
/obj/effect/turf_decal/tile/dark_red/full,
/turf/open/floor/iron/smooth_large,
@@ -1632,6 +1630,10 @@
},
/turf/open/floor/iron/dark/diagonal,
/area/awaymission/beach)
+"uK" = (
+/obj/effect/spawner/random/trash/cigbutt,
+/turf/open/misc/beach/sand,
+/area/awaymission/beach)
"uL" = (
/obj/effect/turf_decal/siding/wood{
dir = 4
@@ -1691,6 +1693,12 @@
/obj/effect/decal/cleanable/oil,
/turf/open/floor/iron/dark/herringbone,
/area/awaymission/beach)
+"vq" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/mapping_helpers/broken_floor,
+/obj/effect/landmark/awaystart/beach,
+/turf/open/floor/plating,
+/area/awaymission/beach)
"vx" = (
/obj/effect/turf_decal/siding/wood{
dir = 10
@@ -2337,6 +2345,11 @@
},
/turf/open/misc/beach/sand,
/area/awaymission/beach)
+"DS" = (
+/obj/effect/mob_spawn/corpse/human/old_pirate_captain,
+/obj/structure/bed/maint,
+/turf/open/misc/beach/sand,
+/area/awaymission/beach)
"DU" = (
/obj/structure/table/bronze,
/turf/open/misc/beach/sand,
@@ -3257,10 +3270,16 @@
},
/turf/open/floor/iron/white/textured_large,
/area/awaymission/beach)
-"Oe" = (
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/landmark/awaystart/beach,
-/turf/open/floor/plating,
+"Oa" = (
+/obj/item/paper/fluff/old_pirate_note{
+ pixel_x = -5;
+ pixel_y = -7
+ },
+/obj/item/pen/fountain{
+ pixel_y = -11;
+ pixel_x = -8
+ },
+/turf/open/misc/beach/sand,
/area/awaymission/beach)
"Og" = (
/obj/effect/turf_decal/siding/wood/corner,
@@ -3399,6 +3418,12 @@
"Qg" = (
/turf/open/floor/wood/parquet,
/area/awaymission/beach)
+"Qj" = (
+/obj/item/fishing_rod,
+/obj/structure/closet/crate/trashcart,
+/obj/item/reagent_containers/cup/glass/bottle/rum/aged,
+/turf/open/misc/beach/sand,
+/area/awaymission/beach)
"Qk" = (
/obj/structure/closet/secure_closet/personal/cabinet,
/obj/item/clothing/suit/jacket/miljacket,
@@ -3589,6 +3614,11 @@
},
/turf/open/floor/wood,
/area/awaymission/beach)
+"SB" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/landmark/awaystart/beach,
+/turf/open/floor/plating,
+/area/awaymission/beach)
"SI" = (
/mob/living/basic/crab/kreb,
/turf/open/misc/beach/sand,
@@ -7415,8 +7445,8 @@ XB
XB
Vf
YV
-VY
-VY
+Qj
+fc
hL
ni
XB
@@ -7672,8 +7702,8 @@ XB
XB
Vf
VY
-VY
-VY
+uK
+DS
Er
BK
XB
@@ -7929,7 +7959,7 @@ XB
XB
Vf
VY
-VY
+Oa
VY
VY
BK
@@ -8187,7 +8217,7 @@ XB
Vf
IZ
VY
-VY
+uK
VY
BK
XB
@@ -13210,7 +13240,7 @@ xv
xv
xv
xv
-dx
+nu
Zp
Zp
mb
@@ -16550,8 +16580,8 @@ fi
uT
uT
Nb
-Oe
-Oe
+SB
+SB
uT
xv
wt
@@ -16806,8 +16836,8 @@ xv
uT
FF
Ge
-Oe
-Oe
+SB
+SB
Qr
KV
xv
@@ -17063,7 +17093,7 @@ xv
Ge
uT
uT
-mu
+vq
La
xv
xv
diff --git a/code/__DEFINES/language.dm b/code/__DEFINES/language.dm
index cd6ee5ec0c9..d530185c142 100644
--- a/code/__DEFINES/language.dm
+++ b/code/__DEFINES/language.dm
@@ -27,6 +27,7 @@
#define LANGUAGE_GLAND "gland"
#define LANGUAGE_HAT "hat"
#define LANGUAGE_QUIRK "quirk"
+#define LANGUAGE_DRINK "drink"
#define LANGUAGE_MALF "malf"
#define LANGUAGE_PIRATE "pirate"
#define LANGUAGE_MASTER "master"
diff --git a/code/game/area/areas/away_content.dm b/code/game/area/areas/away_content.dm
index 86d1ade828c..14ea52648f8 100644
--- a/code/game/area/areas/away_content.dm
+++ b/code/game/area/areas/away_content.dm
@@ -13,16 +13,6 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
sound_environment = SOUND_ENVIRONMENT_ROOM
area_flags = NOTELEPORT|UNIQUE_AREA //SKYRAT EDIT CHANGE
-/area/awaymission/beach
- name = "Beach"
- icon_state = "away"
- static_lighting = FALSE
- base_lighting_alpha = 255
- base_lighting_color = "#FFFFCC"
- requires_power = FALSE
- has_gravity = STANDARD_GRAVITY
- ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag2.ogg','sound/ambience/ambiodd.ogg','sound/ambience/ambinice.ogg')
-
/area/awaymission/museum
name = "Nanotrasen Museum"
icon_state = "awaycontent28"
diff --git a/code/game/objects/effects/spawners/random/exotic.dm b/code/game/objects/effects/spawners/random/exotic.dm
index e802e30056f..cb43d6f06ae 100644
--- a/code/game/objects/effects/spawners/random/exotic.dm
+++ b/code/game/objects/effects/spawners/random/exotic.dm
@@ -16,8 +16,9 @@
name = "language book spawner"
icon_state = "book"
loot = list( // A single roundstart species language book.
- /obj/item/language_manual/roundstart_species = 100,
+ /obj/item/language_manual/roundstart_species = 96,
/obj/item/book/granter/sign_language = 10,
+ /obj/item/language_manual/piratespeak = 4,
/obj/item/language_manual/roundstart_species/five = 3,
/obj/item/language_manual/roundstart_species/unlimited = 1,
)
diff --git a/code/game/objects/effects/spawners/random/food_or_drink.dm b/code/game/objects/effects/spawners/random/food_or_drink.dm
index 192914b6e3d..4ff47f08fe9 100644
--- a/code/game/objects/effects/spawners/random/food_or_drink.dm
+++ b/code/game/objects/effects/spawners/random/food_or_drink.dm
@@ -167,6 +167,7 @@
/obj/item/reagent_containers/cup/glass/bottle/lizardwine = 1,
/obj/item/reagent_containers/cup/glass/bottle/vodka/badminka = 1,
/obj/item/reagent_containers/cup/glass/bottle/trappist = 1,
+ /obj/item/reagent_containers/cup/glass/bottle/rum/aged = 1,
)
/obj/effect/spawner/random/food_or_drink/pizzaparty
diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
index 67ad85668a5..23f6402880d 100644
--- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
@@ -1390,6 +1390,10 @@
/datum/stock_part/capacitor = 1)
needs_anchored = FALSE
+/obj/item/circuitboard/machine/fishing_portal_generator/emagged
+ name = "Emagged Fishing Portal Generator"
+ build_path = /obj/machinery/fishing_portal_generator
+
//Supply
/obj/item/circuitboard/machine/ore_redemption
name = "Ore Redemption"
diff --git a/code/game/objects/items/food/bait.dm b/code/game/objects/items/food/bait.dm
index 41b50c181f2..f31eb44f308 100644
--- a/code/game/objects/items/food/bait.dm
+++ b/code/game/objects/items/food/bait.dm
@@ -60,15 +60,23 @@
*/
/obj/item/food/bait/doughball/synthetic
name = "synthetic doughball"
- icon_state = "doughball"
+ icon_state = "doughball_blue"
preserved_food = TRUE
/obj/item/food/bait/doughball/synthetic/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_OMNI_BAIT, INNATE_TRAIT)
+///Found in the can of omni-baits, only available from the super fishing toolbox, from the fishing mystery box.
+/obj/item/food/bait/doughball/synthetic/super
+ name = "super-doughball"
+ desc = "No fish will be able to resist this."
+ bait_quality = TRAIT_GREAT_QUALITY_BAIT
+
+///Used by the advanced fishing rod
/obj/item/food/bait/doughball/syntethic/unconsumable
/obj/item/food/bait/doughball/synthetic/unconsumable/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_BAIT_UNCONSUMABLE, INNATE_TRAIT)
+
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index 1c55ff47749..821f994a1ed 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -160,6 +160,14 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
throw_range = 5
armour_penetration = 35
+/obj/item/claymore/cutlass/old
+ name = "old cutlass"
+ desc = parent_type::desc + " This one seems a tad old."
+ force = 24
+ throwforce = 17
+ armour_penetration = 20
+ block_chance = 30
+
/obj/item/claymore/carrot
name = "carrot sword"
desc = "A full-sized carrot sword. Definitely not good for the eyes, not anymore."
diff --git a/code/game/objects/structures/cannons/cannon.dm b/code/game/objects/structures/cannons/cannon.dm
index 3408ade8283..3a10cc17189 100644
--- a/code/game/objects/structures/cannons/cannon.dm
+++ b/code/game/objects/structures/cannons/cannon.dm
@@ -140,5 +140,17 @@
new /obj/item/stack/rods(src.loc)
. = ..()
+///A cannon found from the fishing mystery box.
+/obj/structure/cannon/mystery_box
+ icon_state = "mystery_box_cannon" //east facing sprite for the presented item, it'll be changed back to normal on init
+ dir = EAST
+ anchored = FALSE
+
+/obj/structure/cannon/mystery_box/Initialize(mapload)
+ . = ..()
+ icon_state = "falconet_patina"
+ reagents.add_reagent(/datum/reagent/gunpowder, charge_size)
+ loaded_cannonball = new(src)
+
#undef BAD_FUEL_DAMAGE_TAX
#undef BAD_FUEL_EXPLODE_PROBABILTY
diff --git a/code/game/objects/structures/mystery_box.dm b/code/game/objects/structures/mystery_box.dm
index eb56e00e5e8..9bb51ba09cb 100644
--- a/code/game/objects/structures/mystery_box.dm
+++ b/code/game/objects/structures/mystery_box.dm
@@ -85,6 +85,30 @@ GLOBAL_LIST_INIT(mystery_magic, list(
/obj/item/runic_vendor_scepter,
))
+GLOBAL_LIST_INIT(mystery_fishing, list(
+ /obj/item/storage/toolbox/fishing/master,
+ /obj/item/storage/box/fish_revival_kit,
+ /obj/item/circuitboard/machine/fishing_portal_generator/emagged,
+ /obj/item/fishing_rod/telescopic/master,
+ /obj/item/bait_can/super_baits,
+ /obj/item/storage/fish_case/tiziran,
+ /obj/item/storage/fish_case/syndicate,
+ /obj/item/claymore/cutlass/old,
+ /obj/item/gun/energy/laser/retro/old,
+ /obj/item/gun/energy/laser/musket,
+ /obj/item/gun/energy/disabler/smoothbore,
+ /obj/item/gun/ballistic/rifle/boltaction/surplus,
+ /obj/item/food/rationpack,
+ /obj/item/food/canned/squid_ink,
+ /obj/item/reagent_containers/cup/glass/bottle/rum/aged,
+ /obj/item/storage/bag/money/dutchmen,
+ /obj/item/language_manual/piratespeak,
+ /obj/item/clothing/head/costume/pirate/armored,
+ /obj/item/clothing/suit/costume/pirate/armored,
+ /obj/structure/cannon/mystery_box,
+ /obj/item/stack/cannonball/trashball/four,
+ /obj/item/stack/cannonball/four,
+))
/obj/structure/mystery_box
name = "mystery box"
@@ -117,6 +141,10 @@ GLOBAL_LIST_INIT(mystery_magic, list(
var/grant_extra_mag = TRUE
/// Stores the current sound channel we're using so we can cut off our own sounds as needed. Randomized after each roll
var/current_sound_channel
+ /// How many time can it still be used?
+ var/uses_left
+ /// A list of weakrefs to mind datums of people that opened it and how many times.
+ var/list/datum/weakref/minds_that_opened_us
/obj/structure/mystery_box/Initialize(mapload)
. = ..()
@@ -126,6 +154,7 @@ GLOBAL_LIST_INIT(mystery_magic, list(
QDEL_NULL(presented_item)
if(current_sound_channel)
SSsounds.free_sound_channel(current_sound_channel)
+ minds_that_opened_us = null
return ..()
/obj/structure/mystery_box/attack_hand(mob/living/user, list/modifiers)
@@ -163,6 +192,11 @@ GLOBAL_LIST_INIT(mystery_magic, list(
current_sound_channel = SSsounds.reserve_sound_channel(src)
playsound(src, open_sound, 70, FALSE, channel = current_sound_channel, falloff_exponent = 10)
playsound(src, crate_open_sound, 80)
+ if(user.mind)
+ LAZYINITLIST(minds_that_opened_us)
+ var/datum/weakref/ref = WEAKREF(user.mind)
+ minds_that_opened_us[ref] += 1
+ uses_left--
/// The box has finished choosing, mark it as available for grabbing
/obj/structure/mystery_box/proc/present_weapon()
@@ -186,6 +220,9 @@ GLOBAL_LIST_INIT(mystery_magic, list(
box_close_timer = null
box_expire_timer = null
addtimer(CALLBACK(src, PROC_REF(ready_again)), MBOX_DURATION_STANDBY)
+ if(uses_left <= 0)
+ visible_message("[src] breaks down.")
+ deconstruct(disassembled = FALSE)
/// The cooldown between activations has finished, shake to show that
/obj/structure/mystery_box/proc/ready_again()
@@ -196,22 +233,26 @@ GLOBAL_LIST_INIT(mystery_magic, list(
/// Someone attacked the box with an empty hand, spawn the shown prize and give it to them, then close the box
/obj/structure/mystery_box/proc/grant_weapon(mob/living/user)
- var/obj/item/instantiated_weapon = new presented_item.selected_path(src)
- user.put_in_hands(instantiated_weapon)
-
- if(isgun(instantiated_weapon)) // handle pins + possibly extra ammo
- var/obj/item/gun/instantiated_gun = instantiated_weapon
- instantiated_gun.unlock()
- if(grant_extra_mag && istype(instantiated_gun, /obj/item/gun/ballistic))
- var/obj/item/gun/ballistic/instantiated_ballistic = instantiated_gun
- if(!instantiated_ballistic.internal_magazine)
- var/obj/item/ammo_box/magazine/extra_mag = new instantiated_ballistic.spawn_magazine_type(loc)
- user.put_in_hands(extra_mag)
-
+ var/atom/movable/instantiated_weapon = new presented_item.selected_path(loc)
user.visible_message(span_notice("[user] takes [presented_item] from [src]."), span_notice("You take [presented_item] from [src]."), vision_distance = COMBAT_MESSAGE_RANGE)
playsound(src, grant_sound, 70, FALSE, channel = current_sound_channel, falloff_exponent = 10)
close_box()
+ if(!isitem(instantiated_weapon))
+ return
+ user.put_in_hands(instantiated_weapon)
+
+ if(!isgun(instantiated_weapon))
+ return
+ // handle pins + possibly extra ammo
+ var/obj/item/gun/instantiated_gun = instantiated_weapon
+ instantiated_gun.unlock()
+ if(!grant_extra_mag || !istype(instantiated_gun, /obj/item/gun/ballistic))
+ return
+ var/obj/item/gun/ballistic/instantiated_ballistic = instantiated_gun
+ if(!instantiated_ballistic.internal_magazine)
+ var/obj/item/ammo_box/magazine/extra_mag = new instantiated_ballistic.spawn_magazine_type(loc)
+ user.put_in_hands(extra_mag)
/obj/structure/mystery_box/guns
desc = "A wooden crate that seems equally magical and mysterious, capable of granting the user all kinds of different pieces of gear. This one seems focused on firearms."
@@ -231,6 +272,28 @@ GLOBAL_LIST_INIT(mystery_magic, list(
/obj/structure/mystery_box/wands/generate_valid_types()
valid_types = GLOB.mystery_magic
+///One of a kind, rarely found by fishing in the ocean.
+/obj/structure/mystery_box/fishing
+ name = "treasure chest"
+ desc = "A pirate-y chest that seems equally magial and mysterious, capable of granting the user different pieces of gear."
+ icon_state = "treasure"
+ uses_left = 18
+ max_integrity = 100
+ damage_deflection = 30
+ grant_extra_mag = FALSE
+
+/obj/structure/mystery_box/handle_deconstruct(disassembled)
+ new /obj/item/stack/sheet/mineral/wood(drop_location(), 2)
+ return ..()
+
+/obj/structure/mystery_box/fishing/generate_valid_types()
+ valid_types = GLOB.mystery_fishing
+
+/obj/structure/mystery_box/fishing/activate(mob/living/user)
+ if(user.mind && minds_that_opened_us?[WEAKREF(user.mind)] >= 3)
+ to_chat(user, span_warning("[src] refuses to open to you anymore. Perhaps you should present it to someone else..."))
+ return
+ return ..()
/// This represents the item that comes out of the box and is constantly changing before the box finishes deciding. Can probably be just an /atom or /movable.
/obj/mystery_box_item
@@ -290,14 +353,14 @@ GLOBAL_LIST_INIT(mystery_magic, list(
/// animate() isn't up to the task for queueing up icon changes, so this is the proc we call with timers to update our icon
/obj/mystery_box_item/proc/update_random_icon(new_item_type)
- var/obj/item/new_item = new_item_type
- icon = initial(new_item.icon)
- icon_state = initial(new_item.icon_state)
+ var/atom/movable/new_item = new_item_type
+ icon = new_item::icon
+ icon_state = new_item::icon_state
/obj/mystery_box_item/proc/present_item()
- var/obj/item/selected_item = selected_path
+ var/atom/movable/selected_item = selected_path
add_filter("ready_outline", 2, list("type" = "outline", "color" = COLOR_VIVID_YELLOW, "size" = 0.2))
- name = initial(selected_item.name)
+ name = selected_item::name
parent_box.present_weapon()
claimable = TRUE
diff --git a/code/modules/awaymissions/mission_code/Beach.dm b/code/modules/awaymissions/mission_code/Beach.dm
new file mode 100644
index 00000000000..8e05cfe4a5e
--- /dev/null
+++ b/code/modules/awaymissions/mission_code/Beach.dm
@@ -0,0 +1,19 @@
+/area/awaymission/beach
+ name = "Beach"
+ icon_state = "away"
+ static_lighting = FALSE
+ base_lighting_alpha = 255
+ base_lighting_color = "#FFFFCC"
+ requires_power = FALSE
+ has_gravity = STANDARD_GRAVITY
+ ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag2.ogg','sound/ambience/ambiodd.ogg','sound/ambience/ambinice.ogg')
+
+/obj/item/paper/fluff/old_pirate_note
+ name = "rum-stained letter"
+ icon_state = "scrap_mud"
+ desc = "An unsent letter from a terminally drunk pirate."
+ default_raw_text = {"Dear,
+
I'm sorry I won't sail back home soon,
+
son of a biscuit eater walked the plank with me coffer (or treasure chest as landlubbers call'em),
+
so I got me fishing rod, bottles, waiting to fish the booty back.
+
Luv you hun, I hope this letter find you we-"}
diff --git a/code/modules/fishing/aquarium/aquarium_kit.dm b/code/modules/fishing/aquarium/aquarium_kit.dm
index 69cfb478bcc..14d33ea776a 100644
--- a/code/modules/fishing/aquarium/aquarium_kit.dm
+++ b/code/modules/fishing/aquarium/aquarium_kit.dm
@@ -150,6 +150,7 @@
/obj/item/storage/box/aquarium_props
name = "aquarium props box"
desc = "All you need to make your aquarium look good."
+ illustration = "fish"
/obj/item/storage/box/aquarium_props/PopulateContents()
for(var/prop_type in subtypesof(/obj/item/aquarium_prop))
diff --git a/code/modules/fishing/bait.dm b/code/modules/fishing/bait.dm
index b67298fab9f..78d18aa539e 100644
--- a/code/modules/fishing/bait.dm
+++ b/code/modules/fishing/bait.dm
@@ -3,13 +3,16 @@
desc = "there's a lot of them in there, getting them out takes a while though"
icon = 'icons/obj/fishing.dmi'
icon_state = "bait_can"
+ base_icon_state = "bait_can"
w_class = WEIGHT_CLASS_SMALL
/// Tracking until we can take out another bait item
COOLDOWN_DECLARE(bait_removal_cooldown)
/// What bait item it produces
- var/bait_type
+ var/obj/item/bait_type = /obj/item/food/bait
/// Time between bait retrievals
- var/cooldown_time = 10 SECONDS
+ var/cooldown_time = 5 SECONDS
+ /// How many uses does it have left.
+ var/uses_left = 20
/obj/item/bait_can/attack_self(mob/user, modifiers)
. = ..()
@@ -17,19 +20,44 @@
if(fresh_bait)
user.put_in_hands(fresh_bait)
+/obj/item/bait_can/examine(mob/user)
+ . = ..()
+ . += span_info("It[uses_left ? " has got [uses_left] [bait_type::name] left" : "'s empty"].")
+
+/obj/item/bait_can/update_icon_state()
+ . = ..()
+ icon_state = base_icon_state
+ if(uses_left <= initial(uses_left))
+ if(!uses_left)
+ icon_state = "[icon_state]_empty"
+ else
+ icon_state = "[icon_state]_open"
+
/obj/item/bait_can/proc/retrieve_bait(mob/user)
+ if(!uses_left)
+ user.balloon_alert(user, "empty")
+ return
if(!COOLDOWN_FINISHED(src, bait_removal_cooldown))
- user.balloon_alert(user, "wait a bit") //I can't think of generic ic reason.
+ user.balloon_alert(user, "wait a bit")
return
COOLDOWN_START(src, bait_removal_cooldown, cooldown_time)
+ update_appearance()
+ uses_left--
return new bait_type(src)
/obj/item/bait_can/worm
name = "can o' worm"
- desc = "this can got worms."
+ desc = "This can got worms."
bait_type = /obj/item/food/bait/worm
/obj/item/bait_can/worm/premium
name = "can o' worm deluxe"
- desc = "this can got fancy worms."
+ desc = "This can got fancy worms."
bait_type = /obj/item/food/bait/worm/premium
+
+/obj/item/bait_can/super_baits
+ name = "can o' super-baits"
+ desc = "This can got the nectar of god."
+ bait_type = /obj/item/food/bait/doughball/synthetic/super
+ uses_left = 12
+
diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm
index 1761d186ce6..509215e3507 100644
--- a/code/modules/fishing/fish/_fish.dm
+++ b/code/modules/fishing/fish/_fish.dm
@@ -392,6 +392,20 @@
update_appearance()
SEND_SIGNAL(src, COMSIG_FISH_STATUS_CHANGED)
+/obj/item/fish/expose_reagents(list/reagents, datum/reagents/source, methods = TOUCH, volume_modifier = 1, show_message = TRUE)
+ . = ..()
+ if(. & COMPONENT_NO_EXPOSE_REAGENTS || status != FISH_DEAD)
+ return
+ var/datum/reagent/medicine/strange_reagent/revival = locate() in reagents
+ if(!revival)
+ return
+ if(reagents[revival] >= 2 * w_class)
+ set_status(FISH_ALIVE)
+ else
+ balloon_alert_to_viewers("twitches for a moment!")
+ animate(src, pixel_x = 1, time = 0.1 SECONDS, loop = 2, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL)
+ animate(pixel_x = -1, flags = ANIMATION_RELATIVE)
+
/obj/item/fish/proc/use_lazarus(datum/source, obj/item/lazarus_injector/injector, mob/user)
SIGNAL_HANDLER
if(injector.revive_type != SENTIENCE_ORGANIC)
diff --git a/code/modules/fishing/fishing_equipment.dm b/code/modules/fishing/fishing_equipment.dm
index f6b49a9b523..b943f2bcdb7 100644
--- a/code/modules/fishing/fishing_equipment.dm
+++ b/code/modules/fishing/fishing_equipment.dm
@@ -260,7 +260,6 @@
// Can hold fishing rod despite the size
var/static/list/exception_cache = typecacheof(list(
/obj/item/fishing_rod,
- /obj/item/fishing_line,
))
atom_storage.exception_hold = exception_cache
@@ -286,30 +285,73 @@
new /obj/item/fishing_hook(src)
new /obj/item/fishing_line(src)
+/obj/item/storage/toolbox/fishing/master
+ name = "super fishing toolbox"
+ desc = "Contains EVERYTHING (almost) you need for your fishing trip."
+ icon_state = "gold"
+ inhand_icon_state = "toolbox_gold"
+
+/obj/item/storage/toolbox/fishing/master/PopulateContents()
+ new /obj/item/fishing_rod/telescopic/master(src)
+ new /obj/item/storage/box/fishing_hooks/master(src)
+ new /obj/item/storage/box/fishing_lines/master(src)
+ new /obj/item/bait_can/super_baits(src)
+ new /obj/item/fish_feed(src)
+ new /obj/item/aquarium_kit(src)
+ new /obj/item/fish_analyzer(src)
+ new /obj/item/experi_scanner(src)
+
/obj/item/storage/box/fishing_hooks
name = "fishing hook set"
+ illustration = "fish"
/obj/item/storage/box/fishing_hooks/PopulateContents()
- . = ..()
new /obj/item/fishing_hook/magnet(src)
new /obj/item/fishing_hook/shiny(src)
new /obj/item/fishing_hook/weighted(src)
+/obj/item/storage/box/fishing_hooks/master
+
+/obj/item/storage/box/fishing_hooks/master/PopulateContents()
+ . = ..()
+ new /obj/item/fishing_hook/stabilized(src)
+ new /obj/item/fishing_hook/jaws(src)
+
/obj/item/storage/box/fishing_lines
name = "fishing line set"
+ illustration = "fish"
/obj/item/storage/box/fishing_lines/PopulateContents()
- . = ..()
new /obj/item/fishing_line/bouncy(src)
new /obj/item/fishing_line/reinforced(src)
new /obj/item/fishing_line/cloaked(src)
+/obj/item/storage/box/fishing_lines/master
+
+/obj/item/storage/box/fishing_lines/master/PopulateContents()
+ . = ..()
+ new /obj/item/fishing_line/auto_reel(src)
+
/obj/item/storage/box/fish_debug
name = "box full of fish"
+ illustration = "fish"
/obj/item/storage/box/fish_debug/PopulateContents()
for(var/fish_type in subtypesof(/obj/item/fish))
new fish_type(src)
+///From the fishing mystery box. It's basically a lazarus and a few bottles of strange reagents.
+/obj/item/storage/box/fish_revival_kit
+ name = "fish revival kit"
+ desc = "Become a fish doctor today."
+ illustration = "fish"
+
+/obj/item/storage/box/fish_revival_kit/PopulateContents()
+ new /obj/item/lazarus_injector(src)
+ new /obj/item/reagent_containers/cup/bottle/strange_reagent(src)
+ new /obj/item/reagent_containers/cup(src) //to splash the reagents on the fish.
+ new /obj/item/storage/fish_case(src)
+ new /obj/item/storage/fish_case(src)
+
#undef MAGNET_HOOK_BONUS_MULTIPLIER
#undef RESCUE_HOOK_FISH_MULTIPLIER
diff --git a/code/modules/fishing/fishing_portal_machine.dm b/code/modules/fishing/fishing_portal_machine.dm
index 494b29b4183..8b157cbebff 100644
--- a/code/modules/fishing/fishing_portal_machine.dm
+++ b/code/modules/fishing/fishing_portal_machine.dm
@@ -100,3 +100,7 @@
if(!choice || !can_interact(user))
return
activate(available_fish_sources[choice])
+
+/obj/machinery/fishing_portal_generator/emagged
+ obj_flags = parent_type::obj_flags | EMAGGED
+ circuit = /obj/item/circuitboard/machine/fishing_portal_generator/emagged
diff --git a/code/modules/fishing/sources/source_types.dm b/code/modules/fishing/sources/source_types.dm
index dd5602b12f9..e7192bbd09c 100644
--- a/code/modules/fishing/sources/source_types.dm
+++ b/code/modules/fishing/sources/source_types.dm
@@ -9,9 +9,11 @@
/obj/item/fish/lanternfish = 5,
/obj/item/fish/zipzap = 5,
/obj/item/fish/clownfish/lube = 3,
+ /obj/structure/mystery_box/fishing = 1,
)
fish_counts = list(
/obj/item/fish/clownfish/lube = 2,
+ /obj/structure/mystery_box/fishing = 1,
)
fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 5
explosive_malus = TRUE
diff --git a/code/modules/language/_language_manuals.dm b/code/modules/language/_language_manuals.dm
index eb4ca456440..7a4298a06b1 100644
--- a/code/modules/language/_language_manuals.dm
+++ b/code/modules/language/_language_manuals.dm
@@ -85,6 +85,14 @@
. = ..()
name = "extended [initial(language.name)] manual"
+/obj/item/language_manual/piratespeak
+ name = "\improper Captain Pete's Guide to Pirate Lingo"
+ icon_state = "book_pirate"
+ desc = "A book containing all the knowledge, jargon and buzzwords to speak like a true old salt."
+ language = /datum/language/piratespeak
+ flavour_text = "Blimey! I feel less of a landlubber now."
+ charges = 5
+
// So drones can teach borgs and AI dronespeak. For best effect, combine with mother drone lawset.
/obj/item/language_manual/dronespeak_manual
name = "dronespeak manual"
diff --git a/code/modules/mob_spawn/corpses/mob_corpses.dm b/code/modules/mob_spawn/corpses/mob_corpses.dm
index f83dc13f1ed..c6d0cbd55cf 100644
--- a/code/modules/mob_spawn/corpses/mob_corpses.dm
+++ b/code/modules/mob_spawn/corpses/mob_corpses.dm
@@ -162,6 +162,16 @@
head = /obj/item/clothing/head/helmet/space/pirate
back = /obj/item/tank/jetpack/carbondioxide
+/obj/effect/mob_spawn/corpse/human/old_pirate_captain
+ name = "Pirate Captain Skeleton"
+ outfit = /datum/outfit/piratecorpse/captain
+ mob_species = /datum/species/skeleton
+
+/datum/outfit/piratecorpse/captain
+ glasses = /obj/item/clothing/glasses/eyepatch
+ head = /obj/item/clothing/head/costume/pirate
+ suit = /obj/item/clothing/suit/costume/pirate
+
/obj/effect/mob_spawn/corpse/human/russian
name = "Russian"
outfit = /datum/outfit/russiancorpse
diff --git a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
index 7cffa996f22..fca0982d205 100644
--- a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
@@ -345,6 +345,27 @@
ph = 6.5
default_container = /obj/item/reagent_containers/cup/glass/bottle/rum
+/datum/reagent/consumable/ethanol/rum/aged
+ name = "Aged Rum"
+ description = "Sink me! That's some fancy rum to share with buckoos."
+ color = "#c0b675" // rgb: 192,183,117
+ boozepwr = 70
+ taste_description = "extra-spiked butterscotch"
+ default_container = /obj/item/reagent_containers/cup/glass/bottle/rum/aged
+ quality = DRINK_FANTASTIC
+ metabolized_traits = list(TRAIT_STRONG_STOMACH)
+
+/datum/reagent/consumable/ethanol/rum/aged/on_mob_metabolize(mob/living/drinker)
+ . = ..()
+ drinker.add_blocked_language(subtypesof(/datum/language) - /datum/language/piratespeak, LANGUAGE_DRINK)
+ drinker.grant_language(/datum/language/piratespeak, source = LANGUAGE_DRINK)
+
+/datum/reagent/consumable/ethanol/rum/aged/on_mob_end_metabolize(mob/living/drinker)
+ if(!QDELING(drinker))
+ drinker.remove_blocked_language(subtypesof(/datum/language), LANGUAGE_DRINK)
+ drinker.remove_language(/datum/language/piratespeak, source = LANGUAGE_DRINK)
+ return ..()
+
/datum/reagent/consumable/ethanol/tequila
name = "Tequila"
description = "A strong and mildly flavoured, Mexican produced spirit. Feeling thirsty, hombre?"
diff --git a/code/modules/reagents/reagent_containers/cups/bottle.dm b/code/modules/reagents/reagent_containers/cups/bottle.dm
index fda39ed4877..2259cda34d7 100644
--- a/code/modules/reagents/reagent_containers/cups/bottle.dm
+++ b/code/modules/reagents/reagent_containers/cups/bottle.dm
@@ -129,6 +129,11 @@
desc = "A small bottle. Contains cold sauce."
list_reagents = list(/datum/reagent/consumable/frostoil = 30)
+/obj/item/reagent_containers/cup/bottle/strange_reagent
+ name = "Strange Reagent Bottle"
+ desc = "A small bottle. May be used to revive people."
+ list_reagents = list(/datum/reagent/medicine/strange_reagent = 30)
+
/obj/item/reagent_containers/cup/bottle/traitor
name = "syndicate bottle"
desc = "A small bottle. Contains a random nasty chemical."
diff --git a/code/modules/reagents/reagent_containers/cups/glassbottle.dm b/code/modules/reagents/reagent_containers/cups/glassbottle.dm
index b246cc01e07..7b2183b1f22 100644
--- a/code/modules/reagents/reagent_containers/cups/glassbottle.dm
+++ b/code/modules/reagents/reagent_containers/cups/glassbottle.dm
@@ -316,6 +316,12 @@
icon_state = "rumbottle"
list_reagents = list(/datum/reagent/consumable/ethanol/rum = 100)
+/obj/item/reagent_containers/cup/glass/bottle/rum/aged
+ name = "Captain Pete's Vintage spiced rum"
+ desc = "Shiver me timbers, a vintage edition of Captain Pete's rum. It's pratically GRIFF in a bottle from over 50 years ago."
+ icon_state = "rumbottle_gold"
+ list_reagents = list(/datum/reagent/consumable/ethanol/rum/aged = 100)
+
/obj/item/reagent_containers/cup/glass/bottle/maltliquor
name = "\improper Rabid Bear malt liquor"
desc = "A 40 full of malt liquor. Kicks stronger than, well, a rabid bear."
diff --git a/icons/obj/drinks/bottles.dmi b/icons/obj/drinks/bottles.dmi
index 205a67c84e20de01376322a4a81417f1146ad99c..cd3cf9fef09d4d1387c9eec691cc2673607feb79 100644
GIT binary patch
literal 28099
zcmaI7WmKF`@Gdw=kYE9VTkzm6!QI{6g1fr~NeCX?T?cn}cXxMp24~p${de!4-TUEw
znDg44?x(7&tGev3l7b}4XZ+6q002c=N=yX+fD(fIz9GOt-VB%muK@sP1aCDhS1~h}
zpUzf}u2v5A0DxykX3~WH8Z+|H)Qu{_#RBeO`G7(TGR<$oRZV8gh(vDLJYWp&
AW9UExOS>hCBUuhHp=zyT#!qvRMyR%S(E;C#*w0MCteDm0Hk`=M(KOD<{
zISl7+F;zlfHmUT&Q1y$`V?$LW9+?rBl)}-lZ7})aq-JAd;;$pBTg-b-{zG`bmQ^Ga
zpRqOwmP%ary`UI{=$bCecXFcbUx}n%bUfH|qSj`C^^pJ2g9v+BjVH7Qk~zJ+V7q2S
zWzFw0)psKj%NRn=`hSY9w?#{L!mp3-6T(s{wSAu|*IShPTIj&(jm2NVs<7y0-YjB|
zQ;F;kvAaPhf#YKcr{(GNY$3+I<~=y=$>r%57VhmPLu;QQLS4&J7$xAJcU8u%iM;$<
zV&oR9rMQ+KErGmRSwrkk&iJ__pXh4~PCJ*!5eP9IWPf;3EZ@dKa-+Emisavqtv8G%
zXGDrOwp4Qgf8YS xe54LYq$&-@b_Jl%Ifijfc(x)X{)Q
z?9`sl<>Zkzfk`9hmW3%hoIuW6*`2Q@*Z~wyo=1HxCa+!pU0cV5bQdZ+&rkb?kK^Q>
zdO2yxd-z5F1
z)E{IG#v&zWw_7dM{8AnpTh4h8%9X1!_P*XkD9-LIMtgR^1AVg2PhgcHC8}$bAnYTu
z1nu!V5G-Lw+JW{&XRxe1W$#iP5Ews>3wo-^8JE$o$~g06I()=f*}jqd0k3rYK*c0R
zf`6Zp$TbVEI8Yw~?;(omcRDDr%ui8Til?C&TsFuLovRY~m9g6vQXDLb*CF)RGz&X^
z`>^hDJhA=BMGVEHRr=#lPTYa-?x6l9l=7hV)Q&HXs@1t#HT}u3?v