mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 01:34:01 +00:00
Department orders credit reward and cooldown time now use a logarithmic scale (#88797)
## About The Pull Request This PR makes the reward and cooldown for departmental orders scale with crate cost using a logarithmic scaling, instead of comparing the price to preset thresholds for time, or awarding the same amount as the crate's cost. Previously, to calculate the cooldown time, the code was calculated via the following manner: ``` credits = clamp(credits, min, max) time_y = 10 MINUTES * ((credits - min)/(max - min) + 1) ``` Minimum was 320 credits, max was 3000, thus, all crates slid around between 10 minutes to 20 minutes. The reward for delivering the crates was the same as the crate's value. This meant ordering egregiously expensive crates, far beyond 3000 was way too desirable. This PR changes both to use logarithmic scaling. Cooldown time uses `60* log(price)^2.2`, and reward uses `140 * log(price)^1.4`. **Cooldown analysis** At 320 it's 7.54 minutes, at 1400 it's 12.44 minutes, at 3000 (around gun crates) it's 15.5 minutes, at 8000 (hat crate) 20 minutes, at 9000 (expensive atmos cans) it's 20.58 minutes, and at the 20k crate it's 24.76 minutes. **Crate rewards analysis** At 320 it's 475 credits, at 1400 it's 669 credits, at 3000 (around gun crates) its 778, at 8000 (hat crate) it's 925 credits, at 9000 (expensive atmos cans) it's 943 credits, and at the 20k crate it's 1070 credits. Up to 540 credits, you are actually getting a higher reward than what the crate costs, but this is okay, as its a reward for delivering simpler orders. A little surplus for you. For the console UI, I have made items costing 3000 or more display Moderate, and items costing 8000 or more, Long cooldowns. ## Why It's Good For The Game Ordering really expensive crates should be a luxury, not a way to generate money. The money is supposed to be a bonus, in addition to the free crate to sell. Using a logarithmic scale, the credit bonus is reigned in more evenly, making it more predictable for economy tweaking, and avoids players double dipping credits in their free purchase. Decreasing the rewards also give space for other new ways to generate rewards in relation to departmental orders, such as stamping the manifest with the correct head's stamp being worth more money and such. <details> <summary>Old PR Text, which was using a price cap instead</summary> ## About The Pull Request Departmental orders are a neat feature, but some of the available packs had problems economywise. The cooldown of range from 10 to 20 minutes, with 10 minutes being the base for anything costing less than 320 credits, and 20 minutes at 3000 credits. I have no problem with the lower cap, but the upper cap has issues, as recently, a 20k crate was added to cargo, which means it is possible to dump quite a large amount of funds into cargo every 20 minutes. Departmental orders probably need a bigger overhaul, and this solution is imperfect, but I have talked with @ArcaneMusic about this as an interim stop gap measure. This PR also autodocs a proc, and moves some values to global defines, for ease of balancing. This PR affects the following crates, with the uncapped crate values in brackets. Armoury - Combat Shotguns (3500 credits) - Energy Guns (3600 credits) - NT BR-38 Crate (20,000 credits) Engineering - BSA parts (6000 credits) - DNA Vault Parts (4800 credits) Engine Construction - HFR Crate (4800) - Supermatter Shard Crate (4000) Materials - BZ Crate (9000 credits) - Nitrous Oxide (9000 credits) - Water Vapor Crate (3010 credits) Toys - Collectible Hats Crate (8000 credits) ## Why It's Good For The Game Instantly awarding 20k to cargo every 20 minute, in addition to 27k from the other consoles (if both engineering and science orders BZ, service orders collectible hats, and medical orders something around 1000), is a bit too much. The money gained should be along a much more predictable and expected value. With this chance, the most they can get is 13k every 20 minutes across all departments. </details> ## Changelog 🆑 balance: Rewards from departmental orders use a logarithmic scale, resulting in less rewards for high tier crates. The cooldown time is also logarithmic now, which has slightly decreased cooldown values on cheaper crates. /🆑
This commit is contained in:
@@ -47,3 +47,17 @@
|
||||
#define EXPORT_SOLD 1
|
||||
///Sell the item, but for the love of god, don't delete it, we're handling it in a fancier way.
|
||||
#define EXPORT_SOLD_DONT_DELETE 2
|
||||
|
||||
|
||||
//At 320 it's 7.5 minutes, at 1400 it's 12.44 minutes, at 3000 (around gun crates) it's 15.5 minutes, at 8000 (hat crate) 20 minutes, at 9000 (expensive atmos cans) it's 20.58 minutes, and at the 20k crate it's 24.76 minutes.
|
||||
/// Multiplies the logarithmic value calculating the free crate cooldown
|
||||
#define DEPARTMENTAL_ORDER_COOLDOWN_COEFFICIENT 60
|
||||
/// Used for the power of the logarithmic value for the free crate cooldown
|
||||
#define DEPARTMENTAL_ORDER_COOLDOWN_EXPONENT 2.2
|
||||
|
||||
//At 320 it's 475 credits, at 1400 it's 669 credits, at 3000 (around gun crates) its 778, at 8000 (hat crate) it's 925 credits, at 9000 (expensive atmos cans) it's 943 credits, and at the 20k crate it's 1070 credits.
|
||||
|
||||
/// Multiplies the logarithmic value calculating the free crate delivery reward
|
||||
#define DEPARTMENTAL_ORDER_REWARD_COEFFICIENT 120
|
||||
/// Used for the power of the logarithmic value for the free crate delivery reward
|
||||
#define DEPARTMENTAL_ORDER_REWARD_EXPONENT 1.5
|
||||
|
||||
@@ -90,7 +90,8 @@
|
||||
if(area_check(target))
|
||||
//noice, delivered!
|
||||
var/datum/bank_account/cargo_account = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
cargo_account.adjust_money(payment)
|
||||
|
||||
cargo_account.adjust_money(DEPARTMENTAL_ORDER_REWARD_COEFFICIENT * (log(10, payment) ** DEPARTMENTAL_ORDER_REWARD_EXPONENT))
|
||||
remove_lock(target)
|
||||
|
||||
///called to remove the element in a flavorful way, either from delivery or from emagging/breaking open the crate
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
submit_order(orderer, params["id"])
|
||||
return TRUE
|
||||
|
||||
/// Submits the order with the specified supply pack id as the specified orderer
|
||||
/datum/computer_file/program/department_order/proc/submit_order(mob/living/orderer, id)
|
||||
id = text2path(id) || id
|
||||
|
||||
@@ -243,21 +244,16 @@
|
||||
computer.physical.say("Order processed. Cargo will deliver the crate when it comes in on their shuttle. NOTICE: Heads of staff may override the order.")
|
||||
calculate_cooldown(pack.cost)
|
||||
|
||||
///signal when the supply shuttle begins to spawn orders. we forget the current order preventing it from being overridden (since it's already past the point of no return on undoing the order)
|
||||
/// Signal when the supply shuttle begins to spawn orders. We forget the current order preventing it from being overridden (since it's already past the point of no return on undoing the order)
|
||||
/datum/computer_file/program/department_order/proc/finalize_department_order(datum/subsystem)
|
||||
SIGNAL_HANDLER
|
||||
if(!isnull(department_order) && (department_order in SSshuttle.shopping_list))
|
||||
department_order = null
|
||||
UnregisterSignal(subsystem, COMSIG_SUPPLY_SHUTTLE_BUY)
|
||||
|
||||
/// Calculates the cooldown it will take for this department's free order, based on its credit cost
|
||||
/datum/computer_file/program/department_order/proc/calculate_cooldown(credits)
|
||||
//minimum almost the lowest value of a crate
|
||||
var/min = CARGO_CRATE_VALUE * 1.6
|
||||
//maximum fairly expensive crate at 3000
|
||||
var/max = CARGO_CRATE_VALUE * 15
|
||||
credits = clamp(credits, min, max)
|
||||
var/time_y = (credits - min)/(max - min) + 1 //convert to between 1 and 2
|
||||
time_y = 10 MINUTES * time_y
|
||||
var/time_y = DEPARTMENTAL_ORDER_COOLDOWN_COEFFICIENT * (log(10, credits) ** DEPARTMENTAL_ORDER_COOLDOWN_EXPONENT) * (1 SECONDS)
|
||||
department_cooldowns[linked_department] = world.time + time_y
|
||||
|
||||
/datum/computer_file/program/department_order/process_tick(seconds_per_tick)
|
||||
|
||||
@@ -16,8 +16,12 @@ import { BooleanLike } from 'tgui-core/react';
|
||||
import { useBackend } from '../backend';
|
||||
import { NtosWindow } from '../layouts';
|
||||
|
||||
// 15x crate value
|
||||
const COST_UPPER_BOUND = 3000;
|
||||
// 3.5x crate value, 10 minutes
|
||||
const COST_MODERATE_BOUND = 700;
|
||||
// 13.5x crate value, 15 minutes
|
||||
const COST_LONG_BOUND = 2700;
|
||||
// 40x crate value, 20 minutes
|
||||
const COST_VERY_LONG_BOUND = 8000;
|
||||
|
||||
type typePath = string;
|
||||
|
||||
@@ -44,12 +48,14 @@ type Info = {
|
||||
const CooldownEstimate = (props) => {
|
||||
const { cost } = props;
|
||||
const cooldownColor =
|
||||
(cost > COST_UPPER_BOUND * 0.75 && 'red') ||
|
||||
(cost > COST_UPPER_BOUND * 0.25 && 'orange') ||
|
||||
(cost >= COST_VERY_LONG_BOUND && 'red') ||
|
||||
(cost >= COST_LONG_BOUND && 'orange') ||
|
||||
(cost >= COST_MODERATE_BOUND && 'yellow') ||
|
||||
'green';
|
||||
const cooldownText =
|
||||
(cost > COST_UPPER_BOUND * 0.75 && 'long') ||
|
||||
(cost > COST_UPPER_BOUND * 0.25 && 'moderate') ||
|
||||
(cost >= COST_VERY_LONG_BOUND && 'very long') ||
|
||||
(cost >= COST_LONG_BOUND && 'long') ||
|
||||
(cost >= COST_MODERATE_BOUND && 'moderate') ||
|
||||
'short';
|
||||
return (
|
||||
<Box as="span" textColor={cooldownColor}>
|
||||
|
||||
Reference in New Issue
Block a user