mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-02-06 22:39:04 +00:00
## About The Pull Request Unit tests will now fail if there's a decal in a wall or open space turf. Open space turf could be limiting to mappers but I don't think it makes sense for decals (like dirt, glass shards, etc) to be floating around in space in the exact same spot. If there's a decal you want to put in space, decals have a ``turf_loc_check`` var that will bypass this. **Important note: This is not changing existing behavior. Decals already delete themselves when they spawn in these incorrect locations, we're just avoiding them from spawning in the first place.** ### Changes I made - Ash flora are now lava immune, rivers spawn after flora does, so I decided that it would be easiest (and more flavorful) to have them be lava-immune rather than to not have them spawn at all. - Decals can now be spawned in non-turf locations. This is currently done by mail, which can give you bones as part of the mail. Currently it will just delete itself instead. - Trading Card button is now on the same tile as their display, which now uses an offset. Before it would spawn it on the tile next to it, which could be a wall in some instances. - Mirrors now have floating movement type. They ARE floating since they're attached to the wall, and it prevents them from burning up due to lava in the Pride ruin. - I also added a broken mirror subtype because I thought the icon_state check was terrible. - Bubblegum called ``DestroySurroundings`` several times on the same thing, I hopefully fixed some of that. Their charge ability also registered ``COMSIG_MOB_STATCHANGE`` despite ``/datum/action`` doing it by default, so I fixed that too. ## Why It's Good For The Game Decals in walls is already a bad idea, but currently all it does is delete it on Initialize. It would be better if we ensured they wouldn't spawn in the first place. ## Changelog 🆑 fix: Lava will no longer burn 6 of the mirrors in pride ruin fix: Lava will no longer burn plants that spawn in them. /🆑
134 lines
4.7 KiB
Plaintext
134 lines
4.7 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
|
|
/// 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
|
|
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)
|
|
spawned_loot.pixel_x = spawned_loot.pixel_y = ((!(loot_spawned%2)*loot_spawned/2)*-1)+((loot_spawned%2)*(loot_spawned+1)/2*1)
|
|
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) && !SSmapping.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
|