mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-21 22:47:19 +00:00
## About The Pull Request Title. ## Why It's Good For The Game Armories aren't really a dense area mapping wise, just a few guns there, armor there, and some fluff security stuff (like HUDs or whatever). This PR just converts most of the heavy stuff (armor, helmets, guns) into spawning helpers with the aim to make mapping armories just a tad bit quicker and easier. The only thing this does kinda nuke is the neatly stacked stuff, which the mapping helpers kinda suck at doing, but its not totally woeful. ## Changelog 🆑 Jolly, timothymtorres code: Jolly: Armories across all maps have been tweaked slightly. Report to a Nanotrasen security advisor for any missing guns, armor, helmets or anything else that was there previously (that means, post an issue on Github if theres an issue!!) code: timothymtorres: Random item spawners now support better control of their X/Y pixel offset. /🆑 --------- Co-authored-by: Tim <timothymtorres@gmail.com>
139 lines
5.1 KiB
Plaintext
139 lines
5.1 KiB
Plaintext
/**
|
|
* Base class for all random spawners.
|
|
*/
|
|
/obj/effect/spawner/random
|
|
icon = 'icons/effects/random_spawners.dmi'
|
|
icon_state = "loot"
|
|
layer = OBJ_LAYER
|
|
/// Stops persistent lootdrop spawns from being shoved into lockers
|
|
anchored = TRUE
|
|
/// A list of possible items to spawn e.g. list(/obj/item, /obj/structure, /obj/effect)
|
|
var/list/loot
|
|
/// The subtypes AND type to combine with the loot list
|
|
var/loot_type_path
|
|
/// The subtypes (this excludes the provided path) to combine with the loot list
|
|
var/loot_subtype_path
|
|
/// How many items will be spawned
|
|
var/spawn_loot_count = 1
|
|
/// If the same item can be spawned twice
|
|
var/spawn_loot_double = TRUE
|
|
/// Whether the items should be distributed to offsets 0,1,-1,2,-2,3,-3.. This overrides pixel_x/y on the spawner itself
|
|
var/spawn_loot_split = FALSE
|
|
/// The pixel x/y divider offsets for spawn_loot_split (spaced 1 pixel apart by default)
|
|
var/spawn_loot_split_pixel_offsets = 2
|
|
/// Whether the spawner should spawn all the loot in the list
|
|
var/spawn_all_loot = FALSE
|
|
/// The chance for the spawner to create loot (ignores spawn_loot_count)
|
|
var/spawn_loot_chance = 100
|
|
/// Determines how big of a range (in tiles) we should scatter things in.
|
|
var/spawn_scatter_radius = 0
|
|
/// Whether the items should have a random pixel_x/y offset (maxium offset distance is ±16 pixels for x/y)
|
|
var/spawn_random_offset = FALSE
|
|
|
|
/obj/effect/spawner/random/Initialize(mapload)
|
|
. = ..()
|
|
spawn_loot()
|
|
|
|
///If the spawner has any loot defined, randomly picks some and spawns it. Does not cleanup the spawner.
|
|
/obj/effect/spawner/random/proc/spawn_loot(lootcount_override)
|
|
if(!prob(spawn_loot_chance))
|
|
return
|
|
|
|
var/list/spawn_locations = get_spawn_locations(spawn_scatter_radius)
|
|
var/spawn_loot_count = isnull(lootcount_override) ? src.spawn_loot_count : lootcount_override
|
|
|
|
if(spawn_all_loot)
|
|
spawn_loot_count = INFINITY
|
|
spawn_loot_double = FALSE
|
|
|
|
if(loot_type_path)
|
|
loot += typesof(loot_type_path)
|
|
|
|
if(loot_subtype_path)
|
|
loot += subtypesof(loot_subtype_path)
|
|
|
|
if(loot?.len)
|
|
var/loot_spawned = 0
|
|
var/pixel_divider = FLOOR(16 / spawn_loot_split_pixel_offsets, 1) // 16 pixels offsets is max that should be allowed in any direction
|
|
while((spawn_loot_count-loot_spawned) && loot.len)
|
|
var/lootspawn = pick_weight_recursive(loot)
|
|
if(!spawn_loot_double)
|
|
loot.Remove(lootspawn)
|
|
if(lootspawn && (spawn_scatter_radius == 0 || spawn_locations.len))
|
|
var/turf/spawn_loc = loc
|
|
if(spawn_scatter_radius > 0)
|
|
spawn_loc = pick_n_take(spawn_locations)
|
|
|
|
var/atom/movable/spawned_loot = make_item(spawn_loc, lootspawn)
|
|
spawned_loot.setDir(dir)
|
|
|
|
if (!spawn_loot_split && !spawn_random_offset)
|
|
if (pixel_x != 0)
|
|
spawned_loot.pixel_x = pixel_x
|
|
if (pixel_y != 0)
|
|
spawned_loot.pixel_y = pixel_y
|
|
else if (spawn_random_offset)
|
|
spawned_loot.pixel_x = rand(-16, 16)
|
|
spawned_loot.pixel_y = rand(-16, 16)
|
|
else if (spawn_loot_split)
|
|
if (loot_spawned)
|
|
var/column = FLOOR(loot_spawned / pixel_divider, 1)
|
|
spawned_loot.pixel_x = spawn_loot_split_pixel_offsets * (loot_spawned % pixel_divider) + (column * spawn_loot_split_pixel_offsets)
|
|
spawned_loot.pixel_y = spawn_loot_split_pixel_offsets * (loot_spawned % pixel_divider)
|
|
loot_spawned++
|
|
|
|
/**
|
|
* Makes the actual item related to our spawner.
|
|
*
|
|
* spawn_loc - where are we spawning it?
|
|
* type_path_to_make - what are we spawning?
|
|
**/
|
|
/obj/effect/spawner/random/proc/make_item(spawn_loc, type_path_to_make)
|
|
return new type_path_to_make(spawn_loc)
|
|
|
|
///If the spawner has a spawn_scatter_radius set, this creates a list of nearby turfs available
|
|
/obj/effect/spawner/random/proc/get_spawn_locations(radius)
|
|
var/list/scatter_locations = list()
|
|
|
|
if(radius >= 0)
|
|
for(var/turf/turf_in_view in view(radius, get_turf(src)))
|
|
if(isclosedturf(turf_in_view) || (isgroundlessturf(turf_in_view) && !GET_TURF_BELOW(turf_in_view)))
|
|
continue
|
|
scatter_locations += turf_in_view
|
|
|
|
return scatter_locations
|
|
|
|
//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/random/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(mapload)
|
|
. = ..()
|
|
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/random/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_weight_recursive(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
|