Files
Bubberstation/code/modules/power/cell.dm
ArcaneMusic 5624a33c26 Adds a unit test for Cargo Crates to prevent infinite credit oversights. (#89023)
## About The Pull Request

I was kinda shocked that we didn't have something for this considering
that it's an unspoken rule of cargo to check that a crate does not sell
back for more than it's price and that the one comment saying to do so
has been doing some heavy lifting for the last 12 years.

I'm a novice when it comes to unit testing specifically so hopefully the
smoothing out that needs to be done should be fairly quick.

*Edit (2/22/25):*
The following changes were also made in order to allow for this unit
test to work smoothly:

Exports now have a market define added to them, as the purpose of this
unit test is to test exports that occur on the station, bought from
supply and then sold back to supply. As such, these market defines
exclude exports specific to pirates (since the cargo shuttle cannot sell
living mobs back, preventing you from making 10k per parrot crate.).

I've also added the `abstract` variable to some export datums, to
signify that a given export is either variable, or not meant to be
compared against the value of it's own container, such as with gas
canister's base export value as their export datums are generated
dynamically. (The subtypes are not abstract, however.)

The verb, `/mob/living/verb/tally_physical_credits()` has been changed
to `/mob/living/proc/tally_physical_credits()`, because that's my B and
does effect some economy back end but it's a one line fix so I just
absent-mindedly fixed it here instead of atomizing it out. I can
one-line it otherwise.

Mulebots now no longer runtime on spawn as they set their own to their
own `get_turf` as opposed to pulling their `loc`.

A few supply packs have had their prices bumped up slightly to actually
pass the test itself:

* `/datum/supply_pack/misc/candles_bulk`
* `/datum/supply_pack/security/armor`
* `/datum/supply_pack/security/helmets`
* `/datum/supply_pack/security/baton`

## Why It's Good For The Game

Prevents future infinite credit bugs that could have been missed by
simply checking the sale value in game.

## Changelog

🆑
fix: To prevent infinite sales issues, security helmets, armors, and
batons packs now all cost 600 credits, up from 400.
fix: Candle packs now cost 400 credits, up from 300, and candles now
sell for 12.25 cr each.
/🆑

---------

Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
2025-03-13 23:26:53 +01:00

244 lines
8.2 KiB
Plaintext

/**
* # Power cell
*
* Power cells, used primarily for handheld and portable things. Holds a reasonable amount of power.
*/
/obj/item/stock_parts/power_store/cell
name = "power cell"
desc = "A rechargeable electrochemical power cell."
icon = 'icons/obj/machines/cell_charger.dmi'
icon_state = "cell"
inhand_icon_state = "cell"
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
force = 5
throwforce = 5
throw_speed = 2
throw_range = 5
w_class = WEIGHT_CLASS_SMALL
custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT*7, /datum/material/glass=SMALL_MATERIAL_AMOUNT*0.5)
grind_results = list(/datum/reagent/lithium = 15, /datum/reagent/iron = 5, /datum/reagent/silicon = 5)
/obj/item/stock_parts/power_store/cell/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_FISHING_BAIT, INNATE_TRAIT)
ADD_TRAIT(src, TRAIT_POISONOUS_BAIT, INNATE_TRAIT) //bro is fishing using lithium...
/* Cell variants*/
/obj/item/stock_parts/power_store/cell/empty
empty = TRUE
/obj/item/stock_parts/power_store/cell/crap
name = "\improper Nanotrasen brand rechargeable AA cell"
desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT
icon_state = "aa_cell"
maxcharge = STANDARD_CELL_CHARGE * 0.5
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*0.4)
/obj/item/stock_parts/power_store/cell/crap/Initialize(mapload)
AddElement(/datum/element/update_icon_blocker)
return ..()
/obj/item/stock_parts/power_store/cell/crap/empty
empty = TRUE
/obj/item/stock_parts/power_store/cell/upgraded
name = "upgraded power cell"
desc = "A power cell with a slightly higher capacity than normal!"
icon_state = "9v_cell"
maxcharge = STANDARD_CELL_CHARGE * 2.5
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*0.5)
chargerate = STANDARD_CELL_RATE * 0.5
/obj/item/stock_parts/power_store/cell/upgraded/Initialize(mapload)
AddElement(/datum/element/update_icon_blocker)
return ..()
/obj/item/stock_parts/power_store/cell/upgraded/plus
name = "upgraded power cell+"
desc = "A power cell with an even higher capacity than the base model!"
maxcharge = STANDARD_CELL_CHARGE * 5
/obj/item/stock_parts/power_store/cell/secborg
name = "security borg rechargeable D cell"
maxcharge = STANDARD_CELL_CHARGE * 0.6
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*0.4)
/obj/item/stock_parts/power_store/cell/secborg/empty
empty = TRUE
/obj/item/stock_parts/power_store/cell/mini_egun
name = "miniature energy gun power cell"
maxcharge = STANDARD_CELL_CHARGE * 0.6
/obj/item/stock_parts/power_store/cell/hos_gun
name = "X-01 multiphase energy gun power cell"
maxcharge = STANDARD_CELL_CHARGE * 1.2
/obj/item/stock_parts/power_store/cell/pulse //200 pulse shots
name = "pulse rifle power cell"
maxcharge = STANDARD_CELL_CHARGE * 40
chargerate = STANDARD_CELL_RATE * 0.75
/obj/item/stock_parts/power_store/cell/pulse/carbine //25 pulse shots
name = "pulse carbine power cell"
maxcharge = STANDARD_CELL_CHARGE * 5
/obj/item/stock_parts/power_store/cell/pulse/pistol //10 pulse shots
name = "pulse pistol power cell"
maxcharge = STANDARD_CELL_CHARGE * 2
/obj/item/stock_parts/power_store/cell/ninja
name = "black power cell"
icon_state = "bscell"
maxcharge = STANDARD_CELL_CHARGE * 10
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*0.6)
chargerate = STANDARD_CELL_RATE
/obj/item/stock_parts/power_store/cell/high
name = "high-capacity power cell"
icon_state = "hcell"
maxcharge = STANDARD_CELL_CHARGE * 10
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*0.6)
chargerate = STANDARD_CELL_RATE * 0.75
/obj/item/stock_parts/power_store/cell/high/empty
empty = TRUE
/obj/item/stock_parts/power_store/cell/super
name = "super-capacity power cell"
icon_state = "scell"
maxcharge = STANDARD_CELL_CHARGE * 20
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT * 3)
chargerate = STANDARD_CELL_RATE
/obj/item/stock_parts/power_store/cell/super/empty
empty = TRUE
/obj/item/stock_parts/power_store/cell/hyper
name = "hyper-capacity power cell"
icon_state = "hpcell"
maxcharge = STANDARD_CELL_CHARGE * 30
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT * 4)
chargerate = STANDARD_CELL_RATE * 1.5
/obj/item/stock_parts/power_store/cell/hyper/empty
empty = TRUE
/obj/item/stock_parts/power_store/cell/bluespace
name = "bluespace power cell"
desc = "A rechargeable transdimensional power cell."
icon_state = "bscell"
maxcharge = STANDARD_CELL_CHARGE * 40
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*6)
chargerate = STANDARD_CELL_RATE * 2
/obj/item/stock_parts/power_store/cell/bluespace/empty
empty = TRUE
/obj/item/stock_parts/power_store/cell/infinite
name = "infinite-capacity power cell"
icon_state = "icell"
maxcharge = INFINITY //little disappointing if you examine it and it's not huge
custom_materials = list(/datum/material/glass=HALF_SHEET_MATERIAL_AMOUNT)
chargerate = INFINITY
ratingdesc = FALSE
/obj/item/stock_parts/power_store/cell/infinite/use(used, force = FALSE)
return TRUE
/obj/item/stock_parts/power_store/cell/infinite/abductor
name = "void core"
desc = "An alien power cell that produces energy seemingly out of nowhere."
icon = 'icons/obj/antags/abductor.dmi'
icon_state = "cell"
maxcharge = STANDARD_CELL_CHARGE * 50
ratingdesc = FALSE
/obj/item/stock_parts/power_store/cell/infinite/abductor/Initialize(mapload)
AddElement(/datum/element/update_icon_blocker)
return ..()
/obj/item/stock_parts/power_store/cell/potato
name = "potato battery"
desc = "A rechargeable starch based power cell."
icon = 'icons/obj/service/hydroponics/harvest.dmi'
icon_state = "potato"
maxcharge = STANDARD_CELL_CHARGE * 0.3
charge_light_type = null
connector_type = null
custom_materials = null
grown_battery = TRUE //it has the overlays for wires
custom_premium_price = PAYCHECK_CREW
/obj/item/stock_parts/power_store/cell/potato/Initialize(mapload, override_maxcharge)
charge = maxcharge * 0.3
. = ..()
/obj/item/stock_parts/power_store/cell/emproof
name = "\improper EMP-proof cell"
desc = "An EMP-proof cell."
maxcharge = STANDARD_CELL_CHARGE * 0.5
/obj/item/stock_parts/power_store/cell/emproof/Initialize(mapload)
AddElement(/datum/element/empprotection, EMP_PROTECT_SELF)
return ..()
/obj/item/stock_parts/power_store/cell/emproof/empty
empty = TRUE
/obj/item/stock_parts/power_store/cell/emproof/corrupt()
return
/obj/item/stock_parts/power_store/cell/emproof/slime
name = "EMP-proof slime core"
desc = "A yellow slime core infused with plasma. Its organic nature makes it immune to EMPs."
icon = 'icons/mob/simple/slimes.dmi'
icon_state = "yellow-core"
custom_materials = null
maxcharge = STANDARD_CELL_CHARGE * 5
charge_light_type = null
connector_type = "slimecore"
/obj/item/stock_parts/power_store/cell/emergency_light
name = "miniature power cell"
desc = "A tiny power cell with a very low power capacity. Used in light fixtures to power them in the event of an outage."
maxcharge = STANDARD_CELL_CHARGE * 0.12 //Emergency lights use 0.2 W per tick, meaning ~10 minutes of emergency power from a cell
custom_materials = list(/datum/material/glass = SMALL_MATERIAL_AMOUNT*0.2)
w_class = WEIGHT_CLASS_TINY
/obj/item/stock_parts/power_store/cell/emergency_light/Initialize(mapload)
. = ..()
var/area/area = get_area(src)
if(area)
if(!area.lightswitch || !area.light_power)
charge = 0 //For naturally depowered areas, we start with no power
/obj/item/stock_parts/power_store/cell/crystal_cell
name = "crystal power cell"
desc = "A very high power cell made from crystallized plasma"
icon_state = "crystal_cell"
maxcharge = STANDARD_CELL_CHARGE * 50
chargerate = 0
charge_light_type = null
connector_type = "crystal"
custom_materials = null
grind_results = null
/obj/item/stock_parts/power_store/cell/ethereal
name = "ahelp it"
desc = "you sohuldn't see this"
maxcharge = ETHEREAL_CHARGE_DANGEROUS
charge = ETHEREAL_CHARGE_FULL
icon_state = null
charge_light_type = null
connector_type = null
custom_materials = null
grind_results = null
/obj/item/stock_parts/power_store/cell/ethereal/examine(mob/user)
. = ..()
CRASH("[src.type] got examined by [user]")