Decouples free vending machine behavior from the 'onstation' var (#86548)

## About The Pull Request

The `onstation` var was being used for too many things (AI brand
intelligence + whether the products are free or not), and was
overcomplicating the logic.

On top of that it makes things like trying to make a vending machine
that is considered offstation for purposes of the brand intelligence
event but that still dispenses free goods needlessly difficult.

This PR just decouples the two behaviors and gives the 'free' behavior
its own var.

As a result, the majority of the of `onstation` map varedits are no
longer necessary

Tested with various edge cases, all seem working as intended:

<details><summary>arrivals (onstation, all_free_products = null /
FALSE)</summary>


![dreamseeker_bkpGCsXoaN](https://github.com/user-attachments/assets/3f92a454-ac04-41f8-9235-281a0c8dd309)

</details>

<details><summary>arrivals (onstation, all_free_products =
TRUE)</summary>


![dreamseeker_7Osn49NoHg](https://github.com/user-attachments/assets/374e2632-c727-44e3-aa47-f31d5db375ca)

</details>

<details><summary>spacehotel (not onstation, all_free_products =
null)</summary>


![dreamseeker_dtQFNIRlxl](https://github.com/user-attachments/assets/1dc859d9-ac8d-4d38-946f-8070f1176915)

</details>

<details><summary>hauntedruins (not onstation, all_free_products =
FALSE)</summary>


![dreamseeker_JLcsJCaOIK](https://github.com/user-attachments/assets/02948139-615a-477e-b0c5-f0da8d721cae)

</details>

<details><summary>silverscale shuttle (not onstation, all_free_products
= TRUE)</summary>


![dreamseeker_FNgw2JILVg](https://github.com/user-attachments/assets/7deef056-e331-48e6-88a8-fdfd22d706d4)

</details>

<details><summary>labor camp (not onstation, all_free_products =
FALSE)</summary>


![dreamseeker_NWT6dxYV9d](https://github.com/user-attachments/assets/ea0c3ddd-a4dd-477a-8838-ae1ddf8ad198)

</details>


## Why It's Good For The Game

Less complicated vending machines, less varedits in our maps. Less
confusing code. Ability to spawn a vending machine and varedit it to be
free without affecting any other systems.

## Changelog
N/A
This commit is contained in:
Bloop
2024-09-13 13:44:55 +02:00
committed by GitHub
parent 9ebf74d8d4
commit 8d9f1689ba
20 changed files with 66 additions and 84 deletions
@@ -70,7 +70,7 @@
/area/ruin/powered/icemoon_phone_booth)
"W" = (
/obj/machinery/vending/cigarette{
onstation_override = 1
all_products_free = 0
},
/obj/structure/window/reinforced/spawner/directional/east,
/turf/open/floor/plating/icemoon,
@@ -538,9 +538,7 @@
},
/area/ruin/pizzeria)
"yP" = (
/obj/machinery/vending/dinnerware{
onstation = 0
},
/obj/machinery/vending/dinnerware,
/obj/effect/turf_decal/tile/blue/opposingcorners{
dir = 1
},
@@ -13,7 +13,7 @@
/area/ruin/powered/lavaland_phone_booth)
"k" = (
/obj/machinery/vending/snack/green{
onstation_override = 1
all_products_free = 0;
},
/obj/structure/window/reinforced/spawner/directional/east,
/turf/open/floor/plating/lavaland_atmos,
@@ -66,7 +66,7 @@
/area/ruin/powered/lavaland_phone_booth)
"W" = (
/obj/machinery/vending/cigarette{
onstation_override = 1
all_products_free = 0;
},
/obj/structure/window/reinforced/spawner/directional/east,
/turf/open/floor/plating/lavaland_atmos,
@@ -139,7 +139,7 @@
"bq" = (
/obj/structure/cable/layer1,
/obj/machinery/vending/sovietsoda{
onstation_override = 1
all_products_free = 0
},
/obj/structure/sign/poster/contraband/clown/directional/east,
/obj/machinery/duct,
@@ -527,7 +527,7 @@
"dU" = (
/obj/structure/cable/layer1,
/obj/machinery/vending/cigarette/syndicate{
onstation_override = 1
all_products_free = 0
},
/obj/machinery/duct,
/obj/effect/mapping_helpers/broken_machine,
@@ -544,7 +544,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4,
/obj/machinery/duct,
/obj/machinery/vending/clothing{
onstation_override = 1
all_products_free = 0
},
/obj/machinery/firealarm/directional/south,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
@@ -1378,7 +1378,7 @@
/area/ruin/space/has_grav/hauntedtradingpost/office/meetingroom)
"lT" = (
/obj/machinery/vending/cola/black{
onstation_override = 1
all_products_free = 0
},
/obj/machinery/duct,
/obj/effect/mapping_helpers/broken_machine,
@@ -1866,7 +1866,7 @@
/obj/structure/cable/layer1,
/obj/machinery/duct,
/obj/machinery/vending/assist{
onstation_override = 1
all_products_free = 0
},
/obj/machinery/camera/xray/directional/west,
/turf/open/floor/catwalk_floor/iron_smooth,
@@ -2475,7 +2475,7 @@
/obj/structure/cable/layer1,
/obj/machinery/duct,
/obj/machinery/vending/cola/shamblers{
onstation_override = 1
all_products_free = 0
},
/turf/open/floor/catwalk_floor/iron_smooth,
/area/ruin/space/has_grav/hauntedtradingpost/public/corridor)
@@ -4199,7 +4199,7 @@
"KH" = (
/obj/structure/cable/layer1,
/obj/machinery/vending/donksnack{
onstation_override = 1
all_products_free = 0
},
/obj/machinery/duct,
/obj/machinery/camera/autoname/directional/west{
@@ -4516,7 +4516,7 @@
"MO" = (
/obj/machinery/duct,
/obj/machinery/vending/snack{
onstation_override = 1
all_products_free = 0
},
/turf/open/floor/catwalk_floor/iron_smooth,
/area/ruin/space/has_grav/hauntedtradingpost/public/corridor)
@@ -4616,7 +4616,7 @@
"NY" = (
/obj/structure/cable/layer1,
/obj/machinery/vending/coffee{
onstation_override = 1
all_products_free = 0
},
/obj/machinery/duct,
/turf/open/floor/catwalk_floor/iron_smooth,
@@ -4755,7 +4755,7 @@
"Pk" = (
/obj/structure/cable/layer1,
/obj/machinery/vending/tool{
onstation_override = 1
all_products_free = 0
},
/obj/structure/sign/poster/contraband/donk_co/directional/west,
/obj/machinery/duct,
@@ -4886,7 +4886,7 @@
"QM" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4,
/obj/machinery/vending/sovietsoda{
onstation_override = 1
all_products_free = 0
},
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
pipe_color = "#FF7B00";
@@ -5415,7 +5415,7 @@
/obj/structure/cable/layer1,
/obj/machinery/duct,
/obj/machinery/vending/medical{
onstation_override = 1;
all_products_free = 0;
name = "\improper CyberMed +"
},
/turf/open/floor/catwalk_floor/iron_smooth,
@@ -5635,7 +5635,7 @@
/area/ruin/space/has_grav/hauntedtradingpost/office)
"Ww" = (
/obj/machinery/vending/coffee{
onstation_override = 1
all_products_free = 0
},
/obj/structure/cable/layer1,
/obj/machinery/duct,
@@ -5712,7 +5712,7 @@
"Xe" = (
/obj/structure/cable/layer1,
/obj/machinery/vending/cola/shamblers{
onstation_override = 1
all_products_free = 0
},
/obj/machinery/duct,
/obj/effect/overloader_trap,
@@ -5802,7 +5802,7 @@
/area/ruin/space/has_grav/hauntedtradingpost/public)
"XK" = (
/obj/machinery/vending/donksnack{
onstation_override = 1
all_products_free = 0
},
/obj/machinery/duct,
/turf/open/floor/catwalk_floor/iron_smooth,
+3 -9
View File
@@ -1645,9 +1645,7 @@
/area/ruin/space/ancientstation/charlie/hall)
"hr" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/vending/dinnerware{
onstation = 0
},
/obj/machinery/vending/dinnerware,
/turf/open/floor/iron/cafeteria,
/area/ruin/space/ancientstation/charlie/kitchen)
"ht" = (
@@ -2368,9 +2366,7 @@
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/cobweb/cobweb2,
/obj/effect/decal/cleanable/dirt,
/obj/machinery/vending/coffee{
onstation = 0
},
/obj/machinery/vending/coffee,
/turf/open/floor/iron,
/area/ruin/space/ancientstation/charlie/dorms)
"ku" = (
@@ -2744,9 +2740,7 @@
/turf/open/floor/plating,
/area/ruin/space/ancientstation/charlie/hall)
"lU" = (
/obj/machinery/vending/hydronutrients{
onstation = 0
},
/obj/machinery/vending/hydronutrients,
/obj/effect/turf_decal/tile/green/anticorner/contrasted,
/turf/open/floor/iron,
/area/ruin/space/ancientstation/charlie/hydro)
+2 -2
View File
@@ -13,7 +13,7 @@
/area/ruin/space/has_grav/powered/space_phone_booth)
"k" = (
/obj/machinery/vending/snack/green{
onstation_override = 1
all_products_free = 1
},
/obj/structure/window/reinforced/spawner/directional/east,
/turf/open/floor/plating/airless,
@@ -66,7 +66,7 @@
/area/ruin/space/has_grav/powered/space_phone_booth)
"W" = (
/obj/machinery/vending/cigarette{
onstation_override = 1
all_products_free = 0
},
/obj/structure/window/reinforced/spawner/directional/east,
/turf/open/floor/plating/airless,
@@ -44,9 +44,7 @@
},
/area/ruin/space/has_grav/spinwardsmoothies)
"ti" = (
/obj/machinery/vending/boozeomat{
onstation = 0
},
/obj/machinery/vending/boozeomat,
/turf/open/floor/wood/tile,
/area/ruin/space/has_grav/spinwardsmoothies)
"wv" = (
@@ -1331,9 +1331,7 @@
/obj/effect/turf_decal/tile/blue/anticorner/contrasted{
dir = 8
},
/obj/machinery/vending/medical{
onstation = 0
},
/obj/machinery/vending/medical,
/turf/open/floor/iron/showroomfloor/airless,
/area/ruin/space/has_grav/whiteship/box)
"PV" = (
@@ -74196,7 +74196,7 @@
/area/station/security/prison/rec)
"vwG" = (
/obj/machinery/vending/security{
onstation_override = 1
all_products_free = 0
},
/obj/effect/turf_decal/tile/red/half/contrasted{
dir = 8
+1 -1
View File
@@ -8836,7 +8836,7 @@
/area/mine/laborcamp/security)
"Ya" = (
/obj/machinery/vending/security{
onstation_override = 1
all_products_free = 0
},
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 10
+1 -3
View File
@@ -567,9 +567,7 @@
/turf/open/floor/iron,
/area/shuttle/pirate)
"bH" = (
/obj/machinery/vending/boozeomat{
onstation = 0
},
/obj/machinery/vending/boozeomat,
/obj/effect/turf_decal/tile/bar/opposingcorners,
/turf/open/floor/iron,
/area/shuttle/pirate)
+2 -6
View File
@@ -946,9 +946,7 @@
},
/area/shuttle/pirate)
"Cf" = (
/obj/machinery/vending/autodrobe{
onstation = 0
},
/obj/machinery/vending/autodrobe,
/obj/effect/turf_decal/siding/dark_green{
dir = 6
},
@@ -1642,9 +1640,7 @@
/turf/open/floor/wood,
/area/shuttle/pirate)
"QT" = (
/obj/machinery/vending/boozeomat{
onstation = 0
},
/obj/machinery/vending/boozeomat,
/turf/closed/wall/mineral/titanium,
/area/shuttle/pirate)
"QV" = (
+2 -6
View File
@@ -492,9 +492,7 @@
/turf/open/floor/iron/dark,
/area/shuttle/pirate)
"CW" = (
/obj/machinery/vending/boozeomat{
onstation = 0
},
/obj/machinery/vending/boozeomat,
/turf/open/floor/iron/dark/textured,
/area/shuttle/pirate)
"DX" = (
@@ -967,9 +965,7 @@
/turf/open/floor/carpet/royalblack,
/area/shuttle/pirate)
"XB" = (
/obj/machinery/vending/boozeomat{
onstation = 0
},
/obj/machinery/vending/boozeomat,
/obj/machinery/light/small/directional/south,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
dir = 10
+3 -10
View File
@@ -35,9 +35,7 @@
/turf/open/floor/pod/dark,
/area/misc/survivalpod)
"h" = (
/obj/machinery/vending/boozeomat{
onstation = 0
},
/obj/machinery/vending/boozeomat,
/turf/open/floor/pod/dark,
/area/misc/survivalpod)
"i" = (
@@ -146,9 +144,7 @@
/turf/open/floor/carpet/black,
/area/misc/survivalpod)
"z" = (
/obj/machinery/vending/cigarette{
onstation = 0
},
/obj/machinery/vending/cigarette,
/turf/open/floor/carpet/black,
/area/misc/survivalpod)
"A" = (
@@ -226,10 +222,7 @@
/turf/open/floor/carpet/black,
/area/misc/survivalpod)
"L" = (
/obj/machinery/vending/snack/blue{
req_access = null;
onstation = 0
},
/obj/machinery/vending/snack/blue,
/turf/open/floor/carpet/black,
/area/misc/survivalpod)
"M" = (
@@ -17,8 +17,8 @@
grind_results = list(/datum/reagent/silicon = 20)
greyscale_colors = CIRCUIT_COLOR_GENERIC
var/build_path = null
///determines if the circuit board originated from a vendor off station or not.
var/onstation = TRUE
/// whether or not the circuit board will build into a vendor whose products cost nothing (used for offstation vending machines mostly)
var/all_products_free = FALSE
///determines if the board requires specific levels of parts. (ie specifically a femto menipulator vs generic manipulator)
var/specific_parts = FALSE
@@ -159,7 +159,7 @@
mask = /obj/item/clothing/mask/fakemoustache/italian
/obj/machinery/vending/hotdog/museum
onstation_override = TRUE
all_products_free = TRUE
/obj/machinery/vending/hotdog/museum/screwdriver_act(mob/living/user, obj/item/attack_item)
return NONE
+18 -8
View File
@@ -187,16 +187,23 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
/**
* Is this item on station or not
*
* if it doesn't originate from off-station during mapload, everything is free
* if it doesn't originate from off-station during mapload, all_products_free gets automatically set to TRUE if it was unset previously.
* if it's off-station during mapload, it's also safe from the brand intelligence event
*/
var/onstation = TRUE
/**
* A variable to change on a per instance basis on the map that allows the instance
* to ignore whether it's on the station or not.
* Useful to force cost and ID requirements. DO NOT APPLY THIS GLOBALLY.
* DO NOT APPLY THIS GLOBALLY. For mapping var edits only.
* A variable to change on a per instance basis that allows the instance to avoid having onstation set for them during mapload.
* Setting this to TRUE means that the vending machine is treated as if it were still onstation if it spawns off-station during mapload.
* Useful to specify an off-station machine that will be affected by machine-brand intelligence for whatever reason.
*/
var/onstation_override = FALSE
/**
* If this is set to TRUE, all products sold by the vending machine are free (cost nothing).
* If unset, this will get automatically set to TRUE during init if the machine originates from off-station during mapload.
* Defaults to null, set it to TRUE or FALSE explicitly on a per-machine basis if you want to force it to be a certain value.
*/
var/all_products_free
///Items that the players have loaded into the vendor
var/list/vending_machine_input = list()
@@ -260,8 +267,10 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
if(!is_station_level(z))
if(!onstation_override)
onstation = FALSE
if(isnull(all_products_free)) // Only auto-set the free products var if we haven't explicitly assigned a value to it yet.
all_products_free = TRUE
if(circuit)
circuit.onstation = onstation //sync up the circuit so the pricing schema is carried over if it's reconstructed.
circuit.all_products_free = all_products_free //sync up the circuit so the pricing schema is carried over if it's reconstructed.
else if(HAS_TRAIT(SSstation, STATION_TRAIT_VENDING_SHORTAGE))
for (var/datum/data/vending_product/product_record as anything in product_records + coin_records + hidden_records)
@@ -275,9 +284,9 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
if(tiltable && prob(6)) // 1 in 17 chance to start tilted (as an additional hint to the station trait behind it)
INVOKE_ASYNC(src, PROC_REF(tilt), loc)
credits_contained = 0 // If it's tilted, it's been looted, so no credits for you.
else if(circuit && (circuit.onstation != onstation)) //check if they're not the same to minimize the amount of edited values.
onstation = circuit.onstation //if it was constructed outside mapload, sync the vendor up with the circuit's var so you can't bypass price requirements by moving / reconstructing it off station.
if(onstation && !onstation_override)
else if(circuit)
all_products_free = circuit.all_products_free //if it was constructed outside mapload, sync the vendor up with the circuit's var so you can't bypass price requirements by moving / reconstructing it off station.
if(!all_products_free)
AddComponent(/datum/component/payment, 0, SSeconomy.get_dep_account(payment_department), PAYMENT_VENDING)
GLOB.vending_machines_to_restock += src //We need to keep track of the final onstation vending machines so we can keep them restocked.
register_context()
@@ -1218,6 +1227,7 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock)
/obj/machinery/vending/ui_static_data(mob/user)
var/list/data = list()
data["onstation"] = onstation
data["all_products_free"] = all_products_free
data["department"] = payment_department
data["jobDiscount"] = DEPARTMENT_DISCOUNT
data["product_records"] = list()
+1 -1
View File
@@ -10,7 +10,7 @@
circuit = null
product_slogans = "Spawn \" too annoying? Too lazy to open game panel? This one's for you!;Subtype vendor, for all your debugging woes!"
default_price = 0
onstation = FALSE
all_products_free = TRUE
/// Spawns coders by default
var/type_to_vend = /obj/item/food/grown/citrus
+1 -1
View File
@@ -36,7 +36,7 @@
desc = "A vending machine which vends food, as required by section 47-C of the NT's Prisoner Ethical Treatment Agreement. \
This one, however, processes labor points for its products if the user is incarcerated."
icon_state = "sustenance_labor"
onstation_override = TRUE
all_products_free = FALSE
displayed_currency_icon = "digging"
displayed_currency_name = " LP"
+7 -6
View File
@@ -18,6 +18,7 @@ import { DmIcon, Input } from '../components';
import { Window } from '../layouts';
type VendingData = {
all_products_free: boolean;
onstation: boolean;
department: string;
jobDiscount: number;
@@ -218,7 +219,7 @@ const ProductDisplay = (props: {
} = props;
const {
stock,
onstation,
all_products_free,
user,
displayed_currency_icon,
displayed_currency_name,
@@ -231,7 +232,7 @@ const ProductDisplay = (props: {
title="Products"
buttons={
<Stack>
{!!onstation && user && (
{!all_products_free && user && (
<Stack.Item fontSize="16px" color="green">
{(user && user.cash) || 0}
{displayed_currency_name}{' '}
@@ -277,15 +278,15 @@ const ProductDisplay = (props: {
const VendingRow = (props) => {
const { data } = useBackend<VendingData>();
const { custom, product, productStock } = props;
const { access, department, jobDiscount, onstation, user } = data;
const free = !onstation || product.price === 0;
const { access, department, jobDiscount, all_products_free, user } = data;
const free = all_products_free || product.price === 0;
const discount = !product.premium && department === user?.department;
const remaining = custom ? product.amount : productStock.amount;
const redPrice = Math.round(product.price * jobDiscount);
const disabled =
remaining === 0 ||
(onstation && !user) ||
(onstation &&
(!all_products_free && !user) ||
(!all_products_free &&
!access &&
(discount ? redPrice : product.price) > user?.cash);