Merge branch 'master' of https://github.com/tgstation/tgstation into upstream-23-10-2025

This commit is contained in:
Roxy
2025-10-23 17:38:23 -04:00
453 changed files with 20635 additions and 15897 deletions
+56 -52
View File
@@ -30,14 +30,6 @@ Then the player gets the profit from selling his own wasted time.
///set to false if any objects in a dry run were unscannable
var/all_contents_scannable = TRUE
/// Makes sure the exports list is populated and that the report isn't null.
/proc/init_export(datum/export_report/external_report)
if(!length(GLOB.exports_list))
setupExports()
if(isnull(external_report))
external_report = new
return external_report
/*
* Handles exporting a movable atom and its contents
* Arguments:
@@ -52,7 +44,8 @@ Then the player gets the profit from selling his own wasted time.
if(!islist(export_markets))
export_markets = list(export_markets)
external_report = init_export(external_report)
if(!external_report)
external_report = new
var/list/contents = exported_atom.get_all_contents_ignoring(ignore_typecache)
@@ -73,7 +66,8 @@ Then the player gets the profit from selling his own wasted time.
/// It works like export_item_and_contents(), however it ignores the contents. Meaning only `exported_atom` will be valued.
/proc/export_single_item(atom/movable/exported_atom, apply_elastic = TRUE, delete_unsold = TRUE, dry_run = FALSE, datum/export_report/external_report, export_markets = list(EXPORT_MARKET_STATION))
external_report = init_export(external_report)
if(!external_report)
external_report = new
var/sold = _export_loop(exported_atom, apply_elastic, dry_run, external_report, export_markets)
if(!dry_run && (sold || delete_unsold) && sold != EXPORT_SOLD_DONT_DELETE)
@@ -95,23 +89,28 @@ Then the player gets the profit from selling his own wasted time.
external_report.all_contents_scannable = FALSE
break
sold = export.sell_object(exported_atom, external_report, dry_run, apply_elastic)
external_report.exported_atoms += " [exported_atom.name]"
break
return sold
/datum/export
abstract_type = /datum/export
/// Unit name. Only used in "Received [total_amount] [name]s [message]."
var/unit_name = ""
/// Message appended to the sale report
var/message = ""
/// Cost of item, in cargo credits. Must not allow for infinite price dupes, see above.
///Price per unit of an exported item
var/cost = 1
/// whether this export can have a negative impact on the cargo budget or not
var/allow_negative_cost = FALSE
/// coefficient used in marginal price calculation that roughly corresponds to the inverse of price elasticity, or "quantity elasticity"
var/k_elasticity = 1/30
/// Coefficient used in the recovery of elastic price calculation. See Process, this value and k_elasticity are multiplied together to form the exponent that returns the price to normal.
var/k_recovery_elasticity = 1/30
///The percentage of an items real price that is earned when selling that item on cargo
var/k_elasticity = 1
///The percentage decrease on this exports elasticity per unit of item sold
var/k_hit_percentile = 0.05
///Time taken for this exports elasticity to reach back to 100%
var/k_recovery_time = 10 MINUTES
/// The multiplier of the amount sold shown on the report. Useful for exports, such as material, which costs are not strictly per single units sold.
var/amount_report_multiplier = 1
/// Type of the exported object. If none, the export datum is considered base type.
@@ -125,46 +124,55 @@ Then the player gets the profit from selling his own wasted time.
/// Export market that this export applies to. Defaults to EXPORT_MARKET_STATION for items sold to the standard supply shuttle, replacements exist for pirates, etc.
var/sales_market = EXPORT_MARKET_STATION
/// cost includes elasticity, this does not.
var/init_cost
/datum/export/New()
..()
SSprocessing.processing += src
init_cost = cost
export_types = typecacheof(export_types, only_root_path = !include_subtypes, ignore_root_path = FALSE)
export_types = typecacheof(export_types, only_root_path = !include_subtypes)
exclude_types = typecacheof(exclude_types)
/datum/export/Destroy()
SSprocessing.processing -= src
return ..()
/datum/export/process()
cost *= NUM_E**(k_elasticity * k_recovery_elasticity)
// A little note here based on the standard values for k_recovery_elasticity: 1/30 will result in a price that started at 20% to go back to 100% in around 20 minutes, ramping up over time.
if(cost > init_cost)
cost = init_cost
/datum/export/process(seconds_per_tick)
k_elasticity += seconds_per_tick / k_recovery_time
if(k_elasticity >= 1)
k_elasticity = 1
return PROCESS_KILL
/// Checks the cost. 0 cost items are skipped in export.
/datum/export/proc/get_cost(obj/exported_item, apply_elastic = TRUE)
var/amount = get_amount(exported_item)
if(apply_elastic)
if(k_elasticity != 0)
return round((cost/k_elasticity) * (1 - NUM_E**(-1 * k_elasticity * amount))) //anti-derivative of the marginal cost function
else
return round(cost * amount) //alternative form derived from L'Hopital to avoid division by 0
else
return round(init_cost * amount)
/**
* Returns the cost of 1 unit of the exported item
*
* Arguments
* * obj/exported_item - the item we whos base cost we are trying to compute
*/
/datum/export/proc/get_base_cost(obj/exported_item)
return cost
/*
* Checks the amount of exportable in object. Credits in the bill, sheets in the stack, etc.
* Usually acts as a multiplier for a cost, so item that has 0 amount will be skipped in export.
* Returns the amount of exportable in object. Credits in the bill, sheets in the stack, etc.
* Usually acts as a multiplier for a cost, so item that has 0 amount will be skipped in export.
*
* Arguments
* * obj/exported_item - the amount of units in this exported item
*/
/datum/export/proc/get_amount(obj/exported_item)
return 1
/**
* Returns the cost of the xported item i.e. amount * base cost * elasticity if TRUE
*
* Arguments
* * obj/exported_item - the item we are trying to export
* * apply_elastic - should we use elasticity
*/
/datum/export/proc/get_cost(obj/exported_item, apply_elastic = TRUE)
SHOULD_NOT_OVERRIDE(TRUE)
var/total = get_base_cost(exported_item) * get_amount(exported_item)
if(apply_elastic && initial(k_elasticity) > 0)
total *= k_elasticity
return ROUND_UP(total)
/// Checks if the item is fit for export datum.
/datum/export/proc/applies_to(obj/exported_item, apply_elastic = TRUE, export_markets)
for(var/found_market in export_markets)
@@ -206,10 +214,14 @@ Then the player gets the profit from selling his own wasted time.
if(!(export_result & COMPONENT_STOP_EXPORT_REPORT))
report.total_value[src] += export_value
report.total_amount[src] += export_amount * amount_report_multiplier
report.exported_atoms += "[sold_item.name]"
if(!dry_run)
if(apply_elastic)
cost *= NUM_E**(-1 * k_elasticity * export_amount) //marginal cost modifier
if(apply_elastic && k_elasticity > 0)
k_elasticity -= export_amount * k_hit_percentile
if(k_elasticity < 0)
k_elasticity = 0
SSprocessing.processing |= src
SSblackbox.record_feedback("nested tally", "export_sold_cost", 1, list("[sold_item.type]", "[export_value]"))
return EXPORT_SOLD
@@ -242,11 +254,3 @@ Then the player gets the profit from selling his own wasted time.
msg += "."
return msg
GLOBAL_LIST_EMPTY(exports_list)
/// Called when the global exports_list is empty, and sets it up.
/proc/setupExports()
for(var/subtype in subtypesof(/datum/export))
var/datum/export/export_datum = new subtype
if(export_datum.export_types && export_datum.export_types.len) // Exports without a type are invalid/base types
GLOB.exports_list += export_datum
@@ -4,5 +4,5 @@
unit_name = "completed bounty cube"
export_types = list(/obj/item/bounty_cube)
/datum/export/bounty_box/get_cost(obj/item/bounty_cube/cube, apply_elastic)
/datum/export/bounty_box/get_base_cost(obj/item/bounty_cube/cube)
return cube.bounty_value + (cube.bounty_value * cube.speed_bonus)
+3 -4
View File
@@ -1,9 +1,8 @@
/datum/export/fish
cost = 30
k_hit_percentile = 0.03
unit_name = "fish"
export_types = list(/obj/item/fish)
/datum/export/fish/get_cost(obj/item/fish/fish, apply_elastic)
var/elastic_cost = ..()
var/elastic_percent = elastic_cost / init_cost
return round(fish.get_export_price(elastic_cost, elastic_percent))
/datum/export/fish/get_base_cost(obj/item/fish/fish)
return fish.get_export_price(..())
+2 -7
View File
@@ -10,13 +10,8 @@
include_subtypes = TRUE
exclude_types = list(/obj/item/food/grown)
/datum/export/food/get_cost(obj/item/food/object, allowed_categories, apply_elastic)
/datum/export/food/get_base_cost(obj/item/food/object)
if(HAS_TRAIT(object, TRAIT_FOOD_SILVER))
return FOOD_PRICE_WORTHLESS
var/elastic_cost = ..()
if(object.venue_value)
var/elastic_percent = elastic_cost / init_cost
return round(object.venue_value * elastic_percent)
return elastic_cost
return object.venue_value ? object.venue_value : ..()
+20 -22
View File
@@ -1,109 +1,107 @@
/datum/export/gear
/datum/export/gear/sec_helmet
/datum/export/sec_helmet
cost = CARGO_CRATE_VALUE * 0.5
unit_name = "helmet"
export_types = list(/obj/item/clothing/head/helmet/sec)
/datum/export/gear/sec_armor
/datum/export/sec_armor
cost = CARGO_CRATE_VALUE * 0.5
unit_name = "armor vest"
export_types = list(/obj/item/clothing/suit/armor/vest)
/datum/export/gear/riot_shield
/datum/export/riot_shield
cost = CARGO_CRATE_VALUE * 0.5
unit_name = "riot shield"
export_types = list(/obj/item/shield/riot)
/datum/export/gear/mask/breath
/datum/export/breath_mask
cost = CARGO_CRATE_VALUE * 0.01
unit_name = "breath mask"
export_types = list(/obj/item/clothing/mask/breath)
/datum/export/gear/mask/gas
/datum/export/gas_mask
cost = CARGO_CRATE_VALUE * 0.05
unit_name = "gas mask"
export_types = list(/obj/item/clothing/mask/gas)
include_subtypes = FALSE
/datum/export/gear/space/helmet
/datum/export/helmet_space
cost = CARGO_CRATE_VALUE * 0.15
unit_name = "space helmet"
export_types = list(/obj/item/clothing/head/helmet/space, /obj/item/clothing/head/helmet/space/eva, /obj/item/clothing/head/helmet/space/nasavoid)
include_subtypes = FALSE
/datum/export/gear/space/suit
/datum/export/suit_space
cost = CARGO_CRATE_VALUE * 0.3
unit_name = "space suit"
export_types = list(/obj/item/clothing/suit/space, /obj/item/clothing/suit/space/eva, /obj/item/clothing/suit/space/nasavoid)
include_subtypes = FALSE
/datum/export/gear/space/syndiehelmet
/datum/export/syndiehelmet_space
cost = CARGO_CRATE_VALUE * 0.3
unit_name = "Syndicate space helmet"
export_types = list(/obj/item/clothing/head/helmet/space/syndicate)
/datum/export/gear/space/syndiesuit
/datum/export/syndiesuit_space
cost = CARGO_CRATE_VALUE * 0.6
unit_name = "Syndicate space suit"
export_types = list(/obj/item/clothing/suit/space/syndicate)
/datum/export/gear/radhelmet
/datum/export/radhelmet
cost = CARGO_CRATE_VALUE * 0.1
unit_name = "radsuit hood"
export_types = list(/obj/item/clothing/head/utility/radiation)
/datum/export/gear/radsuit
/datum/export/radsuit
cost = CARGO_CRATE_VALUE * 0.2
unit_name = "radsuit"
export_types = list(/obj/item/clothing/suit/utility/radiation)
/datum/export/gear/biohood
/datum/export/biohood
cost = CARGO_CRATE_VALUE * 0.1
unit_name = "biosuit hood"
export_types = list(/obj/item/clothing/head/bio_hood)
/datum/export/gear/biosuit
/datum/export/biosuit
cost = CARGO_CRATE_VALUE * 0.2
unit_name = "biosuit"
export_types = list(/obj/item/clothing/suit/bio_suit)
/datum/export/gear/bombhelmet
/datum/export/bombhelmet
cost = CARGO_CRATE_VALUE * 0.1
unit_name = "bomb suit hood"
export_types = list(/obj/item/clothing/head/utility/bomb_hood)
/datum/export/gear/bombsuit
/datum/export/bombsuit
cost = CARGO_CRATE_VALUE * 0.2
unit_name = "bomb suit"
export_types = list(/obj/item/clothing/suit/utility/bomb_suit)
/datum/export/gear/lizardboots
/datum/export/lizardboots
cost = CARGO_CRATE_VALUE * 0.7
unit_name = "lizard skin boots"
export_types = list(/obj/item/clothing/shoes/cowboy/lizard)
include_subtypes = FALSE
/datum/export/gear/lizardmasterwork
/datum/export/lizardmasterwork
cost = CARGO_CRATE_VALUE * 2
unit_name = "Hugs-the-Feet lizard boots"
export_types = list(/obj/item/clothing/shoes/cowboy/lizard/masterwork)
/datum/export/gear/bilton
/datum/export/bilton
cost = CARGO_CRATE_VALUE * 5
unit_name = "bilton wrangler boots"
export_types = list(/obj/item/clothing/shoes/cowboy/fancy)
/datum/export/gear/ebonydie
/datum/export/ebonydie
cost = CARGO_CRATE_VALUE
unit_name = "ebony die"
export_types = list(/obj/item/dice/d6/ebony)
/datum/export/gear/rare_lighter
/datum/export/rare_lighter
cost = CARGO_CRATE_VALUE * 4
unit_name = "novelty lighter"
export_types = list(
+43 -44
View File
@@ -1,4 +1,4 @@
/datum/export/large/crate
/datum/export/crate
cost = CARGO_CRATE_VALUE
k_elasticity = 0
unit_name = "crate"
@@ -10,119 +10,114 @@
/obj/structure/closet/crate/wooden,
)
/datum/export/large/crate/total_printout(datum/export_report/ex, notes = TRUE) // That's why a goddamn metal crate costs that much.
/datum/export/crate/total_printout(datum/export_report/ex, notes = TRUE) // That's why a goddamn metal crate costs that much.
. = ..()
if(. && notes)
. += " Thanks for participating in Nanotrasen Crates Recycling Program."
/datum/export/large/crate/wooden
cost = CARGO_CRATE_VALUE/5
/datum/export/crate/wooden
cost = CARGO_CRATE_VALUE / 5
unit_name = "large wooden crate"
export_types = list(/obj/structure/closet/crate/large)
exclude_types = list()
/datum/export/large/crate/wooden/ore
/datum/export/crate/wooden/ore
unit_name = "ore box"
export_types = list(/obj/structure/ore_box)
/datum/export/large/crate/wood
/datum/export/crate/wood
cost = CARGO_CRATE_VALUE * 0.48
unit_name = "wooden crate"
export_types = list(/obj/structure/closet/crate/wooden)
exclude_types = list()
/datum/export/large/crate/coffin
/datum/export/crate/coffin
cost = CARGO_CRATE_VALUE/2 //50 wooden crates cost 800 credits, and you can make 10 coffins in seconds with those planks. Each coffin selling for 100 means you can make a net gain of 200 credits for wasting your time making coffins.
unit_name = "coffin"
export_types = list(/obj/structure/closet/crate/coffin)
/datum/export/large/reagent_dispenser
/datum/export/reagent_dispenser
abstract_type = /datum/export/reagent_dispenser
cost = CARGO_CRATE_VALUE * 0.5 // +0-400 depending on amount of reagents left
///cost for an full holder of reagents
var/contents_cost = CARGO_CRATE_VALUE * 0.8
/datum/export/large/reagent_dispenser/get_cost(obj/structure/reagent_dispensers/dispenser)
var/ratio = dispenser.reagents.total_volume / dispenser.reagents.maximum_volume
/datum/export/reagent_dispenser/get_base_cost(obj/structure/reagent_dispensers/dispenser)
return ..() + round(contents_cost * (dispenser.reagents.total_volume / dispenser.reagents.maximum_volume))
return ..() + round(contents_cost * ratio)
/datum/export/large/reagent_dispenser/water
/datum/export/reagent_dispenser/water
unit_name = "watertank"
export_types = list(/obj/structure/reagent_dispensers/watertank)
contents_cost = CARGO_CRATE_VALUE * 0.4
/datum/export/large/reagent_dispenser/fuel
/datum/export/reagent_dispenser/fuel
unit_name = "fueltank"
export_types = list(/obj/structure/reagent_dispensers/fueltank)
/datum/export/large/reagent_dispenser/beer
/datum/export/reagent_dispenser/beer
unit_name = "beer keg"
contents_cost = CARGO_CRATE_VALUE * 3.5
export_types = list(/obj/structure/reagent_dispensers/beerkeg)
/datum/export/large/pipedispenser
/datum/export/pipedispenser
cost = CARGO_CRATE_VALUE * 2.5
unit_name = "pipe dispenser"
export_types = list(/obj/machinery/pipedispenser)
/datum/export/large/emitter
/datum/export/emitter
cost = CARGO_CRATE_VALUE * 2.75
unit_name = "emitter"
export_types = list(/obj/machinery/power/emitter)
/datum/export/large/field_generator
/datum/export/field_generator
cost = CARGO_CRATE_VALUE * 2.75
unit_name = "field generator"
export_types = list(/obj/machinery/field/generator)
/datum/export/large/tesla_coil
/datum/export/tesla_coil
cost = CARGO_CRATE_VALUE * 2.25
unit_name = "tesla coil"
export_types = list(/obj/machinery/power/energy_accumulator/tesla_coil)
/datum/export/large/supermatter
/datum/export/supermatter
cost = CARGO_CRATE_VALUE * 16
unit_name = "supermatter shard"
export_types = list(/obj/machinery/power/supermatter_crystal/shard)
/datum/export/large/grounding_rod
/datum/export/grounding_rod
cost = CARGO_CRATE_VALUE * 1.2
unit_name = "grounding rod"
export_types = list(/obj/machinery/power/energy_accumulator/grounding_rod)
/datum/export/large/iv
/datum/export/iv
cost = CARGO_CRATE_VALUE * 0.25
unit_name = "iv drip"
export_types = list(/obj/machinery/iv_drip)
/datum/export/large/barrier
/datum/export/barrier
cost = CARGO_CRATE_VALUE * 0.25
unit_name = "security barrier"
export_types = list(/obj/item/grenade/barrier, /obj/structure/barricade/security)
/**
* Gas canister exports.
* I'm going to put a quick aside here as this has been a pain to balance for several years now, and I'd like to at least break how to keep gas exports tame.
* So: Gasses are sold in canisters below, which have a variable amount of maximum pressure before they start to break. The largest of which is 9.2e13 kPa.
* This means we can determine a theoretical maximum value for gas sale prices using the ideal gas laws, as we know we have a minimum gas temperature of 2.7 kelvin.
*
* Additional note on base value. Gasses are soft capped to limit how much they're worth at large quantities, and time and time again players will find new ways to break your gasses.
* so please, *PLEASE* try not to go too much further past 10.
///Maximum number of credits you can earn from selling your gas canister cause its theoritically infinite
#define MAX_GAS_CREDITS 15000
* * AUTHORS NOTE: This means the theoretical, insane madman number of moles of a single gas in a can sits at a horrifying 4,098,150,709.4 moles.
* * Use this as you will, and when someone makes a quinquadrillion credits using gas exports, use these metrics as a way to balance the bejesus out of them.
* * For more information, see code\modules\atmospherics\machinery\portable\canister.dm.
*/
/datum/export/large/gas_canister
/**
* Maximum pressure a canister can withstand is 9.2e13 kPa at a minimum of 2.7K which would contain a horrifying 4,098,150,709.4 moles.
* We don't want players making that much credits so we limit the total amount earned to MAX_GAS_CREDITS
*/
/datum/export/gas_canister
cost = CARGO_CRATE_VALUE * 0.05 //Base cost of canister. You get more for nice gases inside.
unit_name = "Gas Canister"
export_types = list(/obj/machinery/portable_atmospherics/canister)
k_elasticity = 0.00033
/datum/export/large/gas_canister/get_cost(obj/machinery/portable_atmospherics/canister/canister)
var/worth = cost
/datum/export/gas_canister/get_base_cost(obj/machinery/portable_atmospherics/canister/canister)
var/datum/gas_mixture/canister_mix = canister.return_air()
if(!canister_mix.total_moles())
return 0
var/canister_gas = canister_mix.gases
var/list/gases_to_check = list(
var/static/list/gases_to_check = list(
/datum/gas/bz,
/datum/gas/nitrium,
/datum/gas/hypernoblium,
@@ -140,14 +135,18 @@
/datum/gas/goblin //BUBBERSTATION CHANGE
)
var/worth = cost
for(var/gasID in gases_to_check)
canister_mix.assert_gas(gasID)
if(canister_gas[gasID][MOLES] > 0)
worth += get_gas_value(gasID, canister_gas[gasID][MOLES])
if(worth > MAX_GAS_CREDITS)
worth = MAX_GAS_CREDITS
break
canister_mix.garbage_collect()
return worth
/datum/export/large/gas_canister/proc/get_gas_value(datum/gas/gasType, moles)
var/baseValue = initial(gasType.base_value)
return round((baseValue/k_elasticity) * (1 - NUM_E**(-1 * k_elasticity * moles)))
/datum/export/gas_canister/proc/get_gas_value(datum/gas/gasType, moles)
return ROUND_UP(initial(gasType.base_value) * moles)
#undef MAX_GAS_CREDITS
+1
View File
@@ -1,6 +1,7 @@
//Tendril chest artifacts and ruin loot.
//Consumable or one-use items like the magic D20 and gluttony's blessing are omitted
/datum/export/lavaland
abstract_type = /datum/export/lavaland
unit_name = "lava planet artifact"
/// Prefix to add to our unit name after generation
var/prefix = null
+3 -6
View File
@@ -36,8 +36,7 @@
return TRUE
return FALSE
/datum/export/manifest_error_denied/get_cost(obj/O)
var/obj/item/paper/fluff/jobs/cargo/manifest/M = O
/datum/export/manifest_error_denied/get_base_cost(obj/item/paper/fluff/jobs/cargo/manifest/M)
return ..() + M.order_cost
@@ -59,8 +58,7 @@
return TRUE
return FALSE
/datum/export/manifest_error/get_cost(obj/O)
var/obj/item/paper/fluff/jobs/cargo/manifest/M = O
/datum/export/manifest_error/get_base_cost(obj/item/paper/fluff/jobs/cargo/manifest/M)
return -min(M.order_cost * 0.5, MAX_MANIFEST_PENALTY)
@@ -82,8 +80,7 @@
return TRUE
return FALSE
/datum/export/manifest_correct_denied/get_cost(obj/O)
var/obj/item/paper/fluff/jobs/cargo/manifest/M = O
/datum/export/manifest_correct_denied/get_base_cost(obj/item/paper/fluff/jobs/cargo/manifest/M)
return -min(M.order_cost * 0.5, MAX_MANIFEST_PENALTY)
#undef MAX_MANIFEST_PENALTY
+86 -62
View File
@@ -1,33 +1,55 @@
/datum/export/material
abstract_type = /datum/export/material
cost = 5 // Cost per SHEET_MATERIAL_AMOUNT, which is 100cm3 as of May 2023.
k_hit_percentile = 0.2 / MAX_STACK_SIZE //Meaning selling 1 full stack of materials will decrease subsequent sales by 20%
k_recovery_time = 8 MINUTES
message = "cm3 of developer's tears. Please, report this on github"
amount_report_multiplier = SHEET_MATERIAL_AMOUNT
var/datum/material/material_id = null
export_types = list(
/obj/item/stack/sheet/mineral,
/obj/item/stack/tile/mineral,
/obj/item/stack/ore,
/obj/item/coin
)
///Material id we are trying to
var/datum/material/material_id = null
// Yes, it's a base type containing export_types.
// But it has no material_id, so any applies_to check will return false, and these types reduce amount of copypasta a lot
/datum/export/material/New()
var/temp_exports = export_types
export_types = null
. = ..()
export_types = init_export_types(temp_exports)
/**
* Inits an list of exports for this type. For performance this usually returns a static list
*
* Arguments
* * export_data - exports whos type cache we are trying to create
*/
/datum/export/material/proc/init_export_types(export_data)
PROTECTED_PROC(TRUE)
var/static/list/shared_exports = null
if(isnull(shared_exports))
shared_exports = typecacheof(export_data, only_root_path = !include_subtypes)
return shared_exports
/datum/export/material/get_amount(obj/O)
if(!material_id)
return 0
if(!isitem(O))
return 0
var/obj/item/I = O
var/list/mat_comp = I.get_material_composition()
var/datum/material/mat_ref = ispath(material_id) ? locate(material_id) in mat_comp : GET_MATERIAL_REF(material_id)
if(isnull(mat_comp[mat_ref]))
var/amount = mat_comp[mat_ref]
if(!amount)
return 0
var/amount = mat_comp[mat_ref]
if(istype(I, /obj/item/stack/ore))
amount *= 0.8 // Station's ore redemption equipment is really goddamn good.
return round(amount / SHEET_MATERIAL_AMOUNT)
// Materials. Static materials exist as parent types, while materials subject to the stock market have a fluid cost as determined by material/market types
@@ -35,7 +57,6 @@
/datum/export/material/plasma
cost = CARGO_CRATE_VALUE * 0.4
k_elasticity = 0
material_id = /datum/material/plasma
message = "cm3 of plasma"
@@ -44,7 +65,7 @@
material_id = /datum/material/bananium
message = "cm3 of bananium"
/datum/export/material/diamond
/datum/export/material/adamantine
cost = CARGO_CRATE_VALUE
material_id = /datum/material/adamantine
message = "cm3 of adamantine"
@@ -70,76 +91,48 @@
material_id = /datum/material/hot_ice
export_types = /obj/item/stack/sheet/hot_ice
/datum/export/material/hot_ice/init_export_types(export_data)
return typecacheof(export_data, only_root_path = !include_subtypes)
/datum/export/material/metal_hydrogen
cost = CARGO_CRATE_VALUE * 1.05
message = "cm3 of metallic hydrogen"
material_id = /datum/material/metalhydrogen
export_types = /obj/item/stack/sheet/mineral/metal_hydrogen
/datum/export/material/metal_hydrogen/init_export_types(export_data)
return typecacheof(export_data, only_root_path = !include_subtypes)
/datum/export/material/market
abstract_type = /datum/export/material/market
cost = 1
k_recovery_elasticity = 1/10 //Modeled such that a stack of materials, selling to drop the cost to ~20%, will recover fully in 8 minutes instead of 20.
export_types = list(
/obj/item/stack/sheet/mineral,
/obj/item/stack/tile/mineral,
/obj/item/stack/ore,
/obj/item/coin,
/obj/item/stock_block,
)
/datum/export/material/market/applies_to(obj/exported_obj, apply_elastic)
. = ..()
if(istype(exported_obj, /obj/item/stock_block))
var/obj/item/stock_block/block = exported_obj
if(!block.export_mat)
return FALSE
if(block.export_mat == material_id)
return TRUE
return FALSE
/datum/export/material/market/get_base_cost(obj/exported_obj)
return ..() * SSstock_market.materials_prices[material_id]
/datum/export/material/market/get_amount(obj/exported_obj)
if(istype(exported_obj, /obj/item/stock_block))
var/obj/item/stock_block/block = exported_obj
return block.quantity
return ..()
/**
* Returns number of sheets in this item
*
* Arguments
* * obj/sold_item - the item whos sheets we are computing
*/
/datum/export/material/market/proc/get_sheets(obj/sold_item)
PROTECTED_PROC(TRUE)
/datum/export/material/market/get_cost(obj/exported_obj, apply_elastic = TRUE)
if(!material_id)
return 0
var/obj/item/exported_item = exported_obj
var/amount = get_amount(exported_item)
if(!amount)
return 0
var/obj/item/stock_block/block
if(istype(exported_item, /obj/item/stock_block))
block = exported_item
if(block.export_mat != material_id)
return 0
var/material_value = 0
if(block)
if(block.fluid)
material_value = SSstock_market.materials_prices[block.export_mat] * amount
else
material_value = block.export_value
else
material_value = SSstock_market.materials_prices[material_id] * amount
return (apply_elastic ? cost : init_cost) * material_value // Cost in this case is only serving as the elastic modifier, where material value is the raw value of the sheets sold.
return get_amount(sold_item)
/datum/export/material/market/sell_object(obj/sold_item, datum/export_report/report, dry_run, apply_elastic)
. = ..()
var/amount = get_amount(sold_item)
if(!amount)
var/sheets = get_sheets(sold_item)
if(!sheets)
return
//This formula should impact lower quantity materials greater, and higher quantity materials less. Still, it's a bit rough. Tweaking may be needed.
if(!dry_run)
//decrease the market price
SSstock_market.adjust_material_price(material_id, -SSstock_market.materials_prices[material_id] * (amount / (amount + SSstock_market.materials_quantity[material_id])))
SSstock_market.adjust_material_price(material_id, -SSstock_market.materials_prices[material_id] * (sheets / (sheets + SSstock_market.materials_quantity[material_id])))
//increase the stock
SSstock_market.adjust_material_quantity(material_id, amount)
SSstock_market.adjust_material_quantity(material_id, sheets)
/datum/export/material/market/diamond
material_id = /datum/material/diamond
@@ -167,8 +160,10 @@
export_types = list(
/obj/item/stack/sheet/bluespace_crystal,
/obj/item/stack/ore/bluespace_crystal,
/obj/item/stock_block,
) //For whatever reason, bluespace crystals are not a mineral
)
/datum/export/material/market/bscrystal/init_export_types(export_data)
return typecacheof(export_data, only_root_path = !include_subtypes)
/datum/export/material/market/iron
message = "cm3 of iron"
@@ -179,9 +174,11 @@
/obj/item/stack/rods,
/obj/item/stack/ore,
/obj/item/coin,
/obj/item/stock_block,
)
/datum/export/material/market/iron/init_export_types(export_data)
return typecacheof(export_data, only_root_path = !include_subtypes)
/datum/export/material/market/glass
message = "cm3 of glass"
material_id = /datum/material/glass
@@ -189,5 +186,32 @@
/obj/item/stack/sheet/glass,
/obj/item/stack/ore,
/obj/item/shard,
/obj/item/stock_block,
)
/datum/export/material/market/glass/init_export_types(export_data)
return typecacheof(export_data, only_root_path = !include_subtypes)
/datum/export/material/market/stock_block
amount_report_multiplier = 1
k_hit_percentile = 0.2 //20% hit per block stock which is synomonous to an full stack of sheets
message = ""
unit_name = "stock block"
export_types = list(/obj/item/stock_block)
/datum/export/material/market/stock_block/init_export_types(export_data)
return typecacheof(export_data, only_root_path = !include_subtypes)
/datum/export/material/market/stock_block/get_amount(obj/item/stock_block/block)
return 1 //sold as 1 stock block but we adjust the markets via get_sheets()
/datum/export/material/market/stock_block/get_sheets(obj/item/stock_block/block)
return block.custom_materials[block.custom_materials[1]] / SHEET_MATERIAL_AMOUNT
/datum/export/material/market/stock_block/get_base_cost(obj/item/stock_block/block)
return (block.fluid ? SSstock_market.materials_prices[block.custom_materials[1].type] : block.export_value) * get_sheets(block)
/datum/export/material/market/stock_block/sell_object(obj/item/stock_block/block, datum/export_report/report, dry_run, apply_elastic)
material_id = block.custom_materials[1].type
return ..()
+5 -5
View File
@@ -1,24 +1,24 @@
/datum/export/mecha/ripley
/datum/export/ripley
cost = CARGO_CRATE_VALUE * 13
unit_name = "APLU MK-II Ripley"
export_types = list(/obj/vehicle/sealed/mecha/ripley/mk2)
/datum/export/mecha/clarke
/datum/export/clarke
cost = CARGO_CRATE_VALUE * 16
unit_name = "Clarke"
export_types = list(/obj/vehicle/sealed/mecha/clarke)
/datum/export/mecha/odysseus
/datum/export/odysseus
cost = CARGO_CRATE_VALUE * 11
unit_name = "Odysseus"
export_types = list(/obj/vehicle/sealed/mecha/odysseus)
/datum/export/mecha/gygax
/datum/export/gygax
cost = CARGO_CRATE_VALUE * 28
unit_name = "Gygax"
export_types = list(/obj/vehicle/sealed/mecha/gygax)
/datum/export/mecha/durand
/datum/export/durand
cost = CARGO_CRATE_VALUE * 20
unit_name = "Durand"
export_types = list(/obj/vehicle/sealed/mecha/durand)
+8 -10
View File
@@ -2,14 +2,13 @@
#define CLIENT_ORGAN_MULT 10
/datum/export/organ
abstract_type = /datum/export/organ
include_subtypes = FALSE //CentCom doesn't need organs from non-humans.
/datum/export/organ/get_cost(obj/exported_item, apply_elastic)
if(HAS_TRAIT(exported_item, TRAIT_CLIENT_STARTING_ORGAN))
// Multiply value for organs that started in a player
// Unaffected by price elasticity as there's a limited amount of these in play
return round(init_cost * CLIENT_ORGAN_MULT)
return ..()
/datum/export/organ/get_base_cost(obj/exported_item)
// Multiply value for organs that started in a player
// Unaffected by price elasticity as there's a limited amount of these in play
return round(..() * HAS_TRAIT(exported_item, TRAIT_CLIENT_STARTING_ORGAN) ? CLIENT_ORGAN_MULT : 1)
/datum/export/organ/heart
cost = CARGO_CRATE_VALUE * 0.2 //For the man who has everything and nothing.
@@ -46,18 +45,17 @@
unit_name = "humanoid tongue"
export_types = list(/obj/item/organ/tongue)
/datum/export/organ/external/tail/lizard
/datum/export/organ/lizard_tail
cost = CARGO_CRATE_VALUE * 1.25
unit_name = "lizard tail"
export_types = list(/obj/item/organ/tail/lizard)
/datum/export/organ/external/tail/cat
/datum/export/organ/cat_tail
cost = CARGO_CRATE_VALUE * 1.5
unit_name = "cat tail"
export_types = list(/obj/item/organ/tail/cat)
/datum/export/organ/ears/cat
/datum/export/organ/cat_ears
cost = CARGO_CRATE_VALUE
unit_name = "cat ears"
export_types = list(/obj/item/organ/ears/cat)
+6 -6
View File
@@ -1,34 +1,34 @@
// Circuit boards, spare parts, etc.
/datum/export/solar/assembly
/datum/export/solar_assembly
cost = CARGO_CRATE_VALUE * 0.25
unit_name = "solar panel assembly"
export_types = list(/obj/item/solar_assembly)
/datum/export/solar/tracker_board
/datum/export/tracker_board
cost = CARGO_CRATE_VALUE * 0.5
unit_name = "solar tracker board"
export_types = list(/obj/item/electronics/tracker)
/datum/export/solar/control_board
/datum/export/control_board
cost = CARGO_CRATE_VALUE * 0.75
unit_name = "solar panel control board"
export_types = list(/obj/item/circuitboard/computer/solar_control)
//Data Disks
/datum/export/modular_part/portabledrive/advanced
/datum/export/advanced_disk
cost = CARGO_CRATE_VALUE * 0.4
unit_name = "advanced data disk"
export_types = list(/obj/item/computer_disk/advanced)
include_subtypes = FALSE
/datum/export/modular_part/portabledrive/super
/datum/export/super_disk
cost = CARGO_CRATE_VALUE * 0.6
unit_name = "super data disk"
export_types = list(/obj/item/computer_disk/super)
include_subtypes = FALSE
/datum/export/modular_part/portabledrive/standard
/datum/export/standard_disk
cost = CARGO_CRATE_VALUE * 0.2
unit_name = "data disk"
export_types = list(/obj/item/computer_disk)
+8 -16
View File
@@ -1,38 +1,30 @@
/datum/export/seed
cost = CARGO_CRATE_VALUE * 0.25 // Gets multiplied by potency
k_elasticity = 1 //price inelastic/quantity elastic, only need to export a few samples
k_elasticity = 0 //price inelastic/quantity elastic, only need to export a few samples
unit_name = "new plant species sample"
export_types = list(/obj/item/seeds)
var/needs_discovery = FALSE // Only for undiscovered species
// Only for undiscovered species
var/needs_discovery = FALSE
// Plants sold on the market
var/static/list/discovered_plants = list()
/datum/export/seed/get_cost(obj/O)
var/obj/item/seeds/S = O
/datum/export/seed/get_base_cost(obj/item/seeds/S)
if(!needs_discovery && (S.type in discovered_plants))
return 0
if(needs_discovery && !(S.type in discovered_plants))
return 0
return ..() * S.rarity // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later.
/datum/export/seed/sell_object(obj/O, datum/export_report/report, dry_run, apply_elastic)
/datum/export/seed/sell_object(obj/item/seeds/S, datum/export_report/report, dry_run, apply_elastic)
. = ..()
if(. && !dry_run)
var/obj/item/seeds/S = O
discovered_plants[S.type] = S.potency
/datum/export/seed/potency
cost = CARGO_CRATE_VALUE * 0.0125 // Gets multiplied by potency and rarity.
unit_name = "improved plant sample"
export_types = list(/obj/item/seeds)
needs_discovery = TRUE // Only for already discovered species
/datum/export/seed/potency/get_cost(obj/O)
var/obj/item/seeds/S = O
var/cost = ..()
if(!cost)
return 0
var/potDiff = (S.potency - discovered_plants[S.type])
return round(..() * potDiff)
/datum/export/seed/potency/get_base_cost(obj/item/seeds/S)
return ..() * (S.potency - discovered_plants[S.type])
+10 -9
View File
@@ -1,4 +1,5 @@
/datum/export/stack
abstract_type = /datum/export/stack
unit_name = "sheet"
/datum/export/stack/get_amount(obj/O)
@@ -9,48 +10,48 @@
// Hides
/datum/export/stack/skin/monkey
/datum/export/stack/monkey
cost = CARGO_CRATE_VALUE * 0.25
unit_name = "monkey hide"
export_types = list(/obj/item/stack/sheet/animalhide/monkey)
/datum/export/stack/skin/human
/datum/export/stack/human
cost = CARGO_CRATE_VALUE * 0.5
unit_name = "piece"
message = "of human skin"
export_types = list(/obj/item/stack/sheet/animalhide/human)
/datum/export/stack/skin/goliath_hide
/datum/export/stack/goliath_hide
cost = CARGO_CRATE_VALUE
unit_name = "goliath hide"
export_types = list(/obj/item/stack/sheet/animalhide/goliath_hide)
/datum/export/stack/skin/cat
/datum/export/stack/cat
cost = CARGO_CRATE_VALUE * 0.75
unit_name = "cat hide"
export_types = list(/obj/item/stack/sheet/animalhide/cat)
/datum/export/stack/skin/corgi
/datum/export/stack/corgi
cost = CARGO_CRATE_VALUE
unit_name = "corgi hide"
export_types = list(/obj/item/stack/sheet/animalhide/corgi)
/datum/export/stack/skin/lizard
/datum/export/stack/lizard
cost = CARGO_CRATE_VALUE * 0.75
unit_name = "lizard hide"
export_types = list(/obj/item/stack/sheet/animalhide/lizard)
/datum/export/stack/skin/gondola
/datum/export/stack/gondola
cost = CARGO_CRATE_VALUE * 10
unit_name = "gondola hide"
export_types = list(/obj/item/stack/sheet/animalhide/gondola)
/datum/export/stack/skin/xeno
/datum/export/stack/xeno
cost = CARGO_CRATE_VALUE * 2.5
unit_name = "alien hide"
export_types = list(/obj/item/stack/sheet/animalhide/xeno)
/datum/export/stack/skin/carp
/datum/export/stack/carp
cost = CARGO_CRATE_VALUE * 0.5
unit_name = "carp skin"
export_types = list(/obj/item/stack/sheet/animalhide/carp)
@@ -5,15 +5,8 @@
exclude_types = list(/obj/item/paperwork/photocopy) //Has its own category
allow_negative_cost = TRUE
/datum/export/paperwork/get_cost(obj/item/paperwork/sold_paperwork)
var/paperwork_cost = cost
if(sold_paperwork.stamped)
paperwork_cost = ..()
else
paperwork_cost = -init_cost //Punishment for improperly filed paperwork.
return paperwork_cost
/datum/export/paperwork/get_base_cost(obj/item/paperwork/sold_paperwork)
return sold_paperwork.stamped ? ..() : -cost
/datum/export/photocopy
cost = CARGO_CRATE_VALUE
@@ -25,7 +18,7 @@
///Used to track if a batch of photocopy exports has backfired
var/backfired = FALSE
/datum/export/photocopy/get_cost(obj/item/paperwork/photocopy/sold_paperwork)
/datum/export/photocopy/get_base_cost(obj/item/paperwork/photocopy/sold_paperwork)
if(sold_paperwork.stamped && !backfired) //Upon backfiring, no more photocopies are processed or sold until the next cargo shipment
if(sold_paperwork.voided)
return 0 //Voided photocopies do nothing
@@ -34,12 +27,12 @@
if(prob(backfire_chance))
backfire_chance = 0
backfired = TRUE
return -init_cost * 4 //too high of an amount to allow for infinite money
return -cost * 4 //too high of an amount to allow for infinite money
else
return ..()
else
return -init_cost
return -cost
/datum/export/photocopy/total_printout(datum/export_report/ex, notes)
. = ..()
+2 -1
View File
@@ -1,6 +1,7 @@
// Weapon exports. Stun batons, disablers, etc.
/datum/export/weapon
abstract_type = /datum/export/weapon
include_subtypes = FALSE
/datum/export/weapon/baton
@@ -79,4 +80,4 @@
cost = CARGO_CRATE_VALUE * 1.5
unit_name = "WT-550 automatic rifle"
export_types = list(/obj/item/gun/ballistic/automatic/wt550)
+8 -10
View File
@@ -1,41 +1,39 @@
/datum/export/slime
/datum/export/slime/grey
/datum/export/slime_extract_grey
cost = CARGO_CRATE_VALUE * 0.05
unit_name = "grey slime core"
export_types = list(/obj/item/slime_extract/grey)
/datum/export/slime/common
/datum/export/slime_extract_common
cost = CARGO_CRATE_VALUE * 0.12
unit_name = "common slime core"
export_types = list(/obj/item/slime_extract/metal,/obj/item/slime_extract/orange,/obj/item/slime_extract/purple,/obj/item/slime_extract/blue)
/datum/export/slime/uncommon
/datum/export/slime_extract_uncommon
cost = CARGO_CRATE_VALUE * 0.2
unit_name = "uncommon slime core"
export_types = list(/obj/item/slime_extract/gold,/obj/item/slime_extract/green,/obj/item/slime_extract/red,/obj/item/slime_extract/pink)
/datum/export/slime/rare
/datum/export/slime_extract_rare
cost = CARGO_CRATE_VALUE * 0.28
unit_name = "rare slime core"
export_types = list(/obj/item/slime_extract/silver,/obj/item/slime_extract/darkblue,/obj/item/slime_extract/darkpurple,/obj/item/slime_extract/yellow)
/datum/export/slime/charged
/datum/export/slime_extract_charged
cost = CARGO_CRATE_VALUE
unit_name = "\improper EMP-proof slime core"
export_types = list(/obj/item/stock_parts/power_store/cell/emproof/slime)
/datum/export/slime/hypercharged
/datum/export/slime_extract_hypercharged
cost = CARGO_CRATE_VALUE * 1.2
unit_name = "hypercharged slime core"
export_types = list(/obj/item/stock_parts/power_store/cell/high/slime_hypercharged)
/datum/export/slime/epic //EPIIIIIIC
/datum/export/slime_extract_epic //EPIIIIIIC
cost = CARGO_CRATE_VALUE * 0.44
unit_name = "epic slime core"
export_types = list(/obj/item/slime_extract/black,/obj/item/slime_extract/cerulean,/obj/item/slime_extract/oil,/obj/item/slime_extract/sepia,/obj/item/slime_extract/pyrite,/obj/item/slime_extract/adamantine,/obj/item/slime_extract/lightpink,/obj/item/slime_extract/bluespace)
/datum/export/slime/rainbow
/datum/export/slime_extract_rainbow
cost = CARGO_CRATE_VALUE
unit_name = "rainbow slime core"
export_types = list(/obj/item/slime_extract/rainbow)
+6
View File
@@ -412,3 +412,9 @@
/obj/item/circuitboard/computer/shuttle/docker,
/obj/item/circuitboard/machine/engine/propulsion = 2,
)
/datum/supply_pack/goody/golfcart_key
name = "Spare Golf Cart Key"
desc = "If you in your carelessness lost the key to your golfcart you can purchase one. Unfortunately not covered by warranty."
cost = PAYCHECK_CREW * 5
contains = list(/obj/item/key/golfcart)
@@ -221,3 +221,12 @@
. = ..()
if(.)
availability_prob *= 0.5
/datum/market_item/misc/tricktrickcigarettes
name = "Trick Trick Cigarettes"
desc = "Cigarettes filled with flash powder. Makes for a fun prank!"
item = /obj/item/storage/fancy/cigarettes/flash_powder
price_min = PAYCHECK_CREW
price_max = PAYCHECK_CREW * 3
stock_max = 3
availability_prob = 25
+36 -55
View File
@@ -17,16 +17,6 @@
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION
light_power = 3
light_range = MINIMUM_USEFUL_LIGHT_RANGE
/// What items can be converted into a stock block? Must be a stack subtype based on current implementation.
var/static/list/exportable_material_items = list(
/obj/item/stack/sheet/iron, //God why are we like this
/obj/item/stack/sheet/glass, //No really, God why are we like this
/obj/item/stack/sheet/mineral,
/obj/item/stack/tile/mineral,
/obj/item/stack/ore,
/obj/item/stack/sheet/bluespace_crystal,
/obj/item/stack/rods
)
/// Are we ordering sheets from our own card balance or the cargo budget?
var/ordering_private = TRUE
@@ -55,47 +45,41 @@
if(default_deconstruction_crowbar(tool))
return ITEM_INTERACT_SUCCESS
/obj/machinery/materials_market/attackby(obj/item/markable_object, mob/user, list/modifiers, list/attack_modifiers)
if(is_type_in_list(markable_object, exportable_material_items))
if(machine_stat & NOPOWER)
balloon_alert(user, "no power!")
return FALSE
var/material_to_export
var/obj/item/stack/exportable = markable_object
for(var/datum/material/mat as anything in SSstock_market.materials_prices)
if(exportable.has_material_type(mat))
material_to_export = mat
break //This is only for trading non-alloys, so we can break here
/obj/machinery/materials_market/item_interaction(mob/living/user, obj/item/stack/exportable, list/modifiers)
. = NONE
if(!isstack(exportable))
return
if(!is_operational)
balloon_alert(user, "no power!")
return ITEM_INTERACT_FAILURE
var/datum/export_report/report = export_item_and_contents(exportable, apply_elastic = FALSE, dry_run = TRUE) // We'll apply elastic price reduction when fully sold.
var/price = 0
var/amount = 0
for(var/exported_datum in report.total_amount)
price += report.total_value[exported_datum]
amount += report.total_amount[exported_datum]
var/list/datum/material/materials = exportable.custom_materials
if(materials.len != 1)
balloon_alert(user, "alloy stacks not allowed")
return ITEM_INTERACT_FAILURE
if(amount <= 1)
balloon_alert(user, "stack too small!")
return FALSE
var/price = SSstock_market.materials_prices[materials[1].type]
if(!price)
balloon_alert(user, "materials in stack are worthless")
return ITEM_INTERACT_FAILURE
if(price <= 0)
balloon_alert(user, "not valuable enough to sell!")
return FALSE
if(!user.transferItemToLoc(exportable, src))
to_chat(user, span_warning("[exportable] is stuck in hand!"))
return ITEM_INTERACT_FAILURE
qdel(markable_object)
var/obj/item/stock_block/new_block = new /obj/item/stock_block(drop_location())
new_block.export_value = price
new_block.export_mat = material_to_export
new_block.quantity = amount / SHEET_MATERIAL_AMOUNT
to_chat(user, span_notice("You have created a stock block worth [new_block.export_value] cr! Sell it before it becomes liquid!"))
playsound(src, 'sound/machines/synth/synth_yes.ogg', 50, FALSE)
return TRUE
return ..()
var/obj/item/stock_block/new_block = new /obj/item/stock_block(drop_location())
new_block.export_value = price
new_block.set_custom_materials(materials)
to_chat(user, span_notice("You have created a stock block worth [new_block.export_value * exportable.amount] cr! Sell it before it becomes liquid!"))
playsound(src, 'sound/machines/synth/synth_yes.ogg', 50, FALSE)
qdel(exportable)
use_energy(active_power_usage)
return ITEM_INTERACT_SUCCESS
/obj/machinery/materials_market/power_change()
. = ..()
if(machine_stat & NOPOWER)
if(!is_operational)
set_light(0, 0)
else
set_light(initial(light_range), initial(light_power))
@@ -192,7 +176,7 @@
//Pulling elastic modifier into data.
for(var/datum/export/material/market/export_est in GLOB.exports_list)
if(export_est.material_id == traded_mat)
elastic_mult = (export_est.cost / export_est.init_cost) * 100
elastic_mult = export_est.k_elasticity * 100
material_data += list(list(
"name" = initial(traded_mat.name),
@@ -288,7 +272,6 @@
var/cost = SSstock_market.materials_prices[material_bought] * quantity
var/list/things_to_order = list()
things_to_order += (sheet_to_buy)
things_to_order[sheet_to_buy] = quantity
// We want to count how many stacks of all sheets we're ordering to make sure they don't exceed the limit of 10
@@ -299,14 +282,14 @@
var/prior_sheets = current_order.pack.contains[sheet_to_buy]
if(prior_sheets + quantity > SSstock_market.materials_quantity[material_bought] )
say("There aren't enough sheets on the market! Please wait for more sheets to be traded before adding more.")
playsound(usr, 'sound/machines/synth/synth_no.ogg', 35, FALSE)
playsound(living_user, 'sound/machines/synth/synth_no.ogg', 35, FALSE)
return
// Check if the order exceeded the purchase limit
var/prior_stacks = ROUND_UP(prior_sheets / MAX_STACK_SIZE)
if(prior_stacks >= MAX_STACK_LIMIT)
say("There are already 10 stacks of sheets on order! Please wait for them to arrive before ordering more.")
playsound(usr, 'sound/machines/synth/synth_no.ogg', 35, FALSE)
playsound(living_user, 'sound/machines/synth/synth_no.ogg', 35, FALSE)
return
// Prevents you from ordering more than the available budget
@@ -367,10 +350,6 @@
icon_state = "stock_block"
/// How many credits was this worth when created?
var/export_value = 0
/// What is the name of the material this was made from?
var/datum/material/export_mat
/// Quantity of export material
var/quantity = 0
/// Is this stock block currently updating its value with the market (aka fluid)?
var/fluid = FALSE
@@ -381,7 +360,11 @@
/obj/item/stock_block/examine(mob/user)
. = ..()
. += span_notice("\The [src] is worth [export_value] cr, from selling [quantity] sheets of [initial(export_mat?.name)].")
var/datum/material/export_mat = custom_materials[1]
var/quantity = custom_materials[export_mat] / SHEET_MATERIAL_AMOUNT
. += span_notice("\The [src] is worth [quantity * export_value] cr, from selling [quantity] sheets of [export_mat.name].")
if(fluid)
. += span_warning("\The [src] is currently liquid! Its value is based on the market price.")
else
@@ -393,9 +376,7 @@
update_appearance(UPDATE_ICON_STATE)
/obj/item/stock_block/proc/update_value()
if(!SSstock_market.materials_prices[export_mat])
return
export_value = quantity * SSstock_market.materials_prices[export_mat]
export_value = SSstock_market.materials_prices[custom_materials[1]]
icon_state = "stock_block_liquid"
update_appearance(UPDATE_ICON_STATE)
visible_message(span_warning("\The [src] becomes liquid!"))
-1
View File
@@ -305,7 +305,6 @@
reason = reason,
paying_account = account,
coupon = applied_coupon,
department_destination = reason ? TRUE : FALSE, // Hijacking reason as a way to determine if an order's requested from at least one budget
charge_on_purchase = TRUE, // SKYRAT EDIT ADDITION
)
working_list += order
+10
View File
@@ -334,3 +334,13 @@
contains = list(/obj/machinery/power/portagrav = 1)
crate_name = "portable gravity unit crate"
crate_type = /obj/structure/closet/crate/engineering
/datum/supply_pack/engineering/golfcart
name = "Golf Cart Parts Kit Crate"
desc = "Contains the parts to build a cart intended for moving heavy machinery and cargo across the station. \
Nanotrasen assumes no liability for carts operated as 'party wagons'."
cost = CARGO_CRATE_VALUE * 11
access_view = ACCESS_ENGINEERING
contains = list(/obj/item/golfcart_kit = 1, /obj/item/key/golfcart = 2, /obj/item/stock_parts/power_store/cell/lead = 1)
crate_name = "golf cart parts kit"
crate_type = /obj/structure/closet/crate/engineering
+8
View File
@@ -226,3 +226,11 @@
/obj/item/pestle,
)
crate_name = "organ growing kit"
/datum/supply_pack/medical/chiral_inversing_buffer
name = "Chiral Inversing Buffer Crate"
desc = "A crate containing a rare sample of an inversing buffer. \
It can transform impure reagents into their inverse counterparts when the right conditions are met."
cost = CARGO_CRATE_VALUE * 3
contains = list(/obj/item/reagent_containers/cup/bottle/inversing_buffer)
crate_name = "chiral inversing buffer crate"
+51 -48
View File
@@ -32,28 +32,61 @@
crate_name = "beekeeping starter crate"
crate_type = /obj/structure/closet/crate/hydroponics
/datum/supply_pack/organic/randomized
test_ignored = TRUE
crate_name = "food crate"
/datum/supply_pack/organic/randomized/fill(obj/structure/closet/crate/C)
for(var/i in 1 to 15)
var/item = pick(contains)
new item(C)
/datum/supply_pack/organic/randomized/chef
name = "Excellent Meat Crate"
desc = "The best cuts in the whole galaxy. Contains a random assortment of exotic meats."
cost = CARGO_CRATE_VALUE * 4
contains = list(/obj/item/food/meat/slab/human/mutant/slime,
/obj/item/food/meat/slab/killertomato,
/obj/item/food/meat/slab/bear,
/obj/item/food/meat/slab/xeno,
/obj/item/food/meat/slab/spider,
/obj/item/food/meat/rawbacon,
/obj/item/food/meat/slab/penguin,
/obj/item/food/spiderleg,
/obj/item/food/fishmeat/carp,
/obj/item/food/meat/slab/human,
/obj/item/food/meat/slab/grassfed,
)
crate_name = "food crate"
contains = list(
/obj/item/food/meat/slab/human/mutant/slime,
/obj/item/food/meat/slab/killertomato,
/obj/item/food/meat/slab/bear,
/obj/item/food/meat/slab/xeno,
/obj/item/food/meat/slab/spider,
/obj/item/food/meat/rawbacon,
/obj/item/food/meat/slab/penguin,
/obj/item/food/spiderleg,
/obj/item/food/fishmeat/carp,
/obj/item/food/meat/slab/human,
/obj/item/food/meat/slab/grassfed,
)
/datum/supply_pack/organic/randomized/chef/fill(obj/structure/closet/crate/C)
for(var/i in 1 to 15)
var/item = pick(contains)
new item(C)
/datum/supply_pack/organic/randomized/fruits
name = "Fruit Crate"
desc = "Rich in vitamins. Contains a lime, orange, watermelon, apple, berries and a lemon."
cost = CARGO_CRATE_VALUE * 3
contains = list(
/obj/item/food/grown/citrus/lime,
/obj/item/food/grown/citrus/orange,
/obj/item/food/grown/watermelon,
/obj/item/food/grown/apple,
/obj/item/food/grown/berries,
/obj/item/food/grown/citrus/lemon,
)
/datum/supply_pack/organic/randomized/vegetables
name = "Vegetables Crate"
desc = "Grown in vats. Contains a chili, corn, tomato, potato, carrot, chanterelle, onion, pumpkin, and cucumber."
cost = CARGO_CRATE_VALUE * 1.8
contains = list(
/obj/item/food/grown/chili,
/obj/item/food/grown/corn,
/obj/item/food/grown/tomato,
/obj/item/food/grown/potato,
/obj/item/food/grown/carrot,
/obj/item/food/grown/mushroom/chanterelle,
/obj/item/food/grown/onion,
/obj/item/food/grown/pumpkin,
/obj/item/food/grown/cucumber,
)
/datum/supply_pack/organic/exoticseeds
name = "Exotic Seeds Crate"
@@ -98,20 +131,6 @@
)
crate_name = "food crate"
/datum/supply_pack/organic/randomized/chef/fruits
name = "Fruit Crate"
desc = "Rich in vitamins. Contains a lime, orange, watermelon, apple, \
berries and a lemon."
cost = CARGO_CRATE_VALUE * 3
contains = list(/obj/item/food/grown/citrus/lime,
/obj/item/food/grown/citrus/orange,
/obj/item/food/grown/watermelon,
/obj/item/food/grown/apple,
/obj/item/food/grown/berries,
/obj/item/food/grown/citrus/lemon,
)
crate_name = "food crate"
/datum/supply_pack/organic/cream_piee
name = "High-yield Clown-grade Cream Pie Crate"
desc = "Designed by Aussec's Advanced Warfare Research Division, \
@@ -276,23 +295,6 @@
crate_name = "seeds crate"
crate_type = /obj/structure/closet/crate/hydroponics
/datum/supply_pack/organic/randomized/chef/vegetables
name = "Vegetables Crate"
desc = "Grown in vats. Contains a chili, corn, tomato, potato, carrot, \
chanterelle, onion, pumpkin, and cucumber."
cost = CARGO_CRATE_VALUE * 1.8
contains = list(/obj/item/food/grown/chili,
/obj/item/food/grown/corn,
/obj/item/food/grown/tomato,
/obj/item/food/grown/potato,
/obj/item/food/grown/carrot,
/obj/item/food/grown/mushroom/chanterelle,
/obj/item/food/grown/onion,
/obj/item/food/grown/pumpkin,
/obj/item/food/grown/cucumber,
)
crate_name = "food crate"
/datum/supply_pack/organic/grill
name = "Grilling Starter Kit"
desc = "Hey dad I'm Hungry. Hi Hungry I'm THE NEW GRILLING STARTER KIT \
@@ -331,6 +333,7 @@
)
crate_name = "\improper Tiziran Supply box"
crate_type = /obj/structure/closet/crate/cardboard/tiziran
test_ignored = TRUE
/datum/supply_pack/organic/mothic_supply
name = "Mothic Supply Box"
+1 -14
View File
@@ -10,6 +10,7 @@
armor_type = /datum/armor/supplypod_beacon
resistance_flags = FIRE_PROOF
interaction_flags_click = ALLOW_SILICON_REACH
obj_flags = UNIQUE_RENAME | RENAME_NO_DESC
/// The linked console
var/obj/machinery/computer/cargo/express/express_console
/// If linked
@@ -103,17 +104,3 @@
return CLICK_ACTION_BLOCKING
unlink_console()
return CLICK_ACTION_SUCCESS
/obj/item/supplypod_beacon/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(!IS_WRITING_UTENSIL(tool))
return NONE
var/new_beacon_name = tgui_input_text(user, "What would you like the tag to be?", "Beacon Tag", max_length = MAX_NAME_LEN)
if(isnull(new_beacon_name))
return ITEM_INTERACT_BLOCKING
if(!user.can_perform_action(src) || !user.can_write(tool))
return ITEM_INTERACT_BLOCKING
name = "[initial(name)] ([new_beacon_name])"
return ITEM_INTERACT_SUCCESS