mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-30 00:29:02 +01:00
Add messages (paper, photos, cash) in bottles. (#85703)
## About The Pull Request This PR adds a new persistent feature: message inside bottles. These are basically glass bottles with inside a piece of paper, a photo or space cash (no holocredits, and most bills rarely go over 1000 credits anyway) from a previous round, which can be fished at the beach, or from the relative fishing portals. Each piece of written paper or photo that isn't map-loaded has a roughly a 0.2% chance to be added to the message bottles database at the end of the round. However, you can also manually toss a glass bottle with inside a paper/photo/bill into the ocean (or a fishing portal generator with the ocean/beach module loaded) for guaranteed results. The bottles are removed from the database once fished up by the by, unless tossed back into the ocean. I've also offset a couple bottle sprites that weren't properly aligned (for the message overlays). TODO: - [x] add a couple (20 prob or less) message bottle spawners to the beach away mission or something. - [x] add a few sounds for adding and removing the message from the bottle. (pickup/drop sounds already handle that) - [x] test it properly. ## Why It's Good For The Game I think it'd be neat to have a way to send photos, snarky "seek grass" messages, as well as the occasional financial aid to future players, and furthermore, another thing to tie fishing to. ## Changelog 🆑 add: You can place papers, photos and cash bills (no holochips) inside bottles and then toss them into the ocean (or fishing portal gen with relative settings) with right-click, for others to fish them up on future rounds. /🆑
This commit is contained in:
@@ -406,6 +406,10 @@
|
||||
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4,
|
||||
/turf/open/floor/plating,
|
||||
/area/ruin/powered/beach)
|
||||
"mv" = (
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/misc/beach/coast,
|
||||
/area/ruin/powered/beach)
|
||||
"mw" = (
|
||||
/obj/structure/flora/coconuts,
|
||||
/turf/open/misc/beach/sand,
|
||||
@@ -985,6 +989,7 @@
|
||||
dir = 1
|
||||
},
|
||||
/obj/machinery/light/directional/south,
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/misc/beach/coast/corner{
|
||||
dir = 8
|
||||
},
|
||||
@@ -1990,7 +1995,7 @@ bG
|
||||
bL
|
||||
VI
|
||||
VI
|
||||
yT
|
||||
mv
|
||||
pz
|
||||
Eu
|
||||
pz
|
||||
|
||||
@@ -92,6 +92,10 @@
|
||||
/obj/structure/sign/clock/directional/north,
|
||||
/turf/open/floor/wood,
|
||||
/area/awaymission/beach)
|
||||
"aY" = (
|
||||
/obj/item/broken_bottle,
|
||||
/turf/open/misc/beach/sand,
|
||||
/area/awaymission/beach)
|
||||
"bg" = (
|
||||
/obj/structure/no_effect_signpost{
|
||||
pixel_y = 6;
|
||||
@@ -174,6 +178,11 @@
|
||||
/obj/machinery/light/directional/west,
|
||||
/turf/open/floor/carpet/cyan,
|
||||
/area/awaymission/beach)
|
||||
"cu" = (
|
||||
/obj/effect/mob_spawn/corpse/human/old_pirate_captain,
|
||||
/obj/structure/bed/maint,
|
||||
/turf/open/misc/beach/sand,
|
||||
/area/awaymission/beach)
|
||||
"cv" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/food/grown/watermelon{
|
||||
@@ -207,6 +216,12 @@
|
||||
dir = 4
|
||||
},
|
||||
/area/awaymission/beach)
|
||||
"cL" = (
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/misc/beach/coast{
|
||||
dir = 1
|
||||
},
|
||||
/area/awaymission/beach)
|
||||
"cR" = (
|
||||
/turf/open/floor/iron/freezer,
|
||||
/area/awaymission/beach)
|
||||
@@ -278,16 +293,6 @@
|
||||
/obj/structure/musician/piano,
|
||||
/turf/open/floor/wood,
|
||||
/area/awaymission/beach)
|
||||
"dx" = (
|
||||
/obj/structure/sign/directions/dorms/north_arrow{
|
||||
pixel_y = 35
|
||||
},
|
||||
/obj/structure/sign/directions/medical/north_arrow{
|
||||
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"
|
||||
@@ -505,10 +510,6 @@
|
||||
},
|
||||
/turf/closed/wall/mineral/wood,
|
||||
/area/awaymission/beach)
|
||||
"gq" = (
|
||||
/obj/item/broken_bottle,
|
||||
/turf/open/misc/beach/sand,
|
||||
/area/awaymission/beach)
|
||||
"gw" = (
|
||||
/obj/item/stack/sheet/mineral/sandstone{
|
||||
pixel_x = -8
|
||||
@@ -575,6 +576,10 @@
|
||||
},
|
||||
/turf/open/floor/wood,
|
||||
/area/awaymission/beach)
|
||||
"hr" = (
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/misc/beach/coast,
|
||||
/area/awaymission/beach)
|
||||
"hC" = (
|
||||
/obj/structure/railing{
|
||||
dir = 8
|
||||
@@ -898,17 +903,6 @@
|
||||
/obj/structure/table/wood,
|
||||
/turf/open/floor/wood/large,
|
||||
/area/awaymission/beach)
|
||||
"lk" = (
|
||||
/obj/effect/turf_decal/siding/wood{
|
||||
dir = 9
|
||||
},
|
||||
/obj/effect/turf_decal/tile/dark/half{
|
||||
pixel_y = -1;
|
||||
pixel_x = 5;
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/water/beach,
|
||||
/area/awaymission/beach)
|
||||
"ll" = (
|
||||
/obj/machinery/door/airlock/wood{
|
||||
name = "Room 11";
|
||||
@@ -1195,10 +1189,6 @@
|
||||
},
|
||||
/turf/open/misc/beach/sand,
|
||||
/area/awaymission/beach)
|
||||
"pq" = (
|
||||
/obj/effect/spawner/random/trash/cigbutt,
|
||||
/turf/open/misc/beach/sand,
|
||||
/area/awaymission/beach)
|
||||
"pr" = (
|
||||
/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind{
|
||||
pixel_x = -17;
|
||||
@@ -1284,6 +1274,11 @@
|
||||
/obj/structure/sink/kitchen/directional/south,
|
||||
/turf/open/floor/wood/large,
|
||||
/area/awaymission/beach)
|
||||
"qb" = (
|
||||
/obj/structure/closet/crate/bin,
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/floor/wood,
|
||||
/area/awaymission/beach)
|
||||
"qf" = (
|
||||
/obj/structure/table/bronze,
|
||||
/obj/item/pai_card{
|
||||
@@ -1710,6 +1705,12 @@
|
||||
},
|
||||
/turf/open/water/beach,
|
||||
/area/awaymission/beach)
|
||||
"vC" = (
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/misc/beach/coast{
|
||||
dir = 4
|
||||
},
|
||||
/area/awaymission/beach)
|
||||
"vF" = (
|
||||
/obj/structure/table/bronze,
|
||||
/obj/structure/sign/poster/random/directional/east,
|
||||
@@ -1840,6 +1841,18 @@
|
||||
},
|
||||
/turf/open/floor/wood/large,
|
||||
/area/awaymission/beach)
|
||||
"xt" = (
|
||||
/obj/effect/turf_decal/siding/wood{
|
||||
dir = 9
|
||||
},
|
||||
/obj/effect/turf_decal/tile/dark/half{
|
||||
pixel_y = -1;
|
||||
pixel_x = 5;
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/water/beach,
|
||||
/area/awaymission/beach)
|
||||
"xv" = (
|
||||
/turf/closed/wall/mineral/wood,
|
||||
/area/awaymission/beach)
|
||||
@@ -2581,13 +2594,6 @@
|
||||
},
|
||||
/turf/open/misc/beach/sand,
|
||||
/area/awaymission/beach)
|
||||
"FJ" = (
|
||||
/obj/item/instrument/guitar{
|
||||
pixel_y = 4;
|
||||
pixel_x = -1
|
||||
},
|
||||
/turf/open/misc/beach/coast,
|
||||
/area/awaymission/beach)
|
||||
"FK" = (
|
||||
/obj/item/toy/seashell{
|
||||
pixel_x = 12;
|
||||
@@ -2629,6 +2635,17 @@
|
||||
},
|
||||
/turf/open/floor/wood/parquet,
|
||||
/area/awaymission/beach)
|
||||
"FX" = (
|
||||
/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)
|
||||
"FY" = (
|
||||
/obj/effect/turf_decal/sand,
|
||||
/obj/effect/turf_decal/siding/wood/corner{
|
||||
@@ -2681,6 +2698,12 @@
|
||||
/obj/machinery/light/directional/north,
|
||||
/turf/open/floor/wood/large,
|
||||
/area/awaymission/beach)
|
||||
"Gy" = (
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/misc/beach/coast/corner{
|
||||
dir = 4
|
||||
},
|
||||
/area/awaymission/beach)
|
||||
"GC" = (
|
||||
/turf/open/floor/carpet,
|
||||
/area/awaymission/beach)
|
||||
@@ -2864,17 +2887,6 @@
|
||||
/obj/machinery/light/directional/west,
|
||||
/turf/open/floor/wood/large,
|
||||
/area/awaymission/beach)
|
||||
"Jv" = (
|
||||
/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)
|
||||
"JF" = (
|
||||
/obj/structure/marker_beacon/burgundy,
|
||||
/turf/open/water/beach,
|
||||
@@ -3070,6 +3082,14 @@
|
||||
/obj/machinery/light/directional/north,
|
||||
/turf/open/floor/wood,
|
||||
/area/awaymission/beach)
|
||||
"LT" = (
|
||||
/obj/item/instrument/guitar{
|
||||
pixel_y = 4;
|
||||
pixel_x = -1
|
||||
},
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/misc/beach/coast,
|
||||
/area/awaymission/beach)
|
||||
"Mm" = (
|
||||
/obj/structure/table/bronze,
|
||||
/turf/open/floor/wood/large,
|
||||
@@ -3349,12 +3369,6 @@
|
||||
},
|
||||
/turf/open/misc/beach/sand,
|
||||
/area/awaymission/beach)
|
||||
"Pb" = (
|
||||
/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)
|
||||
"Pe" = (
|
||||
/turf/open/misc/beach/coast{
|
||||
dir = 5
|
||||
@@ -3403,11 +3417,6 @@
|
||||
},
|
||||
/turf/open/misc/beach/sand,
|
||||
/area/awaymission/beach)
|
||||
"PU" = (
|
||||
/obj/effect/mob_spawn/corpse/human/old_pirate_captain,
|
||||
/obj/structure/bed/maint,
|
||||
/turf/open/misc/beach/sand,
|
||||
/area/awaymission/beach)
|
||||
"Qe" = (
|
||||
/obj/effect/turf_decal/sand,
|
||||
/obj/machinery/door/airlock/wood{
|
||||
@@ -3424,6 +3433,10 @@
|
||||
"Qg" = (
|
||||
/turf/open/floor/wood/parquet,
|
||||
/area/awaymission/beach)
|
||||
"Qi" = (
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/misc/beach/coast/corner,
|
||||
/area/awaymission/beach)
|
||||
"Qk" = (
|
||||
/obj/structure/closet/secure_closet/personal/cabinet,
|
||||
/obj/item/clothing/suit/jacket/miljacket,
|
||||
@@ -3550,6 +3563,12 @@
|
||||
},
|
||||
/turf/open/floor/wood/large,
|
||||
/area/awaymission/beach)
|
||||
"RH" = (
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/misc/beach/coast/corner{
|
||||
dir = 8
|
||||
},
|
||||
/area/awaymission/beach)
|
||||
"RI" = (
|
||||
/obj/machinery/door/airlock/medical/glass{
|
||||
name = "Medbay Clinic"
|
||||
@@ -3750,6 +3769,10 @@
|
||||
/obj/machinery/light/directional/east,
|
||||
/turf/open/floor/wood/large,
|
||||
/area/awaymission/beach)
|
||||
"UV" = (
|
||||
/obj/effect/spawner/random/trash/cigbutt,
|
||||
/turf/open/misc/beach/sand,
|
||||
/area/awaymission/beach)
|
||||
"UX" = (
|
||||
/obj/structure/flora/tree/palm/style_2{
|
||||
pixel_y = 12;
|
||||
@@ -3897,6 +3920,10 @@
|
||||
},
|
||||
/turf/open/misc/beach/sand,
|
||||
/area/awaymission/beach)
|
||||
"WD" = (
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/water/beach,
|
||||
/area/awaymission/beach)
|
||||
"WM" = (
|
||||
/obj/item/reagent_containers/cup/soda_cans/starkist{
|
||||
pixel_x = -6
|
||||
@@ -3911,6 +3938,12 @@
|
||||
/obj/item/clothing/head/soft/black,
|
||||
/turf/open/floor/wood/parquet,
|
||||
/area/awaymission/beach)
|
||||
"WU" = (
|
||||
/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)
|
||||
"Xd" = (
|
||||
/obj/structure/table/optable,
|
||||
/turf/open/floor/wood/large,
|
||||
@@ -3979,6 +4012,11 @@
|
||||
},
|
||||
/turf/open/misc/beach/sand,
|
||||
/area/awaymission/beach)
|
||||
"Yp" = (
|
||||
/obj/structure/closet/crate/trashcart/filled,
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob,
|
||||
/turf/open/floor/wood/large,
|
||||
/area/awaymission/beach)
|
||||
"Yq" = (
|
||||
/obj/item/reagent_containers/cup/watering_can{
|
||||
pixel_y = 19;
|
||||
@@ -4026,6 +4064,16 @@
|
||||
"Zp" = (
|
||||
/turf/open/floor/wood/large,
|
||||
/area/awaymission/beach)
|
||||
"Zq" = (
|
||||
/obj/structure/sign/directions/dorms/north_arrow{
|
||||
pixel_y = 35
|
||||
},
|
||||
/obj/structure/sign/directions/medical/north_arrow{
|
||||
pixel_y = 29
|
||||
},
|
||||
/obj/machinery/computer/slot_machine,
|
||||
/turf/open/floor/wood/large,
|
||||
/area/awaymission/beach)
|
||||
"Zt" = (
|
||||
/obj/structure/table/bronze,
|
||||
/obj/item/storage/toolbox/fishing{
|
||||
@@ -7443,10 +7491,10 @@ XB
|
||||
XB
|
||||
XB
|
||||
XB
|
||||
Vf
|
||||
cL
|
||||
YV
|
||||
Pb
|
||||
gq
|
||||
WU
|
||||
aY
|
||||
hL
|
||||
ni
|
||||
XB
|
||||
@@ -7700,10 +7748,10 @@ XB
|
||||
XB
|
||||
XB
|
||||
XB
|
||||
Vf
|
||||
cL
|
||||
VY
|
||||
pq
|
||||
PU
|
||||
UV
|
||||
cu
|
||||
Er
|
||||
BK
|
||||
XB
|
||||
@@ -7959,7 +8007,7 @@ XB
|
||||
XB
|
||||
Vf
|
||||
VY
|
||||
Jv
|
||||
FX
|
||||
VY
|
||||
VY
|
||||
BK
|
||||
@@ -8217,7 +8265,7 @@ XB
|
||||
Vf
|
||||
IZ
|
||||
VY
|
||||
pq
|
||||
UV
|
||||
VY
|
||||
BK
|
||||
XB
|
||||
@@ -8473,7 +8521,7 @@ XB
|
||||
XB
|
||||
Pe
|
||||
Fb
|
||||
tJ
|
||||
RH
|
||||
zr
|
||||
VY
|
||||
BK
|
||||
@@ -11423,7 +11471,7 @@ FM
|
||||
LJ
|
||||
Gn
|
||||
kI
|
||||
cp
|
||||
qb
|
||||
xv
|
||||
Zp
|
||||
xv
|
||||
@@ -11441,7 +11489,7 @@ VP
|
||||
vM
|
||||
Zt
|
||||
xv
|
||||
MF
|
||||
Gy
|
||||
Wb
|
||||
It
|
||||
VY
|
||||
@@ -12190,7 +12238,7 @@ XB
|
||||
XB
|
||||
XB
|
||||
XB
|
||||
XB
|
||||
WD
|
||||
xv
|
||||
xv
|
||||
xv
|
||||
@@ -13240,7 +13288,7 @@ xv
|
||||
xv
|
||||
xv
|
||||
xv
|
||||
dx
|
||||
Zq
|
||||
Zp
|
||||
Zp
|
||||
mb
|
||||
@@ -13780,7 +13828,7 @@ hL
|
||||
Le
|
||||
Le
|
||||
Le
|
||||
MF
|
||||
Gy
|
||||
VY
|
||||
VY
|
||||
VY
|
||||
@@ -14760,7 +14808,7 @@ XB
|
||||
XB
|
||||
HV
|
||||
mi
|
||||
uV
|
||||
Yp
|
||||
xv
|
||||
eE
|
||||
un
|
||||
@@ -15073,7 +15121,7 @@ VY
|
||||
VY
|
||||
ls
|
||||
VY
|
||||
BK
|
||||
hr
|
||||
XB
|
||||
XB
|
||||
XB
|
||||
@@ -16314,7 +16362,7 @@ vx
|
||||
Bq
|
||||
Xd
|
||||
Ej
|
||||
lk
|
||||
xt
|
||||
LC
|
||||
XB
|
||||
XB
|
||||
@@ -17609,7 +17657,7 @@ xv
|
||||
xv
|
||||
xv
|
||||
xv
|
||||
Fb
|
||||
vC
|
||||
mf
|
||||
VY
|
||||
KL
|
||||
@@ -22783,7 +22831,7 @@ VY
|
||||
EC
|
||||
VY
|
||||
VY
|
||||
Kh
|
||||
Qi
|
||||
Rj
|
||||
XB
|
||||
XB
|
||||
@@ -25323,7 +25371,7 @@ XB
|
||||
XB
|
||||
XB
|
||||
MZ
|
||||
MF
|
||||
Gy
|
||||
VY
|
||||
xv
|
||||
xv
|
||||
@@ -25611,7 +25659,7 @@ VY
|
||||
VY
|
||||
Ff
|
||||
VY
|
||||
BK
|
||||
hr
|
||||
XB
|
||||
XB
|
||||
XB
|
||||
@@ -28665,7 +28713,7 @@ XB
|
||||
XB
|
||||
XB
|
||||
XB
|
||||
Vf
|
||||
cL
|
||||
wA
|
||||
VY
|
||||
xi
|
||||
@@ -29450,7 +29498,7 @@ VY
|
||||
VY
|
||||
Rn
|
||||
VY
|
||||
FJ
|
||||
LT
|
||||
xv
|
||||
CG
|
||||
Gh
|
||||
@@ -29696,7 +29744,7 @@ XB
|
||||
XB
|
||||
XB
|
||||
XB
|
||||
Vf
|
||||
cL
|
||||
VY
|
||||
VY
|
||||
IZ
|
||||
|
||||
@@ -4,3 +4,6 @@
|
||||
#define DB_QUERY_FINISHED 1
|
||||
/// When there was a problem with the execution of a query.
|
||||
#define DB_QUERY_BROKEN 2
|
||||
|
||||
///The probability of non-maploaded photos and papers being saved as bottle messages at the end of the round.
|
||||
#define MESSAGE_BOTTLE_CHANCE 0.2
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
#define FISH_ICON_GEM "gem"
|
||||
#define FISH_ICON_CRAB "crab"
|
||||
#define FISH_ICON_JELLYFISH "jellyfish"
|
||||
#define FISH_ICON_BOTTLE "bottle"
|
||||
#define FISH_ICON_BONE "bone"
|
||||
#define FISH_ICON_ELECTRIC "electric"
|
||||
#define FISH_ICON_WEAPON "weapon"
|
||||
|
||||
@@ -18,3 +18,29 @@
|
||||
#define BARCODE_SCANNER_INVENTORY "inventory"
|
||||
|
||||
#define IS_WRITING_UTENSIL(thing) (thing?.get_writing_implement_details()?["interaction_mode"] == MODE_WRITING)
|
||||
|
||||
/**
|
||||
* key defines used when converting a paper to and fro' a data/json list. It's really important that they stay the same
|
||||
* lest we break persistence.
|
||||
*/
|
||||
#define LIST_PAPER_COLOR "paper_color"
|
||||
#define LIST_PAPER_NAME "paper_name"
|
||||
|
||||
#define LIST_PAPER_RAW_TEXT_INPUT "raw_text_input"
|
||||
#define LIST_PAPER_RAW_FIELD_INPUT "raw_field_input"
|
||||
#define LIST_PAPER_RAW_STAMP_INPUT "raw_stamp_input"
|
||||
|
||||
#define LIST_PAPER_RAW_TEXT "raw_text"
|
||||
#define LIST_PAPER_FONT "font"
|
||||
#define LIST_PAPER_FIELD_COLOR "color"
|
||||
#define LIST_PAPER_BOLD "bold"
|
||||
#define LIST_PAPER_ADVANCED_HTML "advanced_html"
|
||||
|
||||
#define LIST_PAPER_FIELD_INDEX "field_index"
|
||||
#define LIST_PAPER_FIELD_DATA "field_data"
|
||||
#define LIST_PAPER_IS_SIGNATURE "is_signature"
|
||||
|
||||
#define LIST_PAPER_CLASS "class"
|
||||
#define LIST_PAPER_STAMP_X "x"
|
||||
#define LIST_PAPER_STAMP_Y "y"
|
||||
#define LIST_PAPER_ROTATION "rotation"
|
||||
|
||||
@@ -233,6 +233,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_FISHING_SPOT "fishing_spot"
|
||||
///Trait given to mobs that can fish without a rod
|
||||
#define TRAIT_PROFOUND_FISHER "profound_fisher"
|
||||
/// If an atom has this trait, then you can toss a bottle with a message in it.
|
||||
#define TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION "message_in_a_bottle_location"
|
||||
/// This trait lets you evaluate someone's fitness level against your own
|
||||
#define TRAIT_EXAMINE_FITNESS "reveal_power_level"
|
||||
/// These mobs have particularly hygienic tongues
|
||||
|
||||
@@ -23,6 +23,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_FOOD_SILVER" = TRAIT_FOOD_SILVER,
|
||||
"TRAIT_KEEP_TOGETHER" = TRAIT_KEEP_TOGETHER,
|
||||
"TRAIT_LIGHTING_DEBUGGED" = TRAIT_LIGHTING_DEBUGGED,
|
||||
"TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION" = TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION,
|
||||
"TRAIT_RECENTLY_COINED" = TRAIT_RECENTLY_COINED,
|
||||
"TRAIT_RUSTY" = TRAIT_RUSTY,
|
||||
"TRAIT_SPINNING" = TRAIT_SPINNING,
|
||||
|
||||
@@ -48,6 +48,17 @@ SUBSYSTEM_DEF(persistence)
|
||||
var/tram_hits_this_round = 0
|
||||
var/tram_hits_last_round = 0
|
||||
|
||||
/// A json database to data/message_bottles.json
|
||||
var/datum/json_database/message_bottles_database
|
||||
/// An index used to create unique ids for the message bottles database
|
||||
var/message_bottles_index = 0
|
||||
/**
|
||||
* A list of non-maploaded photos or papers that met the 0.2% chance to be saved in the message bottles database
|
||||
* because I don't want the database to feel empty unless there's someone constantly throwing bottles in the
|
||||
* sea or beach/ocean fishing portals.
|
||||
*/
|
||||
var/list/queued_message_bottles
|
||||
|
||||
/datum/controller/subsystem/persistence/Initialize()
|
||||
load_poly()
|
||||
load_wall_engravings()
|
||||
@@ -72,11 +83,13 @@ SUBSYSTEM_DEF(persistence)
|
||||
save_scars()
|
||||
save_custom_outfits()
|
||||
save_delamination_counter()
|
||||
save_queued_message_bottles()
|
||||
if(SStransport.can_fire)
|
||||
for(var/datum/transport_controller/linear/tram/transport as anything in SStransport.transports_by_type[TRANSPORT_TYPE_TRAM])
|
||||
save_tram_history(transport.specific_transport_id)
|
||||
save_tram_counter()
|
||||
|
||||
|
||||
///Loads up Poly's speech buffer.
|
||||
/datum/controller/subsystem/persistence/proc/load_poly()
|
||||
for(var/mob/living/basic/parrot/poly/bird in GLOB.alive_mob_list)
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
///This proc is used to save photos, papers and cash stored inside a bottle when tossed into the ocean.
|
||||
/datum/controller/subsystem/persistence/proc/save_message_bottle(obj/item/message, bottle_type = /obj/item/reagent_containers/cup/glass/bottle)
|
||||
if(isnull(message_bottles_database))
|
||||
message_bottles_database = new("data/message_bottles.json")
|
||||
|
||||
var/list/data = list()
|
||||
data["bottle_type"] = text2path(bottle_type)
|
||||
if(istype(message, /obj/item/paper))
|
||||
var/obj/item/paper/paper = message
|
||||
if(!length(paper.raw_text_inputs) && !length(paper.raw_stamp_data) && !length(paper.raw_field_input_data))
|
||||
return
|
||||
data["paper"] = paper.convert_to_data()
|
||||
else if(istype(message, /obj/item/photo))
|
||||
var/obj/item/photo/photo = message
|
||||
if(!photo.picture?.id)
|
||||
return
|
||||
data["photo_id"] = photo.picture.id
|
||||
else if(istype(message, /obj/item/stack/spacecash))
|
||||
var/obj/item/stack/spacecash/cash = message
|
||||
data["cash"] = text2path(cash.type)
|
||||
data["amount"] = cash.amount
|
||||
message_bottles_index++
|
||||
message_bottles_database.set_key("message-[GLOB.round_id]-[message_bottles_index]", data)
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/load_message_bottle(atom/loc)
|
||||
if(isnull(message_bottles_database))
|
||||
message_bottles_database = new("data/message_bottles.json")
|
||||
|
||||
var/list/data = message_bottles_database.pick_and_take_key()
|
||||
if(!data)
|
||||
var/obj/item/reagent_containers/cup/glass/bottle/bottle = new(loc)
|
||||
return bottle
|
||||
|
||||
var/bottle_type = text2path(data["bottle_type"]) || /obj/item/reagent_containers/cup/glass/bottle
|
||||
var/obj/item/reagent_containers/cup/glass/bottle/bottle = new bottle_type(loc)
|
||||
bottle.reagents.remove_all(bottle.reagents.maximum_volume)
|
||||
if(data["photo_id"])
|
||||
var/obj/item/photo/old/photo = load_photo_from_disk(data["photo_id"], bottle)
|
||||
bottle.message_in_a_bottle = photo
|
||||
else if(data["cash"])
|
||||
var/cash_type = text2path(data["cash"]) || /obj/item/stack/spacecash/c10
|
||||
var/obj/item/stack/spacecash/cash = new cash_type(bottle, data["amount"])
|
||||
bottle.message_in_a_bottle = cash
|
||||
else if(data["paper"])
|
||||
var/obj/item/paper/paper = new(bottle)
|
||||
paper.write_from_data(data["paper"])
|
||||
bottle.message_in_a_bottle = paper
|
||||
|
||||
bottle.update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/save_queued_message_bottles()
|
||||
for(var/item in queued_message_bottles)
|
||||
save_message_bottle(item)
|
||||
queued_message_bottles = null
|
||||
@@ -12,7 +12,7 @@
|
||||
fish_source = configuration
|
||||
else
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
fish_source.on_fishing_spot_init()
|
||||
fish_source.on_fishing_spot_init(src)
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(handle_attackby))
|
||||
RegisterSignal(parent, COMSIG_FISHING_ROD_CAST, PROC_REF(handle_cast))
|
||||
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examined))
|
||||
@@ -22,6 +22,7 @@
|
||||
ADD_TRAIT(parent, TRAIT_FISHING_SPOT, REF(src))
|
||||
|
||||
/datum/component/fishing_spot/Destroy()
|
||||
fish_source.on_fishing_spot_del(src)
|
||||
fish_source = null
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -61,6 +61,16 @@
|
||||
/datum/json_database/proc/get_key(key)
|
||||
return cached_data[key]
|
||||
|
||||
/// Picks the data of a random key and then removes that key from the database.
|
||||
/// Since the list is no longer inside the database, you can mutate and use it as you like.
|
||||
/datum/json_database/proc/pick_and_take_key()
|
||||
if(!length(cached_data))
|
||||
return null
|
||||
var/key = pick(cached_data)
|
||||
. = cached_data[key]
|
||||
cached_data -= key
|
||||
queue_save()
|
||||
|
||||
/// Sets the data at the key to the value, and queues a save.
|
||||
/datum/json_database/proc/set_key(key, value)
|
||||
cached_data[key] = value
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/obj/effect/spawner/message_in_a_bottle
|
||||
name = "message in a bottle"
|
||||
desc = "Sending out an SOS"
|
||||
icon = 'icons/effects/random_spawners.dmi'
|
||||
icon_state = "message_bottle"
|
||||
var/probability = 100
|
||||
|
||||
/obj/effect/spawner/message_in_a_bottle/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!prob(probability))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
if(!SSpersistence.initialized)
|
||||
RegisterSignal(SSpersistence, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(on_persistence_init))
|
||||
else
|
||||
SSpersistence.load_message_bottle(loc)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/effect/spawner/message_in_a_bottle/proc/on_persistence_init(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
UnregisterSignal(SSpersistence, COMSIG_SUBSYSTEM_POST_INITIALIZE)
|
||||
SSpersistence.load_message_bottle(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/spawner/message_in_a_bottle/low_prob
|
||||
probability = 1.5
|
||||
@@ -292,6 +292,14 @@
|
||||
foodtypes = FRUIT | ALCOHOL
|
||||
crafting_complexity = FOOD_COMPLEXITY_2
|
||||
|
||||
/obj/item/food/melonkeg/CheckParts(list/parts_list)
|
||||
. = ..()
|
||||
var/obj/item/reagent_containers/cup/glass/bottle/bottle = locate() in contents
|
||||
if(!bottle)
|
||||
return
|
||||
if(bottle.message_in_a_bottle)
|
||||
bottle.message_in_a_bottle.forceMove(drop_location())
|
||||
|
||||
/obj/item/food/honeybar
|
||||
name = "honey nut bar"
|
||||
desc = "Oats and nuts compressed together into a bar, held together with a honey glaze."
|
||||
|
||||
@@ -41,6 +41,10 @@
|
||||
clawfootstep = FOOTSTEP_WATER
|
||||
heavyfootstep = FOOTSTEP_WATER
|
||||
|
||||
/turf/open/misc/beach/coast/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION, INNATE_TRAIT)
|
||||
|
||||
/turf/open/misc/beach/coast/break_tile()
|
||||
. = ..()
|
||||
icon_state = "beach"
|
||||
|
||||
@@ -43,6 +43,10 @@
|
||||
immerse_overlay_color = "#7799AA"
|
||||
fishing_datum = /datum/fish_source/ocean/beach
|
||||
|
||||
/turf/open/water/beach/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION, INNATE_TRAIT)
|
||||
|
||||
/turf/open/water/lavaland_atmos
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
planetary_atmos = TRUE
|
||||
|
||||
@@ -10,10 +10,14 @@
|
||||
#define MANIFEST_ERROR_ITEM (1 << 2)
|
||||
|
||||
/obj/item/paper/fluff/jobs/cargo/manifest
|
||||
can_become_message_in_bottle = FALSE //A lot of these are spawned each round, they'd only dilute the pool and make it boring.
|
||||
var/order_cost = 0
|
||||
var/order_id = 0
|
||||
var/errors = 0
|
||||
|
||||
/obj/item/paper/requisition
|
||||
can_become_message_in_bottle = FALSE //A lot of these are spawned each round, they'd only dilute the pool and make it boring.
|
||||
|
||||
/obj/item/paper/fluff/jobs/cargo/manifest/Initialize(mapload, id, cost, manifest_can_fail = TRUE)
|
||||
. = ..()
|
||||
order_id = id
|
||||
@@ -99,7 +103,7 @@
|
||||
return round(cost)
|
||||
|
||||
/datum/supply_order/proc/generateRequisition(turf/T)
|
||||
var/obj/item/paper/requisition_paper = new(T)
|
||||
var/obj/item/paper/requisition/requisition_paper = new(T)
|
||||
|
||||
requisition_paper.name = "requisition form - #[id] ([pack.name])"
|
||||
var/requisition_text = "<h2>[station_name()] Supply Requisition</h2>"
|
||||
|
||||
@@ -329,7 +329,7 @@
|
||||
else
|
||||
//create the paper from the SSshuttle.shopping_list
|
||||
if(length(SSshuttle.shopping_list))
|
||||
var/obj/item/paper/requisition_paper = new(get_turf(src))
|
||||
var/obj/item/paper/requisition/requisition_paper = new(get_turf(src))
|
||||
requisition_paper.name = "requisition form - [station_time_timestamp()]"
|
||||
var/requisition_text = "<h2>[station_name()] Supply Requisition</h2>"
|
||||
requisition_text += "<hr/>"
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
/// Background icon state from fishing_hud.dmi
|
||||
var/background = "background_default"
|
||||
/// Fish icon state from fishing_hud.dmi
|
||||
var/fish_icon = "fish"
|
||||
var/fish_icon = FISH_ICON_DEF
|
||||
|
||||
/// Fishing line visual
|
||||
var/datum/beam/fishing_line
|
||||
@@ -164,7 +164,7 @@
|
||||
completion -= MAX_FISH_COMPLETION_MALUS * (difficulty * 0.01)
|
||||
|
||||
if(HAS_MIND_TRAIT(user, TRAIT_REVEAL_FISH))
|
||||
fish_icon = GLOB.specific_fish_icons[reward_path] || "fish"
|
||||
fish_icon = GLOB.specific_fish_icons[reward_path] || FISH_ICON_DEF
|
||||
|
||||
mover.adjust_to_difficulty()
|
||||
|
||||
@@ -352,6 +352,8 @@
|
||||
send_alert("critter!!!")
|
||||
if(FISH_ICON_SEED)
|
||||
send_alert("seed!!!")
|
||||
if(FISH_ICON_BOTTLE)
|
||||
send_alert("bottle!!!")
|
||||
else
|
||||
send_alert("!!!")
|
||||
animate(lure, pixel_y = 3, time = 5, loop = -1, flags = ANIMATION_RELATIVE)
|
||||
|
||||
@@ -18,6 +18,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
/mob/living/basic/mining = FISH_ICON_HOSTILE,
|
||||
/obj/effect/decal/remains = FISH_ICON_BONE,
|
||||
/obj/effect/mob_spawn/corpse = FISH_ICON_BONE,
|
||||
/obj/effect/spawner/message_in_a_bottle = FISH_ICON_BOTTLE,
|
||||
/obj/item/coin = FISH_ICON_COIN,
|
||||
/obj/item/fish = FISH_ICON_DEF,
|
||||
/obj/item/fish/armorfish = FISH_ICON_CRAB,
|
||||
@@ -46,6 +47,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
/obj/item/stack/sheet/mineral = FISH_ICON_GEM,
|
||||
/obj/item/stack/ore = FISH_ICON_GEM,
|
||||
/obj/structure/closet/crate = FISH_ICON_COIN,
|
||||
/obj/structure/mystery_box = FISH_ICON_COIN,
|
||||
))
|
||||
|
||||
return_list[FISHING_RANDOM_SEED] = FISH_ICON_SEED
|
||||
@@ -97,9 +99,12 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
|
||||
return ..()
|
||||
|
||||
///Called when src is set as the fish source of a fishing spot component
|
||||
/datum/fish_source/proc/on_fishing_spot_init(/datum/component/fishing_spot/spot)
|
||||
/datum/fish_source/proc/on_fishing_spot_init(datum/component/fishing_spot/spot)
|
||||
return
|
||||
|
||||
///Called whenever a fishing spot with this fish source attached is deleted
|
||||
/datum/fish_source/proc/on_fishing_spot_del(datum/component/fishing_spot/spot)
|
||||
|
||||
/// Can we fish in this spot at all. Returns DENIAL_REASON or null if we're good to go
|
||||
/datum/fish_source/proc/reason_we_cant_fish(obj/item/fishing_rod/rod, mob/fisherman, atom/parent)
|
||||
return rod.reason_we_cant_fish(src)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/fish_source/ocean
|
||||
fish_table = list(
|
||||
FISHING_DUD = 15,
|
||||
FISHING_DUD = 11,
|
||||
/obj/effect/spawner/message_in_a_bottle = 4,
|
||||
/obj/item/coin/gold = 7,
|
||||
/obj/item/fish/clownfish = 15,
|
||||
/obj/item/fish/pufferfish = 15,
|
||||
@@ -11,7 +12,7 @@
|
||||
/obj/item/fish/zipzap = 7,
|
||||
/obj/item/fish/clownfish/lube = 5,
|
||||
/obj/item/fish/swordfish = 5,
|
||||
/obj/structure/mystery_box/fishing = 1,
|
||||
/obj/structure/mystery_box/fishing = 2,
|
||||
)
|
||||
fish_counts = list(
|
||||
/obj/item/fish/clownfish/lube = 2,
|
||||
@@ -96,7 +97,8 @@
|
||||
|
||||
/datum/fish_source/portal/beach
|
||||
fish_table = list(
|
||||
FISHING_DUD = 10,
|
||||
FISHING_DUD = 7,
|
||||
/obj/effect/spawner/message_in_a_bottle = 3,
|
||||
/obj/item/fish/clownfish = 10,
|
||||
/obj/item/fish/pufferfish = 10,
|
||||
/obj/item/fish/cardinal = 10,
|
||||
@@ -107,6 +109,12 @@
|
||||
radial_state = "palm_beach"
|
||||
overlay_state = "portal_beach"
|
||||
|
||||
/datum/fish_source/portal/beach/on_fishing_spot_init(datum/component/fishing_spot/spot)
|
||||
ADD_TRAIT(spot.parent, TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION, INNATE_TRAIT)
|
||||
|
||||
/datum/fish_source/portal/beach/on_fishing_spot_del(datum/component/fishing_spot/spot)
|
||||
REMOVE_TRAIT(spot.parent, TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION, INNATE_TRAIT)
|
||||
|
||||
/datum/fish_source/portal/chasm
|
||||
background = "background_lavaland"
|
||||
fish_table = list(
|
||||
@@ -123,7 +131,8 @@
|
||||
|
||||
/datum/fish_source/portal/ocean
|
||||
fish_table = list(
|
||||
FISHING_DUD = 5,
|
||||
FISHING_DUD = 3,
|
||||
/obj/effect/spawner/message_in_a_bottle = 2,
|
||||
/obj/item/fish/lanternfish = 5,
|
||||
/obj/item/fish/firefish = 5,
|
||||
/obj/item/fish/dwarf_moonfish = 5,
|
||||
@@ -146,6 +155,12 @@
|
||||
overlay_state = "portal_ocean"
|
||||
radial_state = "seaboat"
|
||||
|
||||
/datum/fish_source/portal/ocean/on_fishing_spot_init(datum/component/fishing_spot/spot)
|
||||
ADD_TRAIT(spot.parent, TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION, INNATE_TRAIT)
|
||||
|
||||
/datum/fish_source/portal/ocean/on_fishing_spot_del(datum/component/fishing_spot/spot)
|
||||
REMOVE_TRAIT(spot.parent, TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION, INNATE_TRAIT)
|
||||
|
||||
/datum/fish_source/portal/hyperspace
|
||||
fish_table = list(
|
||||
FISHING_DUD = 5,
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
|
||||
// This is the home of drink related tablecrafting recipes, I have opted to only let players bottle fancy boozes to reduce the number of entries.
|
||||
|
||||
///Abstract types for all drink recipes that use bottles and result in another bottle, so that the message_in_a_bottle item is properly transferred.
|
||||
/datum/crafting_recipe/bottled
|
||||
parts = list(/obj/item/reagent_containers/cup/glass/bottle = 1)
|
||||
|
||||
///////////////// Booze & Bottles ///////////////////
|
||||
|
||||
/datum/crafting_recipe/lizardwine
|
||||
@@ -14,7 +18,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/lizardwine
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/moonshinejug
|
||||
/datum/crafting_recipe/bottled/moonshinejug
|
||||
name = "Moonshine Jug"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -24,7 +28,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/moonshine
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/hoochbottle
|
||||
/datum/crafting_recipe/bottled/hoochbottle
|
||||
name = "Hooch Bottle"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -35,7 +39,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/hooch
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/blazaambottle
|
||||
/datum/crafting_recipe/bottled/blazaambottle
|
||||
name = "Blazaam Bottle"
|
||||
time = 20
|
||||
reqs = list(
|
||||
@@ -45,7 +49,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/blazaam
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/champagnebottle
|
||||
/datum/crafting_recipe/bottled/champagnebottle
|
||||
name = "Champagne Bottle"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -55,7 +59,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/champagne
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/trappistbottle
|
||||
/datum/crafting_recipe/bottled/trappistbottle
|
||||
name = "Trappist Bottle"
|
||||
time = 15
|
||||
reqs = list(
|
||||
@@ -65,7 +69,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/trappist
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/goldschlagerbottle
|
||||
/datum/crafting_recipe/bottled/goldschlagerbottle
|
||||
name = "Goldschlager Bottle"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -75,7 +79,7 @@
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/goldschlager
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/patronbottle
|
||||
/datum/crafting_recipe/bottled/patronbottle
|
||||
name = "Patron Bottle"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -87,7 +91,7 @@
|
||||
|
||||
////////////////////// Non-alcoholic recipes ///////////////////
|
||||
|
||||
/datum/crafting_recipe/holybottle
|
||||
/datum/crafting_recipe/bottled/holybottle
|
||||
name = "Holy Water Flask"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -99,7 +103,7 @@
|
||||
|
||||
//flask of unholy water is a beaker for some reason, I will try making it a bottle and add it here once the antag freeze is over. t. kryson
|
||||
|
||||
/datum/crafting_recipe/nothingbottle
|
||||
/datum/crafting_recipe/bottled/nothingbottle
|
||||
name = "Nothing Bottle"
|
||||
time = 30
|
||||
reqs = list(
|
||||
@@ -116,7 +120,7 @@
|
||||
reqs = list(/obj/item/stack/sheet/cardboard = 1)
|
||||
category = CAT_CONTAINERS
|
||||
|
||||
/datum/crafting_recipe/candycornliquor
|
||||
/datum/crafting_recipe/bottled/candycornliquor
|
||||
name = "candy corn liquor"
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/candycornliquor
|
||||
time = 30
|
||||
@@ -125,7 +129,7 @@
|
||||
/obj/item/reagent_containers/cup/glass/bottle = 1)
|
||||
category = CAT_DRINK
|
||||
|
||||
/datum/crafting_recipe/kong
|
||||
/datum/crafting_recipe/bottled/kong
|
||||
name = "Kong"
|
||||
result = /obj/item/reagent_containers/cup/glass/bottle/kong
|
||||
time = 30
|
||||
|
||||
@@ -64,6 +64,9 @@
|
||||
///If TRUE, staff can read paper everywhere, but usually from requests panel.
|
||||
var/request_state = FALSE
|
||||
|
||||
///If this paper can be selected as a candidate for a future message in a bottle when spawned outside of mapload. Doesn't affect manually doing that.
|
||||
var/can_become_message_in_bottle = TRUE
|
||||
|
||||
/obj/item/paper/Initialize(mapload)
|
||||
. = ..()
|
||||
pixel_x = base_pixel_x + rand(-9, 9)
|
||||
@@ -74,10 +77,14 @@
|
||||
|
||||
update_appearance()
|
||||
|
||||
if(can_become_message_in_bottle && !mapload && prob(MESSAGE_BOTTLE_CHANCE))
|
||||
LAZYADD(SSpersistence.queued_message_bottles, src)
|
||||
|
||||
/obj/item/paper/Destroy()
|
||||
. = ..()
|
||||
camera_holder = null
|
||||
clear_paper()
|
||||
LAZYREMOVE(SSpersistence.queued_message_bottles, src)
|
||||
return ..()
|
||||
|
||||
/// Determines whether this paper has been written or stamped to.
|
||||
/obj/item/paper/proc/is_empty()
|
||||
@@ -527,22 +534,10 @@
|
||||
|
||||
static_data["user_name"] = user.real_name
|
||||
|
||||
static_data["raw_text_input"] = list()
|
||||
for(var/datum/paper_input/text_input as anything in raw_text_inputs)
|
||||
static_data["raw_text_input"] += list(text_input.to_list())
|
||||
|
||||
static_data["raw_field_input"] = list()
|
||||
for(var/datum/paper_field/field_input as anything in raw_field_input_data)
|
||||
static_data["raw_field_input"] += list(field_input.to_list())
|
||||
|
||||
static_data["raw_stamp_input"] = list()
|
||||
for(var/datum/paper_stamp/stamp_input as anything in raw_stamp_data)
|
||||
static_data["raw_stamp_input"] += list(stamp_input.to_list())
|
||||
static_data += convert_to_data()
|
||||
|
||||
static_data["max_length"] = MAX_PAPER_LENGTH
|
||||
static_data["max_input_field_length"] = MAX_PAPER_INPUT_FIELD_LENGTH
|
||||
static_data["paper_color"] = color ? color : COLOR_WHITE
|
||||
static_data["paper_name"] = name
|
||||
|
||||
static_data["default_pen_font"] = PEN_FONT
|
||||
static_data["default_pen_color"] = COLOR_BLACK
|
||||
@@ -550,6 +545,43 @@
|
||||
|
||||
return static_data;
|
||||
|
||||
/obj/item/paper/proc/convert_to_data()
|
||||
var/list/data = list()
|
||||
|
||||
data[LIST_PAPER_RAW_TEXT_INPUT] = list()
|
||||
for(var/datum/paper_input/text_input as anything in raw_text_inputs)
|
||||
data[LIST_PAPER_RAW_TEXT_INPUT] += list(text_input.to_list())
|
||||
|
||||
data[LIST_PAPER_RAW_FIELD_INPUT] = list()
|
||||
for(var/datum/paper_field/field_input as anything in raw_field_input_data)
|
||||
data[LIST_PAPER_RAW_FIELD_INPUT] += list(field_input.to_list())
|
||||
|
||||
data[LIST_PAPER_RAW_STAMP_INPUT] = list()
|
||||
for(var/datum/paper_stamp/stamp_input as anything in raw_stamp_data)
|
||||
data[LIST_PAPER_RAW_STAMP_INPUT] += list(stamp_input.to_list())
|
||||
|
||||
data[LIST_PAPER_COLOR] = color ? color : COLOR_WHITE
|
||||
data[LIST_PAPER_NAME] = name
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/paper/proc/write_from_data(list/data)
|
||||
for(var/list/input as anything in data[LIST_PAPER_RAW_TEXT_INPUT])
|
||||
add_raw_text(input[LIST_PAPER_RAW_TEXT], input[LIST_PAPER_FONT], input[LIST_PAPER_FIELD_COLOR], input[LIST_PAPER_BOLD], input[LIST_PAPER_ADVANCED_HTML])
|
||||
|
||||
for(var/list/field as anything in data[LIST_PAPER_RAW_FIELD_INPUT])
|
||||
var/list/input = field[LIST_PAPER_FIELD_DATA]
|
||||
add_field_input(field[LIST_PAPER_FIELD_INDEX], input[LIST_PAPER_RAW_TEXT], input[LIST_PAPER_FONT], input[LIST_PAPER_FIELD_COLOR], input[LIST_PAPER_BOLD], field[LIST_PAPER_IS_SIGNATURE])
|
||||
|
||||
for(var/list/stamp as anything in data[LIST_PAPER_RAW_STAMP_INPUT])
|
||||
add_stamp(stamp[LIST_PAPER_CLASS], stamp[LIST_PAPER_STAMP_X], stamp[LIST_PAPER_STAMP_Y], stamp[LIST_PAPER_ROTATION])
|
||||
|
||||
var/new_color = data[LIST_PAPER_COLOR]
|
||||
if(new_color != COLOR_WHITE)
|
||||
add_atom_colour(new_color, FIXED_COLOUR_PRIORITY)
|
||||
|
||||
name = data[LIST_PAPER_NAME]
|
||||
|
||||
/obj/item/paper/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
@@ -753,11 +785,11 @@
|
||||
|
||||
/datum/paper_input/proc/to_list()
|
||||
return list(
|
||||
raw_text = raw_text,
|
||||
font = font,
|
||||
color = colour,
|
||||
bold = bold,
|
||||
advanced_html = advanced_html,
|
||||
LIST_PAPER_RAW_TEXT = raw_text,
|
||||
LIST_PAPER_FONT = font,
|
||||
LIST_PAPER_FIELD_COLOR = colour,
|
||||
LIST_PAPER_BOLD = bold,
|
||||
LIST_PAPER_ADVANCED_HTML = advanced_html,
|
||||
)
|
||||
|
||||
/// Returns the raw contents of the input as html, with **ZERO SANITIZATION**
|
||||
@@ -793,10 +825,10 @@
|
||||
|
||||
/datum/paper_stamp/proc/to_list()
|
||||
return list(
|
||||
class = class,
|
||||
x = stamp_x,
|
||||
y = stamp_y,
|
||||
rotation = rotation,
|
||||
LIST_PAPER_CLASS = class,
|
||||
LIST_PAPER_STAMP_X = stamp_x,
|
||||
LIST_PAPER_STAMP_Y = stamp_y,
|
||||
LIST_PAPER_ROTATION = rotation,
|
||||
)
|
||||
|
||||
/// A reference to some data that replaces a modifiable input field at some given index in paper raw input parsing.
|
||||
@@ -818,9 +850,9 @@
|
||||
|
||||
/datum/paper_field/proc/to_list()
|
||||
return list(
|
||||
field_index = field_index,
|
||||
field_data = field_data.to_list(),
|
||||
is_signature = is_signature,
|
||||
LIST_PAPER_FIELD_INDEX = field_index,
|
||||
LIST_PAPER_FIELD_DATA = field_data.to_list(),
|
||||
LIST_PAPER_IS_SIGNATURE = is_signature,
|
||||
)
|
||||
|
||||
/obj/item/paper/construction
|
||||
|
||||
@@ -9,12 +9,21 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 50
|
||||
drop_sound = 'sound/items/handling/paper_drop.ogg'
|
||||
pickup_sound = 'sound/items/handling/paper_pickup.ogg'
|
||||
grind_results = list(/datum/reagent/iodine = 4)
|
||||
var/datum/picture/picture
|
||||
var/scribble //Scribble on the back.
|
||||
|
||||
/obj/item/photo/Initialize(mapload, datum/picture/P, datum_name = TRUE, datum_desc = TRUE)
|
||||
set_picture(P, datum_name, datum_desc, TRUE)
|
||||
//Photos are quite rarer than papers, so they're more likely to be added to the queue to make things even.
|
||||
if(!mapload && prob(MESSAGE_BOTTLE_CHANCE * 5) && picture?.id)
|
||||
LAZYADD(SSpersistence.queued_message_bottles, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/photo/Destroy()
|
||||
LAZYREMOVE(SSpersistence.queued_message_bottles, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/photo/proc/set_picture(datum/picture/P, setname, setdesc, name_override = FALSE)
|
||||
|
||||
@@ -39,11 +39,93 @@
|
||||
var/bottle_knockdown_duration = BOTTLE_KNOCKDOWN_DEFAULT_DURATION
|
||||
tool_behaviour = TOOL_ROLLINGPIN // Used to knock out the Chef.
|
||||
toolspeed = 1.3 //it's a little awkward to use, but it's a cylinder alright.
|
||||
/// A contained piece of paper, a photo, or space cash, that we can use as a message or gift to future spessmen.
|
||||
var/obj/item/message_in_a_bottle
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/Initialize(mapload, vol)
|
||||
. = ..()
|
||||
var/static/list/recipes = list(/datum/crafting_recipe/molotov)
|
||||
AddElement(/datum/element/slapcrafting, recipes)
|
||||
register_context()
|
||||
register_item_context()
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
|
||||
if(message_in_a_bottle)
|
||||
return NONE
|
||||
if(istype(held_item, /obj/item/paper) || istype(held_item, /obj/item/stack/spacecash) || istype(held_item, /obj/item/photo))
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Insert message"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
return NONE
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/add_item_context(obj/item/source, list/context, atom/target, mob/living/user)
|
||||
if(message_in_a_bottle && HAS_TRAIT(target, TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION))
|
||||
context[SCREENTIP_CONTEXT_RMB] = "Toss message"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
return NONE
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/Exited(atom/movable/gone, atom/newloc)
|
||||
if(gone == message_in_a_bottle)
|
||||
message_in_a_bottle = null
|
||||
if(!QDELETED(src))
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
return ..()
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/CheckParts(list/parts_list)
|
||||
. = ..()
|
||||
var/obj/item/reagent_containers/cup/glass/bottle/bottle = locate() in contents
|
||||
if(bottle.message_in_a_bottle)
|
||||
message_in_a_bottle = bottle.message_in_a_bottle
|
||||
bottle.message_in_a_bottle.forceMove(src)
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/examine(mob/user)
|
||||
. = ..()
|
||||
if(message_in_a_bottle)
|
||||
. += span_info("there's \a [message_in_a_bottle] inside it. Break it to take it out, or find a beach or ocean and toss it with [EXAMINE_HINT("right-click")].")
|
||||
else if(isGlass)
|
||||
. += span_tinynoticeital("you could place a paper, photo or space cash inside it...")
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/update_overlays()
|
||||
. = ..()
|
||||
if(message_in_a_bottle)
|
||||
var/overlay = add_message_overlay()
|
||||
if(overlay)
|
||||
. += overlay
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/interact_with_atom_secondary(atom/target, mob/living/user, list/modifiers)
|
||||
if(user.combat_mode || !HAS_TRAIT(target, TRAIT_MESSAGE_IN_A_BOTTLE_LOCATION))
|
||||
return ..()
|
||||
if(!user.temporarilyRemoveItemFromInventory(src))
|
||||
balloon_alert(user, "it's stuck to your hand!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
user.visible_message(span_notice("[user] tosses [src] in [target]"), span_notice("You toss [src] in [target]"), span_notice("you hear a splash."))
|
||||
SSpersistence.save_message_bottle(message_in_a_bottle, type)
|
||||
playsound(target, 'sound/effects/bigsplash.ogg', 70)
|
||||
qdel(src)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/item_interaction(mob/living/user, obj/item/item, list/modifiers)
|
||||
if(!isGlass)
|
||||
return NONE
|
||||
if(!istype(item, /obj/item/paper) && !istype(item, /obj/item/stack/spacecash) && !istype(item, /obj/item/photo))
|
||||
return NONE
|
||||
if(message_in_a_bottle)
|
||||
balloon_alert(user, "has a message already!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
if(!user.transferItemToLoc(item, src))
|
||||
balloon_alert(user, "it's stuck to your hand!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
balloon_alert(user, "message inserted")
|
||||
message_in_a_bottle = item
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/proc/add_message_overlay()
|
||||
if(istype(message_in_a_bottle, /obj/item/paper))
|
||||
return "paper_in_bottle"
|
||||
if(istype(message_in_a_bottle, /obj/item/photo))
|
||||
return "photo_in_bottle"
|
||||
if(istype(message_in_a_bottle, /obj/item/stack/spacecash))
|
||||
return "cash_in_bottle"
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/small
|
||||
name = "small glass bottle"
|
||||
@@ -56,14 +138,16 @@
|
||||
if(bartender_check(target) && ranged)
|
||||
return
|
||||
SplashReagents(target, ranged, override_spillable = TRUE)
|
||||
var/obj/item/broken_bottle/B = new(drop_location())
|
||||
var/obj/item/broken_bottle/broken = new(drop_location())
|
||||
if(!ranged && thrower)
|
||||
thrower.put_in_hands(B)
|
||||
B.mimic_broken(src, target, break_top)
|
||||
B.inhand_icon_state = broken_inhand_icon_state
|
||||
thrower.put_in_hands(broken)
|
||||
broken.mimic_broken(src, target, break_top)
|
||||
broken.inhand_icon_state = broken_inhand_icon_state
|
||||
if(message_in_a_bottle)
|
||||
message_in_a_bottle.forceMove(drop_location())
|
||||
|
||||
qdel(src)
|
||||
target.Bumped(B)
|
||||
target.Bumped(broken)
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/try_splash(mob/living/user, atom/target)
|
||||
|
||||
@@ -339,6 +423,9 @@
|
||||
list_reagents = list(/datum/reagent/water/holywater = 100)
|
||||
drink_type = NONE
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/holywater/add_message_overlay()
|
||||
return //looks too weird...
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/holywater/hell
|
||||
desc = "A flask of holy water...it's been sitting in the Necropolis a while though."
|
||||
icon_state = "unholyflask"
|
||||
@@ -501,7 +588,6 @@
|
||||
list_reagents = list(/datum/reagent/consumable/ethanol/sake = 100)
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/sake/Initialize(mapload)
|
||||
. = ..()
|
||||
if(prob(10))
|
||||
name = "Fluffy Tail Sake"
|
||||
desc += " On the bottle is a picture of a kitsune with nine touchable tails."
|
||||
@@ -510,6 +596,12 @@
|
||||
name = "Inubashiri's Home Brew"
|
||||
desc += " Awoo."
|
||||
icon_state = "sakebottle_i"
|
||||
return ..()
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/sake/add_message_overlay()
|
||||
if(icon_state == "sakebottle_k") //doesn't fit the sprite
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/fernet
|
||||
name = "Fernet Bronca"
|
||||
@@ -530,6 +622,9 @@
|
||||
icon_state = "curacao_bottle"
|
||||
list_reagents = list(/datum/reagent/consumable/ethanol/curacao = 100)
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/curacao/add_message_overlay()
|
||||
return //doesn't fit the sprite
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/navy_rum
|
||||
name = "Pride of the Union Navy-Strength Rum"
|
||||
desc = "Ironically named, given it's made in Bermuda."
|
||||
@@ -574,6 +669,9 @@
|
||||
///Whether this bottle was a victim of a successful sabrage attempt
|
||||
var/sabraged = FALSE
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/champagne/add_message_overlay()
|
||||
return //doesn't stylistically fit the sprite
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/champagne/cursed
|
||||
sabrage_success_percentile = 0 //force of the sharp item used to sabrage will not increase success chance
|
||||
|
||||
@@ -733,12 +831,18 @@
|
||||
icon_state = "hoochbottle"
|
||||
list_reagents = list(/datum/reagent/consumable/ethanol/hooch = 100)
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/hooch/add_message_overlay()
|
||||
return //doesn't fit the sprite
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/moonshine
|
||||
name = "moonshine jug"
|
||||
desc = "It is said that the ancient Applalacians used these stoneware jugs to capture lightning in a bottle."
|
||||
icon_state = "moonshinebottle"
|
||||
list_reagents = list(/datum/reagent/consumable/ethanol/moonshine = 100)
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/moonshine/add_message_overlay()
|
||||
return //doesn't fit the sprite
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/mushi_kombucha
|
||||
name = "Solzara Brewing Company Mushi Kombucha"
|
||||
desc = "Best drunk over ice to savour the mushroomy flavour."
|
||||
@@ -790,15 +894,15 @@
|
||||
)
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/molotov/CheckParts(list/parts_list)
|
||||
..()
|
||||
var/obj/item/reagent_containers/cup/glass/bottle/B = locate() in contents
|
||||
if(B)
|
||||
icon_state = B.icon_state
|
||||
B.reagents.copy_to(src, 100)
|
||||
if(istype(B, /obj/item/reagent_containers/cup/glass/bottle/juice))
|
||||
desc += " You're not sure if making this out of a carton was the brightest idea."
|
||||
isGlass = FALSE
|
||||
return
|
||||
. = ..()
|
||||
var/obj/item/reagent_containers/cup/glass/bottle/bottle = locate() in contents
|
||||
if(!bottle)
|
||||
return
|
||||
icon_state = bottle.icon_state
|
||||
bottle.reagents.copy_to(src, 100)
|
||||
if(istype(bottle, /obj/item/reagent_containers/cup/glass/bottle/juice))
|
||||
desc += " You're not sure if making this out of a carton was the brightest idea."
|
||||
isGlass = FALSE
|
||||
|
||||
/obj/item/reagent_containers/cup/glass/bottle/molotov/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum, do_splash = FALSE)
|
||||
..(hit_atom, throwingdatum, do_splash = FALSE)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 95 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
@@ -740,6 +740,7 @@
|
||||
#include "code\controllers\subsystem\persistence\counter_tram_hits.dm"
|
||||
#include "code\controllers\subsystem\persistence\custom_outfits.dm"
|
||||
#include "code\controllers\subsystem\persistence\engravings.dm"
|
||||
#include "code\controllers\subsystem\persistence\message_bottles.dm"
|
||||
#include "code\controllers\subsystem\persistence\photo_albums.dm"
|
||||
#include "code\controllers\subsystem\persistence\piggy_banks.dm"
|
||||
#include "code\controllers\subsystem\persistence\recipes.dm"
|
||||
@@ -2291,6 +2292,7 @@
|
||||
#include "code\game\objects\effects\spawners\bombspawner.dm"
|
||||
#include "code\game\objects\effects\spawners\costume.dm"
|
||||
#include "code\game\objects\effects\spawners\gibspawner.dm"
|
||||
#include "code\game\objects\effects\spawners\message_in_a_bottle.dm"
|
||||
#include "code\game\objects\effects\spawners\structure.dm"
|
||||
#include "code\game\objects\effects\spawners\xeno_egg_delivery.dm"
|
||||
#include "code\game\objects\effects\spawners\random\ai_module.dm"
|
||||
|
||||
Reference in New Issue
Block a user