From ca75ba4edd18c55521b48dabedd491575b7ff3cc Mon Sep 17 00:00:00 2001 From: Dennok Date: Wed, 2 Sep 2020 17:10:54 +0300 Subject: [PATCH 01/32] different layers to different piping layers --- code/modules/atmospherics/machinery/atmosmachinery.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 7b265f34612..b8d18479611 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -126,6 +126,10 @@ piping_layer = (pipe_flags & PIPING_DEFAULT_LAYER_ONLY) ? PIPING_LAYER_DEFAULT : new_layer update_icon() +/obj/machinery/atmospherics/update_icon() + layer = initial(layer) + piping_layer / 1000 + return ..() + /obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target, iteration) return connection_check(target, piping_layer) From c86541b11a99749034924047ab5b8d8a0f1f2432 Mon Sep 17 00:00:00 2001 From: Dennok Date: Wed, 2 Sep 2020 20:14:36 +0300 Subject: [PATCH 02/32] parrent call in components/update_icon() --- .../atmospherics/machinery/components/components_base.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm index 951638d378d..c9b8c06eb20 100644 --- a/code/modules/atmospherics/machinery/components/components_base.dm +++ b/code/modules/atmospherics/machinery/components/components_base.dm @@ -45,7 +45,7 @@ plane = showpipe ? GAME_PLANE : FLOOR_PLANE if(!showpipe) - return + return ..() var/connected = 0 //Direction bitset @@ -62,6 +62,7 @@ if(!shift_underlay_only) PIPING_LAYER_SHIFT(src, piping_layer) + return ..() /obj/machinery/atmospherics/components/proc/get_pipe_underlay(state, dir, color = null) if(color) From 09281a1db4e03eb3a93f416267a4f39263fbcfba Mon Sep 17 00:00:00 2001 From: Dennok Date: Thu, 3 Sep 2020 09:09:58 +0300 Subject: [PATCH 03/32] small comment to the layer defines file --- code/__DEFINES/atmospherics.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index c79b21c61a7..55859477bf5 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -350,6 +350,7 @@ //MULTIPIPES //IF YOU EVER CHANGE THESE CHANGE SPRITES TO MATCH. +//layer = initial(layer) + piping_layer / 1000 in atmospherics/update_icon() to determine order of pipe overlap #define PIPING_LAYER_MIN 1 #define PIPING_LAYER_MAX 5 #define PIPING_LAYER_DEFAULT 3 From aa74937d4bf234235792c236ced9511d47842098 Mon Sep 17 00:00:00 2001 From: Dennok Date: Thu, 3 Sep 2020 16:54:54 +0300 Subject: [PATCH 04/32] some more comment --- code/__DEFINES/layers.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 46e8032e055..6beb1828b6d 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -33,12 +33,12 @@ #define ABOVE_NORMAL_TURF_LAYER 2.08 #define LATTICE_LAYER 2.2 #define DISPOSAL_PIPE_LAYER 2.3 -#define GAS_PIPE_HIDDEN_LAYER 2.35 +#define GAS_PIPE_HIDDEN_LAYER 2.35 //layer = initial(layer) + piping_layer / 1000 in atmospherics/update_icon() to determine order of pipe overlap #define WIRE_LAYER 2.4 #define WIRE_BRIDGE_LAYER 2.44 #define WIRE_TERMINAL_LAYER 2.45 -#define GAS_SCRUBBER_LAYER 2.46 -#define GAS_PIPE_VISIBLE_LAYER 2.47 +#define GAS_SCRUBBER_LAYER 2.46 +#define GAS_PIPE_VISIBLE_LAYER 2.47 //layer = initial(layer) + piping_layer / 1000 in atmospherics/update_icon() to determine order of pipe overlap #define GAS_FILTER_LAYER 2.48 #define GAS_PUMP_LAYER 2.49 #define LOW_OBJ_LAYER 2.5 From 576c76fddbddb579681a584aa9049204f4e4fd10 Mon Sep 17 00:00:00 2001 From: Critawakets Date: Fri, 4 Sep 2020 19:17:55 -0400 Subject: [PATCH 05/32] Changes deltastation tcomms to use heat exchanging. --- .../map_files/Deltastation/DeltaStation2.dmm | 315 +++++++++--------- 1 file changed, 153 insertions(+), 162 deletions(-) diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 66cfc5f72f9..19b4429f773 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -2699,6 +2699,21 @@ }, /turf/open/floor/plasteel/dark, /area/maintenance/starboard/fore) +"ait" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) "aiz" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ @@ -56371,25 +56386,6 @@ }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) -"ccF" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - external_pressure_bound = 140; - name = "server vent"; - pressure_checks = 0 - }, -/turf/open/floor/plasteel/dark/telecomms, -/area/tcommsat/server) "ccH" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral{ @@ -56404,30 +56400,6 @@ }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) -"ccI" = ( -/obj/structure/table/glass, -/obj/item/folder/yellow, -/obj/structure/cable, -/turf/open/floor/circuit/green/telecomms/mainframe, -/area/tcommsat/server) -"ccJ" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ - external_pressure_bound = 120; - name = "server vent" - }, -/turf/open/floor/plasteel/dark/telecomms, -/area/tcommsat/server) "ccM" = ( /obj/structure/table/wood, /obj/item/pinpointer/nuke, @@ -57345,57 +57317,6 @@ }, /turf/open/floor/plasteel/dark/telecomms, /area/tcommsat/server) -"cev" = ( -/obj/machinery/telecomms/broadcaster/preset_left, -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 5 - }, -/turf/open/floor/circuit/telecomms/mainframe, -/area/tcommsat/server) -"cex" = ( -/obj/machinery/telecomms/message_server/preset, -/obj/machinery/atmospherics/pipe/manifold/general/hidden{ - dir = 1 - }, -/turf/open/floor/circuit/green/telecomms/mainframe, -/area/tcommsat/server) -"cey" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/dark/telecomms, -/area/tcommsat/server) -"cez" = ( -/obj/machinery/telecomms/hub/preset, -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 4 - }, -/turf/open/floor/circuit/green/telecomms/mainframe, -/area/tcommsat/server) -"ceA" = ( -/obj/machinery/blackbox_recorder, -/obj/machinery/atmospherics/pipe/manifold/general/hidden{ - dir = 1 - }, -/turf/open/floor/circuit/green/telecomms/mainframe, -/area/tcommsat/server) -"ceB" = ( -/obj/machinery/telecomms/broadcaster/preset_right, -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 9 - }, -/turf/open/floor/circuit/telecomms/mainframe, -/area/tcommsat/server) "ceD" = ( /obj/machinery/power/smes{ charge = 5e+006 @@ -58217,20 +58138,6 @@ }, /turf/open/floor/wood, /area/crew_quarters/heads/hop) -"cgk" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/general/hidden, -/turf/open/floor/plasteel/dark/telecomms, -/area/tcommsat/server) "cgm" = ( /obj/machinery/ntnet_relay, /turf/open/floor/circuit/green/telecomms/mainframe, @@ -61222,11 +61129,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/tcommsat/server) -"cmE" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/general/hidden, -/turf/open/floor/plating, -/area/tcommsat/server) "cmF" = ( /obj/machinery/door/firedoor, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -62077,13 +61979,6 @@ "coe" = ( /turf/closed/wall, /area/tcommsat/server) -"cof" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/tcommsat/server) "cog" = ( /obj/machinery/holopad, /obj/effect/turf_decal/stripes/line{ @@ -89980,6 +89875,23 @@ }, /turf/open/floor/plasteel/dark, /area/science/genetics) +"dtf" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 6 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) "dtg" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -108445,6 +108357,10 @@ }, /turf/open/floor/plasteel/white, /area/medical/chemistry) +"fZt" = ( +/obj/machinery/telecomms/hub/preset, +/turf/open/floor/circuit/green/telecomms/mainframe, +/area/tcommsat/server) "gaK" = ( /obj/effect/turf_decal/trimline/blue/filled/corner{ dir = 8 @@ -108754,6 +108670,13 @@ }, /turf/open/floor/plasteel/dark, /area/engine/atmospherics_engine) +"had" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/heat_exchanging/junction{ + dir = 1 + }, +/turf/open/floor/plating, +/area/tcommsat/server) "hdH" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/conveyor{ @@ -109249,21 +109172,6 @@ }, /turf/open/floor/plasteel, /area/security/prison) -"iDI" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/general/hidden, -/turf/open/floor/plasteel/dark/telecomms, -/area/tcommsat/server) "iFA" = ( /turf/open/floor/plasteel/white, /area/maintenance/department/science) @@ -109330,6 +109238,23 @@ /obj/item/storage/crayons, /turf/open/floor/plasteel, /area/security/prison) +"iOJ" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 10 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) "iQh" = ( /obj/structure/bodycontainer/morgue{ dir = 1 @@ -110121,6 +110046,11 @@ }, /turf/open/floor/plating, /area/security/prison) +"lia" = ( +/obj/machinery/telecomms/message_server/preset, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/circuit/green/telecomms/mainframe, +/area/tcommsat/server) "ljP" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -110481,6 +110411,11 @@ /obj/structure/grille, /turf/closed/wall/r_wall, /area/space) +"mcn" = ( +/obj/machinery/blackbox_recorder, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/circuit/green/telecomms/mainframe, +/area/tcommsat/server) "mdG" = ( /obj/machinery/light/small{ dir = 1 @@ -111756,6 +111691,14 @@ "pxG" = ( /turf/closed/wall, /area/medical/pharmacy) +"pzj" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/portable_atmospherics/canister/air, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/tcommsat/server) "pAL" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/sign/poster/random{ @@ -111831,6 +111774,15 @@ }, /turf/closed/wall, /area/security/checkpoint/science/research) +"pHV" = ( +/obj/structure/table/glass, +/obj/item/folder/yellow, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/circuit/green/telecomms/mainframe, +/area/tcommsat/server) "pJb" = ( /obj/item/kirbyplants/random, /turf/open/floor/plasteel, @@ -112691,6 +112643,10 @@ /obj/structure/bed/roller, /turf/open/floor/plasteel/white, /area/medical/sleeper) +"rWL" = ( +/obj/machinery/telecomms/broadcaster/preset_left, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) "rYU" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -112706,6 +112662,20 @@ }, /turf/open/floor/plasteel, /area/medical/medbay/central) +"rZb" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) "saw" = ( /turf/closed/wall/r_wall, /area/science/misc_lab/range) @@ -112932,6 +112902,23 @@ }, /turf/open/floor/plating, /area/security/prison) +"sUc" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/heat_exchanging/simple{ + dir = 4 + }, +/turf/open/floor/plasteel/dark/telecomms, +/area/tcommsat/server) "sUE" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -114304,6 +114291,10 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/security/prison) +"wRg" = ( +/obj/machinery/telecomms/broadcaster/preset_right, +/turf/open/floor/circuit/telecomms/mainframe, +/area/tcommsat/server) "wTa" = ( /obj/machinery/computer/nanite_cloud_controller, /obj/effect/turf_decal/bot, @@ -152635,8 +152626,8 @@ bUH bWX bZf caT -ccF -cev +ccH +rWL bUF cid cjE @@ -152893,7 +152884,7 @@ bWX bZg caU ccH -cey +bUF bUF cie cjF @@ -153149,14 +153140,14 @@ bUI bWY bUF bUF -ccH -cex -cgk -iDI -iDI -iDI -cmE -cof +dtf +lia +rZb +ait +ait +ait +had +pzj cpI cqY csw @@ -153406,8 +153397,8 @@ bUI bUI bUI caY -ccH -cey +sUc +bUF bUF cig bUI @@ -153663,8 +153654,8 @@ bUK bWZ bZi bUF -ccI -cez +pHV +fZt cgm ccH cjG @@ -153920,8 +153911,8 @@ bUI bUI bUI caY -ccH -cey +sUc +bUF bUF cig bUI @@ -154177,13 +154168,13 @@ bUI bXa bUF bUF -ccH -ceA -iDI -iDI -iDI -iDI -cmE +iOJ +mcn +ait +ait +ait +ait +had coj cpM cqY @@ -154435,7 +154426,7 @@ bWX bZj caZ ccH -cey +bUF ccH cih cjH @@ -154691,8 +154682,8 @@ bUG bWX bZk cba -ccJ -ceB +ccH +wRg ccH cii cjI From 8acd462c77937a863018f92a4079c1c08f723d1d Mon Sep 17 00:00:00 2001 From: Dennok Date: Sun, 6 Sep 2020 23:56:49 +0300 Subject: [PATCH 06/32] Tweak passive_gate (#53375) Make some more precise description. Increased max out limit pressure settings to 100 atmospheres, since volume_pump limited 9000 kPa (~90 atmospheres) --- .../machinery/components/binary_devices/passive_gate.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm index 139253644df..a2b22738b7d 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm @@ -3,6 +3,7 @@ Passive gate is similar to the regular pump except: * It doesn't require power * Can not transfer low pressure to higher pressure (so it's more like a valve where you can control the flow) +* Passes gas when output pressure lower than target pressure */ @@ -10,7 +11,7 @@ Passive gate is similar to the regular pump except: icon_state = "passgate_map-3" name = "passive gate" - desc = "A one-way air valve that does not require power." + desc = "A one-way air valve that does not require power. Passes gas when the output pressure is lower than the target pressure." can_unwrench = TRUE shift_underlay_only = FALSE @@ -112,7 +113,7 @@ Passive gate is similar to the regular pump except: pressure = text2num(pressure) . = TRUE if(.) - target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE) + target_pressure = clamp(pressure, 0, ONE_ATMOSPHERE*100) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) update_icon() @@ -134,7 +135,7 @@ Passive gate is similar to the regular pump except: on = !on if("set_output_pressure" in signal.data) - target_pressure = clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) + target_pressure = clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*100) if(on != old_on) investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) From 8c4f48f44936b6c94ce76d5395921f7a54b14da5 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Sun, 6 Sep 2020 13:56:54 -0700 Subject: [PATCH 07/32] Automatic changelog generation for PR #53375 [ci skip] --- html/changelogs/AutoChangeLog-pr-53375.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-53375.yml diff --git a/html/changelogs/AutoChangeLog-pr-53375.yml b/html/changelogs/AutoChangeLog-pr-53375.yml new file mode 100644 index 00000000000..dd874f6bce9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-53375.yml @@ -0,0 +1,5 @@ +author: "Dennok" +delete-after: True +changes: + - tweak: "passive gate max out limit pressure settings increased" + - tweak: "passive gate description more precise" From 0b2d1eeab7d4054d8d840c77a8e3aba526a04bd2 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Sun, 6 Sep 2020 14:01:53 -0700 Subject: [PATCH 08/32] Automatic changelog generation for PR #53450 [ci skip] --- html/changelogs/AutoChangeLog-pr-53450.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-53450.yml diff --git a/html/changelogs/AutoChangeLog-pr-53450.yml b/html/changelogs/AutoChangeLog-pr-53450.yml new file mode 100644 index 00000000000..66dd92e0682 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-53450.yml @@ -0,0 +1,4 @@ +author: "CRITAWAKETS" +delete-after: True +changes: + - tweak: "Nanotrasen has updated the cooling setup of telecommunications rooms in Delta-Pattern Stations. It now makes the simulation faster." From 5abd48b38918a95e371fc48ca094bc0df9877b65 Mon Sep 17 00:00:00 2001 From: Maurukas <66576896+Maurukas@users.noreply.github.com> Date: Sun, 6 Sep 2020 14:58:51 -0700 Subject: [PATCH 09/32] Fix cryo reagent injection (#53477) --- .../atmospherics/machinery/components/unary_devices/cryo.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index c7717b9711d..db3196ee4a2 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -243,7 +243,7 @@ mob_occupant.Unconscious((mob_occupant.bodytemperature * unconscious_factor) * 2000) if(beaker) if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic. - beaker.reagents.trans_to(occupant, 1, efficiency * 0.25, methods = VAPOR) // Transfer reagents. + beaker.reagents.trans_to(occupant, 1, efficiency * 25, methods = VAPOR) // Transfer reagents. air1.gases[/datum/gas/oxygen][MOLES] -= max(0,air1.gases[/datum/gas/oxygen][MOLES] - 2 / efficiency) //Let's use gas for this air1.garbage_collect() if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker). @@ -302,6 +302,7 @@ L.update_mobility() occupant = null flick("pod-open-anim", src) + reagent_transfer = efficiency * 10 - 5 // wait before injecting the next occupant ..() /obj/machinery/atmospherics/components/unary/cryo_cell/close_machine(mob/living/carbon/user) From c129471c82307246da2af83cbd96427edbc7ad48 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Sun, 6 Sep 2020 14:58:55 -0700 Subject: [PATCH 10/32] Automatic changelog generation for PR #53477 [ci skip] --- html/changelogs/AutoChangeLog-pr-53477.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-53477.yml diff --git a/html/changelogs/AutoChangeLog-pr-53477.yml b/html/changelogs/AutoChangeLog-pr-53477.yml new file mode 100644 index 00000000000..1f2e262c039 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-53477.yml @@ -0,0 +1,4 @@ +author: "Maurukas" +delete-after: True +changes: + - bugfix: "Cryo cells work again and are no longer permanent icy prisons" From 5779b5845db958d61b1b80de4151a8c343a256cd Mon Sep 17 00:00:00 2001 From: Changelogs Date: Mon, 7 Sep 2020 00:03:53 +0000 Subject: [PATCH 11/32] Automatic changelog compile [ci skip] --- html/changelog.html | 100 +++++---------------- html/changelogs/.all_changelog.yml | 22 +++++ html/changelogs/AutoChangeLog-pr-53157.yml | 8 -- html/changelogs/AutoChangeLog-pr-53375.yml | 5 -- html/changelogs/AutoChangeLog-pr-53450.yml | 4 - html/changelogs/AutoChangeLog-pr-53477.yml | 4 - 6 files changed, 45 insertions(+), 98 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-53157.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-53375.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-53450.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-53477.yml diff --git a/html/changelog.html b/html/changelog.html index d0a0bf48bfc..9e7e4db93a9 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -51,6 +51,29 @@ -->
+

07 September 2020

+

CRITAWAKETS updated:

+
    +
  • Nanotrasen has updated the cooling setup of telecommunications rooms in Delta-Pattern Stations. It now makes the simulation faster.
  • +
+

Dennok updated:

+
    +
  • passive gate max out limit pressure settings increased
  • +
  • passive gate description more precise
  • +
+

Maurukas updated:

+
    +
  • Cryo cells work again and are no longer permanent icy prisons
  • +
+

Timberpoes updated:

+
    +
  • Reduced Diagnostics nanite program has been removed.
  • +
  • Nanite Debugging nanite program has been added. This program causes your nanites to display their program list when scanned, but comes with a 0.1/s nanite cost.
  • +
  • Reduced Diagnostics nanite program functionality is now default behaviour. The nanite program list is hidden from nanite scanners by default. You now now to include the Nanite Debugging program to show the program list on scan.
  • +
  • Researching Harmonic Nanite Programming now confers a passive boost of 0.1 regen rate to all nanite clouds. This boost takes effects as soon as the node is researched.
  • +
  • Harmonic Nanite Programming research node now requires 3000 General and 3000 Nanite research, an increase of 1000 each.
  • +
+

06 September 2020

Bumtickley00 updated:

    @@ -2819,83 +2842,6 @@
    • The thermal vision modules found on certain Syndicate cyborgs is functional once more.
    - -

    06 July 2020

    -

    ATHATH updated:

    -
      -
    • The default chem capacity of most grown plants is now 100u.
    • -
    -

    Anturk + Arm + other summer ball contributors code, trollbreeder + fikou + jerryderpington mapping updated:

    -
      -
    • Mafia minigame added for ghosts
    • -
    -

    ArcaneMusic updated:

    -
      -
    • Vend-A-Trays are now operated through a UI.
    • -
    -

    Arkatos updated:

    -
      -
    • Jukebox now uses tgui.
    • -
    • You can now set a volume of a jukebox songs.
    • -
    -

    Disco updated:

    -
      -
    • [Icebox] SM exterior cooling pipes have had unnecessary thermal shielding removed
    • -
    -

    EdgeLordExe updated:

    -
      -
    • Added Extreme Medcine Allergy, a new quirk that gives you 2 points!
    • -
    • CHEMS METABOLIZE AGAIN
    • -
    -

    Inept, KathyRyals updated:

    -
      -
    • A few minor map fixes, hot from the oven.
    • -
    -

    Jay Smith & Michael Trauf updated:

    -
      -
    • Portable Chemical Mixer (Requires a vortex anomaly core to activate)
    • -
    • Unique sprites for the Portable Chemical Mixer
    • -
    • Added Portable Chemical Mixer to the Medical Techfab
    • -
    -

    LemonInTheDark updated:

    -
      -
    • Contaminated objects will now glow bright green until cleaned, remember to quarantine rouge free golems.
    • -
    • Buffed rad goggles in general, the text lasts longer, is brighter, and will show more then twice as far away
    • -
    • Fixed the text from radiation goggles not showing above mobs
    • -
    • The APC control console is now tgui rather then html. It should be a lot more usable. I've made other changes, you won't notice.
    • -
    -

    Melbert updated:

    -
      -
    • Brain Tumor damage is now paused when in stasis.
    • -
    • Brain Tumor damage is now paused when having Mannitol metabolizing in you.
    • -
    • Brain Tumor quirk users will now spawn with a pill bottle containing 4 x 5u Mannitol pills.
    • -
    -

    MrDoomBringer / Ryll-Ryll updated:

    -
      -
    • Admins can now add shrapnel clouds of any projectile they desire to supplypods launched with the Config/Launch Supplypod menu!
    • -
    -

    Ryll/Shaps updated:

    -
      -
    • Bubblegum and Legion can no longer cause wounds, as intended
    • -
    -

    ShizCalev updated:

    -
      -
    • Fixed a few awkward messages related to igniting items.
    • -
    • Info messages are now slightly brighter than notification messages when using dark mode.
    • -
    -

    Skoglol updated:

    -
      -
    • BoxStation has been removed in favor of IceBox.
    • -
    -

    Timberpoes & Kathy Ryals updated:

    -
      -
    • The Bluespace Locator now uses TGUI.
    • -
    -

    Wayland-Smithy updated:

    -
      -
    • New alien larva spawn tips!
    • -
    • Alien Queens are now easier to distinguish over hivemind communication similar to a Blob Overmind.
    • -
GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 61ba650bf81..dfad367dc25 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -42719,3 +42719,25 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. tralezab: - bugfix: You can no longer earn achievements in debug mafia games. - refactor: And the achievement code is much nicer :) +2020-09-07: + CRITAWAKETS: + - tweak: Nanotrasen has updated the cooling setup of telecommunications rooms in + Delta-Pattern Stations. It now makes the simulation faster. + Dennok: + - tweak: passive gate max out limit pressure settings increased + - tweak: passive gate description more precise + Maurukas: + - bugfix: Cryo cells work again and are no longer permanent icy prisons + Timberpoes: + - rscdel: Reduced Diagnostics nanite program has been removed. + - rscadd: Nanite Debugging nanite program has been added. This program causes your + nanites to display their program list when scanned, but comes with a 0.1/s nanite + cost. + - tweak: Reduced Diagnostics nanite program functionality is now default behaviour. + The nanite program list is hidden from nanite scanners by default. You now now + to include the Nanite Debugging program to show the program list on scan. + - tweak: Researching Harmonic Nanite Programming now confers a passive boost of + 0.1 regen rate to all nanite clouds. This boost takes effects as soon as the + node is researched. + - tweak: Harmonic Nanite Programming research node now requires 3000 General and + 3000 Nanite research, an increase of 1000 each. diff --git a/html/changelogs/AutoChangeLog-pr-53157.yml b/html/changelogs/AutoChangeLog-pr-53157.yml deleted file mode 100644 index 14aff58ee3f..00000000000 --- a/html/changelogs/AutoChangeLog-pr-53157.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: "Timberpoes" -delete-after: True -changes: - - rscdel: "Reduced Diagnostics nanite program has been removed." - - rscadd: "Nanite Debugging nanite program has been added. This program causes your nanites to display their program list when scanned, but comes with a 0.1/s nanite cost." - - tweak: "Reduced Diagnostics nanite program functionality is now default behaviour. The nanite program list is hidden from nanite scanners by default. You now now to include the Nanite Debugging program to show the program list on scan." - - tweak: "Researching Harmonic Nanite Programming now confers a passive boost of 0.1 regen rate to all nanite clouds. This boost takes effects as soon as the node is researched." - - tweak: "Harmonic Nanite Programming research node now requires 3000 General and 3000 Nanite research, an increase of 1000 each." diff --git a/html/changelogs/AutoChangeLog-pr-53375.yml b/html/changelogs/AutoChangeLog-pr-53375.yml deleted file mode 100644 index dd874f6bce9..00000000000 --- a/html/changelogs/AutoChangeLog-pr-53375.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Dennok" -delete-after: True -changes: - - tweak: "passive gate max out limit pressure settings increased" - - tweak: "passive gate description more precise" diff --git a/html/changelogs/AutoChangeLog-pr-53450.yml b/html/changelogs/AutoChangeLog-pr-53450.yml deleted file mode 100644 index 66dd92e0682..00000000000 --- a/html/changelogs/AutoChangeLog-pr-53450.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "CRITAWAKETS" -delete-after: True -changes: - - tweak: "Nanotrasen has updated the cooling setup of telecommunications rooms in Delta-Pattern Stations. It now makes the simulation faster." diff --git a/html/changelogs/AutoChangeLog-pr-53477.yml b/html/changelogs/AutoChangeLog-pr-53477.yml deleted file mode 100644 index 1f2e262c039..00000000000 --- a/html/changelogs/AutoChangeLog-pr-53477.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Maurukas" -delete-after: True -changes: - - bugfix: "Cryo cells work again and are no longer permanent icy prisons" From 998956ec632f2316cba475e208107259353c7f34 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Sun, 6 Sep 2020 18:26:12 -0700 Subject: [PATCH 12/32] fix discord verification instructions (#53467) these quotes kept getting selected because ie is a microsoft product and microsoft fucking hates their users so they do that thing where selection snaps to word boundaries --- code/modules/discord/accountlink.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/discord/accountlink.dm b/code/modules/discord/accountlink.dm index d19e6959c59..0ea776a0111 100644 --- a/code/modules/discord/accountlink.dm +++ b/code/modules/discord/accountlink.dm @@ -22,7 +22,7 @@ // Will generate one if an expired one doesn't exist already, otherwise will grab existing token var/one_time_token = SSdiscord.get_or_generate_one_time_token_for_ckey(ckey) SSdiscord.reverify_cache[usr.ckey] = one_time_token - message = "Your one time token is: [one_time_token], Assuming you have the required living minutes in game, you can now verify yourself in discord by using the command \".verify [one_time_token]\"" + message = "Your one time token is: [one_time_token], Assuming you have the required living minutes in game, you can now verify yourself in discord by using the command \" .verify [one_time_token] \"" //Now give them a browse window so they can't miss whatever we told them var/datum/browser/window = new/datum/browser(usr, "discordverification", "Discord verification") From 139e7465b0009fe31fdfa8e73e9eb68fa6f2d6fd Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Sun, 6 Sep 2020 20:02:03 -0700 Subject: [PATCH 13/32] Automatic changelog generation for PR #53397 [ci skip] --- html/changelogs/AutoChangeLog-pr-53397.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-53397.yml diff --git a/html/changelogs/AutoChangeLog-pr-53397.yml b/html/changelogs/AutoChangeLog-pr-53397.yml new file mode 100644 index 00000000000..a5fc8db2490 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-53397.yml @@ -0,0 +1,4 @@ +author: "Dennok" +delete-after: True +changes: + - tweak: "pipes should be displayed in a fixed order" From f2e4cdc2c1d9e9cc52eb80a88955828e4ff1a8f6 Mon Sep 17 00:00:00 2001 From: TemporalOroboros Date: Sun, 6 Sep 2020 21:53:04 -0700 Subject: [PATCH 14/32] Fix chemical exposure (#53491) --- code/game/atoms.dm | 3 ++- code/game/objects/objs.dm | 3 ++- code/game/turfs/turf.dm | 3 ++- .../antagonists/blob/blobstrains/_reagent.dm | 10 +++++++--- .../antagonists/blob/blobstrains/blazing_oil.dm | 3 ++- .../blob/blobstrains/cryogenic_poison.dm | 3 ++- .../blob/blobstrains/distributed_neurons.dm | 3 ++- .../blob/blobstrains/electromagnetic_web.dm | 3 ++- .../blob/blobstrains/energized_jelly.dm | 3 ++- .../blob/blobstrains/explosive_lattice.dm | 3 ++- .../blob/blobstrains/networked_fibers.dm | 3 ++- .../blob/blobstrains/pressurized_slime.dm | 3 ++- .../blob/blobstrains/reactive_spines.dm | 8 ++++++-- .../blob/blobstrains/regenerative_materia.dm | 3 ++- .../blob/blobstrains/replicating_foam.dm | 3 ++- .../blob/blobstrains/shifting_fragments.dm | 3 ++- .../blob/blobstrains/synchronous_mesh.dm | 3 ++- code/modules/mob/living/living_defense.dm | 3 ++- code/modules/reagents/chemistry/reagents.dm | 15 ++++++--------- .../chemistry/reagents/cat2_medicine_reagents.dm | 5 ++--- .../reagents/chemistry/reagents/food_reagents.dm | 1 - .../reagents/chemistry/reagents/other_reagents.dm | 8 ++++---- .../reagents/chemistry/reagents/toxin_reagents.dm | 2 +- 23 files changed, 58 insertions(+), 39 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index f31bd028cb5..8f20d39d07a 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -492,7 +492,8 @@ * - show_message: Whether to display anything to mobs when they are exposed. */ /atom/proc/expose_reagents(list/reagents, datum/reagents/source, methods=TOUCH, volume_modifier=1, show_message=TRUE) - if((. = SEND_SIGNAL(src, COMSIG_ATOM_EXPOSE_REAGENTS, reagents, source, methods, volume_modifier, show_message)) & COMPONENT_NO_EXPOSE_REAGENTS) + . = SEND_SIGNAL(src, COMSIG_ATOM_EXPOSE_REAGENTS, reagents, source, methods, volume_modifier, show_message) + if(. & COMPONENT_NO_EXPOSE_REAGENTS) return for(var/reagent in reagents) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 2b26cf1bb41..7bd84c0fc8c 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -358,7 +358,8 @@ /// Handles exposing an object to reagents. /obj/expose_reagents(list/reagents, datum/reagents/source, methods=TOUCH, volume_modifier=1, show_message=TRUE) - if((. = ..()) & COMPONENT_NO_EXPOSE_REAGENTS) + . = ..() + if(. & COMPONENT_NO_EXPOSE_REAGENTS) return for(var/reagent in reagents) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index ad5b05bd1ec..07748bbdabe 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -583,7 +583,8 @@ GLOBAL_LIST_EMPTY(station_turfs) /// Handles exposing a turf to reagents. /turf/expose_reagents(list/reagents, datum/reagents/source, methods=TOUCH, volume_modifier=1, show_message=TRUE) - if((. = ..()) & COMPONENT_NO_EXPOSE_REAGENTS) + . = ..() + if(. & COMPONENT_NO_EXPOSE_REAGENTS) return for(var/reagent in reagents) diff --git a/code/modules/antagonists/blob/blobstrains/_reagent.dm b/code/modules/antagonists/blob/blobstrains/_reagent.dm index 5b7522c8d31..8e253932890 100644 --- a/code/modules/antagonists/blob/blobstrains/_reagent.dm +++ b/code/modules/antagonists/blob/blobstrains/_reagent.dm @@ -27,9 +27,13 @@ can_synth = FALSE penetrates_skin = NONE - -/datum/reagent/blob/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - ..() +/// Used by blob reagents to calculate the reaction volume they should use when exposing mobs. +/datum/reagent/blob/proc/return_mob_expose_reac_volume(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) if(exposed_mob.stat == DEAD || istype(exposed_mob, /mob/living/simple_animal/hostile/blob)) return 0 //the dead, and blob mobs, don't cause reactions return round(reac_volume * min(1.5 - touch_protection, 1), 0.1) //full touch protection means 50% volume, any prot below 0.5 means 100% volume. + +/// Exists to earmark the new overmind arg used by blob reagents. +/datum/reagent/blob/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) + return ..() diff --git a/code/modules/antagonists/blob/blobstrains/blazing_oil.dm b/code/modules/antagonists/blob/blobstrains/blazing_oil.dm index 2383dccf87f..e9d8b6aef2a 100644 --- a/code/modules/antagonists/blob/blobstrains/blazing_oil.dm +++ b/code/modules/antagonists/blob/blobstrains/blazing_oil.dm @@ -32,7 +32,8 @@ color = "#B68D00" /datum/reagent/blob/blazing_oil/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - reac_volume = ..() + . = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) exposed_mob.adjust_fire_stacks(round(reac_volume/10)) exposed_mob.IgniteMob() if(exposed_mob) diff --git a/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm b/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm index 8dea4c1ab5b..78b6c804cac 100644 --- a/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm +++ b/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm @@ -17,7 +17,8 @@ taste_description = "brain freeze" /datum/reagent/blob/cryogenic_poison/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - reac_volume = ..() + . = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) if(exposed_mob.reagents) exposed_mob.reagents.add_reagent(/datum/reagent/consumable/frostoil, 0.3*reac_volume) exposed_mob.reagents.add_reagent(/datum/reagent/consumable/ice, 0.3*reac_volume) diff --git a/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm b/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm index 59b14d611b7..dd029f65365 100644 --- a/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm +++ b/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm @@ -25,7 +25,8 @@ color = "#E88D5D" /datum/reagent/blob/distributed_neurons/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - reac_volume = ..() + . = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) exposed_mob.apply_damage(0.6*reac_volume, TOX) if(overmind && ishuman(exposed_mob)) if(exposed_mob.stat == UNCONSCIOUS || exposed_mob.stat == HARD_CRIT) diff --git a/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm b/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm index f92f71c5388..427e0f839a3 100644 --- a/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm +++ b/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm @@ -30,7 +30,8 @@ color = "#83ECEC" /datum/reagent/blob/electromagnetic_web/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - reac_volume = ..() + . = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) if(prob(reac_volume*2)) exposed_mob.emp_act(EMP_LIGHT) if(exposed_mob) diff --git a/code/modules/antagonists/blob/blobstrains/energized_jelly.dm b/code/modules/antagonists/blob/blobstrains/energized_jelly.dm index 305d22d540f..6b225400df0 100644 --- a/code/modules/antagonists/blob/blobstrains/energized_jelly.dm +++ b/code/modules/antagonists/blob/blobstrains/energized_jelly.dm @@ -27,7 +27,8 @@ color = "#EFD65A" /datum/reagent/blob/energized_jelly/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - reac_volume = ..() + . = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) exposed_mob.losebreath += round(0.2*reac_volume) exposed_mob.adjustStaminaLoss(reac_volume * 1.2) if(exposed_mob) diff --git a/code/modules/antagonists/blob/blobstrains/explosive_lattice.dm b/code/modules/antagonists/blob/blobstrains/explosive_lattice.dm index c49a103f6d6..98847f37501 100644 --- a/code/modules/antagonists/blob/blobstrains/explosive_lattice.dm +++ b/code/modules/antagonists/blob/blobstrains/explosive_lattice.dm @@ -32,8 +32,9 @@ color = "#8B2500" /datum/reagent/blob/explosive_lattice/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) + . = ..() var/initial_volume = reac_volume - reac_volume = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) if(reac_volume >= 10) //if it's not a spore cloud, bad time incoming var/obj/effect/temp_visual/explosion/fast/ex_effect = new /obj/effect/temp_visual/explosion/fast(get_turf(exposed_mob)) ex_effect.alpha = 150 diff --git a/code/modules/antagonists/blob/blobstrains/networked_fibers.dm b/code/modules/antagonists/blob/blobstrains/networked_fibers.dm index f559e722f40..6c6a244d654 100644 --- a/code/modules/antagonists/blob/blobstrains/networked_fibers.dm +++ b/code/modules/antagonists/blob/blobstrains/networked_fibers.dm @@ -37,7 +37,8 @@ color = "#4F4441" /datum/reagent/blob/networked_fibers/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - reac_volume = ..() + . = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) exposed_mob.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND) if(!QDELETED(exposed_mob)) exposed_mob.apply_damage(0.6*reac_volume, BURN, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm b/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm index a8fd6c45b6b..76f4f811509 100644 --- a/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm +++ b/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm @@ -40,7 +40,8 @@ color = "#AAAABB" /datum/reagent/blob/pressurized_slime/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - reac_volume = ..() + . = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) var/turf/open/location_turf = get_turf(exposed_mob) if(istype(location_turf) && prob(reac_volume)) location_turf.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS) diff --git a/code/modules/antagonists/blob/blobstrains/reactive_spines.dm b/code/modules/antagonists/blob/blobstrains/reactive_spines.dm index 24d344e328b..4ca4d513844 100644 --- a/code/modules/antagonists/blob/blobstrains/reactive_spines.dm +++ b/code/modules/antagonists/blob/blobstrains/reactive_spines.dm @@ -24,8 +24,12 @@ taste_description = "rock" color = "#9ACD32" -/datum/reagent/blob/reactive_spines/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - ..() +/datum/reagent/blob/reactive_spines/return_mob_expose_reac_volume(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) if(exposed_mob.stat == DEAD || istype(exposed_mob, /mob/living/simple_animal/hostile/blob)) return 0 //the dead, and blob mobs, don't cause reactions + return reac_volume + +/datum/reagent/blob/reactive_spines/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) + . = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) exposed_mob.adjustBruteLoss(reac_volume) diff --git a/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm b/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm index 0df84417c6d..6b7aa557ef3 100644 --- a/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm +++ b/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm @@ -16,7 +16,8 @@ color = "#A88FB7" /datum/reagent/blob/regenerative_materia/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - reac_volume = ..() + . = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) exposed_mob.adjust_drugginess(reac_volume) if(exposed_mob.reagents) exposed_mob.reagents.add_reagent(/datum/reagent/blob/regenerative_materia, 0.2*reac_volume) diff --git a/code/modules/antagonists/blob/blobstrains/replicating_foam.dm b/code/modules/antagonists/blob/blobstrains/replicating_foam.dm index 236d7dea737..16670ce1158 100644 --- a/code/modules/antagonists/blob/blobstrains/replicating_foam.dm +++ b/code/modules/antagonists/blob/blobstrains/replicating_foam.dm @@ -31,5 +31,6 @@ color = "#7B5A57" /datum/reagent/blob/replicating_foam/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - reac_volume = ..() + . = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) exposed_mob.apply_damage(0.7*reac_volume, BRUTE, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blobstrains/shifting_fragments.dm b/code/modules/antagonists/blob/blobstrains/shifting_fragments.dm index 95be6543526..1a7b92c99de 100644 --- a/code/modules/antagonists/blob/blobstrains/shifting_fragments.dm +++ b/code/modules/antagonists/blob/blobstrains/shifting_fragments.dm @@ -32,5 +32,6 @@ color = "#C8963C" /datum/reagent/blob/shifting_fragments/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - reac_volume = ..() + . = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) exposed_mob.apply_damage(0.7*reac_volume, BRUTE, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/blobstrains/synchronous_mesh.dm b/code/modules/antagonists/blob/blobstrains/synchronous_mesh.dm index c39728ad1dc..1c57edea1c3 100644 --- a/code/modules/antagonists/blob/blobstrains/synchronous_mesh.dm +++ b/code/modules/antagonists/blob/blobstrains/synchronous_mesh.dm @@ -30,7 +30,8 @@ color = "#65ADA2" /datum/reagent/blob/synchronous_mesh/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - reac_volume = ..() + . = ..() + reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind) exposed_mob.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND) if(exposed_mob && reac_volume) for(var/obj/structure/blob/nearby_blob in range(1, exposed_mob)) //if the target is completely surrounded, this is 2.4*reac_volume bonus damage, total of 2.6*reac_volume diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index d5df01524bf..41bc32c042c 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -411,7 +411,8 @@ * If the methods include VAPOR it incorporates permiability protection. */ /mob/living/expose_reagents(list/reagents, datum/reagents/source, methods=TOUCH, volume_modifier=1, show_message=TRUE) - if((. = ..()) & COMPONENT_NO_EXPOSE_REAGENTS) + . = ..() + if(. & COMPONENT_NO_EXPOSE_REAGENTS) return if(methods & INGEST) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 0003b3cc12d..6b207982353 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -95,34 +95,31 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) /datum/reagent/proc/expose_atom(atom/exposed_atom, reac_volume) SHOULD_CALL_PARENT(TRUE) - SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_ATOM, exposed_atom, reac_volume) - SEND_SIGNAL(exposed_atom, COMSIG_ATOM_EXPOSE_REAGENT, src, reac_volume) - return TRUE + . = 0 + . |= SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_ATOM, exposed_atom, reac_volume) + . |= SEND_SIGNAL(exposed_atom, COMSIG_ATOM_EXPOSE_REAGENT, src, reac_volume) /// Applies this reagent to a [/mob/living] /datum/reagent/proc/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE, touch_protection = 0) SHOULD_CALL_PARENT(TRUE) - SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_MOB, exposed_mob, methods, reac_volume, show_message, touch_protection) + . = SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_MOB, exposed_mob, methods, reac_volume, show_message, touch_protection) if((methods & penetrates_skin) && exposed_mob.reagents) //smoke, foam, spray var/amount = round(reac_volume*clamp((1 - touch_protection), 0, 1), 0.1) if(amount >= 0.5) exposed_mob.reagents.add_reagent(type, amount) - return TRUE /// Applies this reagent to an [/obj] /datum/reagent/proc/expose_obj(obj/exposed_obj, reac_volume) SHOULD_CALL_PARENT(TRUE) - SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_OBJ, exposed_obj, reac_volume) - return TRUE + return SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_OBJ, exposed_obj, reac_volume) /// Applies this reagent to a [/turf] /datum/reagent/proc/expose_turf(turf/exposed_turf, reac_volume) SHOULD_CALL_PARENT(TRUE) - SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_TURF, exposed_turf, reac_volume) - return TRUE + return SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_TURF, exposed_turf, reac_volume) /// Called from [/datum/reagents/proc/metabolize] /datum/reagent/proc/on_mob_life(mob/living/carbon/M) diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm index d574e489eb2..d6344f0387f 100644 --- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm @@ -414,12 +414,12 @@ /datum/reagent/medicine/c2/synthflesh/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE) . = ..() if(!iscarbon(exposed_mob)) - return TRUE + return var/mob/living/carbon/carbies = exposed_mob if(carbies.stat == DEAD) show_message = 0 if(!(methods & (PATCH|TOUCH|VAPOR))) - return TRUE + return var/harmies = min(carbies.getBruteLoss(),carbies.adjustBruteLoss(-1.25 * reac_volume)*-1) var/burnies = min(carbies.getFireLoss(),carbies.adjustFireLoss(-1.25 * reac_volume)*-1) for(var/i in carbies.all_wounds) @@ -432,7 +432,6 @@ if(HAS_TRAIT_FROM(exposed_mob, TRAIT_HUSK, "burn") && carbies.getFireLoss() < THRESHOLD_UNHUSK && (carbies.reagents.get_reagent_amount(/datum/reagent/medicine/c2/synthflesh) + reac_volume >= 100)) carbies.cure_husk("burn") carbies.visible_message("A rubbery liquid coats [carbies]'s burns. [carbies] looks a lot healthier!") //we're avoiding using the phrases "burnt flesh" and "burnt skin" here because carbies could be a skeleton or a golem or something - return TRUE /******ORGAN HEALING******/ /*Suffix: -rite*/ diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index cc580905886..bb1c0ce5eb2 100755 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -158,7 +158,6 @@ addtimer(CALLBACK(exposed_mob, /mob/living/proc/unfry_mob), 3) if(FryLoss) exposed_mob.adjustFireLoss(FryLoss) - return TRUE /datum/reagent/consumable/cooking_oil/expose_turf(turf/open/exposed_turf, reac_volume) . = ..() diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 3e3ca95c10f..aedde1ad3ac 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -726,7 +726,7 @@ /datum/reagent/oxygen/expose_obj(obj/exposed_obj, reac_volume) . = ..() if((!exposed_obj) || (!reac_volume)) - return 0 + return var/temp = holder ? holder.chem_temp : T20C exposed_obj.atmos_spawn_air("o2=[reac_volume/2];TEMP=[temp]") @@ -763,7 +763,7 @@ /datum/reagent/nitrogen/expose_obj(obj/exposed_obj, reac_volume) . = ..() if((!exposed_obj) || (!reac_volume)) - return 0 + return var/temp = holder ? holder.chem_temp : T20C exposed_obj.atmos_spawn_air("n2=[reac_volume/2];TEMP=[temp]") @@ -1271,7 +1271,7 @@ /datum/reagent/carbondioxide/expose_obj(obj/exposed_obj, reac_volume) . = ..() if((!exposed_obj) || (!reac_volume)) - return 0 + return var/temp = holder ? holder.chem_temp : T20C exposed_obj.atmos_spawn_air("co2=[reac_volume/5];TEMP=[temp]") @@ -1292,7 +1292,7 @@ /datum/reagent/nitrous_oxide/expose_obj(obj/exposed_obj, reac_volume) . = ..() if((!exposed_obj) || (!reac_volume)) - return 0 + return var/temp = holder ? holder.chem_temp : T20C exposed_obj.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[temp]") diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index a9eb707b338..0589e2f9291 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -90,7 +90,7 @@ /datum/reagent/toxin/plasma/expose_obj(obj/exposed_obj, reac_volume) . = ..() if((!exposed_obj) || (!reac_volume)) - return 0 + return var/temp = holder ? holder.chem_temp : T20C if(temp >= LIQUID_PLASMA_BP) exposed_obj.atmos_spawn_air("plasma=[reac_volume];TEMP=[temp]") From 2f7c2b65a1530b126983a972cd4738d0d4e3b126 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Sun, 6 Sep 2020 21:53:09 -0700 Subject: [PATCH 15/32] Automatic changelog generation for PR #53491 [ci skip] --- html/changelogs/AutoChangeLog-pr-53491.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-53491.yml diff --git a/html/changelogs/AutoChangeLog-pr-53491.yml b/html/changelogs/AutoChangeLog-pr-53491.yml new file mode 100644 index 00000000000..c8220311da1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-53491.yml @@ -0,0 +1,4 @@ +author: "TemporalOroboros" +delete-after: True +changes: + - bugfix: "Chemicals now properly acknowledge exposure. Water is wet again, synthflesh will now apply properly, space lube will now properly make floors slippery again, etc." From c6be808bf3294e08c383a5cd881b7c8ad6575c5b Mon Sep 17 00:00:00 2001 From: Qustinnus Date: Mon, 7 Sep 2020 20:04:14 +0200 Subject: [PATCH 16/32] Moves over cakes to newfood and transfers reagents when crafting (#53316) --- .../LavaRuins/lavaland_surface_pizzaparty.dmm | 2 +- _maps/shuttles/emergency_cruise.dmm | 2 +- .../emergency_imfedupwiththisworld.dmm | 4 +- _maps/shuttles/emergency_luxury.dmm | 2 +- _maps/shuttles/emergency_pubby.dmm | 14 +- code/__DEFINES/dcs/signals.dm | 6 + code/__DEFINES/food.dm | 4 + code/__HELPERS/string_assoc_lists.dm | 18 + code/__HELPERS/string_lists.dm | 14 + code/__HELPERS/unsorted.dm | 4 +- code/datums/components/food/edible.dm | 122 ++++- .../datums/components/storage/food_storage.dm | 2 +- code/game/atoms.dm | 6 +- code/game/objects/items/food/_food.dm | 15 +- code/game/objects/items/food/bread.dm | 49 +- code/game/objects/items/food/burgers.dm | 58 +-- code/game/objects/items/food/cake.dm | 453 +++++++++++++++++ code/modules/cargo/bounties/chef.dm | 2 +- code/modules/clothing/outfits/ert.dm | 2 +- .../food_and_drinks/food/customizables.dm | 13 +- code/modules/food_and_drinks/food/snacks.dm | 2 +- .../food_and_drinks/food/snacks/dough.dm | 2 +- .../food_and_drinks/food/snacks_cake.dm | 455 ------------------ .../recipes/tablecraft/recipes_cake.dm | 84 ++-- code/modules/holiday/easter.dm | 19 +- code/modules/mapping/mapping_helpers.dm | 2 +- .../mob/living/simple_animal/friendly/cat.dm | 2 +- .../xenobiology/crossbreeding/charged.dm | 2 +- tgstation.dme | 4 +- 29 files changed, 745 insertions(+), 619 deletions(-) create mode 100644 code/__HELPERS/string_assoc_lists.dm create mode 100644 code/__HELPERS/string_lists.dm create mode 100644 code/game/objects/items/food/cake.dm delete mode 100644 code/modules/food_and_drinks/food/snacks_cake.dm diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm index 1c08add6097..49e205fbb14 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm @@ -207,7 +207,7 @@ /area/ruin/unpowered) "F" = ( /obj/structure/table/wood, -/obj/item/reagent_containers/food/snacks/store/cake/birthday, +/obj/item/food/cake/birthday, /turf/open/floor/wood{ initial_gas_mix = "LAVALAND_ATMOS" }, diff --git a/_maps/shuttles/emergency_cruise.dmm b/_maps/shuttles/emergency_cruise.dmm index 16596547877..af81ca87d29 100644 --- a/_maps/shuttles/emergency_cruise.dmm +++ b/_maps/shuttles/emergency_cruise.dmm @@ -810,7 +810,7 @@ /area/shuttle/escape) "Aq" = ( /obj/structure/table/wood/fancy, -/obj/item/reagent_containers/food/snacks/cakeslice/chocolate{ +/obj/item/food/cakeslice/chocolate{ pixel_x = 16; pixel_y = -8 }, diff --git a/_maps/shuttles/emergency_imfedupwiththisworld.dmm b/_maps/shuttles/emergency_imfedupwiththisworld.dmm index 27f3f1b198c..8f9369c8341 100644 --- a/_maps/shuttles/emergency_imfedupwiththisworld.dmm +++ b/_maps/shuttles/emergency_imfedupwiththisworld.dmm @@ -78,7 +78,7 @@ /area/shuttle/escape) "o" = ( /obj/structure/table/reinforced, -/obj/item/reagent_containers/food/snacks/store/cake/birthday, +/obj/item/food/cake/birthday, /turf/open/floor/carpet, /area/shuttle/escape) "p" = ( @@ -143,7 +143,7 @@ /obj/machinery/light/small{ dir = 8 }, -/obj/item/reagent_containers/food/snacks/cakeslice/birthday, +/obj/item/food/cakeslice/birthday, /turf/open/floor/carpet, /area/shuttle/escape) "x" = ( diff --git a/_maps/shuttles/emergency_luxury.dmm b/_maps/shuttles/emergency_luxury.dmm index 5cf7597bec8..2c9e2ed5936 100644 --- a/_maps/shuttles/emergency_luxury.dmm +++ b/_maps/shuttles/emergency_luxury.dmm @@ -176,7 +176,7 @@ /turf/open/floor/carpet/red, /area/shuttle/escape/luxury) "aF" = ( -/obj/item/reagent_containers/food/snacks/cakeslice/chocolate{ +/obj/item/food/cakeslice/chocolate{ pixel_y = 1 }, /obj/structure/table/wood/fancy/black, diff --git a/_maps/shuttles/emergency_pubby.dmm b/_maps/shuttles/emergency_pubby.dmm index 1cc371124df..7515ea76a55 100644 --- a/_maps/shuttles/emergency_pubby.dmm +++ b/_maps/shuttles/emergency_pubby.dmm @@ -244,13 +244,13 @@ dir = 1 }, /obj/item/food/butterdog, -/obj/item/reagent_containers/food/snacks/cakeslice/apple, -/obj/item/reagent_containers/food/snacks/cakeslice/brioche, -/obj/item/reagent_containers/food/snacks/cakeslice/cheese, -/obj/item/reagent_containers/food/snacks/cakeslice/chocolate, -/obj/item/reagent_containers/food/snacks/cakeslice/lemon, -/obj/item/reagent_containers/food/snacks/cakeslice/lime, -/obj/item/reagent_containers/food/snacks/cakeslice/orange, +/obj/item/food/cakeslice/apple, +/obj/item/food/cakeslice/brioche, +/obj/item/food/cakeslice/cheese, +/obj/item/food/cakeslice/chocolate, +/obj/item/food/cakeslice/lemon, +/obj/item/food/cakeslice/lime, +/obj/item/food/cakeslice/orange, /turf/open/floor/plasteel/cafeteria, /area/shuttle/escape) "aH" = ( diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index c605f5ea3d2..2e260a8b5f5 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -96,6 +96,8 @@ #define COMSIG_ATOM_FIRE_ACT "atom_fire_act" ///from base of atom/bullet_act(): (/obj/projectile, def_zone) #define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" +///from base of atom/CheckParts(): (list/parts_list, datum/crafting_recipe/R) +#define COMSIG_ATOM_CHECKPARTS "atom_checkparts" ///from base of atom/blob_act(): (/obj/structure/blob) #define COMSIG_ATOM_BLOB_ACT "atom_blob_act" ///from base of atom/acid_act(): (acidpwr, acid_volume) @@ -136,6 +138,8 @@ ///for any tool behaviors: (mob/living/user, obj/item/I, list/recipes) #define COMSIG_ATOM_TOOL_ACT(tooltype) "tool_recipe_discovery_[tooltype]" #define COMPONENT_BLOCK_TOOL_ATTACK (1<<0) +///for when an atom has been created through processing (atom/original_atom, list/chosen_processing_option) +#define COMSIG_ATOM_CREATEDBY_PROCESSING "atom_createdby_processing" ///called when teleporting into a protected turf: (channel, turf/origin) #define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" #define COMPONENT_BLOCK_TELEPORT (1<<0) @@ -510,6 +514,8 @@ #define COMSIG_ITEM_WEARERCROSSED "wearer_crossed" ///called on item when microwaved (): (obj/machinery/microwave/M) #define COMSIG_ITEM_MICROWAVE_ACT "microwave_act" +///called on item when created through microwaving (): (obj/machinery/microwave/M, cooking_efficiency) +#define COMSIG_ITEM_MICROWAVE_COOKED "microwave_cooked" ///from base of item/sharpener/attackby(): (amount, max) #define COMSIG_ITEM_SHARPEN_ACT "sharpen_act" #define COMPONENT_BLOCK_SHARPEN_APPLIED (1<<0) diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm index 5572dec40bc..8631ceb78e1 100644 --- a/code/__DEFINES/food.dm +++ b/code/__DEFINES/food.dm @@ -38,5 +38,9 @@ #define FOOD_MEAT_MUTANT 100 #define FOOD_MEAT_MUTANT_RARE 200 +///Amount of reagents you start with on crafted food excluding the used parts +#define CRAFTED_FOOD_BASE_REAGENT_MODIFIER 0.7 +///Modifier of reagents you get when crafting food from the parts used +#define CRAFTED_FOOD_INGREDIENT_REAGENT_MODIFIER 0.5 #define IS_EDIBLE(O) (istype(O, /obj/item/reagent_containers/food/snacks) || O.GetComponent(/datum/component/edible)) diff --git a/code/__HELPERS/string_assoc_lists.dm b/code/__HELPERS/string_assoc_lists.dm new file mode 100644 index 00000000000..e269da7da5e --- /dev/null +++ b/code/__HELPERS/string_assoc_lists.dm @@ -0,0 +1,18 @@ +GLOBAL_LIST_EMPTY(string_assoc_lists) + + +/** + * Caches associative lists with non-numeric stringify-able index keys and stringify-able values (text/typepath -> text/path/number). + */ +/datum/proc/string_assoc_list(list/values) + var/list/string_id = list() + for(var/val in values) + string_id += "[val]_[values[val]]" + string_id.Join("-") + + . = GLOB.string_assoc_lists[string_id] + + if(.) + return + + return GLOB.string_assoc_lists[string_id] = values diff --git a/code/__HELPERS/string_lists.dm b/code/__HELPERS/string_lists.dm new file mode 100644 index 00000000000..069f9b6dc41 --- /dev/null +++ b/code/__HELPERS/string_lists.dm @@ -0,0 +1,14 @@ +GLOBAL_LIST_EMPTY(string_lists) + +/** + * Caches lists with non-numeric stringify-able values (text or typepath). + */ +/datum/proc/string_list(list/values) + var/string_id = values.Join("-") + + . = GLOB.string_lists[string_id] + + if(.) + return + + return GLOB.string_lists[string_id] = values diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 9b1f6ec3c8c..08ca90cfac9 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1381,8 +1381,8 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) /proc/get_random_food() var/list/blocked = list(/obj/item/food/bread, /obj/item/food/breadslice, - /obj/item/reagent_containers/food/snacks/store/cake, - /obj/item/reagent_containers/food/snacks/cakeslice, + /obj/item/food/cake, + /obj/item/food/cakeslice, /obj/item/reagent_containers/food/snacks/store, /obj/item/reagent_containers/food/snacks/pie, /obj/item/reagent_containers/food/snacks/kebab, diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index 460591b1192..807ae7fe923 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -35,6 +35,14 @@ Behavior that's still missing from this component that original food items had t var/datum/callback/on_consume ///Last time we checked for food likes var/last_check_time + ///The initial reagents of this food when it is made + var/list/initial_reagents + ///The initial volume of the foods reagents + var/volume + ///The flavortext for taste (haha get it flavor text) + var/list/tastes + ///The type of atom this creates when the object is microwaved. + var/microwaved_type /datum/component/edible/Initialize(list/initial_reagents, food_flags = NONE, @@ -44,6 +52,7 @@ Behavior that's still missing from this component that original food items had t list/tastes, list/eatverbs = list("bite","chew","nibble","gnaw","gobble","chomp"), bite_consumption = 2, + microwaved_type, datum/callback/after_eat, datum/callback/on_consume) @@ -52,9 +61,15 @@ Behavior that's still missing from this component that original food items had t RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine) RegisterSignal(parent, COMSIG_ATOM_ATTACK_ANIMAL, .proc/UseByAnimal) + RegisterSignal(parent, COMSIG_ATOM_CHECKPARTS, .proc/OnCraft) + RegisterSignal(parent, COMSIG_ATOM_CREATEDBY_PROCESSING, .proc/OnProcessed) + RegisterSignal(parent, COMSIG_ITEM_MICROWAVE_COOKED, .proc/OnMicrowaveCooked) + if(isitem(parent)) RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/UseFromHand) RegisterSignal(parent, COMSIG_ITEM_FRIED, .proc/OnFried) + RegisterSignal(parent, COMSIG_ITEM_MICROWAVE_ACT, .proc/OnMicrowaved) + var/obj/item/item = parent item.grind_results = list() //Cursed but this is how snacks did it, grinding needs a refactor in the future. @@ -65,22 +80,24 @@ Behavior that's still missing from this component that original food items had t src.food_flags = food_flags src.foodtypes = foodtypes src.eat_time = eat_time - src.eatverbs = eatverbs + src.eatverbs = string_list(eatverbs) src.junkiness = junkiness src.after_eat = after_eat src.on_consume = on_consume + src.initial_reagents = string_assoc_list(initial_reagents) + src.tastes = string_assoc_list(tastes) + src.microwaved_type = microwaved_type var/atom/owner = parent owner.create_reagents(volume, INJECTABLE) - if(initial_reagents) - for(var/rid in initial_reagents) - var/amount = initial_reagents[rid] - if(tastes && tastes.len && (rid == /datum/reagent/consumable/nutriment || rid == /datum/reagent/consumable/nutriment/vitamin)) - owner.reagents.add_reagent(rid, amount, tastes.Copy()) - else - owner.reagents.add_reagent(rid, amount) + for(var/rid in initial_reagents) + var/amount = initial_reagents[rid] + if(length(tastes) && (rid == /datum/reagent/consumable/nutriment || rid == /datum/reagent/consumable/nutriment/vitamin)) + owner.reagents.add_reagent(rid, amount, tastes.Copy()) + else + owner.reagents.add_reagent(rid, amount) /datum/component/edible/InheritComponent(datum/component/C, i_am_original, @@ -142,6 +159,95 @@ Behavior that's still missing from this component that original food items had t qdel(our_atom) return COMSIG_FRYING_HANDLED +///Called when food is created through processing (Usually this means it was sliced). We use this to pass the OG items reagents. +/datum/component/edible/proc/OnProcessed(datum/source, atom/original_atom, list/chosen_processing_option) + SIGNAL_HANDLER + + if(!original_atom.reagents) + return + + var/atom/this_food = parent + var/reagents_for_slice = chosen_processing_option[TOOL_PROCESSING_AMOUNT] + + this_food.create_reagents(volume) //Make sure we have a reagent container + + original_atom.reagents.trans_to(this_food, reagents_for_slice) + + if(original_atom.name != initial(original_atom.name)) + this_food.name = "slice of [original_atom.name]" + if(original_atom.desc != initial(original_atom.desc)) + this_food.desc = "[original_atom.desc]" + +///Called when food is crafted through a crafting recipe datum. +/datum/component/edible/proc/OnCraft(datum/source, list/parts_list, datum/crafting_recipe/food/recipe) + SIGNAL_HANDLER + + var/atom/this_food = parent + + this_food.reagents.clear_reagents() + + for(var/obj/item/crafted_part in this_food.contents) + crafted_part.reagents?.trans_to(this_food.reagents, crafted_part.reagents.maximum_volume, CRAFTED_FOOD_INGREDIENT_REAGENT_MODIFIER) + + var/list/objects_to_delete = list() + + // Remove all non recipe objects from the contents + for(var/content_object in this_food.contents) + for(var/recipe_object in recipe.real_parts) + if(istype(content_object, recipe_object)) + continue + objects_to_delete += content_object + + QDEL_LIST(objects_to_delete) + + for(var/r_id in initial_reagents) + var/amount = initial_reagents[r_id] * CRAFTED_FOOD_BASE_REAGENT_MODIFIER + if(r_id == /datum/reagent/consumable/nutriment || r_id == /datum/reagent/consumable/nutriment/vitamin || r_id == /datum/reagent/consumable/nutriment/protein) + this_food.reagents.add_reagent(r_id, amount, tastes) + else + this_food.reagents.add_reagent(r_id, amount) + + SSblackbox.record_feedback("tally", "food_made", 1, type) + +/datum/component/edible/proc/OnMicrowaved(datum/source, obj/machinery/microwave/used_microwave) + SIGNAL_HANDLER + + var/turf/parent_turf = get_turf(parent) + + if(!microwaved_type) + new /obj/item/reagent_containers/food/snacks/badrecipe(parent_turf) + qdel(src) + return + + + var/obj/item/result + + result = new microwaved_type(parent_turf) + + var/efficiency = istype(used_microwave) ? used_microwave.efficiency : 1 + + SEND_SIGNAL(result, COMSIG_ITEM_MICROWAVE_COOKED, parent, efficiency) + + SSblackbox.record_feedback("tally", "food_made", 1, result.type) + +///Corrects the reagents on the newly cooked food +/datum/component/edible/proc/OnMicrowaveCooked(datum/source, obj/item/source_item, cooking_efficiency = 1) + SIGNAL_HANDLER + + var/atom/this_food = parent + + this_food.reagents.clear_reagents() + + source_item.reagents?.trans_to(this_food, source_item.reagents.total_volume) + + for(var/r_id in initial_reagents) + var/amount = initial_reagents[r_id] * cooking_efficiency * CRAFTED_FOOD_BASE_REAGENT_MODIFIER + if(r_id == /datum/reagent/consumable/nutriment || r_id == /datum/reagent/consumable/nutriment/vitamin || r_id == /datum/reagent/consumable/nutriment/protein) + this_food.reagents.add_reagent(r_id, amount, tastes) + else + this_food.reagents.add_reagent(r_id, amount) + + ///All the checks for the act of eating itself and /datum/component/edible/proc/TryToEat(mob/living/eater, mob/living/feeder) diff --git a/code/datums/components/storage/food_storage.dm b/code/datums/components/storage/food_storage.dm index 63c86bdc9dd..cfabe5c3773 100644 --- a/code/datums/components/storage/food_storage.dm +++ b/code/datums/components/storage/food_storage.dm @@ -176,7 +176,7 @@ return FALSE for(var/obj/item/i in food.contents) //search the food's contents for a replacement item - if(istype(i, /obj/item/reagent_containers/food/snacks)) + if(IS_EDIBLE(i)) continue if(QDELETED(i)) continue diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 8f20d39d07a..ea3e3309f0d 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -410,7 +410,8 @@ * * Otherwise it simply forceMoves the atom into this atom */ -/atom/proc/CheckParts(list/parts_list) +/atom/proc/CheckParts(list/parts_list, datum/crafting_recipe/R) + SEND_SIGNAL(src, COMSIG_ATOM_CHECKPARTS, parts_list, R) if(parts_list) for(var/A in parts_list) if(istype(A, /datum/reagent)) @@ -1218,7 +1219,8 @@ if(I.use_tool(src, user, chosen_option[TOOL_PROCESSING_TIME], volume=50)) var/atom/atom_to_create = chosen_option[TOOL_PROCESSING_RESULT] for(var/i = 1 to chosen_option[TOOL_PROCESSING_AMOUNT]) - new atom_to_create(loc) + var/atom/created_atom = new atom_to_create(loc) + SEND_SIGNAL(created_atom, COMSIG_ATOM_CREATEDBY_PROCESSING, src, chosen_option) to_chat(user, "You manage to create [chosen_option[TOOL_PROCESSING_AMOUNT]] [initial(atom_to_create.name)] from [src]") qdel(src) return diff --git a/code/game/objects/items/food/_food.dm b/code/game/objects/items/food/_food.dm index 6851bf0123a..bb413dbf344 100644 --- a/code/game/objects/items/food/_food.dm +++ b/code/game/objects/items/food/_food.dm @@ -2,6 +2,8 @@ /obj/item/food name = "food" desc = "you eat this" + resistance_flags = FLAMMABLE + w_class = WEIGHT_CLASS_NORMAL ///List of reagents this food gets on creation var/list/food_reagents ///Extra flags for things such as if the food is in a container or not @@ -19,10 +21,16 @@ ///How much reagents per bite var/bite_consumption - /obj/item/food/Initialize() . = ..() + if(food_reagents) + food_reagents = string_assoc_list(food_reagents) + if(tastes) + tastes = string_assoc_list(tastes) + if(eatverbs) + eatverbs = string_list(eatverbs) MakeEdible() + MakeProcessable() ///This proc adds the edible component, overwrite this if you for some reason want to change some specific args like callbacks. /obj/item/food/proc/MakeEdible() @@ -37,5 +45,6 @@ bite_consumption = bite_consumption) - - +///This proc handles processable elements, overwrite this if you want to add behavior such as slicing, forking, spooning, whatever, to turn the item into something else +/obj/item/food/proc/MakeProcessable() + return diff --git a/code/game/objects/items/food/bread.dm b/code/game/objects/items/food/bread.dm index 3e8c947d5fc..da97bf0a61b 100644 --- a/code/game/objects/items/food/bread.dm +++ b/code/game/objects/items/food/bread.dm @@ -13,7 +13,6 @@ /obj/item/food/breadslice icon = 'icons/obj/food/burgerbread.dmi' - food_reagents = list(/datum/reagent/consumable/nutriment = 2) slot_flags = ITEM_SLOT_HEAD foodtypes = GRAIN eat_time = 0.5 SECONDS @@ -26,12 +25,11 @@ name = "bread" desc = "Some plain old earthen bread." icon_state = "bread" - food_reagents = list(/datum/reagent/consumable/nutriment = 17) + food_reagents = list(/datum/reagent/consumable/nutriment = 10) tastes = list("bread" = 10) foodtypes = GRAIN -/obj/item/food/bread/plain/Initialize() - . = ..() +/obj/item/food/bread/plain/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/breadslice/plain, 5, 30) /obj/item/food/breadslice/plain @@ -39,6 +37,7 @@ desc = "A slice of home." icon_state = "breadslice" foodtypes = GRAIN + food_reagents = list(/datum/reagent/consumable/nutriment = 2) /obj/item/food/breadslice/moldy name = "moldy bread slice" @@ -52,12 +51,11 @@ name = "meatbread loaf" desc = "The culinary base of every self-respecting eloquen/tg/entleman." icon_state = "meatbread" - food_reagents = list(/datum/reagent/consumable/nutriment = 25, /datum/reagent/consumable/nutriment/vitamin = 15, /datum/reagent/consumable/nutriment/protein = 17) + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10, /datum/reagent/consumable/nutriment/protein = 12) tastes = list("bread" = 10, "meat" = 10) foodtypes = GRAIN | MEAT -/obj/item/food/bread/meat/Initialize() - . = ..() +/obj/item/food/bread/meat/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/breadslice/meat, 5, 30) /obj/item/food/breadslice/meat @@ -65,36 +63,35 @@ desc = "A slice of delicious meatbread." icon_state = "meatbreadslice" foodtypes = GRAIN | MEAT + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 2, /datum/reagent/consumable/nutriment/protein = 2.4) /obj/item/food/bread/xenomeat name = "xenomeatbread loaf" desc = "The culinary base of every self-respecting eloquen/tg/entleman. Extra Heretical." icon_state = "xenomeatbread" - food_reagents = list(/datum/reagent/consumable/nutriment = 25, /datum/reagent/consumable/nutriment/vitamin = 15, /datum/reagent/consumable/nutriment/protein = 24) + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10, /datum/reagent/consumable/nutriment/protein = 15) tastes = list("bread" = 10, "acid" = 10) foodtypes = GRAIN | MEAT -/obj/item/food/bread/xenomeat/Initialize() - . = ..() +/obj/item/food/bread/xenomeat/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/breadslice/xenomeat, 5, 30) /obj/item/food/breadslice/xenomeat name = "xenomeatbread slice" desc = "A slice of delicious meatbread. Extra Heretical." icon_state = "xenobreadslice" - food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/nutriment/protein = 5) + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 2, /datum/reagent/consumable/nutriment/protein = 3) foodtypes = GRAIN | MEAT /obj/item/food/bread/spidermeat name = "spider meat loaf" desc = "Reassuringly green meatloaf made from spider meat." icon_state = "spidermeatbread" - food_reagents = list(/datum/reagent/consumable/nutriment = 25, /datum/reagent/toxin = 15, /datum/reagent/consumable/nutriment/vitamin = 15, /datum/reagent/consumable/nutriment/protein = 17) + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/toxin = 15, /datum/reagent/consumable/nutriment/vitamin = 10, /datum/reagent/consumable/nutriment/protein = 12) tastes = list("bread" = 10, "cobwebs" = 5) foodtypes = GRAIN | MEAT | TOXIC -/obj/item/food/bread/spidermeat/Initialize() - . = ..() +/obj/item/food/bread/spidermeat/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/breadslice/spidermeat, 5, 30) /obj/item/food/breadslice/spidermeat @@ -108,12 +105,11 @@ name = "banana-nut bread" desc = "A heavenly and filling treat." icon_state = "bananabread" - food_reagents = list(/datum/reagent/consumable/nutriment = 25, /datum/reagent/consumable/banana = 40) + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/banana = 20) tastes = list("bread" = 10) // bananjuice will also flavour foodtypes = GRAIN | FRUIT -/obj/item/food/bread/banana/Initialize() - . = ..() +/obj/item/food/bread/banana/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/breadslice/banana, 5, 30) /obj/item/food/breadslice/banana @@ -127,19 +123,18 @@ name = "Tofubread" desc = "Like meatbread but for vegetarians. Not guaranteed to give superpowers." icon_state = "tofubread" - food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 15, /datum/reagent/consumable/nutriment/protein = 13) + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10, /datum/reagent/consumable/nutriment/protein = 10) tastes = list("bread" = 10, "tofu" = 10) foodtypes = GRAIN | VEGETABLES -/obj/item/food/bread/tofu/Initialize() - . = ..() +/obj/item/food/bread/tofu/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/breadslice/tofu, 5, 30) /obj/item/food/breadslice/tofu name = "tofubread slice" desc = "A slice of delicious tofubread." icon_state = "tofubreadslice" - food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 2, /datum/reagent/consumable/nutriment/vitamin = 1) + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 2, /datum/reagent/consumable/nutriment/vitamin = 2) foodtypes = GRAIN | VEGETABLES /obj/item/food/bread/creamcheese @@ -150,33 +145,31 @@ tastes = list("bread" = 10, "cheese" = 10) foodtypes = GRAIN | DAIRY -/obj/item/food/bread/creamcheese/Initialize() - . = ..() +/obj/item/food/bread/creamcheese/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/breadslice/creamcheese, 5, 30) /obj/item/food/breadslice/creamcheese name = "cream cheese bread slice" desc = "A slice of yum!" icon_state = "creamcheesebreadslice" - food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 1, /datum/reagent/consumable/nutriment/vitamin = 1) + food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 2, /datum/reagent/consumable/nutriment/vitamin = 2) /obj/item/food/bread/mimana name = "mimana bread" desc = "Best eaten in silence." icon_state = "mimanabread" - food_reagents = list(/datum/reagent/consumable/nutriment = 25, /datum/reagent/toxin/mutetoxin = 5, /datum/reagent/consumable/nothing = 5, /datum/reagent/consumable/nutriment/vitamin = 10) + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/toxin/mutetoxin = 5, /datum/reagent/consumable/nothing = 5, /datum/reagent/consumable/nutriment/vitamin = 10) tastes = list("bread" = 10, "silence" = 10) foodtypes = GRAIN | FRUIT -/obj/item/food/bread/mimana/Initialize() - . = ..() +/obj/item/food/bread/mimana/MakeProcessable() AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/breadslice/mimana, 5, 30) /obj/item/food/breadslice/mimana name = "mimana bread slice" desc = "A slice of silence!" icon_state = "mimanabreadslice" - food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/toxin/mutetoxin = 1, /datum/reagent/consumable/nothing = 1, /datum/reagent/consumable/nutriment/vitamin = 1) + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/toxin/mutetoxin = 1, /datum/reagent/consumable/nothing = 1, /datum/reagent/consumable/nutriment/vitamin = 2) foodtypes = GRAIN | FRUIT /obj/item/food/breadslice/custom diff --git a/code/game/objects/items/food/burgers.dm b/code/game/objects/items/food/burgers.dm index 3a68ccd05db..bbbf160e9ab 100644 --- a/code/game/objects/items/food/burgers.dm +++ b/code/game/objects/items/food/burgers.dm @@ -56,7 +56,7 @@ /obj/item/food/burger/appendix name = "appendix burger" desc = "Tastes like appendicitis." - food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 11, /datum/reagent/consumable/nutriment/vitamin = 7) + food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 6) icon_state = "appendixburger" tastes = list("bun" = 4, "grass" = 2) foodtypes = GRAIN | MEAT | GROSS @@ -65,7 +65,7 @@ name = "fillet -o- carp sandwich" desc = "Almost like a carp is yelling somewhere... Give me back that fillet -o- carp, give me that carp." icon_state = "fishburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 7, /datum/reagent/consumable/nutriment/vitamin = 4) + food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 4) tastes = list("bun" = 4, "fish" = 4) foodtypes = GRAIN | MEAT @@ -81,7 +81,7 @@ name = "roburger" desc = "The lettuce is the only organic component. Beep." icon_state = "roburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 8, /datum/reagent/nanomachines = 7, /datum/reagent/consumable/nutriment/vitamin = 6) + food_reagents = list(/datum/reagent/consumable/nutriment = 8, /datum/reagent/nanomachines = 6, /datum/reagent/consumable/nutriment/vitamin = 6) tastes = list("bun" = 4, "lettuce" = 2, "sludge" = 1) foodtypes = GRAIN | TOXIC @@ -90,7 +90,7 @@ desc = "This massive patty looks like poison. Beep." icon_state = "roburger" max_volume = 120 - food_reagents = list(/datum/reagent/consumable/nutriment = 11, /datum/reagent/nanomachines = 140, /datum/reagent/consumable/nutriment/vitamin = 15) + food_reagents = list(/datum/reagent/consumable/nutriment = 11, /datum/reagent/nanomachines = 80, /datum/reagent/consumable/nutriment/vitamin = 15) tastes = list("bun" = 4, "lettuce" = 2, "sludge" = 1) foodtypes = GRAIN | TOXIC @@ -98,7 +98,7 @@ name = "xenoburger" desc = "Smells caustic. Tastes like heresy." icon_state = "xburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 9, /datum/reagent/consumable/nutriment/vitamin = 7) + food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 5) tastes = list("bun" = 4, "acid" = 4) foodtypes = GRAIN | MEAT @@ -106,28 +106,28 @@ name = "bearger" desc = "Best served rawr." icon_state = "bearger" - food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 8, /datum/reagent/consumable/nutriment/vitamin = 7) + food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 5) foodtypes = GRAIN | MEAT /obj/item/food/burger/clown name = "clown burger" desc = "This tastes funny..." icon_state = "clownburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 12, /datum/reagent/medicine/mannitol = 11, /datum/reagent/consumable/nutriment/vitamin = 6) + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/medicine/mannitol = 6, /datum/reagent/consumable/nutriment/vitamin = 6) foodtypes = GRAIN | FRUIT /obj/item/food/burger/mime name = "mime burger" desc = "Its taste defies language." icon_state = "mimeburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/protein = 11, /datum/reagent/consumable/nutriment/vitamin = 7, /datum/reagent/consumable/nothing = 6) + food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/protein = 9, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/consumable/nothing = 6) foodtypes = GRAIN /obj/item/food/burger/brain name = "brainburger" desc = "A strange looking burger. It looks almost sentient." icon_state = "brainburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 12, /datum/reagent/medicine/mannitol = 11, /datum/reagent/consumable/nutriment/vitamin = 6) + food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/medicine/mannitol = 6, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/nutriment/protein = 6) tastes = list("bun" = 4, "brains" = 2) foodtypes = GRAIN | MEAT | GROSS @@ -135,7 +135,7 @@ name = "ghost burger" desc = "Too Spooky!" icon_state = "ghostburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 7, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 13, /datum/reagent/consumable/sodiumchloride = 5) + food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/protein = 4, /datum/reagent/consumable/nutriment/vitamin = 12, /datum/reagent/consumable/sodiumchloride = 5) tastes = list("bun" = 2, "ectoplasm" = 4) foodtypes = GRAIN alpha = 170 @@ -182,63 +182,63 @@ name = "red burger" desc = "Perfect for hiding the fact it's burnt to a crisp." icon_state = "cburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/colorful_reagent/powder/red = 10) + food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/colorful_reagent/powder/red = 10) foodtypes = GRAIN | MEAT /obj/item/food/burger/orange name = "orange burger" desc = "Contains 0% juice." icon_state = "cburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/colorful_reagent/powder/orange = 10) + food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/colorful_reagent/powder/orange = 10) foodtypes = GRAIN | MEAT /obj/item/food/burger/yellow name = "yellow burger" desc = "Bright to the last bite." icon_state = "cburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/colorful_reagent/powder/yellow = 10) + food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/colorful_reagent/powder/yellow = 10) foodtypes = GRAIN | MEAT /obj/item/food/burger/green name = "green burger" desc = "It's not tainted meat, it's painted meat!" icon_state = "cburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/colorful_reagent/powder/green = 10) + food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/colorful_reagent/powder/green = 10) foodtypes = GRAIN | MEAT /obj/item/food/burger/blue name = "blue burger" desc = "Is this blue rare?" icon_state = "cburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/colorful_reagent/powder/blue = 10) + food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/colorful_reagent/powder/blue = 10) foodtypes = GRAIN | MEAT /obj/item/food/burger/purple name = "purple burger" desc = "Regal and low class at the same time." icon_state = "cburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/colorful_reagent/powder/purple = 10) + food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/colorful_reagent/powder/purple = 10) foodtypes = GRAIN | MEAT /obj/item/food/burger/black name = "black burger" desc = "This is overcooked." icon_state = "cburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/colorful_reagent/powder/black = 10) + food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/colorful_reagent/powder/black = 10) foodtypes = GRAIN | MEAT /obj/item/food/burger/white name = "white burger" desc = "Delicous Titanium!" icon_state = "cburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/colorful_reagent/powder/white = 10) + food_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/colorful_reagent/powder/white = 10) foodtypes = GRAIN | MEAT /obj/item/food/burger/spell name = "spell burger" desc = "This is absolutely Ei Nath." icon_state = "spellburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 8, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 11) + food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 10) tastes = list("bun" = 4, "magic" = 2) foodtypes = GRAIN | MEAT @@ -246,7 +246,7 @@ name = "big bite burger" desc = "Forget the Big Mac. THIS is the future!" icon_state = "bigbiteburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 11, /datum/reagent/consumable/nutriment/vitamin = 7) + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 10, /datum/reagent/consumable/nutriment/vitamin = 5) w_class = WEIGHT_CLASS_NORMAL foodtypes = GRAIN | MEAT | DAIRY @@ -258,18 +258,18 @@ foodtypes = GRAIN | MEAT /obj/item/food/burger/jelly/slime - food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/toxin/slimejelly = 10, /datum/reagent/consumable/nutriment/vitamin = 6) + food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/toxin/slimejelly = 6, /datum/reagent/consumable/nutriment/vitamin = 6) foodtypes = GRAIN | TOXIC /obj/item/food/burger/jelly/cherry - food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/cherryjelly = 10, /datum/reagent/consumable/nutriment/vitamin = 6) + food_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/cherryjelly = 6, /datum/reagent/consumable/nutriment/vitamin = 6) foodtypes = GRAIN | FRUIT /obj/item/food/burger/superbite name = "super bite burger" desc = "This is a mountain of a burger. FOOD!" icon_state = "superbiteburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 25, /datum/reagent/consumable/nutriment/protein = 42, /datum/reagent/consumable/nutriment/vitamin = 15) + food_reagents = list(/datum/reagent/consumable/nutriment = 25, /datum/reagent/consumable/nutriment/protein = 40, /datum/reagent/consumable/nutriment/vitamin = 12) w_class = WEIGHT_CLASS_NORMAL bite_consumption = 7 max_volume = 100 @@ -280,14 +280,14 @@ name = "five alarm burger" desc = "HOT! HOT!" icon_state = "fivealarmburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 7, /datum/reagent/consumable/capsaicin = 5, /datum/reagent/consumable/condensedcapsaicin = 5, /datum/reagent/consumable/nutriment/vitamin = 6) + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/capsaicin = 5, /datum/reagent/consumable/condensedcapsaicin = 5, /datum/reagent/consumable/nutriment/vitamin = 6) foodtypes = GRAIN | MEAT /obj/item/food/burger/rat name = "rat burger" desc = "Pretty much what you'd expect..." icon_state = "ratburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 7, /datum/reagent/consumable/nutriment/vitamin = 2) + food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 2) foodtypes = GRAIN | MEAT | GROSS /obj/item/food/burger/baseball @@ -301,7 +301,7 @@ name = "bacon burger" desc = "The perfect combination of all things American." icon_state = "baconburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 11, /datum/reagent/consumable/nutriment/vitamin = 2) + food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 2) tastes = list("bacon" = 4, "bun" = 2) foodtypes = GRAIN | MEAT @@ -309,7 +309,7 @@ name = "empowered burger" desc = "It's shockingly good, if you live off of electricity that is." icon_state = "empoweredburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/liquidelectricity = 5) + food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/liquidelectricity = 5) tastes = list("bun" = 2, "pure electricity" = 4) foodtypes = GRAIN | TOXIC @@ -317,7 +317,7 @@ name = "crab burger" desc = "A delicious patty of the crabby kind, slapped in between a bun." icon_state = "crabburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 7, /datum/reagent/consumable/nutriment/vitamin = 4) + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/consumable/nutriment/vitamin = 4) tastes = list("bun" = 2, "crab meat" = 4) foodtypes = GRAIN | MEAT @@ -325,7 +325,7 @@ name = "soylent burger" desc = "An eco-friendly burger made using upcycled low value biomass." icon_state = "soylentburger" - food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 9, /datum/reagent/consumable/nutriment/vitamin = 4) + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 6, /datum/reagent/consumable/nutriment/vitamin = 4) tastes = list("bun" = 2, "assistant" = 4) foodtypes = GRAIN | MEAT | DAIRY diff --git a/code/game/objects/items/food/cake.dm b/code/game/objects/items/food/cake.dm new file mode 100644 index 00000000000..cefad027f62 --- /dev/null +++ b/code/game/objects/items/food/cake.dm @@ -0,0 +1,453 @@ +/obj/item/food/cake + icon = 'icons/obj/food/piecake.dmi' + bite_consumption = 3 + max_volume = 80 + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5) + tastes = list("cake" = 1) + foodtypes = GRAIN | DAIRY + +/obj/item/food/cake/Initialize() + . = ..() + AddComponent(/datum/component/food_storage) + +/obj/item/food/cakeslice + icon = 'icons/obj/food/piecake.dmi' + //uncomment me when trash is merged trash = /obj/item/trash/plate + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 1) + tastes = list("cake" = 1) + foodtypes = GRAIN | DAIRY + +/obj/item/food/cake/plain + name = "plain cake" + desc = "A plain cake, not a lie." + icon_state = "plaincake" + food_reagents = list(/datum/reagent/consumable/nutriment = 30, /datum/reagent/consumable/nutriment/vitamin = 7) + tastes = list("sweetness" = 2, "cake" = 5) + foodtypes = GRAIN | DAIRY | SUGAR + +/obj/item/food/cake/plain/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/plain, 5, 30) + +/obj/item/food/cakeslice/plain + name = "plain cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "plaincake_slice" + tastes = list("sweetness" = 2,"cake" = 5) + foodtypes = GRAIN | DAIRY | SUGAR + +/obj/item/food/cake/carrot + name = "carrot cake" + desc = "A favorite desert of a certain wascally wabbit. Not a lie." + icon_state = "carrotcake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/medicine/oculine = 10, /datum/reagent/consumable/nutriment/vitamin = 5) + tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1) + foodtypes = GRAIN | DAIRY | VEGETABLES | SUGAR + +/obj/item/food/cake/carrot/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/carrot, 5, 30) + +/obj/item/food/cakeslice/carrot + name = "carrot cake slice" + desc = "Carrotty slice of Carrot Cake, carrots are good for your eyes! Also not a lie." + icon_state = "carrotcake_slice" + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/oculine = 2, /datum/reagent/consumable/nutriment/vitamin = 1) + tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1) + foodtypes = GRAIN | DAIRY | VEGETABLES | SUGAR + +/obj/item/food/cake/brain + name = "brain cake" + desc = "A squishy cake-thing." + icon_state = "braincake" + food_reagents = list(/datum/reagent/consumable/nutriment = 15, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/medicine/mannitol = 10, /datum/reagent/consumable/nutriment/vitamin = 5) + tastes = list("cake" = 5, "sweetness" = 2, "brains" = 1) + foodtypes = GRAIN | DAIRY | MEAT | GROSS | SUGAR + +/obj/item/food/cake/brain/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/brain, 5, 30) + +/obj/item/food/cakeslice/brain + name = "brain cake slice" + desc = "Lemme tell you something about prions. THEY'RE DELICIOUS." + icon_state = "braincakeslice" + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 1, /datum/reagent/medicine/mannitol = 2, /datum/reagent/consumable/nutriment/vitamin = 1) + tastes = list("cake" = 5, "sweetness" = 2, "brains" = 1) + foodtypes = GRAIN | DAIRY | MEAT | GROSS | SUGAR + +/obj/item/food/cake/cheese + name = "cheese cake" + desc = "DANGEROUSLY cheesy." + icon_state = "cheesecake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 8, /datum/reagent/consumable/nutriment/protein = 5) + tastes = list("cake" = 4, "cream cheese" = 3) + foodtypes = GRAIN | DAIRY + +/obj/item/food/cake/cheese/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/cheese, 5, 30) + +/obj/item/food/cakeslice/cheese + name = "cheese cake slice" + desc = "Slice of pure cheestisfaction." + icon_state = "cheesecake_slice" + tastes = list("cake" = 4, "cream cheese" = 3) + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 1, /datum/reagent/consumable/nutriment/vitamin = 1.3) + foodtypes = GRAIN | DAIRY + +/obj/item/food/cake/orange + name = "orange cake" + desc = "A cake with added orange." + icon_state = "orangecake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10) + tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/orange/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/orange, 5, 30) + +/obj/item/food/cakeslice/orange + name = "orange cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "orangecake_slice" + tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/lime + name = "lime cake" + desc = "A cake with added lime." + icon_state = "limecake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10) + tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/lime/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/lime, 5, 30) + +/obj/item/food/cakeslice/lime + name = "lime cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "limecake_slice" + tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/lemon + name = "lemon cake" + desc = "A cake with added lemon." + icon_state = "lemoncake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10) + tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/lemon/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/lemon, 5, 30) + +/obj/item/food/cakeslice/lemon + name = "lemon cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "lemoncake_slice" + tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/chocolate + name = "chocolate cake" + desc = "A cake with added chocolate." + icon_state = "chocolatecake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10) + tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4) + foodtypes = GRAIN | DAIRY | JUNKFOOD | SUGAR + +/obj/item/food/cake/chocolate/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/chocolate, 5, 30) + +/obj/item/food/cakeslice/chocolate + name = "chocolate cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "chocolatecake_slice" + tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4) + foodtypes = GRAIN | DAIRY | JUNKFOOD | SUGAR + +/obj/item/food/cake/birthday + name = "birthday cake" + desc = "Happy Birthday little clown..." + icon_state = "birthdaycake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/sprinkles = 10, /datum/reagent/consumable/nutriment/vitamin = 5) + tastes = list("cake" = 5, "sweetness" = 1) + foodtypes = GRAIN | DAIRY | JUNKFOOD | SUGAR + +/obj/item/food/cake/birthday/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/birthday, 5, 30) + +/obj/item/food/cake/birthday/microwave_act(obj/machinery/microwave/M) //super sekrit club + new /obj/item/clothing/head/hardhat/cakehat(get_turf(src)) + qdel(src) + +/obj/item/food/cakeslice/birthday + name = "birthday cake slice" + desc = "A slice of your birthday." + icon_state = "birthdaycakeslice" + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/sprinkles = 2, /datum/reagent/consumable/nutriment/vitamin = 1) + tastes = list("cake" = 5, "sweetness" = 1) + foodtypes = GRAIN | DAIRY | JUNKFOOD | SUGAR + +/obj/item/food/cake/birthday/energy + name = "energy cake" + desc = "Just enough calories for a whole nuclear operative squad." + icon_state = "energycake" + force = 5 + hitsound = 'sound/weapons/blade1.ogg' + food_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/consumable/sprinkles = 10, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/pwr_game = 10, /datum/reagent/consumable/liquidelectricity = 10) + tastes = list("cake" = 3, "a Vlad's Salad" = 1) + +/obj/item/food/cake/birthday/energy/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/birthday/energy, 5, 30) + +/obj/item/food/cake/birthday/energy/proc/energy_bite(mob/living/user) + to_chat(user, "As you eat the cake, you accidentally hurt yourself on the embedded energy sword!") + user.apply_damage(30,BRUTE,BODY_ZONE_HEAD) + playsound(user, 'sound/weapons/blade1.ogg', 5, TRUE) + +/obj/item/food/cake/birthday/energy/attack(mob/living/M, mob/living/user) + . = ..() + if(HAS_TRAIT(user, TRAIT_PACIFISM) && M != user) //Prevents pacifists from attacking others directly + return + energy_bite(M, user) + +/obj/item/food/cake/birthday/energy/microwave_act(obj/machinery/microwave/M) //super sekriter club + new /obj/item/clothing/head/hardhat/cakehat/energycake(get_turf(src)) + qdel(src) + +/obj/item/food/cakeslice/birthday/energy + name = "energy cake slice" + desc = "For the traitor on the go." + icon_state = "energycakeslice" + force = 2 + hitsound = 'sound/weapons/blade1.ogg' + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/sprinkles = 2, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/pwr_game = 2, /datum/reagent/consumable/liquidelectricity = 2) + tastes = list("cake" = 3, "a Vlad's Salad" = 1) + +/obj/item/food/cakeslice/birthday/energy/proc/energy_bite(mob/living/user) + to_chat(user, "As you eat the cake slice, you accidentally hurt yourself on the embedded energy dagger!") + user.apply_damage(18,BRUTE,BODY_ZONE_HEAD) + playsound(user, 'sound/weapons/blade1.ogg', 5, TRUE) + +/obj/item/food/cakeslice/birthday/energy/attack(mob/living/M, mob/living/user) + . = ..() + if(HAS_TRAIT(user, TRAIT_PACIFISM) && M != user) //Prevents pacifists from attacking others directly + return + energy_bite(M, user) + +/obj/item/food/cake/apple + name = "apple cake" + desc = "A cake centred with Apple." + icon_state = "applecake" + + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 10) + tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/apple/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/apple, 5, 30) + +/obj/item/food/cakeslice/apple + name = "apple cake slice" + desc = "A slice of heavenly cake." + icon_state = "applecakeslice" + tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/slimecake + name = "Slime cake" + desc = "A cake made of slimes. Probably not electrified." + icon_state = "slimecake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5) + tastes = list("cake" = 5, "sweetness" = 1, "slime" = 1) + foodtypes = GRAIN | DAIRY | SUGAR + +/obj/item/food/cake/apple/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/slimecake, 5, 30) + +/obj/item/food/cakeslice/slimecake + name = "slime cake slice" + desc = "A slice of slime cake." + icon_state = "slimecake_slice" + tastes = list("cake" = 5, "sweetness" = 1, "slime" = 1) + foodtypes = GRAIN | DAIRY | SUGAR + +/obj/item/food/cake/pumpkinspice + name = "pumpkin spice cake" + desc = "A hollow cake with real pumpkin." + icon_state = "pumpkinspicecake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5) + tastes = list("cake" = 5, "sweetness" = 1, "pumpkin" = 1) + foodtypes = GRAIN | DAIRY | VEGETABLES | SUGAR + +/obj/item/food/cake/pumpkinspice/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/pumpkinspice, 5, 30) + +/obj/item/food/cakeslice/pumpkinspice + name = "pumpkin spice cake slice" + desc = "A spicy slice of pumpkin goodness." + icon_state = "pumpkinspicecakeslice" + tastes = list("cake" = 5, "sweetness" = 1, "pumpkin" = 1) + foodtypes = GRAIN | DAIRY | VEGETABLES | SUGAR + +/obj/item/food/cake/bsvc // blackberry strawberries vanilla cake + name = "blackberry and strawberry vanilla cake" + desc = "A plain cake, filled with assortment of blackberries and strawberries!" + icon_state = "blackbarry_strawberries_cake_vanilla_cake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5) + tastes = list("blackberry" = 2, "strawberries" = 2, "vanilla" = 2, "sweetness" = 2, "cake" = 3) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/bsvc/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/bsvc, 5, 30) + +/obj/item/food/cakeslice/bsvc + name = "blackberry and strawberry vanilla cake slice" + desc = "Just a slice of cake filled with assortment of blackberries and strawberries!" + icon_state = "blackbarry_strawberries_cake_vanilla_slice" + tastes = list("blackberry" = 2, "strawberries" = 2, "vanilla" = 2, "sweetness" = 2,"cake" = 3) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/bscc // blackbarry strawberries chocolate cake + name = "blackberry and strawberry chocolate cake" + desc = "A chocolate cake, filled with assortment of blackberries and strawberries!" + icon_state = "blackbarry_strawberries_cake_coco_cake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/coco = 5) + tastes = list("blackberry" = 2, "strawberries" = 2, "chocolate" = 2, "sweetness" = 2,"cake" = 3) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/bscc/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/bscc, 5, 30) + +/obj/item/food/cakeslice/bscc + name = "blackberry and strawberry chocolate cake slice" + desc = "Just a slice of cake filled with assortment of blackberries and strawberries!" + icon_state = "blackbarry_strawberries_cake_coco_slice" + tastes = list("blackberry" = 2, "strawberries" = 2, "chocolate" = 2, "sweetness" = 2,"cake" = 3) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/holy_cake + name = "angel food cake" + desc = "A cake made for angels and chaplains alike! Contains holy water." + icon_state = "holy_cake" + food_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 3, /datum/reagent/water/holywater = 10) + tastes = list("cake" = 5, "sweetness" = 1, "clouds" = 1) + foodtypes = GRAIN | DAIRY | SUGAR + +/obj/item/food/cake/holy_cake/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/holy_cake_slice, 5, 30) + +/obj/item/food/cakeslice/holy_cake_slice + name = "angel food cake slice" + desc = "A slice of heavenly cake." + icon_state = "holy_cake_slice" + tastes = list("cake" = 5, "sweetness" = 1, "clouds" = 1) + foodtypes = GRAIN | DAIRY | SUGAR + +/obj/item/food/cake/pound_cake + name = "pound cake" + desc = "A condensed cake made for filling people up quickly." + icon_state = "pound_cake" + food_reagents = list(/datum/reagent/consumable/nutriment = 60, /datum/reagent/consumable/nutriment/vitamin = 5) + tastes = list("cake" = 5, "sweetness" = 1, "batter" = 1) + foodtypes = GRAIN | DAIRY | SUGAR | JUNKFOOD + +/obj/item/food/cake/pound_cake/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/pound_cake_slice, 7, 30) + +/obj/item/food/cakeslice/pound_cake_slice + name = "pound cake slice" + desc = "A slice of condensed cake made for filling people up quickly." + icon_state = "pound_cake_slice" + tastes = list("cake" = 5, "sweetness" = 5, "batter" = 1) + food_reagents = list(/datum/reagent/consumable/nutriment = 9, /datum/reagent/consumable/nutriment/vitamin = 0.5) + foodtypes = GRAIN | DAIRY | SUGAR | JUNKFOOD + +/obj/item/food/cake/hardware_cake + name = "hardware cake" + desc = "A quote on quote cake that is made with electronic boards and leaks acid..." + icon_state = "hardware_cake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/toxin/acid = 15, /datum/reagent/fuel/oil = 15) + tastes = list("acid" = 3, "metal" = 4, "glass" = 5) + foodtypes = GRAIN | GROSS + +/obj/item/food/cake/hardware_cake/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/hardware_cake_slice, 5, 30) + +/obj/item/food/cakeslice/hardware_cake_slice + name = "hardware cake slice" + desc = "A slice of electronic boards and some acid." + icon_state = "hardware_cake_slice" + tastes = list("acid" = 3, "metal" = 4, "glass" = 5) + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/toxin/acid = 3, /datum/reagent/fuel/oil = 3) + foodtypes = GRAIN | GROSS + +/obj/item/food/cake/vanilla_cake + name = "vanilla cake" + desc = "A vanilla frosted cake." + icon_state = "vanillacake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/sugar = 15, /datum/reagent/consumable/vanilla = 15) + tastes = list("cake" = 1, "sugar" = 1, "vanilla" = 10) + foodtypes = GRAIN | SUGAR | DAIRY + +/obj/item/food/cake/vanilla_cake/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/vanilla_slice, 5, 30) + +/obj/item/food/cakeslice/vanilla_slice + name = "vanilla cake slice" + desc = "A slice of vanilla frosted cake." + icon_state = "vanillacake_slice" + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/sugar = 3, /datum/reagent/consumable/vanilla = 3) + tastes = list("cake" = 1, "sugar" = 1, "vanilla" = 10) + foodtypes = GRAIN | SUGAR | DAIRY + +/obj/item/food/cake/clown_cake + name = "clown cake" + desc = "A funny cake with a clown face on it." + icon_state = "clowncake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/sugar = 15) + tastes = list("cake" = 1, "sugar" = 1, "joy" = 10) + foodtypes = GRAIN | SUGAR | DAIRY + +/obj/item/food/cake/clown_cake/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/clown_slice, 5, 30) + +/obj/item/food/cakeslice/clown_slice + name = "clown cake slice" + desc = "A slice of bad jokes, and silly props." + icon_state = "clowncake_slice" + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/sugar = 3) + tastes = list("cake" = 1, "sugar" = 1, "joy" = 10) + foodtypes = GRAIN | SUGAR | DAIRY + +/obj/item/food/cake/trumpet + name = "spaceman's cake" + desc = "A spaceman's trumpet frosted cake." + icon_state = "trumpetcake" + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/medicine/polypyr = 15, /datum/reagent/consumable/cream = 5, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/berryjuice = 5) + tastes = list("cake" = 4, "violets" = 2, "jam" = 2) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/trumpet/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/trumpet, 5, 30) + +/obj/item/food/cakeslice/trumpet + name = "spaceman's cake" + desc = "A spaceman's trumpet frosted cake." + icon_state = "trumpetcakeslice" + food_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/medicine/polypyr = 3, /datum/reagent/consumable/cream = 1, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/berryjuice = 1) + tastes = list("cake" = 4, "violets" = 2, "jam" = 2) + foodtypes = GRAIN | DAIRY | FRUIT | SUGAR + +/obj/item/food/cake/brioche + name = "brioche cake" + desc = "A ring of sweet, glazed buns." + food_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5) + +/obj/item/food/cake/brioche/MakeProcessable() + AddElement(/datum/element/processable, TOOL_KNIFE, /obj/item/food/cakeslice/brioche, 6, 30) + +/obj/item/food/cakeslice/brioche + name = "brioche cake slice" + desc = "Delicious sweet-bread. Who needs anything else?" + icon_state = "briochecake_slice" + food_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 1) diff --git a/code/modules/cargo/bounties/chef.dm b/code/modules/cargo/bounties/chef.dm index e31d816aa6c..6bbee6133e9 100644 --- a/code/modules/cargo/bounties/chef.dm +++ b/code/modules/cargo/bounties/chef.dm @@ -2,7 +2,7 @@ name = "Birthday Cake" description = "Nanotrasen's birthday is coming up! Ship them a birthday cake to celebrate!" reward = 4000 - wanted_types = list(/obj/item/reagent_containers/food/snacks/store/cake/birthday, /obj/item/reagent_containers/food/snacks/cakeslice/birthday) + wanted_types = list(/obj/item/food/cake/birthday, /obj/item/food/cakeslice/birthday) /datum/bounty/item/chef/soup name = "Soup" diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm index 48d88ab7b32..203b6326728 100644 --- a/code/modules/clothing/outfits/ert.dm +++ b/code/modules/clothing/outfits/ert.dm @@ -421,4 +421,4 @@ l_pocket = /obj/item/kitchen/knife backpack_contents = list(/obj/item/storage/box/survival/engineer=1,\ /obj/item/storage/box/fireworks=3,\ - /obj/item/reagent_containers/food/snacks/store/cake/birthday=1) + /obj/item/food/cake/birthday=1) diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index 63304214127..399e32c12e7 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -42,7 +42,7 @@ to_chat(user, "The ingredient is too big for [src]!") else if((ingredients.len >= ingMax) || (reagents.total_volume >= volume)) to_chat(user, "You can't add more ingredients to [src]!") - else if(istype(I, /obj/item/reagent_containers/food/snacks/pizzaslice/custom) || istype(I, /obj/item/reagent_containers/food/snacks/cakeslice/custom)) + else if(istype(I, /obj/item/reagent_containers/food/snacks/pizzaslice/custom)) to_chat(user, "Adding [I.name] to [src] would make a mess.") else if(!user.transferItemToLoc(I, src)) @@ -161,17 +161,6 @@ icon_state = "custburg" foodtype = GRAIN - -/obj/item/reagent_containers/food/snacks/customizable/cake - name = "cake" - ingMax = 6 - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/custom - slices_num = 5 - icon = 'icons/obj/food/piecake.dmi' - icon_state = "plaincake" - foodtype = GRAIN | DAIRY - - /obj/item/reagent_containers/food/snacks/customizable/kebab name = "kebab" desc = "Delicious food on a stick." diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 370b911b91d..055af1ca8d0 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -185,7 +185,7 @@ All foods are distributed among various categories. Use common sense. if(S.w_class > WEIGHT_CLASS_SMALL) to_chat(user, "[S] is too big for [src]!") return FALSE - if(!S.customfoodfilling || istype(W, /obj/item/reagent_containers/food/snacks/customizable) || istype(W, /obj/item/reagent_containers/food/snacks/pizzaslice/custom) || istype(W, /obj/item/reagent_containers/food/snacks/cakeslice/custom)) + if(!S.customfoodfilling || istype(W, /obj/item/reagent_containers/food/snacks/customizable) || istype(W, /obj/item/reagent_containers/food/snacks/pizzaslice/custom)) to_chat(user, "[src] can't be filled with [S]!") return FALSE if(contents.len >= 20) diff --git a/code/modules/food_and_drinks/food/snacks/dough.dm b/code/modules/food_and_drinks/food/snacks/dough.dm index 2f511fa6578..5a72edfd583 100644 --- a/code/modules/food_and_drinks/food/snacks/dough.dm +++ b/code/modules/food_and_drinks/food/snacks/dough.dm @@ -80,7 +80,7 @@ desc = "Cook it to get a cake." icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "cakebatter" - cooked_type = /obj/item/reagent_containers/food/snacks/store/cake/plain + cooked_type = /obj/item/food/cake/plain list_reagents = list(/datum/reagent/consumable/nutriment = 9) w_class = WEIGHT_CLASS_NORMAL tastes = list("batter" = 1) diff --git a/code/modules/food_and_drinks/food/snacks_cake.dm b/code/modules/food_and_drinks/food/snacks_cake.dm deleted file mode 100644 index 721a72ec80b..00000000000 --- a/code/modules/food_and_drinks/food/snacks_cake.dm +++ /dev/null @@ -1,455 +0,0 @@ -/obj/item/reagent_containers/food/snacks/store/cake - icon = 'icons/obj/food/piecake.dmi' - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/plain - slices_num = 5 - bitesize = 3 - volume = 80 - list_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/nutriment/vitamin = 5) - tastes = list("cake" = 1) - foodtype = GRAIN | DAIRY - - -/obj/item/reagent_containers/food/snacks/cakeslice - icon = 'icons/obj/food/piecake.dmi' - trash = /obj/item/trash/plate - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 1) - customfoodfilling = 0 //to avoid infinite cake-ception - tastes = list("cake" = 1) - foodtype = GRAIN | DAIRY - value = FOOD_FAST - -/obj/item/reagent_containers/food/snacks/store/cake/plain - name = "plain cake" - desc = "A plain cake, not a lie." - icon_state = "plaincake" - custom_food_type = /obj/item/reagent_containers/food/snacks/customizable/cake - bonus_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/consumable/nutriment/vitamin = 2) - tastes = list("sweetness" = 2,"cake" = 5) - foodtype = GRAIN | DAIRY | SUGAR - value = FOOD_FAST - -/obj/item/reagent_containers/food/snacks/cakeslice/plain - name = "plain cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "plaincake_slice" - filling_color = "#FFD700" - customfoodfilling = 1 - tastes = list("sweetness" = 2,"cake" = 5) - foodtype = GRAIN | DAIRY | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/carrot - name = "carrot cake" - desc = "A favorite desert of a certain wascally wabbit. Not a lie." - icon_state = "carrotcake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/carrot - slices_num = 5 - bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/medicine/oculine = 5, /datum/reagent/consumable/nutriment/vitamin = 10) - list_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/medicine/oculine = 10, /datum/reagent/consumable/nutriment/vitamin = 5) - tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1) - foodtype = GRAIN | DAIRY | VEGETABLES | SUGAR - value = FOOD_RARE - -/obj/item/reagent_containers/food/snacks/cakeslice/carrot - name = "carrot cake slice" - desc = "Carrotty slice of Carrot Cake, carrots are good for your eyes! Also not a lie." - icon_state = "carrotcake_slice" - filling_color = "#FFA500" - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/medicine/oculine = 2, /datum/reagent/consumable/nutriment/vitamin = 1) - tastes = list("cake" = 5, "sweetness" = 2, "carrot" = 1) - foodtype = GRAIN | DAIRY | VEGETABLES | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/brain - name = "brain cake" - desc = "A squishy cake-thing." - icon_state = "braincake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/brain - slices_num = 5 - bonus_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/medicine/mannitol = 10, /datum/reagent/consumable/nutriment/vitamin = 10) - list_reagents = list(/datum/reagent/consumable/nutriment = 16, /datum/reagent/consumable/nutriment/protein = 5, /datum/reagent/medicine/mannitol = 10, /datum/reagent/consumable/nutriment/vitamin = 5) - tastes = list("cake" = 5, "sweetness" = 2, "brains" = 1) - foodtype = GRAIN | DAIRY | MEAT | GROSS | SUGAR - value = FOOD_FAST - -/obj/item/reagent_containers/food/snacks/cakeslice/brain - name = "brain cake slice" - desc = "Lemme tell you something about prions. THEY'RE DELICIOUS." - icon_state = "braincakeslice" - filling_color = "#FF69B4" - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 1, /datum/reagent/medicine/mannitol = 2, /datum/reagent/consumable/nutriment/vitamin = 1) - tastes = list("cake" = 5, "sweetness" = 2, "brains" = 1) - foodtype = GRAIN | DAIRY | MEAT | GROSS | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/cheese - name = "cheese cake" - desc = "DANGEROUSLY cheesy." - icon_state = "cheesecake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/cheese - slices_num = 5 - bonus_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 8, /datum/reagent/consumable/nutriment/protein = 5) - tastes = list("cake" = 4, "cream cheese" = 3) - foodtype = GRAIN | DAIRY - value = FOOD_RARE - -/obj/item/reagent_containers/food/snacks/cakeslice/cheese - name = "cheese cake slice" - desc = "Slice of pure cheestisfaction." - icon_state = "cheesecake_slice" - filling_color = "#FFFACD" - tastes = list("cake" = 4, "cream cheese" = 3) - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/protein = 1,, /datum/reagent/consumable/nutriment/vitamin = 1) - foodtype = GRAIN | DAIRY - -/obj/item/reagent_containers/food/snacks/store/cake/orange - name = "orange cake" - desc = "A cake with added orange." - icon_state = "orangecake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/orange - slices_num = 5 - bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 10) - tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - value = FOOD_RARE - -/obj/item/reagent_containers/food/snacks/cakeslice/orange - name = "orange cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "orangecake_slice" - filling_color = "#FFA500" - tastes = list("cake" = 5, "sweetness" = 2, "oranges" = 2) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/lime - name = "lime cake" - desc = "A cake with added lime." - icon_state = "limecake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/lime - slices_num = 5 - bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 10) - tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - value = FOOD_RARE - -/obj/item/reagent_containers/food/snacks/cakeslice/lime - name = "lime cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "limecake_slice" - filling_color = "#00FF00" - tastes = list("cake" = 5, "sweetness" = 2, "unbearable sourness" = 2) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/lemon - name = "lemon cake" - desc = "A cake with added lemon." - icon_state = "lemoncake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/lemon - slices_num = 5 - bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 10) - tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - value = FOOD_RARE - -/obj/item/reagent_containers/food/snacks/cakeslice/lemon - name = "lemon cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "lemoncake_slice" - filling_color = "#FFEE00" - tastes = list("cake" = 5, "sweetness" = 2, "sourness" = 2) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/chocolate - name = "chocolate cake" - desc = "A cake with added chocolate." - icon_state = "chocolatecake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/chocolate - slices_num = 5 - bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 10) - tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4) - foodtype = GRAIN | DAIRY | JUNKFOOD | SUGAR - value = FOOD_RARE - -/obj/item/reagent_containers/food/snacks/cakeslice/chocolate - name = "chocolate cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "chocolatecake_slice" - filling_color = "#A0522D" - tastes = list("cake" = 5, "sweetness" = 1, "chocolate" = 4) - foodtype = GRAIN | DAIRY | JUNKFOOD | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/birthday - name = "birthday cake" - desc = "Happy Birthday little clown..." - icon_state = "birthdaycake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/birthday - slices_num = 5 - bonus_reagents = list(/datum/reagent/consumable/nutriment = 7, /datum/reagent/consumable/sprinkles = 10, /datum/reagent/consumable/nutriment/vitamin = 5) - list_reagents = list(/datum/reagent/consumable/nutriment = 20, /datum/reagent/consumable/sprinkles = 10, /datum/reagent/consumable/nutriment/vitamin = 5) - tastes = list("cake" = 5, "sweetness" = 1) - foodtype = GRAIN | DAIRY | JUNKFOOD | SUGAR - value = FOOD_EXOTIC - -/obj/item/reagent_containers/food/snacks/store/cake/birthday/microwave_act(obj/machinery/microwave/M) //super sekrit club - new /obj/item/clothing/head/hardhat/cakehat(get_turf(src)) - qdel(src) - -/obj/item/reagent_containers/food/snacks/cakeslice/birthday - name = "birthday cake slice" - desc = "A slice of your birthday." - icon_state = "birthdaycakeslice" - filling_color = "#DC143C" - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/sprinkles = 2, /datum/reagent/consumable/nutriment/vitamin = 1) - tastes = list("cake" = 5, "sweetness" = 1) - foodtype = GRAIN | DAIRY | JUNKFOOD | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/birthday/energy - name = "energy cake" - desc = "Just enough calories for a whole nuclear operative squad." - icon_state = "energycake" - force = 5 - hitsound = 'sound/weapons/blade1.ogg' - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/birthday/energy - list_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/consumable/sprinkles = 10, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/pwr_game = 10, /datum/reagent/consumable/liquidelectricity = 10) - tastes = list("cake" = 3, "a Vlad's Salad" = 1) - value = FOOD_ILLEGAL - -/obj/item/reagent_containers/food/snacks/store/cake/birthday/energy/proc/energy_bite(mob/living/user) - to_chat(user, "As you eat the cake, you accidentally hurt yourself on the embedded energy sword!") - user.apply_damage(30,BRUTE,BODY_ZONE_HEAD) - playsound(user, 'sound/weapons/blade1.ogg', 5, TRUE) - -/obj/item/reagent_containers/food/snacks/store/cake/birthday/energy/attack(mob/living/M, mob/living/user) - . = ..() - if(HAS_TRAIT(user, TRAIT_PACIFISM) && M != user) //Prevents pacifists from attacking others directly - return - energy_bite(M, user) - -/obj/item/reagent_containers/food/snacks/store/cake/birthday/energy/microwave_act(obj/machinery/microwave/M) //super sekriter club - new /obj/item/clothing/head/hardhat/cakehat/energycake(get_turf(src)) - qdel(src) - -/obj/item/reagent_containers/food/snacks/cakeslice/birthday/energy - name = "energy cake slice" - desc = "For the traitor on the go." - icon_state = "energycakeslice" - force = 2 - hitsound = 'sound/weapons/blade1.ogg' - filling_color = "#00FF00" - list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/sprinkles = 2, /datum/reagent/consumable/nutriment/vitamin = 1, /datum/reagent/consumable/pwr_game = 2, /datum/reagent/consumable/liquidelectricity = 2) - tastes = list("cake" = 3, "a Vlad's Salad" = 1) - -/obj/item/reagent_containers/food/snacks/cakeslice/birthday/energy/proc/energy_bite(mob/living/user) - to_chat(user, "As you eat the cake slice, you accidentally hurt yourself on the embedded energy dagger!") - user.apply_damage(18,BRUTE,BODY_ZONE_HEAD) - playsound(user, 'sound/weapons/blade1.ogg', 5, TRUE) - -/obj/item/reagent_containers/food/snacks/cakeslice/birthday/energy/attack(mob/living/M, mob/living/user) - . = ..() - if(HAS_TRAIT(user, TRAIT_PACIFISM) && M != user) //Prevents pacifists from attacking others directly - return - energy_bite(M, user) - -/obj/item/reagent_containers/food/snacks/store/cake/apple - name = "apple cake" - desc = "A cake centred with Apple." - icon_state = "applecake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/apple - slices_num = 5 - bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 10) - tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - value = FOOD_RARE - -/obj/item/reagent_containers/food/snacks/cakeslice/apple - name = "apple cake slice" - desc = "A slice of heavenly cake." - icon_state = "applecakeslice" - filling_color = "#FF4500" - tastes = list("cake" = 5, "sweetness" = 1, "apple" = 1) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - -/obj/item/reagent_containers/food/snacks/cakeslice/custom - name = "cake slice" - icon_state = "plaincake_slice" - filling_color = "#FFFFFF" - foodtype = GRAIN | DAIRY - -/obj/item/reagent_containers/food/snacks/store/cake/slimecake - name = "Slime cake" - desc = "A cake made of slimes. Probably not electrified." - icon_state = "slimecake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/slimecake - bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 3) - tastes = list("cake" = 5, "sweetness" = 1, "slime" = 1) - foodtype = GRAIN | DAIRY | SUGAR - value = FOOD_EXOTIC - -/obj/item/reagent_containers/food/snacks/cakeslice/slimecake - name = "slime cake slice" - desc = "A slice of slime cake." - icon_state = "slimecake_slice" - filling_color = "#00FFFF" - tastes = list("cake" = 5, "sweetness" = 1, "slime" = 1) - foodtype = GRAIN | DAIRY | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/pumpkinspice - name = "pumpkin spice cake" - desc = "A hollow cake with real pumpkin." - icon_state = "pumpkinspicecake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/pumpkinspice - bonus_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 5) - tastes = list("cake" = 5, "sweetness" = 1, "pumpkin" = 1) - foodtype = GRAIN | DAIRY | VEGETABLES | SUGAR - value = FOOD_RARE - -/obj/item/reagent_containers/food/snacks/cakeslice/pumpkinspice - name = "pumpkin spice cake slice" - desc = "A spicy slice of pumpkin goodness." - icon_state = "pumpkinspicecakeslice" - filling_color = "#FFD700" - tastes = list("cake" = 5, "sweetness" = 1, "pumpkin" = 1) - foodtype = GRAIN | DAIRY | VEGETABLES | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/bsvc // blackberry strawberries vanilla cake - name = "blackberry and strawberry vanilla cake" - desc = "A plain cake, filled with assortment of blackberries and strawberries!" - icon_state = "blackbarry_strawberries_cake_vanilla_cake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/bsvc - bonus_reagents = list(/datum/reagent/consumable/nutriment = 14, /datum/reagent/consumable/nutriment/vitamin = 4) - tastes = list("blackberry" = 2, "strawberries" = 2, "vanilla" = 2, "sweetness" = 2, "cake" = 3) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - value = FOOD_EXOTIC - -/obj/item/reagent_containers/food/snacks/cakeslice/bsvc - name = "blackberry and strawberry vanilla cake slice" - desc = "Just a slice of cake filled with assortment of blackberries and strawberries!" - icon_state = "blackbarry_strawberries_cake_vanilla_slice" - filling_color = "#FFD700" - tastes = list("blackberry" = 2, "strawberries" = 2, "vanilla" = 2, "sweetness" = 2,"cake" = 3) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/bscc // blackbarry strawberries chocolate cake - name = "blackberry and strawberry chocolate cake" - desc = "A chocolate cake, filled with assortment of blackberries and strawberries!" - icon_state = "blackbarry_strawberries_cake_coco_cake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/bscc - bonus_reagents = list(/datum/reagent/consumable/nutriment = 14, /datum/reagent/consumable/nutriment/vitamin = 4, /datum/reagent/consumable/coco = 5) - tastes = list("blackberry" = 2, "strawberries" = 2, "chocolate" = 2, "sweetness" = 2,"cake" = 3) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - value = FOOD_EXOTIC - -/obj/item/reagent_containers/food/snacks/cakeslice/bscc - name = "blackberry and strawberry chocolate cake slice" - desc = "Just a slice of cake filled with assortment of blackberries and strawberries!" - icon_state = "blackbarry_strawberries_cake_coco_slice" - filling_color = "#FFD700" - tastes = list("blackberry" = 2, "strawberries" = 2, "chocolate" = 2, "sweetness" = 2,"cake" = 3) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/holy_cake - name = "angel food cake" - desc = "A cake made for angels and chaplains alike! Contains holy water." - icon_state = "holy_cake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/holy_cake_slice - bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 3, /datum/reagent/water/holywater = 10) - tastes = list("cake" = 5, "sweetness" = 1, "clouds" = 1) - foodtype = GRAIN | DAIRY | SUGAR - value = FOOD_EXOTIC - -/obj/item/reagent_containers/food/snacks/cakeslice/holy_cake_slice - name = "angel food cake slice" - desc = "A slice of heavenly cake." - icon_state = "holy_cake_slice" - filling_color = "#00FFFF" - tastes = list("cake" = 5, "sweetness" = 1, "clouds" = 1) - foodtype = GRAIN | DAIRY | SUGAR - -/obj/item/reagent_containers/food/snacks/store/cake/pound_cake - name = "pound cake" - desc = "A condensed cake made for filling people up quickly." - icon_state = "pound_cake" - slices_num = 7 //Its ment to feed the party - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/pound_cake_slice - bonus_reagents = list(/datum/reagent/consumable/nutriment = 60) - tastes = list("cake" = 5, "sweetness" = 1, "batter" = 1) - foodtype = GRAIN | DAIRY | SUGAR | JUNKFOOD - value = FOOD_EXOTIC - -/obj/item/reagent_containers/food/snacks/cakeslice/pound_cake_slice - name = "pound cake slice" - desc = "A slice of condensed cake made for filling people up quickly." - icon_state = "pound_cake_slice" - filling_color = "#00FFFF" - tastes = list("cake" = 5, "sweetness" = 5, "batter" = 1) - foodtype = GRAIN | DAIRY | SUGAR | JUNKFOOD - -/obj/item/reagent_containers/food/snacks/store/cake/hardware_cake - name = "hardware cake" - desc = "A quote on quote cake that is made with electronic boards and leaks acid..." - icon_state = "hardware_cake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/hardware_cake_slice - bonus_reagents = list(/datum/reagent/toxin/acid = 15, /datum/reagent/fuel/oil = 15) - tastes = list("acid" = 3, "metal" = 4, "glass" = 5) - foodtype = GRAIN | GROSS - value = FOOD_EXOTIC - -/obj/item/reagent_containers/food/snacks/cakeslice/hardware_cake_slice - name = "hardware cake slice" - desc = "A slice of electronic boards and some acid." - icon_state = "hardware_cake_slice" - filling_color = "#00FFFF" - tastes = list("acid" = 3, "metal" = 4, "glass" = 5) - foodtype = GRAIN | GROSS - -/obj/item/reagent_containers/food/snacks/store/cake/vanilla_cake - name = "vanilla cake" - desc = "A vanilla frosted cake." - icon_state = "vanillacake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/vanilla_slice - bonus_reagents = list(/datum/reagent/consumable/sugar = 15, /datum/reagent/consumable/vanilla = 15) - tastes = list("cake" = 1, "sugar" = 1, "vanilla" = 10) - foodtype = GRAIN | SUGAR | DAIRY - value = FOOD_EXOTIC - -/obj/item/reagent_containers/food/snacks/cakeslice/vanilla_slice - name = "vanilla cake slice" - desc = "A slice of vanilla frosted cake." - icon_state = "vanillacake_slice" - filling_color = "#00FFFF" - tastes = list("cake" = 1, "sugar" = 1, "vanilla" = 10) - foodtype = GRAIN | SUGAR | DAIRY - -/obj/item/reagent_containers/food/snacks/store/cake/clown_cake - name = "clown cake" - desc = "A funny cake with a clown face on it." - icon_state = "clowncake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/clown_slice - bonus_reagents = list(/datum/reagent/consumable/sugar = 15) - tastes = list("cake" = 1, "sugar" = 1, "joy" = 10) - foodtype = GRAIN | SUGAR | DAIRY - value = FOOD_EXOTIC - -/obj/item/reagent_containers/food/snacks/cakeslice/clown_slice - name = "clown cake slice" - desc = "A slice of bad jokes, and silly props." - icon_state = "clowncake_slice" - filling_color = "#00FFFF" - tastes = list("cake" = 1, "sugar" = 1, "joy" = 10) - foodtype = GRAIN | SUGAR | DAIRY - -/obj/item/reagent_containers/food/snacks/store/cake/trumpet - name = "spaceman's cake" - desc = "A spaceman's trumpet frosted cake." - icon_state = "trumpetcake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/trumpet - bonus_reagents = list(/datum/reagent/medicine/polypyr = 15, /datum/reagent/consumable/cream = 5, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/berryjuice = 5) - filling_color = "#7A3D80" - tastes = list("cake" = 4, "violets" = 2, "jam" = 2) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR - value = FOOD_EXOTIC - -/obj/item/reagent_containers/food/snacks/cakeslice/trumpet - name = "spaceman's cake" - desc = "A spaceman's trumpet frosted cake." - icon_state = "trumpetcakeslice" - filling_color = "#7A3D80" - tastes = list("cake" = 4, "violets" = 2, "jam" = 2) - foodtype = GRAIN | DAIRY | FRUIT | SUGAR diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm index e1440eec255..95c9613eabb 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_cake.dm @@ -6,190 +6,190 @@ /datum/crafting_recipe/food/carrotcake name = "Carrot cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/grown/carrot = 2 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/carrot + result = /obj/item/food/cake/carrot subcategory = CAT_CAKE /datum/crafting_recipe/food/cheesecake name = "Cheese cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/cheesewedge = 2 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/cheese + result = /obj/item/food/cake/cheese subcategory = CAT_CAKE /datum/crafting_recipe/food/applecake name = "Apple cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/grown/apple = 2 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/apple + result = /obj/item/food/cake/apple subcategory = CAT_CAKE /datum/crafting_recipe/food/orangecake name = "Orange cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/grown/citrus/orange = 2 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/orange + result = /obj/item/food/cake/orange subcategory = CAT_CAKE /datum/crafting_recipe/food/limecake name = "Lime cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/grown/citrus/lime = 2 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/lime + result = /obj/item/food/cake/lime subcategory = CAT_CAKE /datum/crafting_recipe/food/lemoncake name = "Lemon cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/grown/citrus/lemon = 2 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/lemon + result = /obj/item/food/cake/lemon subcategory = CAT_CAKE /datum/crafting_recipe/food/chocolatecake name = "Chocolate cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/chocolatebar = 2 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/chocolate + result = /obj/item/food/cake/chocolate subcategory = CAT_CAKE /datum/crafting_recipe/food/birthdaycake name = "Birthday cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/candle = 1, /datum/reagent/consumable/sugar = 5, /datum/reagent/consumable/caramel = 2 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/birthday + result = /obj/item/food/cake/birthday subcategory = CAT_CAKE /datum/crafting_recipe/food/energycake name = "Energy cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/birthday = 1, + /obj/item/food/cake/birthday = 1, /obj/item/melee/transforming/energy/sword = 1, ) - blacklist = list(/obj/item/reagent_containers/food/snacks/store/cake/birthday/energy) - result = /obj/item/reagent_containers/food/snacks/store/cake/birthday/energy + blacklist = list(/obj/item/food/cake/birthday/energy) + result = /obj/item/food/cake/birthday/energy subcategory = CAT_CAKE /datum/crafting_recipe/food/braincake name = "Brain cake" reqs = list( /obj/item/organ/brain = 1, - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1 + /obj/item/food/cake/plain = 1 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/brain + result = /obj/item/food/cake/brain subcategory = CAT_CAKE /datum/crafting_recipe/food/slimecake name = "Slime cake" reqs = list( /obj/item/slime_extract = 1, - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1 + /obj/item/food/cake/plain = 1 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/slimecake + result = /obj/item/food/cake/slimecake subcategory = CAT_CAKE /datum/crafting_recipe/food/pumpkinspicecake name = "Pumpkin spice cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/grown/pumpkin = 2 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/pumpkinspice + result = /obj/item/food/cake/pumpkinspice subcategory = CAT_CAKE /datum/crafting_recipe/food/holycake name = "Angel food cake" reqs = list( /datum/reagent/water/holywater = 15, - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1 + /obj/item/food/cake/plain = 1 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/holy_cake + result = /obj/item/food/cake/holy_cake subcategory = CAT_CAKE /datum/crafting_recipe/food/poundcake name = "Pound cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 4 + /obj/item/food/cake/plain = 4 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/pound_cake + result = /obj/item/food/cake/pound_cake subcategory = CAT_CAKE /datum/crafting_recipe/food/hardwarecake name = "Hardware cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/circuitboard = 2, /datum/reagent/toxin/acid = 5 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/hardware_cake + result = /obj/item/food/cake/hardware_cake subcategory = CAT_CAKE /datum/crafting_recipe/food/bscccake name = "blackberry and strawberry chocolate cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/chocolatebar = 2, /obj/item/reagent_containers/food/snacks/grown/berries = 5 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/bscc + result = /obj/item/food/cake/bscc subcategory = CAT_CAKE /datum/crafting_recipe/food/bscvcake name = "blackberry and strawberry vanilla cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/grown/berries = 5 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/bsvc + result = /obj/item/food/cake/bsvc subcategory = CAT_CAKE /datum/crafting_recipe/food/clowncake name = "clown cake" always_available = FALSE reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/sundae = 2, /obj/item/reagent_containers/food/snacks/grown/banana = 5 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/clown_cake + result = /obj/item/food/cake/clown_cake subcategory = CAT_CAKE /datum/crafting_recipe/food/vanillacake name = "vanilla cake" always_available = FALSE reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/grown/vanillapod = 2 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/vanilla_cake + result = /obj/item/food/cake/vanilla_cake subcategory = CAT_CAKE /datum/crafting_recipe/food/trumpetcake name = "Spaceman's Cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /obj/item/reagent_containers/food/snacks/grown/trumpet = 2, /datum/reagent/consumable/cream = 5, /datum/reagent/consumable/berryjuice = 5 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/trumpet + result = /obj/item/food/cake/trumpet subcategory = CAT_CAKE @@ -198,7 +198,7 @@ reqs = list( /obj/item/organ/brain = 1, /obj/item/organ/heart = 1, - /obj/item/reagent_containers/food/snacks/store/cake/birthday = 1, + /obj/item/food/cake/birthday = 1, /obj/item/reagent_containers/food/snacks/meat/slab = 3, /datum/reagent/blood = 30, /datum/reagent/consumable/sprinkles = 5, diff --git a/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm index d1148986ec4..2167d8e2294 100644 --- a/code/modules/holiday/easter.dm +++ b/code/modules/holiday/easter.dm @@ -180,28 +180,13 @@ result = /obj/item/reagent_containers/food/snacks/hotcrossbun subcategory = CAT_MISCFOOD - -/obj/item/reagent_containers/food/snacks/store/cake/brioche - name = "brioche cake" - desc = "A ring of sweet, glazed buns." - icon_state = "briochecake" - slice_path = /obj/item/reagent_containers/food/snacks/cakeslice/brioche - slices_num = 6 - bonus_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/consumable/nutriment/vitamin = 2) - -/obj/item/reagent_containers/food/snacks/cakeslice/brioche - name = "brioche cake slice" - desc = "Delicious sweet-bread. Who needs anything else?" - icon_state = "briochecake_slice" - filling_color = "#FFD700" - /datum/crafting_recipe/food/briochecake name = "Brioche cake" reqs = list( - /obj/item/reagent_containers/food/snacks/store/cake/plain = 1, + /obj/item/food/cake/plain = 1, /datum/reagent/consumable/sugar = 2 ) - result = /obj/item/reagent_containers/food/snacks/store/cake/brioche + result = /obj/item/food/cake/brioche subcategory = CAT_MISCFOOD /obj/item/reagent_containers/food/snacks/scotchegg diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm index 5dba56e15b6..5a20bd34d76 100644 --- a/code/modules/mapping/mapping_helpers.dm +++ b/code/modules/mapping/mapping_helpers.dm @@ -275,7 +275,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava) //cake + knife to cut it! var/turf/food_turf = get_turf(pick(table)) new /obj/item/kitchen/knife(food_turf) - var/obj/item/reagent_containers/food/snacks/store/cake/birthday/iancake = new(food_turf) + var/obj/item/food/cake/birthday/iancake = new(food_turf) iancake.desc = "Happy birthday, Ian!" //some balloons! this picks an open turf and pops a few balloons in and around that turf, yay. for(var/i in 1 to balloon_clusters) diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index b9cad100f66..d0ae301b4cf 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -258,7 +258,7 @@ maxHealth = 50 gender = FEMALE harm_intent_damage = 10 - butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/reagent_containers/food/snacks/cakeslice/birthday = 3, \ + butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/food/cakeslice/birthday = 3, \ /obj/item/reagent_containers/food/snacks/meat/slab = 2) response_harm_continuous = "takes a bite out of" response_harm_simple = "take a bite out of" diff --git a/code/modules/research/xenobiology/crossbreeding/charged.dm b/code/modules/research/xenobiology/crossbreeding/charged.dm index 6b699521588..858fa6a8d3e 100644 --- a/code/modules/research/xenobiology/crossbreeding/charged.dm +++ b/code/modules/research/xenobiology/crossbreeding/charged.dm @@ -107,7 +107,7 @@ Charged extracts: effect_desc = "Creates a slime cake and some drinks." /obj/item/slimecross/charged/silver/do_effect(mob/user) - new /obj/item/reagent_containers/food/snacks/store/cake/slimecake(get_turf(user)) + new /obj/item/food/cake/slimecake(get_turf(user)) for(var/i in 1 to 10) var/drink_type = get_random_drink() new drink_type(get_turf(user)) diff --git a/tgstation.dme b/tgstation.dme index 8f44e450acd..5174fc621f7 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -164,6 +164,8 @@ #include "code\__HELPERS\sanitize_values.dm" #include "code\__HELPERS\shell.dm" #include "code\__HELPERS\stat_tracking.dm" +#include "code\__HELPERS\string_assoc_lists.dm" +#include "code\__HELPERS\string_lists.dm" #include "code\__HELPERS\text.dm" #include "code\__HELPERS\time.dm" #include "code\__HELPERS\type2type.dm" @@ -1082,6 +1084,7 @@ #include "code\game\objects\items\food\_food.dm" #include "code\game\objects\items\food\bread.dm" #include "code\game\objects\items\food\burgers.dm" +#include "code\game\objects\items\food\cake.dm" #include "code\game\objects\items\grenades\antigravity.dm" #include "code\game\objects\items\grenades\chem_grenade.dm" #include "code\game\objects\items\grenades\clusterbuster.dm" @@ -1927,7 +1930,6 @@ #include "code\modules\food_and_drinks\food\condiment.dm" #include "code\modules\food_and_drinks\food\customizables.dm" #include "code\modules\food_and_drinks\food\snacks.dm" -#include "code\modules\food_and_drinks\food\snacks_cake.dm" #include "code\modules\food_and_drinks\food\snacks_egg.dm" #include "code\modules\food_and_drinks\food\snacks_frozen.dm" #include "code\modules\food_and_drinks\food\snacks_meat.dm" From 3d13c9ec1f52781afceeef048c04137e7aba875a Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Mon, 7 Sep 2020 11:04:19 -0700 Subject: [PATCH 17/32] Automatic changelog generation for PR #53316 [ci skip] --- html/changelogs/AutoChangeLog-pr-53316.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-53316.yml diff --git a/html/changelogs/AutoChangeLog-pr-53316.yml b/html/changelogs/AutoChangeLog-pr-53316.yml new file mode 100644 index 00000000000..2e25a76ba5a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-53316.yml @@ -0,0 +1,6 @@ +author: "floyd" +delete-after: True +changes: + - code_imp: "moved cakes to newfood code" + - balance: "i fucked up some food lists because i misunderstood them, thats now fixed." + - code_imp: "edible component now properly handles transfering reagents on processing, microwaving and crafting" From 53df2b2fe64168032779cc9d2c3024de2de0d3f0 Mon Sep 17 00:00:00 2001 From: Shirbu Date: Mon, 7 Sep 2020 12:48:32 -0700 Subject: [PATCH 18/32] Reduces the light range of all beam (lasers, disablers, emitter shots) projectiles (#53328) --- code/modules/projectiles/projectile/beams.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 2629569f32b..1a2445187b5 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -10,7 +10,7 @@ eyeblur = 2 impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser light_system = MOVABLE_LIGHT - light_range = 2 + light_range = 1 light_power = 1 light_color = COLOR_SOFT_RED ricochets_max = 50 //Honk! From 1770a1af762fa335690083143244b2ac38fb9f22 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Mon, 7 Sep 2020 12:48:35 -0700 Subject: [PATCH 19/32] Automatic changelog generation for PR #53328 [ci skip] --- html/changelogs/AutoChangeLog-pr-53328.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-53328.yml diff --git a/html/changelogs/AutoChangeLog-pr-53328.yml b/html/changelogs/AutoChangeLog-pr-53328.yml new file mode 100644 index 00000000000..926371f684f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-53328.yml @@ -0,0 +1,5 @@ +author: "Shirbu" +delete-after: True +changes: + - balance: "nightmares can now dodge beam projectiles on dark tiles" + - tweak: "lasers', emitters', and disablers' projectiles, now emit light only on their own tile, instead of a 3x3 square" From 5543c6db4608e9a1f28cf0b030471e423fba936e Mon Sep 17 00:00:00 2001 From: Ghilker <42839747+Ghilker@users.noreply.github.com> Date: Mon, 7 Sep 2020 21:52:10 +0200 Subject: [PATCH 20/32] crystal invasion balancing and fixes (Now with extra rework!) (#53399) Refractored code so that the more_portals() proc gets called by the event instead of a CALLBACK Balanced mobs spawn from portal and how much damage they deal Fixed grammar stuff on crystal consume announcement Ligthing aoe projectile now have a no_stun version for the boss rank Lowered time needed to use the crystal stabilizer to 7 second total Crystal mobs have TRAIT_TESLA_SHOCKIMMUNE to prevent boss from hurting himself and the other crystal mobs Added check at start of event for presence of the supermatter crystal New: Revamped event a bit, now instead of random portal appearing a random, there will be from 2 to 5 main portals and around those 6 more portals will appear; after that centcomm will announce the position of those new portals. Now the players will have to close those main portals before being able to stabilize the crystal because there will be a shield around it powered by those portals. Everything else will be the same (like how to close the portals and stabilize the crystal) --- code/modules/events/crystal_event.dm | 308 +++++++++++++------ code/modules/projectiles/projectile/magic.dm | 5 + icons/obj/supermatter.dmi | Bin 26587 -> 35902 bytes 3 files changed, 225 insertions(+), 88 deletions(-) diff --git a/code/modules/events/crystal_event.dm b/code/modules/events/crystal_event.dm index 999a4d5637a..6cbd4262304 100644 --- a/code/modules/events/crystal_event.dm +++ b/code/modules/events/crystal_event.dm @@ -1,3 +1,4 @@ +///Global list that stores the 4 kinds of waves the crystal invasion can have and the portals each one can spawn GLOBAL_LIST_INIT(crystal_invasion_waves, list( "small wave" = list( /obj/structure/crystal_portal/small=4, @@ -11,17 +12,18 @@ GLOBAL_LIST_INIT(crystal_invasion_waves, list( "big wave" = list( /obj/structure/crystal_portal/small=5, /obj/structure/crystal_portal/medium=3, - /obj/structure/crystal_portal/big=2, - /obj/structure/crystal_portal/huge=1 + /obj/structure/crystal_portal/big=2 ), "huge wave" = list( /obj/structure/crystal_portal/small=7, /obj/structure/crystal_portal/medium=5, - /obj/structure/crystal_portal/big=3, - /obj/structure/crystal_portal/huge=2 + /obj/structure/crystal_portal/big=3 ), )) +///Global list that stores the all the instantiated portals around the station, used when stabilizing the crystal GLOBAL_LIST_EMPTY(crystal_portals) +///Global list that store the huge portals that spawn at the start of the event +GLOBAL_LIST_EMPTY(huge_crystal_portals) /* This section is for the event controller @@ -48,12 +50,120 @@ This section is for the event controller var/obj/machinery/destabilized_crystal/dest_crystal ///Check if the event will end badly var/is_zk_scenario = TRUE + ///Ticks that have to pass before second wave + var/second_wave = 310 + ///Store the areas where the huge portals appears + var/list/center_areas = list() /datum/round_event/crystal_invasion/start() + destabilize_supermatter_crystal() choose_wave_type() + addtimer(CALLBACK(src, .proc/create_random_portals), 2 SECONDS) + +///Destabilize the Supermatter crystal and spawn 6 portals around it +/datum/round_event/crystal_invasion/proc/destabilize_supermatter_crystal() + var/list/sm_crystal = list() + for(var/obj/machinery/power/supermatter_crystal/temp in GLOB.machines) + if(istype(temp, /obj/machinery/power/supermatter_crystal/shard)) + continue + sm_crystal += temp + if(!length(sm_crystal)) + log_game("No engine found, killing the crystal invasion event.") + kill() + return + + var/obj/machinery/power/supermatter_crystal/crystal = pick(sm_crystal) + dest_crystal = crystal.destabilize(portal_numbers) + RegisterSignal(dest_crystal, COMSIG_PARENT_QDELETING, .proc/on_dest_crystal_qdel) + + for(var/t in RANGE_TURFS(8, dest_crystal.loc)) + var/turf/turf_loc = t + var/distance_from_center = get_dist(turf_loc, dest_crystal.loc) + switch(distance_from_center) + if(0) + distance_from_center = 1 //Same tile, let's avoid a division by zero. + if(-1) + kill() + CRASH("Negative distance measurement from the center turf detected, this should never happen") + if(prob(325 / distance_from_center)) + if(isopenturf(turf_loc) || isspaceturf(turf_loc)) + turf_loc.ChangeTurf(/turf/open/indestructible/crystal_floor, flags = CHANGETURF_INHERIT_AIR) + else + turf_loc.ChangeTurf(/turf/closed/indestructible/crystal_wall) + + var/list/crystal_spawner_turfs = list() + for(var/range_turf in RANGE_TURFS(6, dest_crystal.loc)) + if(!isopenturf(range_turf) || isspaceturf(range_turf)) + continue + crystal_spawner_turfs += range_turf + + for(var/i in 1 to 6) + var/pick_portal = pickweight(GLOB.crystal_invasion_waves["big wave"]) + var/turf/portal_spawner_turf = pick(crystal_spawner_turfs) + new pick_portal(portal_spawner_turf) + +///Chooses random areas where to put the main huge portals and then spawn around them 6 more portals +/datum/round_event/crystal_invasion/proc/create_random_portals() + var/list/center_finder = list() + for(var/es in GLOB.generic_event_spawns) + var/obj/effect/landmark/event_spawn/temp = es + if(is_station_level(temp.z)) + center_finder += temp + if(!center_finder.len) + kill() + CRASH("No landmarks on the station map, aborting") + for(var/j in 1 to portal_numbers) + if(!length(center_finder)) + kill() + CRASH("center_finder had less entries than portal_numbers ([j]/[portal_numbers])") + var/obj/center = pick_n_take(center_finder) + var/turf/center_turf = center.loc + var/area/center_area = get_area(center_turf) + center_areas += center_area + + explosion(center_turf,0,0,5,7,7) + + new /obj/structure/crystal_portal/huge(center_turf) + + for(var/t in RANGE_TURFS(5, center_turf)) + var/turf/turf_loc = t + var/distance_from_center = get_dist(turf_loc, center_turf) + switch(distance_from_center) + if(0) + distance_from_center = 1 //Same tile, let's avoid a division by zero. + if(-1) + kill() + CRASH("Negative distance error here") + if(prob(250 / distance_from_center)) + if(isopenturf(turf_loc) || isspaceturf(turf_loc)) + turf_loc.ChangeTurf(/turf/open/indestructible/crystal_floor, flags = CHANGETURF_INHERIT_AIR) + else + turf_loc.ChangeTurf(/turf/closed/indestructible/crystal_wall) + + var/list/portal_spawner_turfs = list() + for(var/range_turf in RANGE_TURFS(6, center_turf)) + if(!isopenturf(range_turf) || isspaceturf(range_turf)) + continue + portal_spawner_turfs += range_turf + + for(var/i in 1 to 6) + if(!length(portal_spawner_turfs)) + break + var/pick_portal = pickweight(GLOB.crystal_invasion_waves[wave_name]) + var/turf/portal_spawner_turf = pick_n_take(portal_spawner_turfs) + new pick_portal(portal_spawner_turf) + dest_crystal.icon_state = "psy_shielded" + dest_crystal.changed_icon = FALSE + addtimer(CALLBACK(src, .proc/announce_locations), 8 SECONDS) + +///After 8 seconds from the initial explosions centcom will announce the location of the huge portals +/datum/round_event/crystal_invasion/proc/announce_locations() + priority_announce("WARNING - After tracking the powerspikes from your station we have determined that huge portals have appeared at the following locations:[center_areas.Join(", ")]. \ + Please close those before attempting to stabilize the crystal.", "Alert") + sound_to_playing_players('sound/misc/notice1.ogg') /datum/round_event/crystal_invasion/announce(fake) - priority_announce("WARNING - Destabilization of the Supermatter Crystal Matrix detected, please stand by waiting further instructions", "Alert") + priority_announce("WARNING - Destabilization of the Supermatter Crystal Matrix detected, please stand by and await further instructions.", "Alert") sound_to_playing_players('sound/misc/notice1.ogg') ///Choose the type of the wave @@ -66,70 +176,22 @@ This section is for the event controller "huge wave" = 5)) switch(wave_name) if("small wave") - portal_numbers = rand(9, 11) + portal_numbers = 2 if("medium wave") - portal_numbers = rand(8, 12) + portal_numbers = rand(2, 3) if("big wave") - portal_numbers = rand(9, 13) + portal_numbers = rand(3, 4) if("huge wave") - portal_numbers = rand(11, 15) + portal_numbers = rand(4, 5) else kill() CRASH("Wave name of [wave_name] not recognised.") - var/list/sm_crystal = list() - for(var/obj/machinery/power/supermatter_crystal/temp in GLOB.machines) - if(istype(temp, /obj/machinery/power/supermatter_crystal/shard)) - continue - sm_crystal += temp - if(sm_crystal == null) - log_game("No engine found, killing the crystal invasion event.") - kill() - return - var/obj/machinery/power/supermatter_crystal/crystal = pick(sm_crystal) - dest_crystal = crystal.destabilize(portal_numbers) - RegisterSignal(dest_crystal, COMSIG_PARENT_QDELETING, .proc/on_dest_crystal_qdel) - priority_announce("WARNING - Numerous energy fluctuations have been detected from your Supermatter; we estimate a [wave_name] of crystalline creatures \ - coming from \[REDACTED]; there will be [portal_numbers] portals spread around the station that you must close. Harvest a \[REDACTED] \ - anomaly from a portal by using the anomaly neutralizer, place it inside a crystal stabilizer, and inject it into your Supermatter to stop a ZK-Lambda-Class Cosmic Fragmentation Scenario from occurring.", "Alert") + coming from \[REDACTED]; there will be [portal_numbers] main portals spread around the station that you must close. Harvest a \[REDACTED] \ + crystal from a portal by using the anomaly neutralizer, place it inside a crystal stabilizer, and inject it into your Supermatter to stop a ZK-Lambda-Class Cosmic Fragmentation Scenario from occurring.", "Alert") sound_to_playing_players('sound/misc/notice1.ogg') - addtimer(CALLBACK(src, .proc/spawn_portals), 3 SECONDS) - -///Pick a location from the generic_event_spawns list that are present on the maps and call the spawn anomaly and portal procs -/datum/round_event/crystal_invasion/proc/spawn_portals() - var/list/spawners = list() - for(var/es in GLOB.generic_event_spawns) - var/obj/effect/landmark/event_spawn/temp = es - if(is_station_level(temp.z)) - spawners += temp - for(var/i in 1 to portal_numbers) - spawn_portal(GLOB.crystal_invasion_waves[wave_name], spawners) - for(var/i in 1 to 6) - spawn_anomaly(spawners) - - var/list/crystal_spawner_turfs = list() - for(var/range_turf in RANGE_TURFS(6, dest_crystal.loc)) - if(!isopenturf(range_turf) || isspaceturf(range_turf)) - continue - crystal_spawner_turfs += range_turf - for(var/i in 1 to 6) - if(!length(crystal_spawner_turfs)) - break - var/pick_portal = pickweight(GLOB.crystal_invasion_waves["big wave"]) - var/turf/crystal_spawner_turf = pick_n_take(crystal_spawner_turfs) - new pick_portal(crystal_spawner_turf) - - addtimer(CALLBACK(src, .proc/more_portals, GLOB.crystal_invasion_waves[wave_name]), 10 MINUTES) - -///Spawn an anomaly randomly in a different location than spawn_portal() -/datum/round_event/crystal_invasion/proc/spawn_anomaly(list/spawners) - if(!spawners.len) - CRASH("No landmarks on the station map, aborting") - var/obj/spawner = pick(spawners) - new/obj/effect/anomaly/flux(spawner.loc, 30 SECONDS, FALSE, FALSE) - ///Spawn one portal in a random location choosen from the generic_event_spawns list /datum/round_event/crystal_invasion/proc/spawn_portal(list/wave_type, list/spawners) if(!spawners.len) @@ -149,9 +211,11 @@ This section is for the event controller if(is_station_level(temp.z)) spawners += temp for(var/i in 1 to rand(10, 15)) - spawn_portal(GLOB.crystal_invasion_waves["small wave"], spawners) + spawn_portal(GLOB.crystal_invasion_waves["medium wave"], spawners) /datum/round_event/crystal_invasion/tick() + if(activeFor == second_wave) + more_portals() if(dest_crystal.is_stabilized == TRUE) processing = FALSE is_zk_scenario = FALSE @@ -208,6 +272,49 @@ This section is for the event controller dest_crystal = null kill() +/turf/open/indestructible/crystal_floor + name = "Crystal floor" + desc = "A crystallized floor" + icon_state = "noslip-damaged1" + baseturfs = /turf/open/space + +/turf/open/indestructible/crystal_floor/examine(mob/user) + . += ..() + . += "The floor is made of sturdy crystals." + +/turf/open/indestructible/crystal_floor/welder_act(mob/living/user, obj/item/I) + . = ..() + if(!I.tool_start_check(user, amount=0)) + return FALSE + to_chat(user, "You begin heating up the crystal...") + if(I.use_tool(src, user, 2.5 SECONDS, volume=100)) + to_chat(user, "The crystal crumbles into dust.") + ScrapeAway(flags = CHANGETURF_INHERIT_AIR) + return TRUE + return FALSE + +/turf/closed/indestructible/crystal_wall + name = "Crystal wall" + desc = "A crystallized wall" + icon = 'icons/turf/mining.dmi' + icon_state = "rock_highchance" + baseturfs = /turf/open/space + +/turf/closed/indestructible/crystal_wall/examine(mob/user) + . += ..() + . += "The wall is made of sturdy crystals." + +/turf/open/indestructible/crystal_floor/welder_act(mob/living/user, obj/item/I) + . = ..() + if(!I.tool_start_check(user, amount=0)) + return FALSE + to_chat(user, "You begin heating up the crystal...") + if(I.use_tool(src, user, 2.5 SECONDS, volume=100)) + to_chat(user, "The crystal crumbles into dust.") + ScrapeAway(flags = CHANGETURF_INHERIT_AIR) + return TRUE + return FALSE + /* This section is for the destabilized SM */ @@ -228,6 +335,8 @@ This section is for the destabilized SM ///Our sound loop var/datum/looping_sound/destabilized_crystal/soundloop + var/changed_icon = TRUE + /obj/machinery/destabilized_crystal/Initialize() . = ..() soundloop = new(list(src), TRUE) @@ -245,12 +354,18 @@ This section is for the destabilized SM playsound(loc, 'sound/weapons/emitter2.ogg', 100, TRUE, extrarange = 10) if(prob(15)) fire_nuclear_particle() + if(length(GLOB.huge_crystal_portals) == 0 && !changed_icon) + icon_state = "psy" + changed_icon = TRUE + var/turf/loc_turf = loc var/datum/gas_mixture/env = loc_turf.return_air() var/datum/gas_mixture/removed var/gasefficency = 0.5 removed = env.remove(gasefficency * env.total_moles()) removed.assert_gases(/datum/gas/bz, /datum/gas/miasma) + if(!removed || !removed.total_moles() || isspaceturf(loc_turf)) + removed.gases[/datum/gas/bz][MOLES] += 0.5 removed.gases[/datum/gas/bz][MOLES] += 15.5 removed.gases[/datum/gas/miasma][MOLES] += 5.5 env.merge(removed) @@ -260,21 +375,24 @@ This section is for the destabilized SM if(!istype(user)) return if(istype(W, /obj/item/crystal_stabilizer)) + if(length(GLOB.huge_crystal_portals) > 0) + to_chat(user, "The shield protecting the crystal is still up! Close all the main portals before attempting this again!") + return var/obj/item/crystal_stabilizer/injector = W if(!injector.filled) to_chat(user, "\The [W] is empty!") return - to_chat(user, "You carefully begin injecting \the [src] with \the [W]... take care not to move untill all the steps are finished!") - if(!W.use_tool(src, user, 5 SECONDS, volume = 100)) + to_chat(user, "You carefully begin injecting \the [src] with \the [W]... take care not to move until all the steps are finished!") + if(!W.use_tool(src, user, 1 SECONDS, volume = 100)) return to_chat(user, "Seems that \the [src] internal resonance is fading with the fluid!") playsound(get_turf(src), 'sound/effects/supermatter.ogg', 35, TRUE) - if(!W.use_tool(src, user, 6.5 SECONDS, volume = 100)) + if(!W.use_tool(src, user, 1.5 SECONDS, volume = 100)) return to_chat(user, "The [src] is reacting violently with the fluid!") fire_nuclear_particle() - radiation_pulse(src, 2500, 6) - if(!W.use_tool(src, user, 7.5 SECONDS, volume = 100)) + radiation_pulse(src, 1000, 6) + if(!W.use_tool(src, user, 2 SECONDS, volume = 100)) return to_chat(user, "The [src] has been restored and restabilized!") playsound(get_turf(src), 'sound/effects/supermatter.ogg', 35, TRUE) @@ -285,6 +403,10 @@ This section is for the destabilized SM /obj/machinery/destabilized_crystal/examine(mob/user) . = ..() . += "The Crystal appears to be heavily destabilized. Maybe it can be fixed by injecting it with something from another world." + if(length(GLOB.huge_crystal_portals) > 0) + . += "The Destabilized Crystal appears to be protected by some kind of shield." + else + . += "The shield that was protecting the Crystal is gone, it's time to restore it." /obj/machinery/destabilized_crystal/Bumped(atom/movable/movable_atom) if(!isliving(movable_atom)) @@ -309,7 +431,7 @@ This section is for the destabilized SM for(var/find_portal in GLOB.crystal_portals) var/obj/structure/crystal_portal/portal = find_portal portal.modify_component() - priority_announce("The sacrifice of a member of the station (we hope was the clown) has weakened the portals and the monsters generation is slowing down!") + priority_announce("The sacrifice of a crewmember (hopefully the clown) appears to have weakened the portals and slowed down the number of monsters coming through!") sound_to_playing_players('sound/misc/notice2.ogg') /* @@ -461,7 +583,7 @@ This section is for the crystal portals variations name = "Small Portal" desc = "A small portal to an unkown dimension!" color = COLOR_BRIGHT_BLUE - max_mobs = 3 + max_mobs = 2 spawn_time = 5 SECONDS mob_types = list( /mob/living/simple_animal/hostile/crystal_monster/minion, @@ -472,8 +594,8 @@ This section is for the crystal portals variations name = "Medium Portal" desc = "A medium portal to an unkown dimension!" color = COLOR_GREEN - max_mobs = 4 - spawn_time = 10 SECONDS + max_mobs = 3 + spawn_time = 15 SECONDS mob_types = list( /mob/living/simple_animal/hostile/crystal_monster/minion, /mob/living/simple_animal/hostile/crystal_monster/thug, @@ -484,8 +606,8 @@ This section is for the crystal portals variations name = "Big Portal" desc = "A big portal to an unkown dimension!" color = COLOR_RED - max_mobs = 5 - spawn_time = 10 SECONDS + max_mobs = 4 + spawn_time = 15 SECONDS mob_types = list( /mob/living/simple_animal/hostile/crystal_monster/minion, /mob/living/simple_animal/hostile/crystal_monster/thug, @@ -497,16 +619,22 @@ This section is for the crystal portals variations name = "Huge Portal" desc = "A huge portal to an unkown dimension!" color = COLOR_BLACK - max_mobs = 6 - spawn_time = 15 SECONDS + max_mobs = 5 + spawn_time = 20 SECONDS mob_types = list( - /mob/living/simple_animal/hostile/crystal_monster/minion, - /mob/living/simple_animal/hostile/crystal_monster/thug, /mob/living/simple_animal/hostile/crystal_monster/recruit, /mob/living/simple_animal/hostile/crystal_monster/killer, /mob/living/simple_animal/hostile/crystal_monster/boss, ) +/obj/structure/crystal_portal/huge/Initialize() + . = ..() + GLOB.huge_crystal_portals += src + +/obj/structure/crystal_portal/huge/Destroy() + GLOB.huge_crystal_portals -= src + return ..() + /* This section is for the crystal monsters variations */ @@ -543,6 +671,10 @@ This section is for the crystal monsters variations stop_automated_movement_when_pulled = FALSE wander = TRUE +/mob/living/simple_animal/hostile/crystal_monster/Initialize() + . = ..() + ADD_TRAIT(src, TRAIT_TESLA_SHOCKIMMUNE, INNATE_TRAIT) + /mob/living/simple_animal/hostile/crystal_monster/minion name = "crystal minion" desc = "A monster made of crystals similar to the Supermatter ones." @@ -553,9 +685,9 @@ This section is for the crystal monsters variations maxHealth = 20 health = 20 speed = 0.8 - harm_intent_damage = 11 - melee_damage_lower = 20 - melee_damage_upper = 35 + harm_intent_damage = 7 + melee_damage_lower = 10 + melee_damage_upper = 15 move_force = MOVE_FORCE_WEAK move_resist = MOVE_FORCE_WEAK pull_force = MOVE_FORCE_WEAK @@ -582,8 +714,8 @@ This section is for the crystal monsters variations health = 20 speed = 0.9 harm_intent_damage = 11 - melee_damage_lower = 20 - melee_damage_upper = 35 + melee_damage_lower = 10 + melee_damage_upper = 15 move_force = MOVE_FORCE_NORMAL move_resist = MOVE_FORCE_NORMAL pull_force = MOVE_FORCE_NORMAL @@ -614,8 +746,8 @@ This section is for the crystal monsters variations health = 20 speed = 1.2 harm_intent_damage = 11 - melee_damage_lower = 20 - melee_damage_upper = 35 + melee_damage_lower = 15 + melee_damage_upper = 20 move_force = MOVE_FORCE_STRONG move_resist = MOVE_FORCE_STRONG pull_force = MOVE_FORCE_STRONG @@ -639,9 +771,9 @@ This section is for the crystal monsters variations maxHealth = 35 health = 35 speed = 0.75 - harm_intent_damage = 20 - melee_damage_lower = 25 - melee_damage_upper = 45 + harm_intent_damage = 15 + melee_damage_lower = 30 + melee_damage_upper = 35 move_force = MOVE_FORCE_VERY_STRONG move_resist = MOVE_FORCE_VERY_STRONG pull_force = MOVE_FORCE_VERY_STRONG @@ -652,7 +784,7 @@ This section is for the crystal monsters variations projectilesound = 'sound/weapons/pierce.ogg' ranged = 1 ranged_message = "throws" - ranged_cooldown_time = 25 + ranged_cooldown_time = 3.5 SECONDS /obj/projectile/temp/crystal_killer name = "freezing blast" @@ -688,11 +820,11 @@ This section is for the crystal monsters variations move_resist = MOVE_FORCE_EXTREMELY_STRONG pull_force = MOVE_FORCE_EXTREMELY_STRONG environment_smash = ENVIRONMENT_SMASH_RWALLS - projectiletype = /obj/projectile/magic/aoe/lightning + projectiletype = /obj/projectile/magic/aoe/lightning/no_zap projectilesound = 'sound/weapons/pierce.ogg' ranged = 1 ranged_message = "throws" - ranged_cooldown_time = 45 + ranged_cooldown_time = 5.5 SECONDS /mob/living/simple_animal/hostile/crystal_monster/boss/Bump(atom/clong) . = ..() diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index c93d94c2f48..e6ac1f33b91 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -651,6 +651,11 @@ tesla_zap(src, zap_range, zap_power, zap_flags) qdel(src) +/obj/projectile/magic/aoe/lightning/no_zap + zap_power = 10000 + zap_range = 4 + zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE + /obj/projectile/magic/aoe/lightning/Destroy() qdel(chain) . = ..() diff --git a/icons/obj/supermatter.dmi b/icons/obj/supermatter.dmi index 6d4429a9d9fd739154469c5ddec4ed7a2c57db88..4fd64bb4fc025e4f9f670a394e0be01dcc453b0f 100644 GIT binary patch literal 35902 zcmV)(K#RYLP)V=-0C=2@k+Dw0Fc5}k`zcQCdO|q3q8+?csj3X^D?|ogYYVrDe1<4IJp)4` zearpjUkWiB~V=0Zd1@qh@QtkkLr1B z*$0Y_797u$L*Xnx8ULw}vwaCMd@j9T$u%6#HPoj@egSWTtk_0~Z3_SZAOJ~3K~#90 z%-nf&T-SXk`0wv-Z>f5<7pkxj1h}svC6Uy=nvvwlaS|uC)zTe$%6^)OI0R5v@1KoIBD)k=c^ZfdAQSOb`f6%eM24;}(Jhp%Q zU%CD0BO+K@0^fLjZtji8Z$4@@P^kpEVMaMnCIbqBo*M)p1H8TtUR@6~9*Zvy6Rs)qwpu&dq2LY&%hq&S1Ftz&2_aI4o*N`OOwRIxj<}d_0o!&+GJ~#+K?e_O3sMP{@I_xf;m(`b^%sx^mu6{Jk!U_Ur zXNfnB0+%lRbX9x$forYXo6kmr5xIg%8dCIA3hTVsCl zJ96OVr!o%@4y}DuX{7lz=Fu@=X%YO~bM$%;S^(qYpi&89aFAUg56TxHiv_Uf14=?f zIUw*MlmaCw1OQ~hH*D*A*J4v}nu3>?nV&x<2c9{ed8kxg``D%tq}Q**t*kO-%X6wkddNnfcjca^Ne+GY^%^YabgOK{|IG zZgrJ8>iZYpc8+_j2nR}V;`5t?%bI_|I;K$-JGzTuaPJT8`@)Bx z|BIu?@42gc;>I+`hdmZutK{h(AH{jl%ag;lKYS_Fp=v-#PxyKmMiq#M?jh zSNU>eScF2r)dv~n3MiikRVokw=`es00y;q!56VK%+sh7SwD&3=Wc4sW6u-KrRO= zmmx|eNatXTffNF&ScC{Otb7mB^C9CdDdVy9dlu=G4g zW1x(NOf8Jkkbw`S6r|RWQbH&NF*F4H(VxhXAO6uh-y>--v$XQnQ+M5-OiWFaRI=BN zv}vy;4?~j5z?942(Y~L{LF6LHd2KeidD4}gj#h*A+UpM&gldxj9Cb2&((p^Sm@40JzlwD0wv*BkPnUIYH{ zV{+u)NALVeL-owH<*%JOdRuaSZjK}aP_j3aXth8=NHS@Yekjn!;&e)0IL@wsdbGKx0V*^H}K3H3n| zTei7wJ`bwbA%Xyu%R%@)RILW~Jc#LOcv8Xney`>i5@KZ;UKGIwLCLh++vM%0dJIgj7(2btcb) zoS7wG2)H1G5CkCv#OfNEFl6U>8+-;k2Ny*U@B78ld$b&@rFLRz`bvCZaS^7F2Rs8> zZ}k4B(*-x05SusuWnU?%df%U&C0}mvNkFW<$;X@gAN|GBdyE{b#dcz8uJ7OI#^3Pc zE_l5Ov40=O)iOjb51Gk8L|I4@P`kFXkQ(CpbqcfudwwtNf*@Ac$@`x41I!HP99$-Y z#wYHsDYFvviEiS=C*^AXph^{@ScLR^h>;N>n}rBNNFpeuAxDN8*(^x+ zTOF+-w1KErfKPl}*6%oS-=i)*v+UA~*9Nyuf9}fVUh5;o8!eDlK)VgMeLF|IAT3;Nmbs_&D4DffLPq1BuG$Da_j@f~+P)U{`qQ@${FWY^4>=K8+;K7OePQ7-oi zU!edMhODv~NaI2I9(3Q*TEPJDgn(BpLVDioX@5Nr!VvVtQ=&Gs^{%&d+?mxbU!1#l z=ggPq=OKjxDMjQQSO~ybu-0�&ivf4fa|-`Pcb7{&)YD_50I>zsleGSa{%%ABbn~ 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 KN!??si2niWUC__~ From 1c3af6762c75c3780cf87702c9411f4cee995182 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Mon, 7 Sep 2020 12:52:14 -0700 Subject: [PATCH 21/32] Automatic changelog generation for PR #53399 [ci skip] --- html/changelogs/AutoChangeLog-pr-53399.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-53399.yml diff --git a/html/changelogs/AutoChangeLog-pr-53399.yml b/html/changelogs/AutoChangeLog-pr-53399.yml new file mode 100644 index 00000000000..f611d447d5d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-53399.yml @@ -0,0 +1,11 @@ +author: "Ghilker" +delete-after: True +changes: + - rscadd: "Ligthing aoe projectile now have a no_stun version for the boss rank" + - rscadd: "Crystal mobs have TRAIT_TESLA_SHOCKIMMUNE to prevent boss from hurting himself and the other crystal mobs" + - rscadd: "Revamped mode, announced main portals with location, close them to be able to stabilize the SM" + - balance: "Balanced mobs spawn from portal and how much damage they deal" + - bugfix: "Fixed grammar stuff on crystal consume announcement" + - tweak: "Lowered time needed to use the crystal stabilizer to 7 second total" + - refactor: "Refractored code so that the more_portals() proc gets called by the event instead of a CALLBACK" + - code_imp: "Added check at start of event for presence of the supermatter crystal" From d9aff3da6e3d771a635a3ac763ae5a8949a304c0 Mon Sep 17 00:00:00 2001 From: YPOQ <30683121+YPOQ@users.noreply.github.com> Date: Mon, 7 Sep 2020 14:24:10 -0600 Subject: [PATCH 22/32] Fixes the arena shuttle (#53458) This splits the actual arena of the arena shuttle into its own map file that is loaded onto it's own z-level. The old method of including a non-shuttle area in the shuttle map file doesn't work with the current shuttle loader. It also fixes shuttles being loaded twice when purchased which created problems with landmarks being left behind in the reserved z-level. --- _maps/shuttles/emergency_arena.dmm | 2353 --------------- _maps/templates/the_arena.dmm | 2622 +++++++++++++++++ code/datums/shuttles.dm | 13 + .../game/machinery/computer/communications.dm | 1 - code/modules/events/shuttle_catastrophe.dm | 1 - 5 files changed, 2635 insertions(+), 2355 deletions(-) create mode 100644 _maps/templates/the_arena.dmm diff --git a/_maps/shuttles/emergency_arena.dmm b/_maps/shuttles/emergency_arena.dmm index 1314b8a7325..14f0c918e46 100644 --- a/_maps/shuttles/emergency_arena.dmm +++ b/_maps/shuttles/emergency_arena.dmm @@ -1,21 +1,4 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/closed/indestructible/necropolis, -/area/shuttle_arena) -"b" = ( -/turf/open/indestructible/necropolis/air, -/area/shuttle_arena) -"c" = ( -/obj/effect/forcefield/arena_shuttle, -/turf/open/indestructible/necropolis/air, -/area/shuttle_arena) -"d" = ( -/turf/open/lava/smooth, -/area/shuttle_arena) -"e" = ( -/obj/effect/landmark/shuttle_arena_entrance, -/turf/open/indestructible/necropolis/air, -/area/shuttle_arena) "f" = ( /turf/template_noop, /area/template_noop) @@ -71,34 +54,6 @@ /area/shuttle/escape/arena) (1,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -f g g g @@ -123,34 +78,6 @@ g f "} (2,1,1) = {" -a -b -b -b -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -f g g g @@ -175,34 +102,6 @@ g g "} (3,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -f g h j @@ -227,34 +126,6 @@ p g "} (4,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -e -b -b -b -b -b -b -b -b -b -b -b -b -e -b -a -f g h k @@ -279,34 +150,6 @@ p g "} (5,1,1) = {" -a -b -e -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -b -b -b -b -b -b -b -b -a -f g i h @@ -331,34 +174,6 @@ p g "} (6,1,1) = {" -a -a -b -b -a -b -b -b -b -b -b -b -b -b -b -b -b -a -b -b -b -b -b -b -b -b -a -f g i i @@ -383,34 +198,6 @@ p g "} (7,1,1) = {" -a -b -b -b -b -b -b -b -b -a -b -d -d -d -b -b -b -a -a -b -b -e -b -b -b -b -a -f g i i @@ -435,34 +222,6 @@ p g "} (8,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -d -d -d -d -b -b -b -b -b -b -b -b -b -b -b -a -f g i h @@ -487,34 +246,6 @@ p g "} (9,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -b -b -b -b -b -b -b -b -b -b -a -f g h k @@ -539,34 +270,6 @@ p g "} (10,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -f g h j @@ -591,34 +294,6 @@ g g "} (11,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -f g g g @@ -642,2031 +317,3 @@ g g f "} -(12,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -f -f -f -f -f -f -f -f -f -f -f -f -f -f -f -f -f -f -f -f -f -f -f -"} -(13,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} -(14,1,1) = {" -a -b -b -b -b -b -a -b -b -b -e -b -b -a -b -b -b -b -b -b -b -b -b -b -d -d -d -b -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(15,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -a -b -b -b -b -b -b -b -b -b -b -d -d -b -b -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(16,1,1) = {" -a -b -e -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -b -b -a -b -b -b -b -b -b -b -b -e -b -b -b -b -b -b -b -b -b -b -b -a -"} -(17,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -e -b -b -b -b -b -d -d -b -b -b -b -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(18,1,1) = {" -a -a -a -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(19,1,1) = {" -a -a -a -a -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(20,1,1) = {" -a -a -a -a -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -b -b -a -a -b -b -b -a -"} -(21,1,1) = {" -a -c -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -b -b -b -b -a -b -b -b -a -b -b -b -a -"} -(22,1,1) = {" -a -c -b -b -b -b -b -b -b -b -d -d -b -b -b -b -b -b -b -d -d -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -b -b -b -b -b -a -b -b -b -a -b -b -b -a -"} -(23,1,1) = {" -a -c -b -b -b -b -b -b -b -b -d -d -d -b -b -b -b -b -b -d -d -b -b -b -b -b -b -b -e -b -b -b -b -b -d -b -b -b -b -b -b -a -b -e -b -a -b -b -b -a -"} -(24,1,1) = {" -a -c -b -b -b -b -b -b -b -b -b -b -d -d -b -b -b -b -b -d -d -b -b -b -b -b -b -b -b -b -b -b -b -b -d -b -b -b -b -b -b -a -b -b -b -a -b -b -b -a -"} -(25,1,1) = {" -a -a -a -a -a -b -b -b -b -b -b -b -b -d -b -b -b -b -b -d -d -b -b -b -b -b -b -b -b -b -b -b -b -b -d -b -b -b -b -b -b -a -a -a -a -a -b -b -b -a -"} -(26,1,1) = {" -a -a -a -a -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -b -b -b -b -b -b -b -b -b -b -b -b -e -a -"} -(27,1,1) = {" -a -a -a -a -b -b -b -b -e -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -a -b -b -b -b -b -b -d -d -d -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(28,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -a -b -b -b -b -b -b -d -d -d -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(29,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(30,1,1) = {" -a -b -b -b -b -b -b -b -a -b -b -b -b -b -b -b -b -b -b -a -a -a -a -a -a -a -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(31,1,1) = {" -a -b -b -b -b -b -b -b -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(32,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -e -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -e -b -b -b -b -b -b -b -b -b -a -"} -(33,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -e -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(34,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(35,1,1) = {" -a -b -b -e -b -b -b -b -b -b -b -b -a -a -a -a -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -a -a -a -a -a -a -a -b -b -b -b -b -b -a -"} -(36,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -a -a -a -a -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -b -b -b -b -b -b -b -b -a -"} -(37,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -b -b -a -b -b -b -b -b -b -b -b -a -"} -(38,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -b -e -a -b -b -b -b -b -b -b -b -a -"} -(39,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -e -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -a -a -a -b -b -b -b -b -b -b -b -a -"} -(40,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -b -b -b -b -b -b -b -b -a -"} -(41,1,1) = {" -a -b -b -b -a -a -a -a -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -b -b -b -b -b -a -b -b -b -b -b -b -b -e -a -"} -(42,1,1) = {" -a -b -b -b -b -b -b -b -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(43,1,1) = {" -a -b -b -b -b -b -b -b -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -"} -(44,1,1) = {" -a -b -b -b -b -b -b -b -a -b -b -b -b -b -b -b -e -b -b -b -b -b -b -b -b -b -a -a -a -a -d -d -d -d -d -b -b -b -b -b -b -b -b -b -b -b -a -b -b -a -"} -(45,1,1) = {" -a -b -b -b -b -e -b -b -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -a -e -b -b -d -d -d -d -d -b -b -b -b -b -b -b -b -b -b -b -a -b -b -a -"} -(46,1,1) = {" -a -b -b -b -b -b -b -b -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -d -d -d -b -b -b -b -b -b -b -b -a -b -b -a -"} -(47,1,1) = {" -a -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -b -b -b -b -b -e -b -b -b -b -b -a -"} -(48,1,1) = {" -a -d -d -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -b -b -b -b -b -b -b -b -b -a -"} -(49,1,1) = {" -a -d -d -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -b -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -d -b -b -b -b -b -b -b -b -b -a -"} -(50,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -"} diff --git a/_maps/templates/the_arena.dmm b/_maps/templates/the_arena.dmm new file mode 100644 index 00000000000..acf086c041f --- /dev/null +++ b/_maps/templates/the_arena.dmm @@ -0,0 +1,2622 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/closed/indestructible/necropolis, +/area/shuttle_arena) +"b" = ( +/turf/open/indestructible/necropolis/air, +/area/shuttle_arena) +"c" = ( +/obj/effect/forcefield/arena_shuttle, +/turf/open/indestructible/necropolis/air, +/area/shuttle_arena) +"d" = ( +/turf/open/lava/smooth, +/area/shuttle_arena) +"e" = ( +/obj/effect/landmark/shuttle_arena_entrance, +/turf/open/indestructible/necropolis/air, +/area/shuttle_arena) +"f" = ( +/turf/template_noop, +/area/template_noop) + +(1,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +"} +(2,1,1) = {" +a +b +b +b +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +"} +(3,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +"} +(4,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +b +b +b +b +b +e +b +a +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +"} +(5,1,1) = {" +a +b +e +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +b +b +b +b +b +b +b +b +a +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +"} +(6,1,1) = {" +a +a +b +b +a +b +b +b +b +b +b +b +b +b +b +b +b +a +b +b +b +b +b +b +b +b +a +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +"} +(7,1,1) = {" +a +b +b +b +b +b +b +b +b +a +b +d +d +d +b +b +b +a +a +b +b +e +b +b +b +b +a +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +"} +(8,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +d +d +d +d +b +b +b +b +b +b +b +b +b +b +b +a +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +"} +(9,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +d +d +d +d +d +b +b +b +b +b +b +b +b +b +b +a +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +"} +(10,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +"} +(11,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +"} +(12,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +f +"} +(13,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +d +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(14,1,1) = {" +a +b +b +b +b +b +a +b +b +b +e +b +b +a +b +b +b +b +b +b +b +b +b +b +d +d +d +b +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(15,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +a +b +b +b +b +b +b +b +b +b +b +d +d +b +b +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(16,1,1) = {" +a +b +e +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +d +d +d +d +b +b +a +b +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +b +b +b +b +a +"} +(17,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +e +b +b +b +b +b +d +d +b +b +b +b +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(18,1,1) = {" +a +a +a +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(19,1,1) = {" +a +a +a +a +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(20,1,1) = {" +a +a +a +a +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +b +b +a +a +b +b +b +a +"} +(21,1,1) = {" +a +c +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +d +d +b +b +b +b +a +b +b +b +a +b +b +b +a +"} +(22,1,1) = {" +a +c +b +b +b +b +b +b +b +b +d +d +b +b +b +b +b +b +b +d +d +b +b +b +b +b +b +b +b +b +b +b +b +b +d +d +b +b +b +b +b +a +b +b +b +a +b +b +b +a +"} +(23,1,1) = {" +a +c +b +b +b +b +b +b +b +b +d +d +d +b +b +b +b +b +b +d +d +b +b +b +b +b +b +b +e +b +b +b +b +b +d +b +b +b +b +b +b +a +b +e +b +a +b +b +b +a +"} +(24,1,1) = {" +a +c +b +b +b +b +b +b +b +b +b +b +d +d +b +b +b +b +b +d +d +b +b +b +b +b +b +b +b +b +b +b +b +b +d +b +b +b +b +b +b +a +b +b +b +a +b +b +b +a +"} +(25,1,1) = {" +a +a +a +a +a +b +b +b +b +b +b +b +b +d +b +b +b +b +b +d +d +b +b +b +b +b +b +b +b +b +b +b +b +b +d +b +b +b +b +b +b +a +a +a +a +a +b +b +b +a +"} +(26,1,1) = {" +a +a +a +a +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +d +d +d +b +b +b +b +b +b +b +b +b +b +b +b +e +a +"} +(27,1,1) = {" +a +a +a +a +b +b +b +b +e +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +a +b +b +b +b +b +b +d +d +d +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(28,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +a +b +b +b +b +b +b +d +d +d +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(29,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(30,1,1) = {" +a +b +b +b +b +b +b +b +a +b +b +b +b +b +b +b +b +b +b +a +a +a +a +a +a +a +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(31,1,1) = {" +a +b +b +b +b +b +b +b +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(32,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +b +b +a +"} +(33,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(34,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(35,1,1) = {" +a +b +b +e +b +b +b +b +b +b +b +b +a +a +a +a +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +a +a +a +a +a +a +a +b +b +b +b +b +b +a +"} +(36,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +a +a +a +a +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +b +b +b +b +b +b +b +b +a +"} +(37,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +b +b +a +b +b +b +b +b +b +b +b +a +"} +(38,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +b +e +a +b +b +b +b +b +b +b +b +a +"} +(39,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +a +a +a +b +b +b +b +b +b +b +b +a +"} +(40,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +b +b +b +b +b +b +b +b +a +"} +(41,1,1) = {" +a +b +b +b +a +a +a +a +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +d +d +d +d +d +b +b +b +b +b +a +b +b +b +b +b +b +b +e +a +"} +(42,1,1) = {" +a +b +b +b +b +b +b +b +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +d +d +d +d +d +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(43,1,1) = {" +a +b +b +b +b +b +b +b +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +d +d +d +d +d +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +"} +(44,1,1) = {" +a +b +b +b +b +b +b +b +a +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +b +b +a +a +a +a +d +d +d +d +d +b +b +b +b +b +b +b +b +b +b +b +a +b +b +a +"} +(45,1,1) = {" +a +b +b +b +b +e +b +b +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +a +e +b +b +d +d +d +d +d +b +b +b +b +b +b +b +b +b +b +b +a +b +b +a +"} +(46,1,1) = {" +a +b +b +b +b +b +b +b +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +d +d +d +d +d +d +d +d +b +b +b +b +b +b +b +b +a +b +b +a +"} +(47,1,1) = {" +a +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +d +d +d +d +d +d +d +d +d +d +d +d +d +d +d +b +b +b +b +b +e +b +b +b +b +b +a +"} +(48,1,1) = {" +a +d +d +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +d +d +d +d +d +d +d +d +d +d +d +d +d +d +d +d +d +b +b +b +b +b +b +b +b +b +a +"} +(49,1,1) = {" +a +d +d +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +b +d +d +d +d +d +d +d +d +d +d +d +d +d +d +d +d +d +b +b +b +b +b +b +b +b +b +a +"} +(50,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} diff --git a/code/datums/shuttles.dm b/code/datums/shuttles.dm index 198dad7c469..f3210dbc820 100644 --- a/code/datums/shuttles.dm +++ b/code/datums/shuttles.dm @@ -244,12 +244,25 @@ description = "The crew must pass through an otherworldy arena to board this shuttle. Expect massive casualties. The source of the Bloody Signal must be tracked down and eliminated to unlock this shuttle." admin_notes = "RIP AND TEAR." credit_cost = 10000 + /// Whether the arena z-level has been created + var/arena_loaded = FALSE /datum/map_template/shuttle/emergency/arena/prerequisites_met() if(SHUTTLE_UNLOCK_BUBBLEGUM in SSshuttle.shuttle_purchase_requirements_met) return TRUE return FALSE +/datum/map_template/shuttle/emergency/arena/post_load(obj/docking_port/mobile/M) + . = ..() + if(!arena_loaded) + arena_loaded = TRUE + var/datum/map_template/arena/arena_template = new() + arena_template.load_new_z() + +/datum/map_template/arena + name = "The Arena" + mappath = "_maps/templates/the_arena.dmm" + /datum/map_template/shuttle/emergency/birdboat suffix = "birdboat" name = "Birdboat Station Emergency Shuttle" diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index a9b4e335aa8..78b0b4c89d1 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -173,7 +173,6 @@ if(points_to_check >= S.credit_cost) SSshuttle.shuttle_purchased = SHUTTLEPURCHASE_PURCHASED SSshuttle.unload_preview() - SSshuttle.load_template(S) SSshuttle.existing_shuttle = SSshuttle.emergency SSshuttle.action_load(S) D.adjust_money(-S.credit_cost) diff --git a/code/modules/events/shuttle_catastrophe.dm b/code/modules/events/shuttle_catastrophe.dm index 5bb61f559e3..e9587c76d8d 100644 --- a/code/modules/events/shuttle_catastrophe.dm +++ b/code/modules/events/shuttle_catastrophe.dm @@ -33,7 +33,6 @@ /datum/round_event/shuttle_catastrophe/start() SSshuttle.shuttle_purchased = SHUTTLEPURCHASE_FORCED SSshuttle.unload_preview() - SSshuttle.load_template(new_shuttle) SSshuttle.existing_shuttle = SSshuttle.emergency SSshuttle.action_load(new_shuttle) log_shuttle("Shuttle Catastrophe set a new shuttle, [new_shuttle.name].") From 4cd1a30ad5433d2a3f6af7237d4fb93c74ab78b5 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Mon, 7 Sep 2020 13:24:15 -0700 Subject: [PATCH 23/32] Automatic changelog generation for PR #53458 [ci skip] --- html/changelogs/AutoChangeLog-pr-53458.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-53458.yml diff --git a/html/changelogs/AutoChangeLog-pr-53458.yml b/html/changelogs/AutoChangeLog-pr-53458.yml new file mode 100644 index 00000000000..dd647087479 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-53458.yml @@ -0,0 +1,4 @@ +author: "YPOQ" +delete-after: True +changes: + - bugfix: "The arena shuttle no longer teleports people into space." From d5d57703635d6d6d8a489c22c9d92333af403339 Mon Sep 17 00:00:00 2001 From: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com> Date: Mon, 7 Sep 2020 13:30:59 -0700 Subject: [PATCH 24/32] Make repository config default to HUMANS_NEED_SURNAMES (#53465) --- config/game_options.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/game_options.txt b/config/game_options.txt index e4c458a5a7e..03a18aed8cb 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -50,7 +50,7 @@ MULTIPLICATIVE_MOVESPEED /mob/living/simple_animal 0 ## NAMES ### ## If uncommented this adds a random surname to a player's name if they only specify one name. -#HUMANS_NEED_SURNAMES +HUMANS_NEED_SURNAMES ## If uncommented, this forces all players to use random names !and appearances!. #FORCE_RANDOM_NAMES From d4cdb49133897a52529ef780489d978d65010b8b Mon Sep 17 00:00:00 2001 From: TiviPlus <57223640+TiviPlus@users.noreply.github.com> Date: Mon, 7 Sep 2020 22:44:54 +0200 Subject: [PATCH 25/32] Mecha followup one (#53470) fixes #53384 fixes #53327 fixes a bug where mechs could move too fast fixes cooldown being inconsistent makes strafe behavior better fixes lights being very small fixes #50639 fixes #47373 fixes #43605 Moved some code to the correct spots and did the varedit bitfield thing --- code/__DEFINES/mecha.dm | 8 +++ code/__DEFINES/vehicles.dm | 10 --- code/_globalvars/bitfields.dm | 17 +++++ code/modules/cargo/bounties/mech.dm | 4 +- code/modules/vehicles/mecha/_mecha.dm | 69 ++++++++++--------- .../mecha/equipment/tools/work_tools.dm | 2 +- .../mecha/equipment/weapons/weapons.dm | 2 +- code/modules/vehicles/mecha/mecha_wreckage.dm | 2 +- code/modules/vehicles/mecha/working/ripley.dm | 24 ++++--- code/modules/vehicles/sealed.dm | 5 +- 10 files changed, 84 insertions(+), 59 deletions(-) diff --git a/code/__DEFINES/mecha.dm b/code/__DEFINES/mecha.dm index bf62e6b67ba..f5fad9cdf68 100644 --- a/code/__DEFINES/mecha.dm +++ b/code/__DEFINES/mecha.dm @@ -4,6 +4,14 @@ #define MECHA_INT_TANK_BREACH (1<<3) #define MECHA_INT_CONTROL_LOST (1<<4) +#define ADDING_ACCESS_POSSIBLE (1<<0) +#define ADDING_MAINT_ACCESS_POSSIBLE (1<<1) +#define CANSTRAFE (1<<2) +#define LIGHTS_ON (1<<3) +#define SILICON_PILOT (1<<4) +#define IS_ENCLOSED (1<<5) +#define HAS_LIGHTS (1<<6) + #define MECHA_MELEE (1 << 0) #define MECHA_RANGED (1 << 1) diff --git a/code/__DEFINES/vehicles.dm b/code/__DEFINES/vehicles.dm index 4b59e585aa3..a15c211d877 100644 --- a/code/__DEFINES/vehicles.dm +++ b/code/__DEFINES/vehicles.dm @@ -4,15 +4,5 @@ #define VEHICLE_CONTROL_DRIVE 2 #define VEHICLE_CONTROL_KIDNAPPED 4 //Can't leave vehicle voluntarily, has to resist. -//Mech flags -#define ADDING_ACCESS_POSSIBLE (1<<0) -#define ADDING_MAINT_ACCESS_POSSIBLE (1<<1) -#define CANSTRAFE (1<<2) -#define LIGHTS_ON (1<<3) -#define SILICON_PILOT (1<<4) -#define IS_ENCLOSED (1<<5) -#define HAS_LIGHTS (1<<6) - - //Car trait flags #define CAN_KIDNAP 1 diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 00b1c54bedc..239e4bd14c8 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -166,6 +166,23 @@ DEFINE_BITFIELD(machine_stat, list( "NOPOWER" = NOPOWER, )) +DEFINE_BITFIELD(internal_damage, list( + "MECHA_INT_FIRE" = MECHA_INT_FIRE, + "MECHA_INT_TEMP_CONTROL" = MECHA_INT_TEMP_CONTROL, + "MECHA_INT_TANK_BREACH" = MECHA_INT_TANK_BREACH, + "MECHA_INT_CONTROL_LOST" = MECHA_INT_CONTROL_LOST, +)) + +DEFINE_BITFIELD(mecha_flags, list( + "ADDING_ACCESS_POSSIBLE" = ADDING_ACCESS_POSSIBLE, + "ADDING_MAINT_ACCESS_POSSIBLE" = ADDING_MAINT_ACCESS_POSSIBLE, + "CANSTRAFE" = CANSTRAFE, + "LIGHTS_ON" = LIGHTS_ON, + "SILICON_PILOT" = SILICON_PILOT, + "IS_ENCLOSED" = IS_ENCLOSED, + "HAS_LIGHTS" = HAS_LIGHTS, +)) + DEFINE_BITFIELD(mob_biotypes, list( "MOB_BEAST" = MOB_BEAST, "MOB_BUG" = MOB_BUG, diff --git a/code/modules/cargo/bounties/mech.dm b/code/modules/cargo/bounties/mech.dm index 3651be1af4e..b3dd8d580d1 100644 --- a/code/modules/cargo/bounties/mech.dm +++ b/code/modules/cargo/bounties/mech.dm @@ -13,10 +13,10 @@ /datum/bounty/item/mech/mark_high_priority(scale_reward) return ..(max(scale_reward * 0.7, 1.2)) -/datum/bounty/item/mech/ripleymkii +/datum/bounty/item/mech/ripleymk2 name = "APLU MK-II \"Ripley\"" reward = 13000 - wanted_types = list(/obj/vehicle/sealed/mecha/working/ripley/mkii) + wanted_types = list(/obj/vehicle/sealed/mecha/working/ripley/mk2) /datum/bounty/item/mech/clarke name = "Clarke" diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index 9fe8ceb9bc1..7be1eccf148 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -31,6 +31,7 @@ COOLDOWN_DECLARE(mecha_bump_smash) light_system = MOVABLE_LIGHT light_on = FALSE + light_range = 4 ///What direction will the mech face when entered/powered on? Defaults to South. var/dir_in = SOUTH ///How much energy the mech will consume each time it moves. This variable is a backup for when leg actuators affect the energy drain. @@ -257,7 +258,7 @@ mob_occupant.update_mouse_pointer() /obj/vehicle/sealed/mecha/CheckParts(list/parts_list) - ..() + . = ..() cell = locate(/obj/item/stock_parts/cell) in contents scanmod = locate(/obj/item/stock_parts/scanning_module) in contents capacitor = locate(/obj/item/stock_parts/capacitor) in contents @@ -650,8 +651,16 @@ if(!allow_diagonal_movement && ISDIAGONALDIR(direction)) return TRUE + var/keyheld = FALSE + if(strafe) + for(var/D in return_drivers()) + var/mob/driver = D + if(driver.client?.keys_held["Alt"]) + keyheld = TRUE + break + //if we're not facing the way we're going rotate us - if(dir != direction && !strafe || forcerotate) + if(dir != direction && !strafe || forcerotate || keyheld) setDir(direction) if(turnsound) playsound(src,turnsound,40,TRUE) @@ -662,10 +671,6 @@ . = step(src,direction, dir) if(strafe) - for(var/D in return_drivers()) - var/mob/driver = D - if(driver.client?.keys_held["Alt"]) - return setDir(olddir) @@ -771,7 +776,8 @@ to_chat(user, "Take control of exosuit?
") /obj/vehicle/sealed/mecha/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) - if(!..()) + . = ..() + if(!.) return //Transfer from core or card to mech. Proc is called by mech. @@ -796,15 +802,15 @@ AI.remote_control = null to_chat(AI, "You have been downloaded to a mobile storage device. Wireless connection offline.") to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) removed from [name] and stored within local memory.") + return if(AI_MECH_HACK) //Called by AIs on the mech AI.linked_core = new /obj/structure/ai_core/deactivated(AI.loc) - if(AI.can_dominate_mechs) - if(LAZYLEN(occupants)) //Oh, I am sorry, were you using that? - to_chat(AI, "Occupants detected! Forced ejection initiated!") - to_chat(occupants, "You have been forcibly ejected!") - ejectall() //IT IS MINE, NOW. SUCK IT, RD! - ai_enter_mech(AI, interaction) + if(AI.can_dominate_mechs && LAZYLEN(occupants)) //Oh, I am sorry, were you using that? + to_chat(AI, "Occupants detected! Forced ejection initiated!") + to_chat(occupants, "You have been forcibly ejected!") + ejectall() //IT IS MINE, NOW. SUCK IT, RD! + AI.can_shunt = FALSE //ONE AI ENTERS. NO AI LEAVES. if(AI_TRANS_FROM_CARD) //Using an AI card to upload to a mech. AI = card.AI @@ -823,10 +829,10 @@ AI.radio_enabled = TRUE to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") card.AI = null - ai_enter_mech(AI, interaction) + ai_enter_mech(AI) //Hack and From Card interactions share some code, so leave that here for both to use. -/obj/vehicle/sealed/mecha/proc/ai_enter_mech(mob/living/silicon/ai/AI, interaction) +/obj/vehicle/sealed/mecha/proc/ai_enter_mech(mob/living/silicon/ai/AI) AI.ai_restore_power() mecha_flags |= SILICON_PILOT moved_inside(AI) @@ -834,8 +840,6 @@ AI.controlled_mech = src AI.remote_control = src AI.mobility_flags = ALL //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow. - if(interaction == AI_MECH_HACK) - AI.can_shunt = FALSE //ONE AI ENTERS. NO AI LEAVES. to_chat(AI, AI.can_dominate_mechs ? "Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!" :\ "You have been uploaded to a mech's onboard computer.") to_chat(AI, "Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions.") @@ -939,21 +943,20 @@ initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_view_stats) initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/strafe) -/obj/vehicle/sealed/mecha/proc/moved_inside(mob/living/H) - . = FALSE - if(!(H?.client)) - return - if(ishuman(H) && !Adjacent(H)) - return - add_occupant(H) - H.forceMove(src) - H.update_mouse_pointer() - add_fingerprint(H) - log_message("[H] moved in as pilot.", LOG_MECHA) +/obj/vehicle/sealed/mecha/proc/moved_inside(mob/living/newoccupant) + if(!(newoccupant?.client)) + return FALSE + if(ishuman(newoccupant) && !Adjacent(newoccupant)) + return FALSE + add_occupant(newoccupant) + newoccupant.forceMove(src) + newoccupant.update_mouse_pointer() + add_fingerprint(newoccupant) + log_message("[newoccupant] moved in as pilot.", LOG_MECHA) setDir(dir_in) playsound(src, 'sound/machines/windowdoor.ogg', 50, TRUE) if(!internal_damage) - SEND_SOUND(H, sound('sound/mecha/nominal.ogg',volume=50)) + SEND_SOUND(newoccupant, sound('sound/mecha/nominal.ogg',volume=50)) return TRUE /obj/vehicle/sealed/mecha/proc/mmi_move_inside(obj/item/mmi/M, mob/user) @@ -997,7 +1000,6 @@ B.remote_control = src B.update_mobility() B.update_mouse_pointer() - update_icon() setDir(dir_in) log_message("[M] moved in as pilot.", LOG_MECHA) if(!internal_damage) @@ -1067,7 +1069,6 @@ mmi.mecha = null mmi.update_icon() L.mobility_flags = NONE - update_icon() setDir(dir_in) return ..() @@ -1076,21 +1077,21 @@ RegisterSignal(M, COMSIG_MOB_DEATH, .proc/mob_exit) RegisterSignal(M, COMSIG_MOB_CLICKON, .proc/on_mouseclick) RegisterSignal(M, COMSIG_MOB_SAY, .proc/display_speech_bubble) + . = ..() update_icon() - return ..() /obj/vehicle/sealed/mecha/remove_occupant(mob/M) UnregisterSignal(M, COMSIG_MOB_DEATH) UnregisterSignal(M, COMSIG_MOB_CLICKON) UnregisterSignal(M, COMSIG_MOB_SAY) - update_icon() M.clear_alert("charge") M.clear_alert("mech damage") if(M.client) M.update_mouse_pointer() M.client.view_size.resetToDefault() zoom_mode = 0 - return ..() + . = ..() + update_icon() ///////////////////////// ////// Access stuff ///// diff --git a/code/modules/vehicles/mecha/equipment/tools/work_tools.dm b/code/modules/vehicles/mecha/equipment/tools/work_tools.dm index 361106a31a5..ad911ba7dd0 100644 --- a/code/modules/vehicles/mecha/equipment/tools/work_tools.dm +++ b/code/modules/vehicles/mecha/equipment/tools/work_tools.dm @@ -373,7 +373,7 @@ return TRUE /obj/item/mecha_parts/mecha_equipment/ripleyupgrade/attach(obj/vehicle/sealed/mecha/M) - var/obj/vehicle/sealed/mecha/working/ripley/mkii/N = new /obj/vehicle/sealed/mecha/working/ripley/mkii(get_turf(M),1) + var/obj/vehicle/sealed/mecha/working/ripley/mk2/N = new (get_turf(M),1) if(!N) return QDEL_NULL(N.cell) diff --git a/code/modules/vehicles/mecha/equipment/weapons/weapons.dm b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm index f9e2933a75a..846b768b96f 100644 --- a/code/modules/vehicles/mecha/equipment/weapons/weapons.dm +++ b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm @@ -49,7 +49,7 @@ if(kickback) chassis.newtonian_move(newtonian_target) chassis.log_message("Fired from [src.name], targeting [target].", LOG_MECHA) - return ..() + return //Base energy weapon type /obj/item/mecha_parts/mecha_equipment/weapon/energy diff --git a/code/modules/vehicles/mecha/mecha_wreckage.dm b/code/modules/vehicles/mecha/mecha_wreckage.dm index c70d711560f..8fd45616fac 100644 --- a/code/modules/vehicles/mecha/mecha_wreckage.dm +++ b/code/modules/vehicles/mecha/mecha_wreckage.dm @@ -154,7 +154,7 @@ /obj/item/mecha_parts/part/ripley_left_leg, /obj/item/mecha_parts/part/ripley_right_leg) -/obj/structure/mecha_wreckage/ripley/mkii +/obj/structure/mecha_wreckage/ripley/mk2 name = "\improper Ripley MK-II wreckage" icon_state = "ripleymkii-broken" diff --git a/code/modules/vehicles/mecha/working/ripley.dm b/code/modules/vehicles/mecha/working/ripley.dm index 3cc13ab6883..3ef07ff3c71 100644 --- a/code/modules/vehicles/mecha/working/ripley.dm +++ b/code/modules/vehicles/mecha/working/ripley.dm @@ -30,13 +30,12 @@ . = ..() update_pressure() -/obj/vehicle/sealed/mecha/working/ripley/mob_exit(mob/M, silent, forced) - ..() - update_icon() - -/obj/vehicle/sealed/mecha/working/ripley/moved_inside(mob/living/carbon/human/H) - ..() - update_icon() +/obj/vehicle/sealed/mecha/working/ripley/generate_actions() //isnt allowed to have internal air + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_eject) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_cycle_equip) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_lights) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_view_stats) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/strafe) /obj/vehicle/sealed/mecha/working/ripley/check_for_internal_damage(list/possible_int_damage, ignore_threshold = FALSE) if (!enclosed) @@ -55,7 +54,7 @@ cargo.Cut() return ..() -/obj/vehicle/sealed/mecha/working/ripley/mkii +/obj/vehicle/sealed/mecha/working/ripley/mk2 desc = "Autonomous Power Loader Unit MK-II. This prototype Ripley is refitted with a pressurized cabin, trading its prior speed for atmospheric protection and armor." name = "\improper APLU MK-II \"Ripley\"" icon_state = "ripleymkii" @@ -65,11 +64,18 @@ max_temperature = 30000 max_integrity = 250 armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 60, BIO = 0, RAD = 70, FIRE = 100, ACID = 100) - wreckage = /obj/structure/mecha_wreckage/ripley/mkii + wreckage = /obj/structure/mecha_wreckage/ripley/mk2 enclosed = TRUE enter_delay = 40 silicon_icon_state = null +/obj/vehicle/sealed/mecha/working/ripley/mk2/generate_actions() + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_eject) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_internals) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_cycle_equip) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_lights) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_view_stats) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/strafe) /obj/vehicle/sealed/mecha/working/ripley/deathripley desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE" diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm index e3a019427bf..de8be112025 100644 --- a/code/modules/vehicles/sealed.dm +++ b/code/modules/vehicles/sealed.dm @@ -91,9 +91,12 @@ user.put_in_hands(inserted_key) inserted_key = null +/obj/vehicle/sealed/obj_destruction(damage_flag) + explosion(loc, 0, 1, 2, 3, 0) + return ..() + /obj/vehicle/sealed/Destroy() DumpMobs() - explosion(loc, 0, 1, 2, 3, 0) return ..() /obj/vehicle/sealed/proc/DumpMobs(randomstep = TRUE) From 4d41487f3e704f384ca0cd6cb79fb0e1f3c2b04e Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Mon, 7 Sep 2020 13:45:00 -0700 Subject: [PATCH 26/32] Automatic changelog generation for PR #53470 [ci skip] --- html/changelogs/AutoChangeLog-pr-53470.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-53470.yml diff --git a/html/changelogs/AutoChangeLog-pr-53470.yml b/html/changelogs/AutoChangeLog-pr-53470.yml new file mode 100644 index 00000000000..43ac442de90 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-53470.yml @@ -0,0 +1,8 @@ +author: "TiviPlus" +delete-after: True +changes: + - bugfix: "fixed mech icons and lights" + - bugfix: "Made strafe behavior better" + - bugfix: "fixed mechs exploding" + - bugfix: "fixed mech weapon cooldowns being inconsistent" + - code_imp: "cleaned up mech code some more" From 978d79dc2ca1018a6df87bd1b3c2cbd08f27a59d Mon Sep 17 00:00:00 2001 From: Coffee <63162339+CoffeeDragon16@users.noreply.github.com> Date: Mon, 7 Sep 2020 16:47:00 -0400 Subject: [PATCH 27/32] Fixes shuttle call text (#53474) Shuttle call text for Mother Russia Bleeds read as the Box Emergency Shuttle, this fixes it by making it read properly. --- _maps/shuttles/emergency_russiafightpit.dmm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_maps/shuttles/emergency_russiafightpit.dmm b/_maps/shuttles/emergency_russiafightpit.dmm index 4cdaf8380f9..62c481011b9 100644 --- a/_maps/shuttles/emergency_russiafightpit.dmm +++ b/_maps/shuttles/emergency_russiafightpit.dmm @@ -277,7 +277,7 @@ "aW" = ( /obj/docking_port/mobile/emergency{ height = 15; - name = "Box emergency shuttle" + name = "Mother Russia Bleeds" }, /obj/machinery/door/airlock/security/glass{ name = "Emergency Shuttle Airlock" From bfe3e3ea6375396b7db484a9b14cfe8c02d79f06 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Mon, 7 Sep 2020 13:47:04 -0700 Subject: [PATCH 28/32] Automatic changelog generation for PR #53474 [ci skip] --- html/changelogs/AutoChangeLog-pr-53474.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-53474.yml diff --git a/html/changelogs/AutoChangeLog-pr-53474.yml b/html/changelogs/AutoChangeLog-pr-53474.yml new file mode 100644 index 00000000000..f6b3a1f2fb6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-53474.yml @@ -0,0 +1,4 @@ +author: "CoffeeDragon16" +delete-after: True +changes: + - bugfix: "Announcements now correctly read Mother Russia Bleeds" From 7a6b673b3c4c630aea4d29cfb1c33dc5e8c8d422 Mon Sep 17 00:00:00 2001 From: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com> Date: Mon, 7 Sep 2020 13:48:21 -0700 Subject: [PATCH 29/32] Fixes the meat sprites on the crashed ship (#53475) --- _maps/RandomRuins/SpaceRuins/crashedship.dmm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_maps/RandomRuins/SpaceRuins/crashedship.dmm b/_maps/RandomRuins/SpaceRuins/crashedship.dmm index 10e2869fd54..5a620d04096 100644 --- a/_maps/RandomRuins/SpaceRuins/crashedship.dmm +++ b/_maps/RandomRuins/SpaceRuins/crashedship.dmm @@ -499,7 +499,7 @@ /obj/structure/table, /obj/item/kitchen/knife/butcher, /obj/item/reagent_containers/food/drinks/beer, -/obj/item/reagent_containers/food/snacks/meat, +/obj/item/reagent_containers/food/snacks/meat/slab/human, /obj/effect/turf_decal/tile/blue{ dir = 4 }, @@ -1508,7 +1508,7 @@ /area/awaymission/bmpship/fore) "fO" = ( /obj/structure/closet/crate/freezer, -/obj/item/reagent_containers/food/snacks/meat, +/obj/item/reagent_containers/food/snacks/meat/slab/human, /turf/open/floor/plasteel/showroomfloor, /area/awaymission/bmpship/aft) "fP" = ( From a6755f7421523a69aad7260e683253066f03ab07 Mon Sep 17 00:00:00 2001 From: tgstation-server Date: Mon, 7 Sep 2020 13:48:25 -0700 Subject: [PATCH 30/32] Automatic changelog generation for PR #53475 [ci skip] --- html/changelogs/AutoChangeLog-pr-53475.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-53475.yml diff --git a/html/changelogs/AutoChangeLog-pr-53475.yml b/html/changelogs/AutoChangeLog-pr-53475.yml new file mode 100644 index 00000000000..57430ee3988 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-53475.yml @@ -0,0 +1,4 @@ +author: "Jared-Fogle" +delete-after: True +changes: + - bugfix: "The crashed ship ruin now has proper meat." From e9ee817cb4d2c4509b6a3176402ee65baafd364e Mon Sep 17 00:00:00 2001 From: Ryll Ryll <3589655+Ryll-Ryll@users.noreply.github.com> Date: Mon, 7 Sep 2020 16:49:14 -0400 Subject: [PATCH 31/32] Fixes admin tickets displaying as improper nouns (#53485) Admin tickets were having "the" prepended to them when displayed in the status tab, because ahelps are treated as datums and BYOND likes to help out and treat them as nouns when printed. This resolves that. --- code/modules/admin/verbs/adminhelp.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 76e9a07cd9d..6722e2a6560 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -98,7 +98,8 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) for(var/I in active_tickets) var/datum/admin_help/AH = I if(AH.initiator) - L[++L.len] = list("#[AH.id]. [AH.initiator_key_name]:", "[AH.statclick.update()]", REF(AH)) + var/obj/effect/statclick/updated = AH.statclick.update() + L[++L.len] = list("#[AH.id]. [AH.initiator_key_name]:", "[updated.name]", REF(AH)) else ++num_disconnected if(num_disconnected) From 97e7b9683dd31b0cb3cc869b556ee81d600c957d Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Mon, 7 Sep 2020 13:54:26 -0700 Subject: [PATCH 32/32] Fix bicon, fix asset hashes being incorrect. (#53441) icon2html will now always show the south direction unless passed a specific direction to show. Null can be explicitly passed with an atom to use the atom's direction. This is to work around icon() returning a blank icon if passed a direction that the icon doesn't define, instead of defaulting to south like the client does. This should also cut down on the number of assets generated by shift clicks If icon2html is given an atom with an invalid icon state, it will use the atom's compile time icon_state, so smoothed icons can show their mapper's helper icon instead of the entire dmi. Asset cache will now copy files to disk before md5ing them, to deal with byond not always returning the correct md5 for rsc references. --- code/__HELPERS/files.dm | 15 +++++++++++++++ code/__HELPERS/icons.dm | 16 ++++++++++++---- code/modules/asset_cache/asset_cache_item.dm | 8 +++----- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/code/__HELPERS/files.dm b/code/__HELPERS/files.dm index 6fc48ded6a6..b4c8fecf54a 100644 --- a/code/__HELPERS/files.dm +++ b/code/__HELPERS/files.dm @@ -73,3 +73,18 @@ /proc/pathflatten(path) return replacetext(path, "/", "_") + +/// Returns the md5 of a file at a given path. +/proc/md5filepath(path) + . = md5(file(path)) + +/// Save file as an external file then md5 it. +/// Used because md5ing files stored in the rsc sometimes gives incorrect md5 results. +/proc/md5asfile(file) + var/static/notch = 0 + // its importaint this code can handle md5filepath sleeping instead of hard blocking, if it's converted to use rust_g. + var/filename = "tmp/md5asfile.[world.realtime].[world.timeofday].[world.time].[world.tick_usage].[notch]" + notch = WRAP(notch+1, 0, 2^15) + fcopy(file, filename) + . = md5filepath(filename) + fdel(filename) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index cc90ccc5dbf..0c7b5ea1de6 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1124,12 +1124,13 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico var/list/partial = splittext(iconData, "{") return replacetext(copytext_char(partial[2], 3, -5), "\n", "") -/proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE, sourceonly = FALSE) +/proc/icon2html(thing, target, icon_state, dir = SOUTH, frame = 1, moving = FALSE, sourceonly = FALSE) if (!thing) return var/key var/icon/I = thing + if (!target) return if (target == world) @@ -1153,11 +1154,18 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico return SSassets.transport.get_asset_url(name) return "" var/atom/A = thing - if (isnull(dir)) - dir = A.dir + + I = A.icon if (isnull(icon_state)) icon_state = A.icon_state - I = A.icon + if (!(icon_state in icon_states(I, 1))) + icon_state = initial(A.icon_state) + if (isnull(dir)) + dir = initial(A.dir) + + if (isnull(dir)) + dir = A.dir + if (ishuman(thing)) // Shitty workaround for a BYOND issue. var/icon/temp = I I = icon() diff --git a/code/modules/asset_cache/asset_cache_item.dm b/code/modules/asset_cache/asset_cache_item.dm index 41cee06db1e..059ebaebca8 100644 --- a/code/modules/asset_cache/asset_cache_item.dm +++ b/code/modules/asset_cache/asset_cache_item.dm @@ -24,12 +24,10 @@ /datum/asset_cache_item/New(name, file) if (!isfile(file)) file = fcopy_rsc(file) - hash = md5(file) + + hash = md5asfile(file) //icons sent to the rsc sometimes md5 incorrectly if (!hash) - hash = md5(fcopy_rsc(file)) - if (!hash) - CRASH("invalid asset sent to asset cache") - debug_world_log("asset cache unexpected success of second fcopy_rsc") + CRASH("invalid asset sent to asset cache") src.name = name var/extstart = findlasttext(name, ".") if (extstart)