Fishing bluespace capsules (#87639)

## About The Pull Request
With this PR, I'm introducing fishing bluespace capsules to the game.
They can be found on the black market, but I'll get a couple more ways
to get them before it's ready.

Anyway, they're special bluespace capsules that spawn a fishing spot of
your choice. The fishing spot can be changed by alt-clicking the
capsule, and so far it has 5 choices, plus 2 locked behind emagging for
obvious reasons:
- Freshwater: pretty basic, you get freshwater fish from this.
- Saltwater: mainly saltwater fish.
- Tiziran: You get tiziran fish here, like the gunner jellyfish,
armorfish, needlefish, dwarves moonfish and the new, bigger zagoskian
moonfish. By the by, moonfish now periodically lay moonfish eggs, a
staple of lizardfolk cuisine.
- Ice fishing spot: A small ice turf with a hole dug in it; salmon,
arctic char, arctic chrabs and the bonemass (skeleton fish).
- Hot Spring: Somehow the new home to the ought-to-be-extinct
sacabambaspis. It also doubles as a better shower overall, with mild
healing on top of stamina recovery. Felinids still hate it though, and
won't benefit from the healing.
- Lava: A 2x2 square of pure lava. Requires an emag for obvious reasons.
- Plasma: Ditto, but it's plasma instead of lava.

As a sidenote, unlike standard shelter capsules, these require their
area to be clear of pipes and cables on top of the other requirements,
unless emagged. Obviously, I've done some changes to allow pipes and
cables to not be hidden by water turfs, though I'm still keeping these
reqs because I don't think these fishing spots would look great if
riddled with cables and pipes. I may remove this extra req later if it
proves to be a tad too tedious.

Also they don't knock you back when expanding.

Screenshot from a recent test (fixed the misplaced decal and tweaked a
few things since then):

![immagine](https://github.com/user-attachments/assets/6bbcddfb-ff1c-4e96-834a-2129cadbb31f)


## Why It's Good For The Game
The idea stems from how not all fishing spots aren't designed to be
accessible every round, which is fine, because we have the fish-porter
for that. However, even the fish-porter should have its limits in terms
of what it can provide by itself (linking is all fair and game), so I've
thought having something of a middle point would been neat, also as a
way to mess around with the station layout a bit, to empower the player
with a little extra "terraforming".

## Changelog

🆑
add: Added fishing bluespace capsules to the game, which can be used to
spawn a variety of fishing spots, from freshwater to tiziran sea to hot
springs, and also lava and plasma if emagged.
add: Added two new fish: the zagoskian moonfish and the sacabambaspis.
Moonfish will now periodically lay moonfish eggs.
map: The 'crashed pod' lavaland ruin now has a hot spring, and the
cursed hotspring on icemoon now has a plastic chair and a fishing
toolbox.
/🆑
This commit is contained in:
Ghom
2024-11-11 08:01:09 +13:00
committed by GitHub
parent 48beb20406
commit e5472d9be4
50 changed files with 1409 additions and 277 deletions
@@ -6,7 +6,7 @@
/turf/closed/mineral/random/snow,
/area/icemoon/surface/outdoors/unexplored)
"c" = (
/turf/open/water/cursed_spring,
/turf/open/water/hot_spring/cursed,
/area/icemoon/surface/outdoors/noteleport)
"d" = (
/obj/item/paper/crumpled{
@@ -14,6 +14,14 @@
},
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors)
"l" = (
/obj/structure/chair/plastic,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors)
"G" = (
/obj/item/storage/toolbox/fishing,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors)
(1,1,1) = {"
b
@@ -70,7 +78,7 @@ b
(5,1,1) = {"
b
a
a
G
c
c
c
@@ -83,7 +91,7 @@ b
(6,1,1) = {"
b
a
a
l
c
c
c
@@ -62,7 +62,7 @@
/turf/open/floor/plating/lavaland_atmos,
/area/ruin/unpowered)
"l" = (
/turf/open/water/lavaland_atmos,
/turf/open/water/hot_spring,
/area/lavaland/surface)
"m" = (
/obj/machinery/door/airlock/survival_pod/glass,
+128 -128
View File
@@ -358,16 +358,6 @@
/obj/machinery/light/directional/east,
/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/entry)
"ahg" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/obj/machinery/duct,
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 10
},
/obj/structure/cable,
/obj/structure/sign/eyechart/directional/west,
/turf/open/floor/iron/white,
/area/station/medical/cryo)
"ahj" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
@@ -3477,16 +3467,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/white,
/area/station/science/research)
"bjK" = (
/obj/structure/tank_holder/extinguisher,
/obj/machinery/camera/directional/east{
c_tag = "Medbay Cryogenics";
network = list("ss13","medbay")
},
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/machinery/airalarm/directional/north,
/turf/open/floor/iron/white,
/area/station/medical/cryo)
"bjP" = (
/turf/closed/wall/r_wall,
/area/station/ai_monitored/turret_protected/aisat/foyer)
@@ -6639,6 +6619,16 @@
/obj/effect/mapping_helpers/airlock/access/all/service/lawyer,
/turf/open/floor/wood,
/area/station/service/lawoffice)
"ctg" = (
/obj/item/radio/intercom/directional/east,
/obj/effect/turf_decal/siding/white{
dir = 5
},
/obj/structure/railing{
dir = 4
},
/turf/open/water/no_planet_atmos,
/area/station/service/hydroponics/garden)
"ctn" = (
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/iron,
@@ -15267,15 +15257,6 @@
/obj/structure/sign/warning/pods,
/turf/closed/wall,
/area/station/commons/locker)
"ftQ" = (
/obj/effect/turf_decal/siding/white{
dir = 4
},
/obj/structure/railing{
dir = 4
},
/turf/open/water,
/area/station/service/hydroponics/garden)
"fuc" = (
/obj/structure/frame/machine{
anchored = 1
@@ -16048,6 +16029,12 @@
/obj/effect/mapping_helpers/airlock/access/all/medical/general,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
"fLo" = (
/obj/effect/turf_decal/siding/white{
dir = 8
},
/turf/open/water/no_planet_atmos,
/area/station/service/hydroponics/garden)
"fLq" = (
/obj/machinery/door/window/left/directional/north{
name = "Inner Pipe Access";
@@ -23814,6 +23801,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark,
/area/station/security/courtroom)
"izs" = (
/obj/structure/cable,
/obj/structure/sink/directional/east,
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/structure/mirror/directional/west,
/turf/open/floor/iron/white,
/area/station/medical/cryo)
"izv" = (
/obj/item/flashlight/lantern{
pixel_y = 7
@@ -25350,17 +25345,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
"iZS" = (
/obj/machinery/atmospherics/components/unary/portables_connector/visible{
dir = 1
},
/obj/effect/turf_decal/stripes/line{
dir = 1
},
/obj/machinery/portable_atmospherics/canister/anesthetic_mix,
/obj/machinery/light_switch/directional/south,
/turf/open/floor/iron/dark,
/area/station/medical/cryo)
"jaj" = (
/obj/structure/chair,
/obj/structure/cable,
@@ -26613,34 +26597,6 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron/dark,
/area/station/science/ordnance)
"jwp" = (
/obj/structure/table/glass,
/obj/machinery/power/apc/auto_name/directional/north,
/obj/structure/cable,
/obj/item/reagent_containers/cup/beaker/cryoxadone{
pixel_x = -6;
pixel_y = 10
},
/obj/item/reagent_containers/cup/beaker/cryoxadone{
pixel_x = 6;
pixel_y = 10
},
/obj/item/reagent_containers/cup/beaker/cryoxadone{
pixel_x = -6;
pixel_y = 6
},
/obj/item/reagent_containers/cup/beaker/cryoxadone{
pixel_x = 6;
pixel_y = 6
},
/obj/item/storage/pill_bottle/mannitol,
/obj/item/reagent_containers/dropper{
pixel_y = 6
},
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/item/radio/intercom/directional/west,
/turf/open/floor/iron/white,
/area/station/medical/cryo)
"jws" = (
/obj/structure/table,
/obj/item/storage/toolbox/mechanical{
@@ -26930,6 +26886,15 @@
/obj/machinery/holopad,
/turf/open/floor/iron,
/area/station/science/robotics/lab)
"jAE" = (
/obj/effect/turf_decal/siding/white{
dir = 4
},
/obj/structure/railing{
dir = 4
},
/turf/open/water/no_planet_atmos,
/area/station/service/hydroponics/garden)
"jAN" = (
/obj/machinery/airalarm/directional/north,
/obj/effect/turf_decal/tile/red/half/contrasted,
@@ -28342,12 +28307,6 @@
/obj/machinery/status_display/evac/directional/east,
/turf/open/floor/iron/dark,
/area/station/command/gateway)
"jYu" = (
/obj/effect/turf_decal/siding/white{
dir = 9
},
/turf/open/water,
/area/station/service/hydroponics/garden)
"jYv" = (
/obj/machinery/meter,
/obj/machinery/atmospherics/pipe/smart/simple/green/visible,
@@ -30517,6 +30476,16 @@
/obj/effect/turf_decal/tile/purple,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
"kMo" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/obj/machinery/duct,
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 10
},
/obj/structure/cable,
/obj/structure/sign/eyechart/directional/west,
/turf/open/floor/iron/white,
/area/station/medical/cryo)
"kMr" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/obj/effect/turf_decal/siding/wood{
@@ -34545,6 +34514,34 @@
},
/turf/open/floor/iron/white,
/area/station/science/research)
"mpV" = (
/obj/structure/table/glass,
/obj/machinery/power/apc/auto_name/directional/north,
/obj/structure/cable,
/obj/item/reagent_containers/cup/beaker/cryoxadone{
pixel_x = -6;
pixel_y = 10
},
/obj/item/reagent_containers/cup/beaker/cryoxadone{
pixel_x = 6;
pixel_y = 10
},
/obj/item/reagent_containers/cup/beaker/cryoxadone{
pixel_x = -6;
pixel_y = 6
},
/obj/item/reagent_containers/cup/beaker/cryoxadone{
pixel_x = 6;
pixel_y = 6
},
/obj/item/storage/pill_bottle/mannitol,
/obj/item/reagent_containers/dropper{
pixel_y = 6
},
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/item/radio/intercom/directional/west,
/turf/open/floor/iron/white,
/area/station/medical/cryo)
"mqe" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -38569,6 +38566,12 @@
/obj/structure/easel,
/turf/open/floor/plating,
/area/station/maintenance/disposal)
"nIy" = (
/obj/effect/turf_decal/siding/white{
dir = 9
},
/turf/open/water/no_planet_atmos,
/area/station/service/hydroponics/garden)
"nIP" = (
/obj/structure/table/glass,
/obj/item/paper_bin{
@@ -40506,16 +40509,6 @@
},
/turf/open/floor/iron,
/area/station/science/lab)
"otG" = (
/obj/item/radio/intercom/directional/east,
/obj/effect/turf_decal/siding/white{
dir = 5
},
/obj/structure/railing{
dir = 4
},
/turf/open/water,
/area/station/service/hydroponics/garden)
"otI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -43475,6 +43468,15 @@
/obj/machinery/telecomms/processor/preset_four,
/turf/open/floor/circuit/telecomms/mainframe,
/area/station/tcommsat/server)
"pwp" = (
/obj/effect/turf_decal/siding/white{
dir = 6
},
/obj/structure/railing{
dir = 4
},
/turf/open/water/no_planet_atmos,
/area/station/service/hydroponics/garden)
"pwx" = (
/obj/structure/chair{
dir = 4
@@ -46581,14 +46583,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/port/aft)
"qCL" = (
/obj/structure/cable,
/obj/structure/sink/directional/east,
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/structure/mirror/directional/west,
/turf/open/floor/iron/white,
/area/station/medical/cryo)
"qCM" = (
/obj/structure/cable,
/obj/machinery/door/airlock/external{
@@ -50123,6 +50117,16 @@
/obj/machinery/firealarm/directional/west,
/turf/open/floor/plating,
/area/station/command/teleporter)
"rKN" = (
/obj/effect/turf_decal/siding/white{
dir = 10
},
/obj/structure/railing{
dir = 8
},
/obj/structure/sign/clock/directional/south,
/turf/open/water/no_planet_atmos,
/area/station/service/hydroponics/garden)
"rKQ" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
@@ -56895,6 +56899,16 @@
/obj/machinery/newscaster/directional/south,
/turf/open/floor/iron/white,
/area/station/medical/chemistry)
"ubP" = (
/obj/structure/tank_holder/extinguisher,
/obj/machinery/camera/directional/east{
c_tag = "Medbay Cryogenics";
network = list("ss13","medbay")
},
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/machinery/airalarm/directional/north,
/turf/open/floor/iron/white,
/area/station/medical/cryo)
"ubQ" = (
/obj/effect/turf_decal/tile/neutral{
dir = 8
@@ -60404,12 +60418,6 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/engineering/atmospherics_engine)
"vmU" = (
/obj/effect/turf_decal/siding/white{
dir = 8
},
/turf/open/water,
/area/station/service/hydroponics/garden)
"vmX" = (
/obj/machinery/light/directional/west,
/obj/structure/disposalpipe/segment,
@@ -61078,6 +61086,17 @@
/obj/effect/turf_decal/tile/purple/opposingcorners,
/turf/open/floor/iron,
/area/station/science/research)
"vxW" = (
/obj/machinery/atmospherics/components/unary/portables_connector/visible{
dir = 1
},
/obj/effect/turf_decal/stripes/line{
dir = 1
},
/obj/machinery/portable_atmospherics/canister/anesthetic_mix,
/obj/machinery/light_switch/directional/south,
/turf/open/floor/iron/dark,
/area/station/medical/cryo)
"vye" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/rack,
@@ -66765,15 +66784,6 @@
"xww" = (
/turf/closed/wall/r_wall,
/area/station/engineering/storage/tech)
"xwB" = (
/obj/effect/turf_decal/siding/white{
dir = 6
},
/obj/structure/railing{
dir = 4
},
/turf/open/water,
/area/station/service/hydroponics/garden)
"xwD" = (
/obj/effect/turf_decal/trimline/yellow/filled/corner,
/turf/open/floor/iron/white,
@@ -66920,16 +66930,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/chemistry)
"xyI" = (
/obj/effect/turf_decal/siding/white{
dir = 10
},
/obj/structure/railing{
dir = 8
},
/obj/structure/sign/clock/directional/south,
/turf/open/water,
/area/station/service/hydroponics/garden)
"xyM" = (
/obj/structure/cable,
/turf/open/floor/plating,
@@ -89498,10 +89498,10 @@ pOa
shl
cIW
pOa
jwp
qCL
mpV
izs
uIM
ahg
kMo
grm
sSp
wvP
@@ -90526,11 +90526,11 @@ clp
etn
ayH
pOa
bjK
ubP
jqQ
mbV
hEA
iZS
vxW
sSp
jFB
bHE
@@ -106420,9 +106420,9 @@ wRF
jzC
oCO
xUE
jYu
vmU
xyI
nIy
fLo
rKN
qXB
kbo
qXB
@@ -106677,9 +106677,9 @@ lbH
mie
pRM
ivb
otG
ftQ
xwB
ctg
jAE
pwp
qXB
psZ
qXB
+10 -15
View File
@@ -3330,10 +3330,9 @@
/obj/effect/turf_decal/siding/thinplating_new/dark{
dir = 1
},
/turf/open/water/jungle{
/turf/open/water/no_planet_atmos{
desc = "Filthy.";
name = "untreated water";
planetary_atmos = 0
name = "untreated water"
},
/area/station/maintenance/floor1/port/aft)
"aSq" = (
@@ -11244,10 +11243,9 @@
/obj/effect/turf_decal/siding/thinplating_new/dark{
dir = 5
},
/turf/open/water/jungle{
/turf/open/water/no_planet_atmos{
desc = "Filthy.";
name = "untreated water";
planetary_atmos = 0
name = "untreated water"
},
/area/station/maintenance/floor1/port/aft)
"cPR" = (
@@ -43703,10 +43701,9 @@
/obj/effect/turf_decal/siding/thinplating_new/dark{
dir = 4
},
/turf/open/water/jungle{
/turf/open/water/no_planet_atmos{
desc = "Filthy.";
name = "untreated water";
planetary_atmos = 0
name = "untreated water"
},
/area/station/maintenance/floor1/port/aft)
"loa" = (
@@ -51275,10 +51272,9 @@
desc = "This is in our water? Gross!";
name = "algae mass"
},
/turf/open/water/jungle{
/turf/open/water/no_planet_atmos{
desc = "Filthy.";
name = "untreated water";
planetary_atmos = 0
name = "untreated water"
},
/area/station/maintenance/floor1/port/aft)
"nhV" = (
@@ -86666,10 +86662,9 @@
/area/station/maintenance/department/engine/atmos)
"wor" = (
/obj/machinery/light/red/dim/directional/south,
/turf/open/water/jungle{
/turf/open/water/no_planet_atmos{
desc = "Filthy.";
name = "untreated water";
planetary_atmos = 0
name = "untreated water"
},
/area/station/maintenance/floor1/port/aft)
"wot" = (
+98
View File
@@ -0,0 +1,98 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"a" = (
/obj/effect/turf_decal/siding/blue/corner{
dir = 8
},
/turf/template_noop,
/area/template_noop)
"b" = (
/obj/effect/turf_decal/siding/blue,
/turf/template_noop,
/area/template_noop)
"c" = (
/obj/effect/turf_decal/siding/blue/corner{
dir = 1
},
/turf/template_noop,
/area/template_noop)
"d" = (
/turf/template_noop,
/area/template_noop)
"e" = (
/obj/structure/chair/plastic,
/obj/item/reagent_containers/cup/soda_cans/beer{
pixel_x = 12;
pixel_y = -5
},
/obj/effect/turf_decal/siding/blue/inner_corner{
dir = 8
},
/turf/template_noop,
/area/template_noop)
"f" = (
/obj/effect/turf_decal/siding/blue{
dir = 4
},
/turf/template_noop,
/area/template_noop)
"g" = (
/obj/effect/turf_decal/siding/blue/corner{
dir = 4
},
/turf/template_noop,
/area/template_noop)
"i" = (
/turf/open/water/no_planet_atmos,
/area/template_noop)
"j" = (
/obj/effect/turf_decal/siding/blue{
dir = 8
},
/turf/template_noop,
/area/template_noop)
"m" = (
/obj/effect/turf_decal/siding/blue/corner,
/turf/template_noop,
/area/template_noop)
"o" = (
/obj/effect/turf_decal/siding/blue{
dir = 1
},
/turf/template_noop,
/area/template_noop)
(1,1,1) = {"
m
f
f
f
g
"}
(2,1,1) = {"
b
i
i
i
o
"}
(3,1,1) = {"
b
i
i
i
o
"}
(4,1,1) = {"
a
e
i
i
o
"}
(5,1,1) = {"
d
a
j
j
c
"}
+74
View File
@@ -0,0 +1,74 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"a" = (
/obj/effect/turf_decal/weather/dirt,
/turf/open/water/hot_spring,
/area/template_noop)
"b" = (
/obj/effect/turf_decal/weather/dirt{
dir = 4
},
/obj/effect/turf_decal/weather/dirt{
dir = 1
},
/turf/open/water/hot_spring,
/area/template_noop)
"e" = (
/turf/open/water/hot_spring,
/area/template_noop)
"o" = (
/obj/effect/turf_decal/weather/dirt{
dir = 4
},
/turf/open/water/hot_spring,
/area/template_noop)
"p" = (
/obj/effect/turf_decal/weather/dirt{
dir = 1
},
/obj/effect/turf_decal/weather/dirt{
dir = 8
},
/turf/open/water/hot_spring,
/area/template_noop)
"v" = (
/obj/effect/turf_decal/weather/dirt{
dir = 1
},
/turf/open/water/hot_spring,
/area/template_noop)
"J" = (
/obj/effect/turf_decal/weather/dirt,
/obj/effect/turf_decal/weather/dirt{
dir = 8
},
/turf/open/water/hot_spring,
/area/template_noop)
"U" = (
/obj/effect/turf_decal/weather/dirt,
/obj/effect/turf_decal/weather/dirt{
dir = 4
},
/turf/open/water/hot_spring,
/area/template_noop)
"W" = (
/obj/effect/turf_decal/weather/dirt{
dir = 8
},
/turf/open/water/hot_spring,
/area/template_noop)
(1,1,1) = {"
p
W
J
"}
(2,1,1) = {"
v
e
a
"}
(3,1,1) = {"
b
o
U
"}
+68
View File
@@ -0,0 +1,68 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"a" = (
/obj/effect/turf_decal/siding/dark_blue{
dir = 1
},
/turf/template_noop,
/area/template_noop)
"b" = (
/turf/open/misc/ice/icemoon/no_planet_atmos/holed,
/area/template_noop)
"d" = (
/obj/effect/turf_decal/siding/dark_blue/corner{
dir = 4
},
/turf/template_noop,
/area/template_noop)
"i" = (
/obj/effect/turf_decal/siding/dark_blue/corner,
/turf/template_noop,
/area/template_noop)
"o" = (
/obj/effect/turf_decal/siding/dark_blue/corner{
dir = 8
},
/turf/template_noop,
/area/template_noop)
"q" = (
/obj/effect/turf_decal/siding/dark_blue,
/obj/item/clothing/suit/caution,
/turf/template_noop,
/area/template_noop)
"E" = (
/obj/effect/turf_decal/siding/dark_blue{
dir = 4
},
/obj/structure/chair/plastic{
dir = 4
},
/turf/template_noop,
/area/template_noop)
"R" = (
/obj/effect/turf_decal/siding/dark_blue{
dir = 8
},
/turf/template_noop,
/area/template_noop)
"X" = (
/obj/effect/turf_decal/siding/dark_blue/corner{
dir = 1
},
/turf/template_noop,
/area/template_noop)
(1,1,1) = {"
i
E
d
"}
(2,1,1) = {"
q
b
a
"}
(3,1,1) = {"
o
R
X
"}
+13
View File
@@ -0,0 +1,13 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"a" = (
/turf/open/lava/smooth,
/area/template_noop)
(1,1,1) = {"
a
a
"}
(2,1,1) = {"
a
a
"}
+13
View File
@@ -0,0 +1,13 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"a" = (
/turf/open/lava/plasma,
/area/template_noop)
(1,1,1) = {"
a
a
"}
(2,1,1) = {"
a
a
"}
+107
View File
@@ -0,0 +1,107 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"a" = (
/obj/effect/turf_decal/siding/yellow/corner{
dir = 8
},
/turf/template_noop,
/area/template_noop)
"b" = (
/obj/effect/turf_decal/siding/yellow,
/turf/template_noop,
/area/template_noop)
"c" = (
/obj/effect/turf_decal/siding/yellow/corner{
dir = 1
},
/turf/template_noop,
/area/template_noop)
"d" = (
/turf/template_noop,
/area/template_noop)
"e" = (
/obj/structure/chair/plastic,
/obj/item/reagent_containers/cup/glass/bottle/beer/light{
pixel_x = 13;
pixel_y = -2
},
/obj/effect/turf_decal/siding/yellow/inner_corner{
dir = 8
},
/turf/template_noop,
/area/template_noop)
"f" = (
/obj/effect/turf_decal/siding/yellow{
dir = 4
},
/turf/template_noop,
/area/template_noop)
"g" = (
/obj/effect/turf_decal/siding/yellow/corner{
dir = 4
},
/turf/template_noop,
/area/template_noop)
"i" = (
/turf/open/water/beach,
/area/template_noop)
"j" = (
/obj/effect/turf_decal/siding/yellow{
dir = 8
},
/turf/template_noop,
/area/template_noop)
"m" = (
/obj/effect/turf_decal/siding/yellow/corner{
dir = 2
},
/turf/template_noop,
/area/template_noop)
"o" = (
/obj/effect/turf_decal/siding/yellow{
dir = 1
},
/turf/template_noop,
/area/template_noop)
"N" = (
/obj/item/toy/seashell{
pixel_x = 9;
pixel_y = 9
},
/turf/open/water/beach,
/area/template_noop)
(1,1,1) = {"
m
f
f
f
g
"}
(2,1,1) = {"
b
N
i
i
o
"}
(3,1,1) = {"
b
i
i
i
o
"}
(4,1,1) = {"
a
e
i
i
o
"}
(5,1,1) = {"
d
a
j
j
c
"}
+98
View File
@@ -0,0 +1,98 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"a" = (
/obj/effect/turf_decal/siding/green/corner{
dir = 8
},
/turf/template_noop,
/area/template_noop)
"b" = (
/obj/effect/turf_decal/siding/green,
/turf/template_noop,
/area/template_noop)
"c" = (
/obj/effect/turf_decal/siding/green/corner{
dir = 1
},
/turf/template_noop,
/area/template_noop)
"d" = (
/turf/template_noop,
/area/template_noop)
"e" = (
/obj/structure/chair/plastic,
/obj/effect/turf_decal/siding/green/inner_corner{
dir = 8
},
/obj/item/food/canned/desert_snails{
pixel_x = 14;
pixel_y = -3
},
/turf/template_noop,
/area/template_noop)
"f" = (
/obj/effect/turf_decal/siding/green{
dir = 4
},
/turf/template_noop,
/area/template_noop)
"g" = (
/obj/effect/turf_decal/siding/green/corner{
dir = 4
},
/turf/template_noop,
/area/template_noop)
"i" = (
/turf/open/water/beach/tizira,
/area/template_noop)
"j" = (
/obj/effect/turf_decal/siding/green{
dir = 8
},
/turf/template_noop,
/area/template_noop)
"m" = (
/obj/effect/turf_decal/siding/green/corner,
/turf/template_noop,
/area/template_noop)
"o" = (
/obj/effect/turf_decal/siding/green{
dir = 1
},
/turf/template_noop,
/area/template_noop)
(1,1,1) = {"
m
f
f
f
g
"}
(2,1,1) = {"
b
i
i
i
o
"}
(3,1,1) = {"
b
i
i
i
o
"}
(4,1,1) = {"
a
e
i
i
o
"}
(5,1,1) = {"
d
a
j
j
c
"}
+19 -16
View File
@@ -137,25 +137,28 @@
// NOTICE: we break from the pattern of increasing in steps of like 0.01 here
// Because TOPDOWN_LAYER is 10000 and that's enough to floating point our modifications away
#define LOW_FLOOR_LAYER (1 + TOPDOWN_LAYER)
#define TURF_PLATING_DECAL_LAYER (2 + TOPDOWN_LAYER)
#define TURF_DECAL_LAYER (3 + TOPDOWN_LAYER) //Makes turf decals appear in DM how they will look inworld.
#define CULT_OVERLAY_LAYER (4 + TOPDOWN_LAYER)
#define MID_TURF_LAYER (5 + TOPDOWN_LAYER)
#define HIGH_TURF_LAYER (6 + TOPDOWN_LAYER)
#define LATTICE_LAYER (7 + TOPDOWN_LAYER)
#define DISPOSAL_PIPE_LAYER (8 + TOPDOWN_LAYER)
#define WIRE_LAYER (9 + TOPDOWN_LAYER)
#define GLASS_FLOOR_LAYER (10 + TOPDOWN_LAYER)
#define TRAM_RAIL_LAYER (11 + TOPDOWN_LAYER)
#define ABOVE_OPEN_TURF_LAYER (12 + TOPDOWN_LAYER)
//lower than LOW_FLOOR_LAYER, for turfs with stuff on the edge that should be covered by other turfs
#define LOWER_FLOOR_LAYER (1 + TOPDOWN_LAYER)
#define LOW_FLOOR_LAYER (2 + TOPDOWN_LAYER)
#define TURF_PLATING_DECAL_LAYER (3 + TOPDOWN_LAYER)
#define TURF_DECAL_LAYER (4 + TOPDOWN_LAYER) //Makes turf decals appear in DM how they will look inworld.
#define CULT_OVERLAY_LAYER (5 + TOPDOWN_LAYER)
#define MID_TURF_LAYER (6 + TOPDOWN_LAYER)
#define HIGH_TURF_LAYER (7 + TOPDOWN_LAYER)
#define LATTICE_LAYER (8 + TOPDOWN_LAYER)
#define DISPOSAL_PIPE_LAYER (9 + TOPDOWN_LAYER)
#define WIRE_LAYER (10 + TOPDOWN_LAYER)
#define GLASS_FLOOR_LAYER (11 + TOPDOWN_LAYER)
#define TRAM_RAIL_LAYER (12 + TOPDOWN_LAYER)
#define ABOVE_OPEN_TURF_LAYER (13 + TOPDOWN_LAYER)
///catwalk overlay of /turf/open/floor/plating/catwalk_floor
#define CATWALK_LAYER (13 + TOPDOWN_LAYER)
#define LOWER_RUNE_LAYER (14 + TOPDOWN_LAYER)
#define RUNE_LAYER (15 + TOPDOWN_LAYER)
#define CATWALK_LAYER (14 + TOPDOWN_LAYER)
#define LOWER_RUNE_LAYER (15 + TOPDOWN_LAYER)
#define RUNE_LAYER (16 + TOPDOWN_LAYER)
/// [GAME_CLEAN_LAYER] but for floors.
/// Basically any layer below this (numerically) is "on" a floor for the purposes of washing
#define FLOOR_CLEAN_LAYER (20 + TOPDOWN_LAYER)
#define FLOOR_CLEAN_LAYER (21 + TOPDOWN_LAYER)
//WALL_PLANE layers
#define BELOW_CLOSED_TURF_LAYER 2.053
+8
View File
@@ -195,9 +195,17 @@ Always compile, always use that verb, and always make sure that it works for wha
#define SHELTER_DEPLOY_BAD_AREA "bad area"
/// Shelter spot has anchored objects that restrict deployment
#define SHELTER_DEPLOY_ANCHORED_OBJECTS "anchored objects"
/// Sheter spot has banned objects that restrict deployment
#define SHELTER_DEPLOY_BANNED_OBJECTS "banned objects"
/// Shelter spot is out of bounds from the maps x/y coordinates
#define SHELTER_DEPLOY_OUTSIDE_MAP "outside map"
//Flags for survival capsules to ignore some deploy checks
///Ignore anchored, dense objects in the area
#define CAPSULE_IGNORE_ANCHORED_OBJECTS (1<<0)
///Ignore banned objects in the area
#define CAPSULE_IGNORE_BANNED_OBJECTS (1<<1)
/// A map key that corresponds to being one exclusively for Space.
#define SPACE_KEY "space"
@@ -210,6 +210,7 @@ GLOBAL_LIST_INIT(uncommon_loot, list(//uncommon: useful items
/obj/item/storage/box/clown = 1,
/obj/item/weaponcrafting/receiver = 1,
/obj/item/book/granter/crafting_recipe/death_sandwich = 1,
/obj/item/survivalcapsule/fishing = 1,
) = 8,
list(//medical and chemicals
+2 -2
View File
@@ -56,7 +56,7 @@
var/growth = growth_rate * deciseconds_elapsed
if(HAS_TRAIT(source, TRAIT_FISH_QUICK_GROWTH))
growth *= 2
if(SEND_SIGNAL(source, COMSIG_FISH_BEFORE_GROWING, seconds_per_tick, growth) & COMPONENT_DONT_GROW)
if(SEND_SIGNAL(source, COMSIG_FISH_BEFORE_GROWING, seconds_per_tick, growth, result_type) & COMPONENT_DONT_GROW)
return
maturation += growth
if(maturation >= 100)
@@ -87,7 +87,7 @@
addtimer(CALLBACK(result, TYPE_PROC_REF(/mob/living/basic, hop_on_nearby_turf)), 0.1 SECONDS)
if(is_evo || location == source.loc)
var/message_verb = del_on_grow ? "grows into" : "generates"
var/message_verb = del_on_grow ? "grows into" : "lays"
location.visible_message(span_notice("[source] [message_verb] \a [result]."), vision_distance = 3)
if(inherit_name && HAS_TRAIT(source, TRAIT_WAS_RENAMED))
+18
View File
@@ -81,6 +81,24 @@
mood_change = -2
timeout = 3 MINUTES
/datum/mood_event/hot_spring
description = "It's so relaxing to bathe in steamy water..."
mood_change = 5
/datum/mood_event/hot_spring_hater
description = "No, no, no, no, I don't want to take a bath!"
mood_change = -2
/datum/mood_event/hot_spring_left
description = "That was an enjoyable bath."
mood_change = 4
timeout = 4 MINUTES
/datum/mood_event/hot_spring_hater_left
description = "I hate baths! And I hate how cold it's once you step out of it!"
mood_change = -3
timeout = 2 MINUTES
/datum/mood_event/fresh_laundry
description = "There's nothing like the feeling of a freshly laundered jumpsuit."
mood_change = 2
+58 -27
View File
@@ -610,40 +610,71 @@
SIGNAL_HANDLER
qdel(src)
/atom/movable/screen/alert/status_effect/shower_regen
/datum/status_effect/washing_regen
id = "shower_regen"
duration = -1
status_type = STATUS_EFFECT_UNIQUE
alert_type = /atom/movable/screen/alert/status_effect/washing_regen
///The screen alert shown if you hate water
var/hater_alert = /atom/movable/screen/alert/status_effect/washing_regen/hater
/// How much stamina we regain from washing
var/stamina_heal_per_tick = -4
/// How much brute, tox and fie damage we heal from this
var/heal_per_tick = 0
/datum/status_effect/washing_regen/on_apply()
. = ..()
if(HAS_TRAIT(owner, TRAIT_WATER_HATER) && !HAS_TRAIT(owner, TRAIT_WATER_ADAPTATION))
alert_type = hater_alert
/datum/status_effect/washing_regen/tick(seconds_between_ticks)
. = ..()
var/water_adaptation = HAS_TRAIT(owner, TRAIT_WATER_ADAPTATION)
var/water_hater = HAS_TRAIT(owner, TRAIT_WATER_HATER)
var/stam_recovery = (water_hater && !water_adaptation ? -stamina_heal_per_tick : stamina_heal_per_tick) * seconds_between_ticks
var/recovery = heal_per_tick
if(water_adaptation)
recovery -= 1
stam_recovery *= 1.5
else if(water_hater)
recovery *= 0
recovery *= seconds_between_ticks
var/healed = 0
if(recovery) //very mild healing for those with the water adaptation trait (fish infusion)
healed += owner.adjustOxyLoss(recovery * (water_adaptation ? 1.5 : 1), updating_health = FALSE, required_biotype = MOB_ORGANIC)
healed += owner.adjustFireLoss(recovery, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
healed += owner.adjustToxLoss(recovery, updating_health = FALSE, required_biotype = MOB_ORGANIC)
healed += owner.adjustBruteLoss(recovery, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
healed += owner.adjustStaminaLoss(stam_recovery, updating_stamina = FALSE)
if(healed)
owner.updatehealth()
/atom/movable/screen/alert/status_effect/washing_regen
name = "Washing"
desc = "A good wash fills me with energy!"
icon_state = "shower_regen"
/atom/movable/screen/alert/status_effect/shower_regen/hater
name = "Washing"
/atom/movable/screen/alert/status_effect/washing_regen/hater
desc = "Waaater... Fuck this WATER!!"
icon_state = "shower_regen_catgirl"
/datum/status_effect/shower_regen
id = "shower_regen"
duration = -1
status_type = STATUS_EFFECT_UNIQUE
alert_type = /atom/movable/screen/alert/status_effect/shower_regen
/// How many heals from washing.
var/stamina_heal_per_tick = 4
/datum/status_effect/washing_regen/hot_spring
alert_type = /atom/movable/screen/alert/status_effect/washing_regen/hotspring
hater_alert = /atom/movable/screen/alert/status_effect/washing_regen/hotspring/hater
stamina_heal_per_tick = -4.5
heal_per_tick = -0.4
/datum/status_effect/shower_regen/on_apply()
/datum/status_effect/washing_regen/hot_spring/tick(seconds_between_ticks)
. = ..()
if(HAS_TRAIT(owner, TRAIT_WATER_HATER) && !HAS_TRAIT(owner, TRAIT_WATER_ADAPTATION))
alert_type = /atom/movable/screen/alert/status_effect/shower_regen/hater
owner.adjust_bodytemperature(10 * seconds_between_ticks, 0, T0C + 45)
/datum/status_effect/shower_regen/tick(seconds_between_ticks)
. = ..()
var/water_adaptation = HAS_TRAIT(owner, TRAIT_WATER_ADAPTATION)
var/heal_or_deal = HAS_TRAIT(owner, TRAIT_WATER_HATER) && !water_adaptation ? 1 : -1
var/healed = 0
if(water_adaptation) //very mild healing for those with the water adaptation trait (fish infusion)
healed += owner.adjustOxyLoss(-1.5 * seconds_between_ticks, updating_health = FALSE, required_biotype = MOB_ORGANIC)
healed += owner.adjustFireLoss(-1 * seconds_between_ticks, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
healed += owner.adjustToxLoss(-1 * seconds_between_ticks, updating_health = FALSE, required_biotype = MOB_ORGANIC)
healed += owner.adjustBruteLoss(-1 * seconds_between_ticks, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)
heal_or_deal *= 1.5
healed += owner.adjustStaminaLoss(stamina_heal_per_tick * heal_or_deal * seconds_between_ticks, updating_stamina = FALSE)
if(healed)
owner.updatehealth()
/atom/movable/screen/alert/status_effect/washing_regen/hotspring
name = "Hotspring"
desc = "Hot Springs are so relaxing..."
icon_state = "hotspring_regen"
/atom/movable/screen/alert/status_effect/washing_regen/hotspring/hater
name = "Hotspring"
desc = "Waaater... FUCK THIS HOT WATER!!"
icon_state = "hotspring_regen_catgirl"
@@ -231,6 +231,9 @@
/obj/effect/turf_decal/siding/corner
icon_state = "siding_plain_corner"
/obj/effect/turf_decal/siding/inner_corner
icon_state = "siding_plain_corner_inner"
/obj/effect/turf_decal/siding/end
icon_state = "siding_plain_end"
@@ -240,6 +243,9 @@
/obj/effect/turf_decal/siding/white/corner
icon_state = "siding_plain_corner"
/obj/effect/turf_decal/siding/white/inner_corner
icon_state = "siding_plain_corner_inner"
/obj/effect/turf_decal/siding/white/end
icon_state = "siding_plain_end"
@@ -249,6 +255,9 @@
/obj/effect/turf_decal/siding/red/corner
icon_state = "siding_plain_corner"
/obj/effect/turf_decal/siding/red/inner_corner
icon_state = "siding_plain_corner_inner"
/obj/effect/turf_decal/siding/red/end
icon_state = "siding_plain_end"
@@ -258,6 +267,9 @@
/obj/effect/turf_decal/siding/dark_red/corner
icon_state = "siding_plain_corner"
/obj/effect/turf_decal/siding/dark_red/inner_corner
icon_state = "siding_plain_corner_inner"
/obj/effect/turf_decal/siding/dark_red/end
icon_state = "siding_plain_end"
@@ -267,6 +279,9 @@
/obj/effect/turf_decal/siding/green/corner
icon_state = "siding_plain_corner"
/obj/effect/turf_decal/siding/green/inner_corner
icon_state = "siding_plain_corner_inner"
/obj/effect/turf_decal/siding/green/end
icon_state = "siding_plain_end"
@@ -276,6 +291,9 @@
/obj/effect/turf_decal/siding/dark_green/corner
icon_state = "siding_plain_corner"
/obj/effect/turf_decal/siding/dark_green/inner_corner
icon_state = "siding_plain_corner_inner"
/obj/effect/turf_decal/siding/dark_green/end
icon_state = "siding_plain_end"
@@ -285,6 +303,9 @@
/obj/effect/turf_decal/siding/blue/corner
icon_state = "siding_plain_corner"
/obj/effect/turf_decal/siding/blue/inner_corner
icon_state = "siding_plain_corner_inner"
/obj/effect/turf_decal/siding/blue/end
icon_state = "siding_plain_end"
@@ -294,6 +315,9 @@
/obj/effect/turf_decal/siding/dark_blue/corner
icon_state = "siding_plain_corner"
/obj/effect/turf_decal/siding/dark_blue/inner_corner
icon_state = "siding_plain_corner_inner"
/obj/effect/turf_decal/siding/dark_blue/end
icon_state = "siding_plain_end"
@@ -303,6 +327,9 @@
/obj/effect/turf_decal/siding/yellow/corner
icon_state = "siding_plain_corner"
/obj/effect/turf_decal/siding/yellow/inner_corner
icon_state = "siding_plain_corner_inner"
/obj/effect/turf_decal/siding/yellow/end
icon_state = "siding_plain_end"
@@ -312,6 +339,9 @@
/obj/effect/turf_decal/siding/purple/corner
icon_state = "siding_plain_corner"
/obj/effect/turf_decal/siding/purple/inner_corner
icon_state = "siding_plain_corner_inner"
/obj/effect/turf_decal/siding/purple/end
icon_state = "siding_plain_end"
@@ -321,6 +351,9 @@
/obj/effect/turf_decal/siding/brown/corner
icon_state = "siding_plain_corner"
/obj/effect/turf_decal/siding/brown/inner_corner
icon_state = "siding_plain_corner_inner"
/obj/effect/turf_decal/siding/brown/end
icon_state = "siding_plain_end"
@@ -330,6 +363,9 @@
/obj/effect/turf_decal/siding/dark/corner
icon_state = "siding_plain_corner"
/obj/effect/turf_decal/siding/dark/inner_corner
icon_state = "siding_plain_corner_inner"
/obj/effect/turf_decal/siding/dark/end
icon_state = "siding_plain_end"
+45 -1
View File
@@ -26,7 +26,7 @@
// Mouse opacity can get set to opaque by some objects when placed into the object's contents (storage containers).
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
src.particle_flags = particle_flags
particles = new particle_path()
particles = get_particle_effect(particle_path)
// /atom doesn't have vis_contents, /turf and /atom/movable do
var/atom/movable/lie_about_areas = parent
lie_about_areas.vis_contents += src
@@ -36,6 +36,9 @@
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
on_move(parent, null, NORTH)
/obj/effect/abstract/particle_holder/proc/get_particle_effect(particle_path)
return new particle_path()
/obj/effect/abstract/particle_holder/Destroy(force)
QDEL_NULL(particles)
parent = null
@@ -67,3 +70,44 @@
/// Sets the particles position to the passed coordinates
/obj/effect/abstract/particle_holder/proc/set_particle_position(x = 0, y = 0, z = 0)
particles.position = list(x, y, z)
/**
* A subtype of particle holder that reuses the same particles to reduce client lag
* when rendering certain atoms, usually found in large quantities and close together.
* Since it reuses the same instances, modifying an instance of particles will affect all atoms
* that show it, therefore procs like set_particle_position() shouldn't be used here.
*/
/obj/effect/abstract/particle_holder/cached
///A static list meant to contain the availables instances of a particle path to use.
var/static/list/particles_by_type
/**
* The length of the pool of particles from which the chosen instance will be picked
* This provides an ever-so-lightly variety to the particles, so they don't all jarringly look EXACTLY the same
*/
var/max_particle_index = 4
/obj/effect/abstract/particle_holder/cached/Initialize(mapload, particle_path = /particles/smoke, particle_flags = NONE, max_particle_index)
src.max_particle_index = max_particle_index
return ..()
/obj/effect/abstract/particle_holder/cached/Destroy(force)
particles = null
return ..()
/obj/effect/abstract/particle_holder/cached/get_particle_effect(particle_path)
LAZYINITLIST(particles_by_type)
LAZYINITLIST(particles_by_type[particle_path])
var/list/particles_list = particles_by_type[particle_path]
var/index = rand(1, max_particle_index)
var/particles/chosen
if(length(particles_list) < index)
chosen = new particle_path()
particles_list += chosen
else
chosen = particles_list[index]
return chosen
/obj/effect/abstract/particle_holder/cached/set_particle_position(x = 0, y = 0, z = 0)
CRASH("[type] doesn't support set_particle_position()")
@@ -97,3 +97,26 @@
/particles/smoke/cyborg/heavy_damage
lifespan = 0.8 SECONDS
fade = 0.8 SECONDS
/particles/hotspring_steam
icon = 'icons/effects/particles/smoke.dmi'
icon_state = list(
"steam_cloud_1" = 1,
"steam_cloud_2" = 1,
"steam_cloud_3" = 1,
"steam_cloud_4" = 1,
"steam_cloud_5" = 1,
)
color = "#FFFFFFAA"
count = 6
spawning = 0.5
lifespan = 3 SECONDS
fade = 1.2 SECONDS
fadein = 0.4 SECONDS
position = generator(GEN_BOX, list(-17,-15,0), list(24,15,0), NORMAL_RAND)
scale = generator(GEN_VECTOR, list(0.9,0.9), list(1.1,1.1), NORMAL_RAND)
drift = generator(GEN_SPHERE, list(-0.01,0), list(0.01,0.01), UNIFORM_RAND)
spin = generator(GEN_NUM, list(-3,3), NORMAL_RAND)
gravity = list(0.05, 0.28)
friction = 0.3
grow = 0.037
@@ -23,6 +23,7 @@
/obj/item/storage/box/donkpockets = 10,
/obj/effect/spawner/random/contraband/plus = 10,
/obj/item/reagent_containers/pill/maintenance = 5,
/obj/item/survivalcapsule/fishing = 5,
)
@@ -42,6 +43,7 @@
/obj/item/reagent_containers/cup/blastoff_ampoule = 5,
/obj/item/food/drug/moon_rock = 5,
/obj/item/grenade/empgrenade = 5,
/obj/item/survivalcapsule/fishing/hacked = 1,
/obj/effect/spawner/random/contraband/armory = 1,
)
+25 -1
View File
@@ -125,7 +125,8 @@
/obj/item/food/moonfish_eggs
name = "moonfish eggs"
desc = "The moonfish lays large, transparent white eggs which are prized in lizard cooking. Their flavour is similar to caviar, but generally is described as deeper and more complex."
gender = PLURAL
desc = "The moonfish lays large, translucent blue eggs which are prized in lizard cooking. Their flavour is similar to caviar, but generally is described as deeper and more complex."
icon = 'icons/obj/food/lizard.dmi'
icon_state = "moonfish_eggs"
food_reagents = list(
@@ -137,6 +138,29 @@
w_class = WEIGHT_CLASS_SMALL
crafting_complexity = FOOD_COMPLEXITY_1
/obj/item/food/moonfish_eggs/Initialize(mapload)
. = ..()
//Moonfish can lay eggs (unaffected by breeding, so think of them as unfertilizard)
RegisterSignal(src, COMSIG_AQUARIUM_CONTENT_GENERATE_APPEARANCE, PROC_REF(generate_aquarium_appearance))
RegisterSignal(src, AQUARIUM_CONTENT_RANDOMIZE_POSITION, PROC_REF(randomize_aquarium_position))
AddComponent(/datum/component/aquarium_content, beauty = 100)
/obj/item/food/moonfish_eggs/proc/generate_aquarium_appearance(datum/source, obj/effect/aquarium/visual)
SIGNAL_HANDLER
visual.icon = icon
visual.icon_state = "moonfish_eggs_aquarium"
visual.layer_mode = AQUARIUM_LAYER_MODE_BOTTOM
/obj/item/food/moonfish_eggs/proc/randomize_aquarium_position(datum/source, obj/structure/aquarium/current_aquarium, obj/effect/aquarium/visual)
SIGNAL_HANDLER
var/list/aq_properties = current_aquarium.get_surface_properties()
var/sprite_width = 5
var/px_min = aq_properties[AQUARIUM_PROPERTIES_PX_MIN]
var/px_max = aq_properties[AQUARIUM_PROPERTIES_PX_MAX] - sprite_width
visual.pixel_x = rand(px_min,px_max)
visual.pixel_y = rand(-1, 1)
/obj/item/food/moonfish_caviar
name = "moonfish caviar paste"
desc = "A rich paste made from moonfish eggs. Generally the only way most lizards can get them, and used fairly heavily in coastal cooking."
+10 -12
View File
@@ -250,7 +250,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16))
if(locate_new_shower && isturf(exiter.loc))
return
var/mob/living/take_his_status_effect = exiter
take_his_status_effect.remove_status_effect(/datum/status_effect/shower_regen)
take_his_status_effect.remove_status_effect(/datum/status_effect/washing_regen)
/obj/machinery/shower/proc/wash_atom(atom/target)
target.wash(CLEAN_RAD | CLEAN_WASH)
@@ -259,7 +259,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16))
return
var/mob/living/living_target = target
check_heat(living_target)
living_target.apply_status_effect(/datum/status_effect/shower_regen)
living_target.apply_status_effect(/datum/status_effect/washing_regen)
if(!HAS_TRAIT(target, TRAIT_WATER_HATER) || HAS_TRAIT(target, TRAIT_WATER_ADAPTATION))
living_target.add_mood_event("shower", /datum/mood_event/nice_shower)
else
@@ -294,7 +294,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16))
if(isopenturf(loc))
var/turf/open/tile = loc
tile.MakeSlippery(TURF_WET_WATER, min_wet_time = 5 SECONDS, wet_time_to_add = 1 SECONDS)
for(var/mob/living/showerer in loc)
showerer.remove_status_effect(/datum/status_effect/washing_regen)
return TRUE
/obj/machinery/shower/process(seconds_per_tick)
@@ -336,18 +337,15 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16))
if(has_water_reclaimer)
new /obj/item/stock_parts/water_recycler(drop_location())
/obj/machinery/shower/proc/check_heat(mob/living/L)
var/mob/living/carbon/C = L
/obj/machinery/shower/proc/check_heat(mob/living/living)
if(current_temperature == SHOWER_FREEZING)
if(iscarbon(L))
C.adjust_bodytemperature(-80, 80)
to_chat(L, span_warning("[src] is freezing!"))
living.adjust_bodytemperature(-80, 80)
to_chat(living, span_warning("[src] is freezing!"))
else if(current_temperature == SHOWER_BOILING)
if(iscarbon(L))
C.adjust_bodytemperature(35, 0, 500)
L.adjustFireLoss(5)
to_chat(L, span_danger("[src] is searing!"))
living.adjust_bodytemperature(35, 0, 500)
living.adjustFireLoss(5)
to_chat(living, span_danger("[src] is searing!"))
/obj/structure/showerframe
+11 -3
View File
@@ -60,13 +60,16 @@
if(!do_after(user, 5 SECONDS, src))
return FALSE
balloon_alert(user, "dug hole")
spawn_hole()
return TRUE
/turf/open/misc/ice/proc/spawn_hole()
AddComponent(/datum/component/fishing_spot, GLOB.preset_fish_sources[/datum/fish_source/ice_fishing])
ADD_TRAIT(src, TRAIT_CATCH_AND_RELEASE, INNATE_TRAIT)
add_overlay(mutable_appearance('icons/turf/overlays.dmi', "ice_hole"))
can_make_hole = FALSE
RemoveElement(/datum/element/contextual_screentip_tools, tool_screentips)
flags_1 &= ~HAS_CONTEXTUAL_SCREENTIPS_1
return TRUE
/turf/open/misc/ice/smooth
icon_state = "ice_turf-255"
@@ -82,13 +85,18 @@
/turf/open/misc/ice/icemoon/no_planet_atmos
planetary_atmos = FALSE
can_make_hole = FALSE
///Ice turf with a fishing spot already dug
/turf/open/misc/ice/icemoon/no_planet_atmos/holed
/turf/open/misc/ice/icemoon/no_planet_atmos/holed/Initialize(mapload)
. = ..()
spawn_hole()
/turf/open/misc/ice/temperate
baseturfs = /turf/open/misc/ice/temperate
desc = "Somehow, it is not melting under these conditions. Must be some very thick ice. Just as slippery too."
initial_gas_mix = COLD_ATMOS //it works with /turf/open/misc/asteroid/snow/temperatre
can_make_hole = FALSE
//For when you want real, genuine ice in your kitchen's cold room.
/turf/open/misc/ice/coldroom
+118 -3
View File
@@ -4,7 +4,7 @@
desc = "Shallow water."
icon = 'icons/turf/floors.dmi'
icon_state = "riverwater_motion"
baseturfs = /turf/open/chasm/lavaland
baseturfs = /turf/open/water
planetary_atmos = TRUE
slowdown = 1
bullet_sizzle = TRUE
@@ -14,19 +14,22 @@
barefootstep = FOOTSTEP_WATER
clawfootstep = FOOTSTEP_WATER
heavyfootstep = FOOTSTEP_WATER
underfloor_accessibility = UNDERFLOOR_INTERACTABLE
/**
* Used as the color arg/var for the immerse element. It should be kept more or less in line with
* the hue of the turf, as semi-transparent vis overlays can opacify the semi-transparent bits of an icon,
* and we're kinda trying to offset that issue.
*/
var/immerse_overlay_color = "#5AAA88"
///The transparency of the immerse element's overlay
var/immerse_overlay_alpha = 180
/// Fishing element for this specific water tile
var/datum/fish_source/fishing_datum = /datum/fish_source/river
/turf/open/water/Initialize(mapload)
. = ..()
AddElement(/datum/element/immerse, icon, icon_state, "immerse", immerse_overlay_color)
AddElement(/datum/element/immerse, icon, icon_state, "immerse", immerse_overlay_color, alpha = immerse_overlay_alpha)
AddElement(/datum/element/watery_tile)
if(!isnull(fishing_datum))
AddElement(/datum/element/lazy_fishing_spot, fishing_datum)
@@ -34,6 +37,10 @@
/turf/open/water/jungle
/turf/open/water/no_planet_atmos
baseturfs = /turf/open/water/no_planet_atmos
planetary_atmos = FALSE
/turf/open/water/beach
planetary_atmos = FALSE
gender = PLURAL
@@ -51,4 +58,112 @@
/turf/open/water/lavaland_atmos
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
planetary_atmos = TRUE
/turf/open/water/beach/tizira
desc = "Shallow water. It somehow reminds you of lizardfolk."
icon_state = "tizira_water"
base_icon_state = "tizira_water"
baseturfs = /turf/open/water/beach/tizira
/**
* A special subtype of water with steam particles and a status effect similar to showers, that's however only applied if
* the living mob inside the turf is actually immersed in it (eg. not flying, not floating).
*/
/turf/open/water/hot_spring
name = "hot spring"
icon_state = "pool_1"
desc = "Water kept warm through some unknown heat source, possibly a geothermal heat source far underground. \
Whatever it is, it feels pretty damn nice to swim, and you can even catch a glimpse of \
the odd fish darting through the water."
baseturfs = /turf/open/water/hot_spring
planetary_atmos = FALSE
immerse_overlay_color = "#A0E2DE"
immerse_overlay_alpha = 190
fishing_datum = /datum/fish_source/hot_spring
/// Holder for the steam particles
var/obj/effect/abstract/particle_holder/cached/particle_effect
/turf/open/water/hot_spring/Initialize(mapload)
. = ..()
icon_state = "pool_[rand(1, 4)]"
particle_effect = new(src, /particles/hotspring_steam, 4)
//render the steam over mobs and objects on the game plane
particle_effect.vis_flags &= ~VIS_INHERIT_PLANE
//And be unaffected by ambient occlusions, which would render the steam grey
particle_effect.plane = MUTATE_PLANE(MASSIVE_OBJ_PLANE, src)
add_filter("hot_spring_waves", 1, wave_filter(y = 1, size = 1, offset = 0, flags = WAVE_BOUNDED))
var/filter = get_filter("hot_spring_waves")
animate(filter, offset = 1, time = 3 SECONDS, loop = -1, easing = SINE_EASING|EASE_IN|EASE_OUT)
animate(offset = -1, time = 3 SECONDS, easing = SINE_EASING|EASE_IN|EASE_OUT)
/**
* turf/Initialize() calls Entered on its contents, however
* we need to wait for movables that still need to be initialized.
*/
RegisterSignal(src, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, PROC_REF(enter_initialized_movable))
/turf/open/water/hot_spring/Destroy()
QDEL_NULL(particle_effect)
remove_filter("hot_spring_waves")
for(var/atom/movable/movable as anything in contents)
exit_hot_spring(movable)
UnregisterSignal(src, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON)
return ..()
/turf/open/water/hot_spring/Entered(atom/movable/arrived, atom/old_loc)
. = ..()
if(!(flags_1 & INITIALIZED_1))
return
enter_hot_spring(arrived)
/turf/open/water/hot_spring/proc/enter_initialized_movable(datum/source, atom/movable/movable)
SIGNAL_HANDLER
enter_hot_spring(movable)
///Registers the signals from the immerse element and calls dip_in if the movable has the required trait.
/turf/open/water/hot_spring/proc/enter_hot_spring(atom/movable/movable)
RegisterSignal(movable, SIGNAL_ADDTRAIT(TRAIT_IMMERSED), PROC_REF(dip_in))
if(isliving(movable)) //so far, exiting a hot spring only has effects on living mobs.
RegisterSignal(movable, SIGNAL_REMOVETRAIT(TRAIT_IMMERSED), PROC_REF(dip_out))
if(HAS_TRAIT(movable, TRAIT_IMMERSED))
dip_in(movable)
///Handles washing the movable and adding a status effect plus mood event to living mobs.
/turf/open/water/hot_spring/proc/dip_in(atom/movable/movable)
SIGNAL_HANDLER
movable.wash(CLEAN_RAD | CLEAN_WASH)
if(!isliving(movable))
return
var/mob/living/living = movable
if(living.has_status_effect(/datum/status_effect/washing_regen/hot_spring))
return
living.apply_status_effect(/datum/status_effect/washing_regen/hot_spring)
if(!HAS_TRAIT(living, TRAIT_WATER_HATER) || HAS_TRAIT(living, TRAIT_WATER_ADAPTATION))
living.add_mood_event("hot_spring", /datum/mood_event/hot_spring)
else
living.add_mood_event("hot_spring", /datum/mood_event/hot_spring_hater)
/turf/open/water/hot_spring/Exited(atom/movable/gone, atom/new_loc)
. = ..()
exit_hot_spring(gone)
//Unregister the signals and remove the status effect from mobs unless they're moving to another hot spring turf.
/turf/open/water/hot_spring/proc/exit_hot_spring(atom/movable/movable)
UnregisterSignal(movable, list(SIGNAL_ADDTRAIT(TRAIT_IMMERSED), SIGNAL_REMOVETRAIT(TRAIT_IMMERSED)))
if(!isliving(movable))
return
var/mob/living/living = movable
if(!living.has_status_effect(/datum/status_effect/washing_regen/hot_spring) || istype(living.loc, /turf/open/water/hot_spring))
return
dip_out(living)
///Handles removing the status effect from mobs.
/turf/open/water/hot_spring/proc/dip_out(mob/living/living)
SIGNAL_HANDLER
living.remove_status_effect(/datum/status_effect/washing_regen/hot_spring)
if(!HAS_TRAIT(living, TRAIT_WATER_HATER) || HAS_TRAIT(living, TRAIT_WATER_ADAPTATION))
living.add_mood_event("hot_spring", /datum/mood_event/hot_spring_left)
else
living.add_mood_event("hot_spring", /datum/mood_event/hot_spring_hater_left)
@@ -661,7 +661,7 @@
continue
var/turf/node_turf = get_turf(node)
if(isplatingturf(node_turf) || iscatwalkturf(node_turf))
if(node_turf.underfloor_accessibility > UNDERFLOOR_HIDDEN)
continue
var/connected_dir = get_dir(src, node)
@@ -125,6 +125,17 @@
stock_max = 1
availability_prob = 15
/datum/market_item/misc/fishing_capsule
name = "Fishing Spot Capsule"
//IUU stands for Illegal Unreported and Unregulated fishing. Ironic.
desc = "A repurposed mining capsule connected to a selection of exclusive fishing spots. Approved by the Intergalactic IUU Fishing Association."
price_min = CARGO_CRATE_VALUE * 1.125
price_max = CARGO_CRATE_VALUE * 2.125
item = /obj/item/survivalcapsule/fishing
stock_min = 1
stock_max = 4
availability_prob = 80
/datum/market_item/misc/fish
name = "Fish"
desc = "Fish! Fresh fish! Fish you can cut, grind and even keep in aquarium if you want to! Get some before the next fight at my village breaks out!"
@@ -72,7 +72,13 @@
name = "imported fish case"
/obj/item/storage/fish_case/tiziran/get_fish_type()
return pick(/obj/item/fish/dwarf_moonfish, /obj/item/fish/gunner_jellyfish, /obj/item/fish/needlefish, /obj/item/fish/armorfish)
return pick_weight(list(
/obj/item/fish/moonfish/dwarf = 2,
/obj/item/fish/gunner_jellyfish = 2,
/obj/item/fish/needlefish = 2,
/obj/item/fish/armorfish = 2,
/obj/item/fish/moonfish = 1,
))
///Subtype bought from the blackmarket at a gratuitously cheap price. The catch? The fish inside it is dead.
/obj/item/storage/fish_case/blackmarket
@@ -169,3 +169,28 @@ GLOBAL_LIST_EMPTY(fishes_by_fish_evolution)
if(source.size >= (/obj/item/fish/fryish/fritterish::average_size * 1.5) && source.size >= (/obj/item/fish/fryish/fritterish::average_weight * 1.5))
return ..()
return FALSE
/datum/fish_evolution/moonfish
probability = 200 //guaranteed if the conditions are met
new_fish_type = /obj/item/fish/moonfish
conditions_note = "Requires the dwarf moonfish to be big enough."
/datum/fish_evolution/moonfish/check_conditions(obj/item/fish/source, obj/item/fish/mate, obj/structure/aquarium/aquarium)
if(source.size < (/obj/item/fish/moonfish/dwarf::average_size * 1.5) && source.size < (/obj/item/fish/moonfish/dwarf::average_weight * 1.5))
return ..()
if(mate && (mate.size < (/obj/item/fish/moonfish::average_size * 1.3) && mate.size < (/obj/item/fish/moonfish::average_weight * 1.3)))
return FALSE
return FALSE
/datum/fish_evolution/dwarf_moonfish
probability = 200 //guaranteed if the conditions are met
new_fish_type = /obj/item/fish/moonfish/dwarf
conditions_note = "Requires the moonfish to be small enough."
/datum/fish_evolution/dwarf_moonfish/check_conditions(obj/item/fish/source, obj/item/fish/mate, obj/structure/aquarium/aquarium)
if(source.size > (/obj/item/fish/moonfish::average_size * 0.66) && source.size > (/obj/item/fish/moonfish::average_weight * 0.66))
return FALSE
if(mate && (mate.size > (/obj/item/fish/moonfish::average_size * 0.7) && mate.size > (/obj/item/fish/moonfish::average_weight * 0.7)))
return FALSE
return ..()
+1 -1
View File
@@ -167,7 +167,7 @@
AddComponent(/datum/component/fish_growth, /mob/living/basic/carp/advanced, growth_rate)
/obj/item/fish/baby_carp/proc/growth_checks(datum/source, seconds_per_tick)
/obj/item/fish/baby_carp/proc/growth_checks(datum/source, seconds_per_tick, growth, result_path)
SIGNAL_HANDLER
var/hunger = CLAMP01((world.time - last_feeding) / feeding_frequency)
if(health <= initial(health) * 0.6 || hunger >= 0.6) //if too hurt or hungry, don't grow.
+21 -1
View File
@@ -196,7 +196,7 @@
else
deltimer(del_timerid)
/obj/item/fish/tadpole/proc/growth_checks(datum/source, seconds_per_tick, growth)
/obj/item/fish/tadpole/proc/growth_checks(datum/source, seconds_per_tick, growth, result_path)
SIGNAL_HANDLER
var/hunger = get_hunger()
if(hunger >= 0.7) //too hungry to grow
@@ -234,3 +234,23 @@
/obj/item/fish,
/obj/item/fishing_lure, //they love lures in general.
)
///Memetic fish from a paleontologically inaccurate, goofy replica of a specimen. Sells decently for its size.
/obj/item/fish/sacabambaspis
name = "sacabambaspis"
fish_id = "sacabambaspis"
desc = "A jawless fish ought to be extinct by the end of the Ordovician period. Some speculate alien intervention may have been behind its survival and inevitable evolution as a dweller of hot springs."
icon_state = "sacabambaspis"
sprite_width = 5
sprite_height = 3
stable_population = 7
average_size = 27
average_weight = 500
required_temperature_min = MIN_AQUARIUM_TEMP+20
required_temperature_max = MIN_AQUARIUM_TEMP+45
random_case_rarity = FISH_RARITY_GOOD_LUCK_FINDING_THIS
beauty = FISH_BEAUTY_GOOD
fish_traits = list(/datum/fish_trait/necrophage, /datum/fish_trait/wary)
/obj/item/fish/sacabambaspis/get_export_price(price, percent)
return ..() * 4.5
+1 -1
View File
@@ -68,7 +68,7 @@
if(.)
anger -= min(anger, 6.5)
/obj/item/fish/chasm_crab/proc/growth_checks(datum/source, seconds_per_tick, growth)
/obj/item/fish/chasm_crab/proc/growth_checks(datum/source, seconds_per_tick, growth, result_path)
SIGNAL_HANDLER
var/hunger = get_hunger()
if(health <= initial(health) * 0.6 || hunger >= 0.6) //if too hurt or hungry, don't grow.
+64 -9
View File
@@ -1,20 +1,71 @@
//Tiziran Fish.
/obj/item/fish/dwarf_moonfish
/obj/item/fish/moonfish
name = "zagoskian moonfish"
fish_id = "moonfish"
desc = "A disc-shaped fish native of the less shallow areas of Tizira's oceans, roughly the size of a tuna. Highly prized in lizard cuisine for their large eggs."
icon_state = "tizira_moonfish"
sprite_height = 7
sprite_width = 7
fillet_type = /obj/item/food/fishmeat/moonfish
required_fluid_type = AQUARIUM_FLUID_SALTWATER
stable_population = 2
average_size = 95
average_weight = 2000
required_temperature_min = MIN_AQUARIUM_TEMP+20
required_temperature_max = MIN_AQUARIUM_TEMP+30
beauty = FISH_BEAUTY_GOOD
weight_size_deviation = 0.1
fishing_difficulty_modifier = 10
random_case_rarity = FISH_RARITY_RARE
fish_traits = list(/datum/fish_trait/predator)
compatible_types = list(/obj/item/fish/moonfish, /obj/item/fish/moonfish/dwarf)
evolution_types = list(/datum/fish_evolution/dwarf_moonfish)
favorite_bait = list(
/obj/item/fish/armorfish,
/obj/item/fish/needlefish,
/obj/item/fish/gunner_jellyfish,
)
var/egg_laying_time = 2.75 MINUTES
/obj/item/fish/moonfish/Initialize(mapload, apply_qualities = TRUE)
. = ..()
AddComponent(/datum/component/fish_growth, /obj/item/food/moonfish_eggs, egg_laying_time, use_drop_loc = FALSE, del_on_grow = FALSE, inherit_name = FALSE)
RegisterSignal(src, COMSIG_FISH_BEFORE_GROWING, PROC_REF(egg_checks))
///Stop laying eggs if we're in an unsafe environment, starving of if there are simply too many eggs already.
/obj/item/fish/moonfish/proc/egg_checks(datum/source, seconds_per_tick, growth, result_path)
if(result_path != /obj/item/food/moonfish_eggs) //Don't stop the growth of the dwarf subtype.
return
if(!proper_environment() || is_starving())
return COMPONENT_DONT_GROW
var/count = 0
for(var/obj/item/food/moonfish_eggs/egg in loc)
count ++
if(count > 10)
return COMPONENT_DONT_GROW
/obj/item/fish/moonfish/dwarf
name = "dwarf moonfish"
fish_id = "dwarf_moonfish"
desc = "Ordinarily in the wild, the Zagoskian moonfish is around the size of a tuna, however through selective breeding a smaller breed suitable for being kept as an aquarium pet has been created."
icon_state = "dwarf_moonfish"
sprite_height = 6
sprite_width = 6
required_fluid_type = AQUARIUM_FLUID_SALTWATER
stable_population = 2
fillet_type = /obj/item/food/fishmeat/moonfish
average_size = 60
average_weight = 1000
required_temperature_min = MIN_AQUARIUM_TEMP+20
required_temperature_max = MIN_AQUARIUM_TEMP+30
beauty = FISH_BEAUTY_GOOD
stable_population = 3
average_size = 50
average_weight = 950
fishing_difficulty_modifier = 0
egg_laying_time = 4.25 MINUTES
random_case_rarity = FISH_RARITY_BASIC
fish_traits = list()
evolution_types = list(/datum/fish_evolution/moonfish)
/obj/item/fish/moonfish/dwarf/update_size_and_weight(new_size = average_size, new_weight = average_weight, update_materials = TRUE)
. = ..()
var/multiplier = (size / (average_size * 1.5)) * (weight / (average_weight * 1.5))
AddComponent(/datum/component/fish_growth, /datum/fish_evolution/moonfish, 2.5 MINUTES * multiplier, use_drop_loc = FALSE)
/obj/item/fish/gunner_jellyfish
name = "gunner jellyfish"
@@ -30,6 +81,10 @@
required_temperature_min = MIN_AQUARIUM_TEMP+24
required_temperature_max = MIN_AQUARIUM_TEMP+32
beauty = FISH_BEAUTY_GOOD
favorite_bait = list(
/obj/item/fish/armorfish,
/obj/item/fish/needlefish,
)
/obj/item/fish/gunner_jellyfish/Initialize(mapload, apply_qualities = TRUE)
. = ..()
+96
View File
@@ -477,5 +477,101 @@
Do <b>not</b> spin while the light is still <b>red</b>.<br><br>\
That's all, best of luck to your angling journey."
///A modified mining capsule from the black market and sometimes random loot.
/obj/item/survivalcapsule/fishing
name = "fishing spot capsule"
desc = "An illegally modified mining capsule containing a small fishing spot connected to some faraway place."
icon_state = "capsule_fishing"
initial_language_holder = /datum/language_holder/speaking_machine
verb_say = "beeps"
verb_yell = "blares"
voice_filter = "alimiter=0.9,acompressor=threshold=0.3:ratio=40:attack=15:release=350:makeup=1.5,highpass=f=1000,rubberband=pitch=1.5"
template_id = "fishing_default"
yeet_back = FALSE
/obj/item/survivalcapsule/fishing/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_CONTRABAND, INNATE_TRAIT)
register_context()
if(SStts.tts_enabled) //This capsule informs you on why it cannot be deployed in a sliiiiightly different way.
voice = pick(SStts.available_speakers)
/obj/item/survivalcapsule/fishing/add_context(atom/source, list/context, obj/item/held_item, mob/user)
if(!held_item || held_item == src)
context[SCREENTIP_CONTEXT_RMB] = "Change fishing spot"
return CONTEXTUAL_SCREENTIP_SET
/obj/item/survivalcapsule/fishing/examine(mob/user)
. = ..()
. += span_info("[EXAMINE_HINT("Right-Click")] to change the selected fishing spot when held.")
/obj/item/survivalcapsule/fishing/examine_more(mob/user)
. = ..()
. += span_tinynotice("A tiny print on the side reads: \"Use a cryptographic sequencer to disable safeties\".")
/obj/item/survivalcapsule/fishing/emag_act(mob/user, obj/item/card/emag/emag_card)
if(obj_flags & EMAGGED)
return FALSE
obj_flags |= EMAGGED
balloon_alert(user, "safeties disabled")
playsound(src, SFX_SPARKS, 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
return TRUE
/obj/item/survivalcapsule/fishing/attack_self_secondary(mob/living/user)
. = ..()
if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
return
. = SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
if(used)
return
var/list/choices = list()
var/list/spot_ids_by_name = list()
for(var/datum/map_template/shelter/fishing/spot as anything in typesof(/datum/map_template/shelter/fishing))
if(!spot::safe && !(obj_flags & EMAGGED))
continue
choices[spot::name] = image('icons/hud/radial_fishing.dmi', spot::radial_icon)
spot_ids_by_name[spot::name] = spot::shelter_id
var/choice = show_radial_menu(user, src, choices, radius = 38, custom_check = CALLBACK(src, TYPE_PROC_REF(/atom, can_interact), user), tooltips = TRUE)
if(!choice || used || !can_interact(user))
return
template_id = spot_ids_by_name[choice]
template = SSmapping.shelter_templates[template_id]
to_chat(user, span_notice("You change [src]'s selected fishing spot to [choice]."))
playsound(src, 'sound/items/pen_click.ogg', 20, TRUE, -3)
return
/obj/item/survivalcapsule/fishing/get_ignore_flags()
. = ..()
if(obj_flags & EMAGGED)
. += CAPSULE_IGNORE_ANCHORED_OBJECTS|CAPSULE_IGNORE_BANNED_OBJECTS
/obj/item/survivalcapsule/fishing/fail_feedback(status)
switch(status)
if(SHELTER_DEPLOY_BAD_AREA)
say("I refuse to deploy in this area.")
if(SHELTER_DEPLOY_BAD_TURFS)
say("The walls are too close! I need [template.width]x[template.height] area to deploy.")
if(SHELTER_DEPLOY_ANCHORED_OBJECTS)
say("Get these anchored objects out of the way! I need [template.width]x[template.height] area to deploy.")
if(SHELTER_DEPLOY_BANNED_OBJECTS)
say("Remove all cables and pipes around me in a [template.width]x[template.height] area or I won't deploy.")
if(SHELTER_DEPLOY_OUTSIDE_MAP)
say("For fucks sake, deploy me somewhere less far fatched!")
/obj/item/survivalcapsule/fishing/trigger_admin_alert(mob/triggerer, turf/trigger_loc)
var/datum/map_template/shelter/fishing/spot = template
if(spot.safe) //Don't log if the fishing spot is safe
return
var/area/area = get_area(src)
if(!area.outdoors)
message_admins("[ADMIN_LOOKUPFLW(triggerer)] activated an unsafe fishing capsule at [ADMIN_VERBOSEJMP(trigger_loc)]")
log_admin("[key_name(triggerer)] activated an unsafe fishing capsule at [AREACOORD(trigger_loc)]")
/obj/item/survivalcapsule/fishing/hacked
obj_flags = parent_type::obj_flags | EMAGGED
#undef MAGNET_HOOK_BONUS_MULTIPLIER
#undef RESCUE_HOOK_FISH_MULTIPLIER
@@ -43,6 +43,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
/obj/item/fish/stingray = FISH_ICON_WEAPON,
/obj/item/fish/swordfish = FISH_ICON_WEAPON,
/obj/item/fish/zipzap = FISH_ICON_ELECTRIC,
/obj/item/fishing_rod = FISH_ICON_COIN,
/obj/item/instrument/trumpet/spectral = FISH_ICON_BONE,
/obj/item/instrument/saxophone/spectral = FISH_ICON_BONE,
/obj/item/instrument/trombone/spectral = FISH_ICON_BONE,
@@ -53,6 +54,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons())
/obj/item/stack/sheet/bone = FISH_ICON_BONE,
/obj/item/stack/sheet/mineral = FISH_ICON_GEM,
/obj/item/stack/ore = FISH_ICON_GEM,
/obj/item/survivalcapsule/fishing = FISH_ICON_COIN,
/obj/structure/closet/crate = FISH_ICON_COIN,
/obj/structure/mystery_box = FISH_ICON_COIN,
))
+45 -1
View File
@@ -128,6 +128,10 @@
/obj/item/fish/greenchromis = 10,
/obj/item/fish/squid = 8,
/obj/item/fish/plaice = 8,
/obj/item/survivalcapsule/fishing = 1,
)
fish_counts = list(
/obj/item/survivalcapsule/fishing = 1,
)
catalog_description = "Beach dimension (Fishing portal generator)"
radial_name = "Beach"
@@ -160,14 +164,15 @@
/obj/effect/spawner/message_in_a_bottle = 2,
/obj/item/fish/lanternfish = 5,
/obj/item/fish/firefish = 5,
/obj/item/fish/dwarf_moonfish = 5,
/obj/item/fish/gunner_jellyfish = 5,
/obj/item/fish/moonfish/dwarf = 4,
/obj/item/fish/needlefish = 5,
/obj/item/fish/armorfish = 5,
/obj/item/fish/zipzap = 5,
/obj/item/fish/stingray = 4,
/obj/item/fish/monkfish = 4,
/obj/item/fish/swordfish = 3,
/obj/item/fish/moonfish = 1,
)
fish_counts = list(
/obj/item/fish/swordfish = 2,
@@ -358,6 +363,7 @@
/datum/fish_source/lavaland/icemoon
catalog_description = "Liquid plasma vents"
radial_state = "plasma"
fish_table = list(
FISHING_DUD = 5,
/obj/item/fish/chasm_crab/ice = 30,
@@ -397,9 +403,11 @@
/obj/item/fish/sludgefish = 18,
/obj/item/fish/slimefish = 4,
/obj/item/storage/wallet/money = 2,
/obj/item/survivalcapsule/fishing = 1,
)
fish_counts = list(
/obj/item/storage/wallet/money = 2,
/obj/item/survivalcapsule/fishing = 1,
)
fishing_difficulty = FISHING_EASY_DIFFICULTY //For beginners
@@ -623,3 +631,39 @@
/obj/item/fish/fryish/fritterish = 6 MINUTES,
)
fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 13
/datum/fish_source/hot_spring
catalog_description = "Hot Springs"
radial_state = "onsen"
overlay_state = "portal_ocean"
fish_table = list(
FISHING_DUD = 20,
/obj/item/fish/bumpy = 10,
/obj/item/fish/sacabambaspis = 10,
/mob/living/basic/frog = 2,
/obj/item/fishing_rod/telescopic/master = 1,
)
fish_counts = list(
/obj/item/fish/sacabambaspis = 5,
/obj/item/fishing_rod/telescopic/master = 2,
)
fish_count_regen = list(
/obj/item/fish/sacabambaspis = 4 MINUTES,
)
fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 20
fish_source_flags = FISH_SOURCE_FLAG_EXPLOSIVE_MALUS
/datum/fish_source/tizira
catalog_description = "Tiziran Sea"
radial_state = "planet"
overlay_state = "portal_beach"
fish_table = list(
FISHING_DUD = 10,
/obj/item/fish/needlefish = 5,
/obj/item/fish/armorfish = 5,
/obj/item/fish/gunner_jellyfish = 4,
/obj/item/fish/moonfish/dwarf = 2,
/obj/item/fish/moonfish = 2,
)
fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 10
fish_source_flags = FISH_SOURCE_FLAG_EXPLOSIVE_MALUS
@@ -10,33 +10,30 @@
*
*/
/turf/open/water/cursed_spring
name = "cursed spring"
baseturfs = /turf/open/water/cursed_spring
/turf/open/water/hot_spring/cursed
baseturfs = /turf/open/water/hot_spring/cursed
planetary_atmos = TRUE
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
fishing_datum = /datum/fish_source/cursed_spring
/turf/open/water/cursed_spring/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
. = ..()
if(!isliving(arrived))
return
var/mob/living/to_transform = arrived
var/datum/mind/transforming_mind = to_transform.mind
if(!to_transform.client || to_transform.incorporeal_move || !transforming_mind)
return
if(HAS_TRAIT(transforming_mind, TRAIT_HOT_SPRING_CURSED)) // no double dipping
return
/turf/open/water/hot_spring/cursed/dip_in(atom/movable/movable)
if(!isliving(movable))
return ..()
var/mob/living/living = movable
if(!living.client || living.incorporeal_move || !living.mind)
return ..()
if(HAS_MIND_TRAIT(living, TRAIT_HOT_SPRING_CURSED)) // no double dipping
return ..()
ADD_TRAIT(transforming_mind, TRAIT_HOT_SPRING_CURSED, TRAIT_GENERIC)
var/mob/living/transformed_mob = to_transform.wabbajack(pick(WABBAJACK_HUMAN, WABBAJACK_ANIMAL), change_flags = RACE_SWAP)
ADD_TRAIT(living.mind, TRAIT_HOT_SPRING_CURSED, TRAIT_GENERIC)
var/mob/living/transformed_mob = living.wabbajack(pick(WABBAJACK_HUMAN, WABBAJACK_ANIMAL), change_flags = RACE_SWAP)
if(!transformed_mob)
// Wabbajack failed, maybe the mob had godmode or something.
if(!QDELETED(to_transform))
to_chat(to_transform, span_notice("The water seems to have no effect on you."))
if(!QDELETED(living))
to_chat(living, span_notice("The water seems to have no effect on you."))
// because it failed, let's allow them to try again in a lil' bit
addtimer(TRAIT_CALLBACK_REMOVE(transforming_mind, TRAIT_HOT_SPRING_CURSED, TRAIT_GENERIC), 10 SECONDS)
return
addtimer(TRAIT_CALLBACK_REMOVE(living.mind, TRAIT_HOT_SPRING_CURSED, TRAIT_GENERIC), 10 SECONDS)
return ..()
var/turf/return_turf = find_safe_turf(extended_safety_checks = TRUE, dense_atoms = FALSE)
transformed_mob.forceMove(return_turf)
+25 -9
View File
@@ -15,9 +15,14 @@
icon_state = "capsule"
icon = 'icons/obj/mining.dmi'
w_class = WEIGHT_CLASS_TINY
///The id we use to fetch the template datum
var/template_id = "shelter_alpha"
///The template datum we use to load the shelter
var/datum/map_template/shelter/template
///If true, this capsule is active and will deploy the area if conditions are met.
var/used = FALSE
///Will this capsule yeet mobs back once the area is deployed?
var/yeet_back = TRUE
/obj/item/survivalcapsule/proc/get_template()
if(template)
@@ -37,7 +42,7 @@
. += "This capsule has the [template.name] stored."
. += template.description
/obj/item/survivalcapsule/interact(mob/user)
/obj/item/survivalcapsule/interact(mob/living/user)
. = ..()
if(.)
return .
@@ -50,6 +55,9 @@
loc.visible_message(span_warning("[src] begins to shake. Stand back!"))
used = TRUE
addtimer(CALLBACK(src, PROC_REF(expand), user), 5 SECONDS)
if(iscarbon(user))
var/mob/living/carbon/carbon = user
carbon.throw_mode_on(THROW_MODE_TOGGLE)
return TRUE
/// Expands the capsule into a full shelter, placing the template at the item's location (NOT triggerer's location)
@@ -58,24 +66,32 @@
return
var/turf/deploy_location = get_turf(src)
var/status = template.check_deploy(deploy_location)
switch(status)
if(SHELTER_DEPLOY_BAD_AREA)
loc.visible_message(span_warning("[src] will not function in this area."))
if(SHELTER_DEPLOY_BAD_TURFS, SHELTER_DEPLOY_ANCHORED_OBJECTS, SHELTER_DEPLOY_OUTSIDE_MAP)
loc.visible_message(span_warning("[src] doesn't have room to deploy! You need to clear a [template.width]x[template.height] area!"))
var/status = template.check_deploy(deploy_location, src, get_ignore_flags())
if(status != SHELTER_DEPLOY_ALLOWED)
fail_feedback(status)
used = FALSE
return
yote_nearby(deploy_location)
if(yeet_back)
yote_nearby(deploy_location)
template.load(deploy_location, centered = TRUE)
trigger_admin_alert(triggerer, deploy_location)
playsound(src, 'sound/effects/phasein.ogg', 100, TRUE)
new /obj/effect/particle_effect/fluid/smoke(get_turf(src))
qdel(src)
/// Returns a bitfield used to ignore some checks in template.check_deploy()
/obj/item/survivalcapsule/proc/get_ignore_flags()
return NONE
///Returns a message including the reason why it couldn't be deployed
/obj/item/survivalcapsule/proc/fail_feedback(status)
switch(status)
if(SHELTER_DEPLOY_BAD_AREA)
loc.visible_message(span_warning("[src] will not function in this area."))
if(SHELTER_DEPLOY_BAD_TURFS, SHELTER_DEPLOY_ANCHORED_OBJECTS, SHELTER_DEPLOY_OUTSIDE_MAP, SHELTER_DEPLOY_BANNED_OBJECTS)
loc.visible_message(span_warning("[src] doesn't have room to deploy! You need to clear a [template.width]x[template.height] area!"))
/// Throws any mobs near the deployed location away from the item / shelter
/// Does some math to make closer mobs get thrown further
/obj/item/survivalcapsule/proc/yote_nearby(turf/deploy_location)
+95 -21
View File
@@ -1,36 +1,39 @@
///Map templates used for bluespace survival capsules.
/datum/map_template/shelter
var/shelter_id
var/description
var/list/blacklisted_turfs
var/list/whitelisted_turfs
var/list/banned_areas
var/list/banned_objects
has_ceiling = TRUE
ceiling_turf = /turf/open/floor/engine/hull
ceiling_baseturfs = list(/turf/open/floor/plating)
///The id of the shelter template in the relative list from the mapping subsystem
var/shelter_id
///The description of the shelter, shown when examining survival capsule.
var/description
///If turf in the affected turfs is in this list, the survival capsule cannot be deployed.
var/list/blacklisted_turfs
///Areas where the capsule cannot be deployed.
var/list/banned_areas
///If any object in this list is found in the affected turfs, the capsule cannot deploy.
var/list/banned_objects = list()
/datum/map_template/shelter/New()
. = ..()
blacklisted_turfs = typecacheof(/turf/closed)
whitelisted_turfs = list()
banned_areas = typecacheof(/area/shuttle)
banned_objects = list()
/datum/map_template/shelter/proc/check_deploy(turf/deploy_location)
/datum/map_template/shelter/proc/check_deploy(turf/deploy_location, obj/item/survivalcapsule/capsule, ignore_flags = NONE)
var/affected = get_affected_turfs(deploy_location, centered=TRUE)
for(var/turf/T in affected)
var/area/A = get_area(T)
if(is_type_in_typecache(A, banned_areas))
for(var/turf/turf in affected)
var/area/area = get_area(turf)
if(is_type_in_typecache(area, banned_areas))
return SHELTER_DEPLOY_BAD_AREA
var/banned = is_type_in_typecache(T, blacklisted_turfs)
var/permitted = is_type_in_typecache(T, whitelisted_turfs)
if(banned && !permitted)
if(is_type_in_typecache(turf, blacklisted_turfs))
return SHELTER_DEPLOY_BAD_TURFS
for(var/obj/O in T)
if((O.density && O.anchored) || is_type_in_typecache(O, banned_objects))
for(var/obj/object in turf)
if(!(ignore_flags & CAPSULE_IGNORE_ANCHORED_OBJECTS) && object.density && object.anchored)
return SHELTER_DEPLOY_ANCHORED_OBJECTS
if(!(ignore_flags & CAPSULE_IGNORE_BANNED_OBJECTS) && is_type_in_typecache(object, banned_objects))
return SHELTER_DEPLOY_BANNED_OBJECTS
// Check if the shelter sticks out of map borders
var/shelter_origin_x = deploy_location.x - round(width/2)
@@ -53,7 +56,7 @@
/datum/map_template/shelter/alpha/New()
. = ..()
whitelisted_turfs = typecacheof(/turf/closed/mineral)
blacklisted_turfs -= typesof(/turf/closed/mineral)
banned_objects = typecacheof(/obj/structure/stone_tile)
/datum/map_template/shelter/beta
@@ -68,7 +71,7 @@
/datum/map_template/shelter/beta/New()
. = ..()
whitelisted_turfs = typecacheof(/turf/closed/mineral)
blacklisted_turfs -= typesof(/turf/closed/mineral)
banned_objects = typecacheof(/obj/structure/stone_tile)
/datum/map_template/shelter/charlie
@@ -83,7 +86,7 @@
/datum/map_template/shelter/charlie/New()
. = ..()
whitelisted_turfs = typecacheof(/turf/closed/mineral)
blacklisted_turfs -= typesof(/turf/closed/mineral)
banned_objects = typecacheof(/obj/structure/stone_tile)
/datum/map_template/shelter/toilet
@@ -96,5 +99,76 @@
/datum/map_template/shelter/toilet/New()
. = ..()
whitelisted_turfs = typecacheof(/turf/closed/mineral)
blacklisted_turfs -= typesof(/turf/closed/mineral)
banned_objects = typecacheof(/obj/structure/stone_tile)
///Not exactly mining shelters, but they make use of survival capsules code.
/datum/map_template/shelter/fishing
name = "Freshwater Spring"
shelter_id = "fishing_default"
description = "A spring from which you can fish several freshwater fish, including goldfish, catfish and pikes."
mappath = "_maps/templates/fishing_freshwater.dmm"
has_ceiling = FALSE
///The icon shown in the radial menu
var/radial_icon = "river"
/**
* If FALSE, the capsule needs to be emagged for this template to be selectable.
* its usage will also be logged, and admins warned if used indoors.
*/
var/safe = TRUE
/datum/map_template/shelter/fishing/New()
. = ..()
blacklisted_turfs -= typesof(/turf/closed/mineral)
blacklisted_turfs += typecacheof(/turf/open/openspace)
// Stop the capsule from being used around pipes and cables (if not emagged) cuz it'd look bad and a bit disruptive.
banned_objects = typecacheof(list(
/obj/structure/disposalpipe,
/obj/machinery/atmospherics/pipe,
/obj/structure/cable,
/obj/structure/transit_tube,
))
/datum/map_template/shelter/fishing/beach
name = "Saltwater Spring"
shelter_id = "fishing_beach"
mappath = "_maps/templates/fishing_saltwater.dmm"
description = "A spring from which you can fish several saltwater fish, including clownfish, pufferfish and stingrays."
radial_icon = "seaboat"
/datum/map_template/shelter/fishing/tizira
name = "Tiziran Spring"
shelter_id = "fishing_tizira"
mappath = "_maps/templates/fishing_tizira.dmm"
description = "A spring from which you can fish several fish native to the lizardfolk's native planet, Tizira."
radial_icon = "planet"
/datum/map_template/shelter/fishing/hot_spring
name = "Hot Spring"
shelter_id = "fishing_hot_spring"
mappath = "_maps/templates/fishing_hot_spring.dmm"
description = "A hot spring. Its purposes as a fishing spot is limited, but at least you get to have a relaxing bath."
radial_icon = "onsen"
/datum/map_template/shelter/fishing/ice
name = "Ice Fishing Spot"
shelter_id = "fishing_ice"
mappath = "_maps/templates/fishing_ice.dmm"
description = "A small, already dug ice hole surrounded by snow. You can catch salmon and arctic char here."
radial_icon = "ice"
/datum/map_template/shelter/fishing/lava
name = "Lava Fishing Spot"
shelter_id = "fishing_lava"
mappath = "_maps/templates/fishing_lava.dmm"
description = "A small 2x2 puddle of not-safe-for-live lava. You can catch lava loops here, and maybe a chest."
radial_icon = "lava"
safe = FALSE
/datum/map_template/shelter/fishing/plasma
name = "Plasma Fishing Spot"
shelter_id = "fishing_plasma"
mappath = "_maps/templates/fishing_plasma.dmm"
description = "A small 2x2 puddle of not-safe-for-live plasma. You can catch lava loops and arctic chrabs here."
radial_icon = "plasma"
safe = FALSE
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 KiB

After

Width:  |  Height:  |  Size: 382 KiB

+1 -1
View File
@@ -4642,7 +4642,7 @@
#include "code\modules\mapfluff\ruins\generic.dm"
#include "code\modules\mapfluff\ruins\lavaland_ruin_code.dm"
#include "code\modules\mapfluff\ruins\icemoonruin_code\commsagent.dm"
#include "code\modules\mapfluff\ruins\icemoonruin_code\hotsprings.dm"
#include "code\modules\mapfluff\ruins\icemoonruin_code\cursed_spring.dm"
#include "code\modules\mapfluff\ruins\icemoonruin_code\lavaland_incursion.dm"
#include "code\modules\mapfluff\ruins\icemoonruin_code\library.dm"
#include "code\modules\mapfluff\ruins\icemoonruin_code\mailroom.dm"
@@ -0,0 +1 @@
/turf/open/water/cursed_spring : /turf/open/water/hot_spring/cursed{@OLD}