GMM UI & Cargo budget handling tweaks (#79145)

## About The Pull Request
- Fixes #79115

This PR is a 2-part solution as specified by the last paragraph of the
above-mentioned issue.

> but also, for you to be prevented from adding more to an order that
you don't reasonably have the funds in that account to afford.

The GMM will now not add stacks to an existing order if it exceeds the
available (private or cargo depending on the mode of ordering) budget or
if it exceeds the available market quantity on the market.

The UI is improved.
- Much larger to display all materials without scrolling
- Now shows the total cost of the order
- Display's number of sheets ordered next to each material type
- Has a clear button to cancel the order
- Order buttons greys out if the order quantity is greater than what's
available in the market or if you don't have the available budget for it
![Screenshot
(340)](https://github.com/tgstation/tgstation/assets/110812394/b2e0dc50-9eee-457f-a85e-c011de014cc6)

But this is not enough. The below example will explain why.

Say you have a budget of 500 cr in both private & cargo.
1. Place an order of materials worth 500 cr be it private or by cargo
budget.
2. Now go spend that budget on something such that it falls below 500
cr, say in this example you overspend, and the available budget becomes
0(you broke)
3. Now go call the shuttle. The order gets rejected but it's left
hanging in the cargo checkout queue and will only be cleared till you
raise your budget above 500 cr and again call the shuttle.

This example just applies to 500 cr but with larger amounts you order
will be hanging in the queue indefinitely till your broke... makes the
available budget to finally purchase it

To fix this we go to the 2nd part of the paragraph.

> An ideal fix would be for GMM orders to be cancellable.

cargo will now **"remove/cancel"** this order and will not leave it
hanging in the queue indefinitely. So, this way if you by accident made
a material order way beyond your available budget cargo will forgive you
and clear you of that debt so you can start a fresh order.

Of course, this fix is only useful if you send the order without
checking the budget but even if you do there is plan B so it's helpful
to know.

## Changelog
🆑
fix: Cargo will remove/cancel orders from its cart if that order exceeds
the available budget (both private or cargo) and the player cannot
cancel this order manually. All order costs are rounded up to integer
values
fix: Galactic material market will deny appending stacks to your
existing order if it exceeds the available (private or cargo depending
on the mode of ordering) budget & if it exceeds the available materials
on the market. Galactic material market UI is overall improved.
/🆑

---------

Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com>
Co-authored-by: Jacquerel <hnevard@gmail.com>
This commit is contained in:
SyncIt21
2023-10-31 01:49:17 +00:00
committed by GitHub
co-authored by ArcaneMusic Jacquerel
parent a864ef1644
commit e39276b869
5 changed files with 297 additions and 133 deletions
+21 -14
View File
@@ -157,37 +157,39 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
var/value = 0
var/purchases = 0
var/price
var/pack_cost
var/list/goodies_by_buyer = list() // if someone orders more than GOODY_FREE_SHIPPING_MAX goodies, we upcharge to a normal crate so they can't carry around 20 combat shotties
var/list/rejected_orders = list() //list of all orders that exceeded the available budget and are uncancelable
for(var/datum/supply_order/spawning_order in SSshuttle.shopping_list)
if(!empty_turfs.len)
break
var/price = spawning_order.pack.get_cost()
if(spawning_order.applied_coupon)
price *= (1 - spawning_order.applied_coupon.discount_pct_off)
var/datum/bank_account/paying_for_this
price = spawning_order.get_final_cost()
//department orders EARN money for cargo, not the other way around
var/datum/bank_account/paying_for_this
if(!spawning_order.department_destination && spawning_order.charge_on_purchase)
if(spawning_order.paying_account) //Someone paid out of pocket
paying_for_this = spawning_order.paying_account
var/list/current_buyer_orders = goodies_by_buyer[spawning_order.paying_account] // so we can access the length a few lines down
if(!spawning_order.pack.goody)
price *= 1.1 //TODO make this customizable by the quartermaster
// note this is before we increment, so this is the GOODY_FREE_SHIPPING_MAX + 1th goody to ship. also note we only increment off this step if they successfully pay the fee, so there's no way around it
else if(LAZYLEN(current_buyer_orders) == GOODY_FREE_SHIPPING_MAX)
price += CRATE_TAX
paying_for_this.bank_card_talk("Goody order size exceeds free shipping limit: Assessing [CRATE_TAX] credit S&H fee.")
if(spawning_order.pack.goody)
var/list/current_buyer_orders = goodies_by_buyer[spawning_order.paying_account]
if(LAZYLEN(current_buyer_orders) == GOODY_FREE_SHIPPING_MAX)
price = round(price + CRATE_TAX)
paying_for_this.bank_card_talk("Goody order size exceeds free shipping limit: Assessing [CRATE_TAX] credit S&H fee.")
else
paying_for_this = SSeconomy.get_dep_account(ACCOUNT_CAR)
if(paying_for_this)
if(!paying_for_this.adjust_money(-price, "Cargo: [spawning_order.pack.name]"))
if(spawning_order.paying_account)
paying_for_this.bank_card_talk("Cargo order #[spawning_order.id] rejected due to lack of funds. Credits required: [price]")
if(!spawning_order.can_be_cancelled) //only if it absolutly cannot be canceled by the player do we cancel it for them
rejected_orders += spawning_order
continue
pack_cost = spawning_order.pack.get_cost()
if(spawning_order.paying_account)
paying_for_this = spawning_order.paying_account
if(spawning_order.pack.goody)
@@ -198,8 +200,8 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
paying_for_this.bank_card_talk(reciever_message)
SSeconomy.track_purchase(paying_for_this, price, spawning_order.pack.name)
var/datum/bank_account/department/cargo = SSeconomy.get_dep_account(ACCOUNT_CAR)
cargo.adjust_money(price - spawning_order.pack.get_cost()) //Cargo gets the handling fee
value += spawning_order.pack.get_cost()
cargo.adjust_money(price - pack_cost) //Cargo gets the handling fee
value += pack_cost
SSshuttle.shopping_list -= spawning_order
SSshuttle.order_history += spawning_order
QDEL_NULL(spawning_order.applied_coupon)
@@ -217,6 +219,11 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
message_admins("\A [spawning_order.pack.name] ordered by [ADMIN_LOOKUPFLW(spawning_order.orderer_ckey)], paid by [from_whom] has shipped.")
purchases++
//clear out all rejected uncancellable orders
for(var/datum/supply_order/rejected_order in rejected_orders)
SSshuttle.shopping_list -= rejected_order
qdel(rejected_order)
// we handle packing all the goodies last, since the type of crate we use depends on how many goodies they ordered. If it's more than GOODY_FREE_SHIPPING_MAX
// then we send it in a crate (including the CRATE_TAX cost), otherwise send it in a free shipping case
for(var/buyer_key in goodies_by_buyer)