mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 05:30:05 +01:00
Maintenance loot table revamp (#47646)
* new maint loot tables * Loot spawn probability finder * maint loot pool changes
This commit is contained in:
@@ -1,112 +1,242 @@
|
||||
//How to balance this table
|
||||
//-------------------------
|
||||
//The total added weight of all the entries should be (roughly) equal to the total number of lootdrops
|
||||
//(take in account those that spawn more than one object!)
|
||||
//
|
||||
//While this is random, probabilities tells us that item distribution will have a tendency to look like
|
||||
//the content of the weighted table that created them.
|
||||
//The less lootdrops, the less even the distribution.
|
||||
//
|
||||
//If you want to give items a weight <1 you can multiply all the weights by 10
|
||||
//
|
||||
//the "" entry will spawn nothing, if you increase this value,
|
||||
//ensure that you balance it with more spawn points
|
||||
//as of:10/28/2019:
|
||||
//boxstation: ~153 loot items spawned
|
||||
//metastation: ~183 loot items spawned
|
||||
//deltastation: ~165 loot items spawned
|
||||
|
||||
//table data:
|
||||
//-----------
|
||||
//aft maintenance: 24 items, 18 spots 2 extra (28/08/2014)
|
||||
//asmaint: 16 items, 11 spots 0 extra (08/08/2014)
|
||||
//asmaint2: 36 items, 26 spots 2 extra (28/08/2014)
|
||||
//fpmaint: 5 items, 4 spots 0 extra (08/08/2014)
|
||||
//fpmaint2: 12 items, 11 spots 2 extra (28/08/2014)
|
||||
//fsmaint: 0 items, 0 spots 0 extra (08/08/2014)
|
||||
//fsmaint2: 40 items, 27 spots 5 extra (28/08/2014)
|
||||
//maintcentral: 2 items, 2 spots 0 extra (08/08/2014)
|
||||
//port: 5 items, 5 spots 0 extra (08/08/2014)
|
||||
//how to balance maint loot spawns:
|
||||
// 1) Ensure each category has items of approximately the same power level
|
||||
// 2) Tune weight of each category until average power of a maint loot spawn is acceptable
|
||||
// 3) Mapping considerations - Loot value should scale with difficulty of acquisition, or an assistaint will run through collecting free gear with no risk
|
||||
|
||||
GLOBAL_LIST_INIT(maintenance_loot, list(
|
||||
/obj/item/bodybag = 1,
|
||||
/obj/item/clothing/glasses/meson = 2,
|
||||
/obj/item/clothing/glasses/sunglasses = 1,
|
||||
/obj/item/clothing/gloves/color/fyellow = 1,
|
||||
/obj/item/clothing/head/hardhat = 1,
|
||||
/obj/item/clothing/head/hardhat/red = 1,
|
||||
/obj/item/clothing/head/that = 1,
|
||||
/obj/item/clothing/head/ushanka = 1,
|
||||
/obj/item/clothing/head/welding = 1,
|
||||
/obj/item/clothing/mask/gas = 15,
|
||||
/obj/item/clothing/suit/hazardvest = 1,
|
||||
/obj/item/clothing/under/misc/vice_officer = 1,
|
||||
/obj/item/clothing/suit/hooded/flashsuit = 2,
|
||||
/obj/item/assembly/prox_sensor = 4,
|
||||
/obj/item/assembly/timer = 3,
|
||||
/obj/item/flashlight = 4,
|
||||
/obj/item/flashlight/pen = 1,
|
||||
/obj/effect/spawner/lootdrop/glowstick = 4,
|
||||
/obj/item/multitool = 2,
|
||||
/obj/item/radio/off = 2,
|
||||
/obj/item/t_scanner = 5,
|
||||
/obj/item/airlock_painter = 1,
|
||||
/obj/item/stack/cable_coil = 4,
|
||||
/obj/item/stack/cable_coil/five = 6,
|
||||
/obj/item/stack/medical/suture = 1,
|
||||
/obj/item/stack/rods/ten = 9,
|
||||
/obj/item/stack/rods/twentyfive = 1,
|
||||
/obj/item/stack/rods/fifty = 1,
|
||||
/obj/item/stack/sheet/cardboard = 2,
|
||||
/obj/item/stack/sheet/metal/twenty = 1,
|
||||
/obj/item/stack/sheet/mineral/plasma = 1,
|
||||
/obj/item/stack/sheet/rglass = 1,
|
||||
/obj/item/book/manual/wiki/engineering_construction = 1,
|
||||
/obj/item/book/manual/wiki/engineering_hacking = 1,
|
||||
/obj/item/clothing/head/cone = 1,
|
||||
/obj/item/coin/silver = 1,
|
||||
/obj/item/coin/twoheaded = 1,
|
||||
/obj/item/poster/random_contraband = 1,
|
||||
/obj/item/poster/random_official = 1,
|
||||
/obj/item/crowbar = 1,
|
||||
/obj/item/crowbar/red = 1,
|
||||
/obj/item/extinguisher = 11,
|
||||
/obj/item/hand_labeler = 1,
|
||||
/obj/item/paper/crumpled = 1,
|
||||
/obj/item/reagent_containers/hypospray/medipen/pumpup = 6,
|
||||
/obj/item/pen = 1,
|
||||
/obj/item/reagent_containers/spray/pestspray = 1,
|
||||
/obj/item/reagent_containers/glass/rag = 3,
|
||||
/obj/item/stock_parts/cell = 3,
|
||||
/obj/item/storage/belt/utility = 2,
|
||||
/obj/item/storage/box = 2,
|
||||
/obj/item/storage/box/cups = 1,
|
||||
/obj/item/storage/box/donkpockets = 1,
|
||||
/obj/item/storage/box/lights/mixed = 3,
|
||||
/obj/item/storage/box/hug/medical = 1,
|
||||
/obj/item/storage/fancy/cigarettes/dromedaryco = 1,
|
||||
/obj/item/storage/toolbox/mechanical = 1,
|
||||
/obj/item/screwdriver = 3,
|
||||
/obj/item/tank/internals/emergency_oxygen = 2,
|
||||
/obj/item/vending_refill/cola = 1,
|
||||
/obj/item/weldingtool = 3,
|
||||
/obj/item/wirecutters = 1,
|
||||
/obj/item/wrench = 4,
|
||||
/obj/item/relic = 3,
|
||||
/obj/item/weaponcrafting/receiver = 2,
|
||||
/obj/item/clothing/head/cone = 2,
|
||||
/obj/item/grenade/smokebomb = 2,
|
||||
/obj/item/geiger_counter = 3,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/orange = 1,
|
||||
/obj/item/radio/headset = 1,
|
||||
/obj/item/assembly/infra = 1,
|
||||
/obj/item/assembly/igniter = 2,
|
||||
/obj/item/assembly/signaler = 2,
|
||||
/obj/item/assembly/mousetrap = 2,
|
||||
/obj/item/reagent_containers/syringe = 2,
|
||||
/obj/effect/spawner/lootdrop/gloves = 8,
|
||||
/obj/item/clothing/shoes/laceup = 1,
|
||||
/obj/item/storage/secure/briefcase = 3,
|
||||
/obj/item/storage/toolbox/artistic = 2,
|
||||
/obj/item/toy/eightball = 1,
|
||||
/obj/item/reagent_containers/pill/floorpill = 1,
|
||||
/obj/item/reagent_containers/food/snacks/canned/peaches/maint = 1,
|
||||
/obj/item/throwing_star = 1,
|
||||
"" = 3
|
||||
//goal of maint loot:
|
||||
// 1) Provide random equipment to people who take effort to crawl maint
|
||||
// 2) Create memorable moments with very rare, crazy items
|
||||
|
||||
//Loot tables
|
||||
|
||||
GLOBAL_LIST_INIT(trash_loot, list(//junk: useless, very easy to get, or ghetto chemistry items
|
||||
list(//trash
|
||||
/obj/item/trash = 1,
|
||||
/obj/item/trash/can = 1,
|
||||
/obj/item/trash/raisins = 1,
|
||||
/obj/item/trash/candy = 1,
|
||||
/obj/item/trash/cheesie = 1,
|
||||
/obj/item/trash/chips = 1,
|
||||
/obj/item/trash/popcorn = 1,
|
||||
/obj/item/trash/sosjerky = 1,
|
||||
/obj/item/trash/plate = 1,
|
||||
/obj/item/trash/pistachios = 1,
|
||||
|
||||
/obj/item/poster/random_contraband = 1,
|
||||
/obj/item/poster/random_official = 1,
|
||||
/obj/item/folder/yellow = 1,
|
||||
/obj/item/hand_labeler = 1,
|
||||
/obj/item/pen = 1,
|
||||
/obj/item/paper = 1,
|
||||
/obj/item/paper/crumpled = 1,
|
||||
/obj/item/photo/old = 1,
|
||||
/obj/item/disk/data = 1,
|
||||
/obj/item/stack/sheet/cardboard = 1,
|
||||
/obj/item/storage/box = 1,
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/drinkingglass = 1,
|
||||
/obj/item/coin/silver = 1,
|
||||
/obj/effect/decal/cleanable/ash = 1,
|
||||
/obj/item/cigbutt = 1,
|
||||
/obj/item/camera = 1,
|
||||
/obj/item/camera_film = 1,
|
||||
/obj/item/light/bulb = 1,
|
||||
/obj/item/light/tube = 1,
|
||||
/obj/item/reagent_containers/food/snacks/urinalcake = 1,
|
||||
|
||||
/obj/item/airlock_painter = 1,
|
||||
/obj/item/pipe = 1,
|
||||
/obj/item/rack_parts = 1,
|
||||
/obj/item/clothing/mask/breath = 1,
|
||||
/obj/item/shard = 1,
|
||||
|
||||
/obj/item/reagent_containers/pill/floorpill = 1,
|
||||
/obj/item/toy/eightball = 1,
|
||||
) = 8,
|
||||
|
||||
list(//tier 1 stock parts
|
||||
/obj/item/stock_parts/capacitor = 1,
|
||||
/obj/item/stock_parts/scanning_module = 1,
|
||||
/obj/item/stock_parts/manipulator = 1,
|
||||
/obj/item/stock_parts/micro_laser = 1,
|
||||
/obj/item/stock_parts/matter_bin = 1,
|
||||
) = 1,
|
||||
))
|
||||
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(common_loot, list( //common: basic items
|
||||
list(//tools
|
||||
/obj/item/screwdriver = 1,
|
||||
/obj/item/wirecutters = 1,
|
||||
/obj/item/wrench = 1,
|
||||
/obj/item/crowbar = 1,
|
||||
/obj/item/t_scanner = 1,
|
||||
/obj/item/geiger_counter = 1,
|
||||
/obj/item/analyzer = 1,
|
||||
/obj/item/mop = 1,
|
||||
/obj/item/reagent_containers/glass/bucket = 1,
|
||||
/obj/item/toy/crayon/spraycan = 1,
|
||||
) = 1,
|
||||
|
||||
list(//equipment
|
||||
/obj/item/clothing/mask/gas = 1,
|
||||
/obj/item/radio/headset = 1,
|
||||
/obj/item/storage/backpack = 1,
|
||||
/obj/item/clothing/shoes/sneakers/black = 1,
|
||||
/obj/item/clothing/suit/hazardvest = 1,
|
||||
/obj/item/clothing/suit/toggle/labcoat = 1,
|
||||
/obj/item/clothing/under/color/grey = 1,
|
||||
/obj/item/clothing/gloves/color/fyellow = 1,
|
||||
/obj/effect/spawner/lootdrop/gloves = 1,
|
||||
/obj/item/storage/wallet/random = 1,
|
||||
/obj/item/clothing/glasses/science = 1,
|
||||
/obj/item/clothing/glasses/meson = 1,
|
||||
/obj/item/storage/belt/fannypack = 1,
|
||||
) = 1,
|
||||
|
||||
list(//construction and crafting
|
||||
/obj/item/stack/cable_coil = 1,
|
||||
/obj/item/stock_parts/cell = 1,
|
||||
/obj/item/stack/rods/twentyfive = 1,
|
||||
/obj/item/stack/sheet/metal/twenty = 1,
|
||||
/obj/item/stack/sheet/mineral/plasma = 1,
|
||||
|
||||
//assemblies
|
||||
/obj/item/assembly/infra = 1,
|
||||
/obj/item/assembly/signaler = 1,
|
||||
/obj/item/assembly/mousetrap = 1,
|
||||
/obj/item/assembly/prox_sensor = 1,
|
||||
/obj/item/assembly/timer = 1,
|
||||
/obj/item/assembly/igniter = 1,
|
||||
/obj/item/assembly/health = 1,
|
||||
|
||||
/obj/item/stack/packageWrap = 1,
|
||||
) = 1,
|
||||
|
||||
list(//medical and chemicals
|
||||
/obj/item/storage/fancy/cigarettes/dromedaryco = 1,
|
||||
/obj/item/grenade/chem_grenade/cleaner = 1,
|
||||
/obj/item/storage/box/matches = 1,
|
||||
/obj/item/reagent_containers/syringe = 1,
|
||||
/obj/item/reagent_containers/glass/beaker = 1,
|
||||
/obj/item/reagent_containers/glass/rag = 1,
|
||||
/obj/item/reagent_containers/hypospray/medipen/pumpup = 2,
|
||||
) = 1,
|
||||
|
||||
list(//food
|
||||
/obj/item/reagent_containers/food/drinks/beer = 1,
|
||||
/obj/item/reagent_containers/food/drinks/coffee = 1,
|
||||
) = 1,
|
||||
|
||||
list(//misc
|
||||
/obj/item/radio/off = 1,
|
||||
/obj/item/extinguisher = 1,
|
||||
/obj/item/tank/internals/emergency_oxygen = 1,
|
||||
/obj/item/bodybag = 1,
|
||||
/obj/item/grenade/smokebomb = 1,
|
||||
/obj/item/stack/spacecash/c10 = 1,
|
||||
|
||||
//light sources
|
||||
/obj/item/flashlight = 1,
|
||||
/obj/effect/spawner/lootdrop/glowstick = 1,
|
||||
/obj/item/clothing/head/hardhat/red = 1,
|
||||
/obj/item/flashlight/flare = 1,
|
||||
) = 1,
|
||||
))
|
||||
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(uncommon_loot, list(//uncommon: useful items
|
||||
list(//tools
|
||||
/obj/item/weldingtool/mini = 1,
|
||||
/obj/item/multitool = 1,
|
||||
/obj/item/hatchet = 1,
|
||||
/obj/item/roller = 1,
|
||||
/obj/item/restraints/legcuffs/bola = 1,
|
||||
/obj/item/restraints/handcuffs/cable = 1,
|
||||
/obj/item/twohanded/spear = 1,
|
||||
/obj/item/shield/riot/buckler = 1,
|
||||
/obj/item/grenade/iedcasing = 1,
|
||||
/obj/item/melee/baton/cattleprod = 1,
|
||||
/obj/item/throwing_star = 1,
|
||||
) = 1,
|
||||
|
||||
list(//equipment
|
||||
/obj/item/clothing/head/welding = 1,
|
||||
/obj/item/clothing/glasses/welding = 1,
|
||||
/obj/item/clothing/glasses/hud/health = 1,
|
||||
/obj/item/clothing/glasses/hud/diagnostic = 1,
|
||||
/obj/item/storage/belt/utility = 1,
|
||||
/obj/item/storage/belt/medical = 1,
|
||||
|
||||
/obj/item/clothing/suit/armor/vest/old = 1,
|
||||
/obj/item/clothing/head/helmet/old = 1,
|
||||
/obj/item/clothing/mask/muzzle = 1,
|
||||
/obj/item/clothing/ears/earmuffs = 1,
|
||||
/obj/item/clothing/gloves/color/black = 1,
|
||||
) = 1,
|
||||
|
||||
list(//construction and crafting
|
||||
/obj/item/stock_parts/cell/high = 1,
|
||||
/obj/item/stack/sheet/mineral/wood/fifty = 1,
|
||||
/obj/item/beacon = 1,
|
||||
/obj/item/weaponcrafting/receiver = 1,
|
||||
) = 1,
|
||||
|
||||
list(//medical and chemicals
|
||||
list(//basic healing items
|
||||
/obj/item/stack/medical/suture = 1,
|
||||
/obj/item/stack/medical/mesh = 1,
|
||||
/obj/item/stack/medical/gauze = 1,
|
||||
) = 1,
|
||||
list(//medical chems
|
||||
/obj/item/reagent_containers/glass/bottle/multiver = 1,
|
||||
/obj/item/reagent_containers/syringe/convermol = 1,
|
||||
) = 1,
|
||||
list(//drinks
|
||||
/obj/item/reagent_containers/food/drinks/bottle/vodka = 1,
|
||||
/obj/item/reagent_containers/food/drinks/soda_cans/grey_bull = 1,
|
||||
) = 1,
|
||||
list(//sprayers
|
||||
/obj/item/reagent_containers/spray = 1,
|
||||
/obj/item/watertank = 1,
|
||||
/obj/item/watertank/janitor = 1,
|
||||
) = 1,
|
||||
) = 1,
|
||||
|
||||
list(//food
|
||||
/obj/item/reagent_containers/food/snacks/canned/peaches/maint = 1,
|
||||
/obj/item/storage/box/donkpockets = 1,
|
||||
/obj/item/reagent_containers/food/snacks/monkeycube = 1,
|
||||
) = 1,
|
||||
|
||||
list(//strange objects
|
||||
/obj/item/relic = 1,
|
||||
) = 1,
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(oddity_loot, list(//oddity: strange or crazy items
|
||||
//keeping commented out until there are more, otherwise the same ones may appear too often
|
||||
// /obj/effect/rune/teleport = 1,
|
||||
"" = 1 //nothing, so loot spawner doesn't break while nothing else is here
|
||||
))
|
||||
|
||||
//Maintenance loot spawner pools
|
||||
#define maint_trash_weight 4499
|
||||
#define maint_common_weight 4500
|
||||
#define maint_uncommon_weight 1000
|
||||
#define maint_oddity_weight 1 //1 out of 10,000 would give metastation (180 spawns) a 2 in 111 chance of spawning an oddity per round, similar to xeno egg
|
||||
|
||||
//Loot pool used by default maintenance loot spawners
|
||||
GLOBAL_LIST_INIT(maintenance_loot, list(
|
||||
GLOB.trash_loot = maint_trash_weight,
|
||||
GLOB.common_loot = maint_common_weight,
|
||||
GLOB.uncommon_loot = maint_uncommon_weight,
|
||||
GLOB.oddity_loot = maint_oddity_weight,
|
||||
))
|
||||
|
||||
@@ -360,3 +360,43 @@
|
||||
/obj/item/circuitboard/computer/apc_control,
|
||||
/obj/item/circuitboard/computer/robotics
|
||||
)
|
||||
|
||||
//finds the probabilities of items spawning from a loot spawner's loot pool
|
||||
/obj/item/loot_table_maker
|
||||
icon = 'icons/effects/landmarks_static.dmi'
|
||||
icon_state = "random_loot"
|
||||
var/spawner_to_test = /obj/effect/spawner/lootdrop/maintenance //what lootdrop spawner to use the loot pool of
|
||||
var/loot_count = 180 //180 is about how much maint loot spawns per map as of 11/14/2019
|
||||
//result outputs
|
||||
var/list/spawned_table //list of all items "spawned" and how many
|
||||
var/list/stat_table //list of all items "spawned" and their occurrance probability
|
||||
|
||||
/obj/item/loot_table_maker/Initialize()
|
||||
. = ..()
|
||||
make_table()
|
||||
|
||||
/obj/item/loot_table_maker/attack_self(mob/user)
|
||||
to_chat(user, "Loot pool re-rolled.")
|
||||
make_table()
|
||||
|
||||
/obj/item/loot_table_maker/proc/make_table()
|
||||
spawned_table = list()
|
||||
stat_table = list()
|
||||
var/obj/effect/spawner/lootdrop/spawner_to_table = new spawner_to_test
|
||||
var/lootpool = spawner_to_table.loot
|
||||
qdel(spawner_to_table)
|
||||
for(var/i in 1 to loot_count)
|
||||
var/loot_spawn = pick_loot(lootpool)
|
||||
if(!(loot_spawn in spawned_table))
|
||||
spawned_table[loot_spawn] = 1
|
||||
else
|
||||
spawned_table[loot_spawn] += 1
|
||||
stat_table += spawned_table
|
||||
for(var/item in stat_table)
|
||||
stat_table[item] /= loot_count
|
||||
|
||||
/obj/item/loot_table_maker/proc/pick_loot(lootpool) //selects path from loot table and returns it
|
||||
var/lootspawn = pickweight(lootpool)
|
||||
while(islist(lootspawn))
|
||||
lootspawn = pickweight(lootspawn)
|
||||
return lootspawn
|
||||
|
||||
Reference in New Issue
Block a user