Skip to content

Commit

Permalink
Mining Rework Part 1: First of his Name (shiptest-ss13#2446)
Browse files Browse the repository at this point in the history
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->

## About The Pull Request
In a vain attempt to make mining less boring and actually require more
player engagement I have cobbled together the groundwork to a sizable
reworking of the mining system from that thing you send out that one
random crew member to go do for a couple minutes to a team-based
activity focused around the use of specialized equipment.

The gameplay loop for mining I envision within my mind's eye is one
where most members of the ship's crew, even down to the engineers and
medics, have to cooperate in order to properly secure large amounts of
ore from dangerous environments, with most other non-mining ships
needing to at least partially rely on mining ships to supply them with
minerals.

This PR specifically adds; ore veins (they use the same sprites as
geysers pending a better one) that spawn on lava, sand, rock, and ice
planets currently and at varying levels of difficulty and yeild, a drill
with which to mine said veins, a scanner to find the aforementioned
veins, and an outpost mission that is essentially just a mission to go
drill ore veins but with money as the reward instead of ore. Oh and I
also cut surface mineral spawn rates roughly in half pending a better
gauge of the balance involved there.

Here's the harrowing story of one such man who tried to use this drill
with no armaments and no crew:

![screenshot1](https://github.com/shiptest-ss13/Shiptest/assets/112462947/1a737ff6-5372-46ab-bda3-72363dbfe94d)

![screenshot2](https://github.com/shiptest-ss13/Shiptest/assets/112462947/fb9452b8-c6cd-4e9e-8986-59bbb272bdf3)

![screenshot3](https://github.com/shiptest-ss13/Shiptest/assets/112462947/812c4c8f-d3f7-4bde-a119-e8e6f35790e8)


<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->

## Why It's Good For The Game
Mining in its current state is just kinda bad. It's boring to actually
focus on doing and way too easy to just drown your ship in minerals.
This PR would at bare minimum partially fix that. That's not to say it's
perfect and doesn't need to be balanced and polished to hell and back,
but it's a good first step I feel.

<!-- Please add a short description of why you think these changes would
benefit the game. If you can't justify it in words, it might not be
worth adding. -->

## Changelog

:cl:
add: Ore veins and a drill to mine them with
add: Mining based missions
tweak: Lowered the spawn rate of some other mob spawners like tendrils
tweak: Added the ability for mob spawners to spawn mobs a distance from
their source
balance: Cut most ore sources in half and tweaked the spawn weights
/:cl:

<!-- Both :cl:'s are required for the changelog to work! You can put
your name to the right of the first :cl: if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->

---------

Signed-off-by: BogCreature <112462947+BogCreature@users.noreply.github.com>
Co-authored-by: thgvr <81882910+thgvr@users.noreply.github.com>
Co-authored-by: Mark Suckerberg <mark@suckerberg.gay>
  • Loading branch information
3 people authored and MysticalFaceLesS committed Feb 28, 2024
1 parent b02df56 commit 961ff1a
Show file tree
Hide file tree
Showing 22 changed files with 1,033 additions and 57 deletions.
4 changes: 4 additions & 0 deletions code/__DEFINES/dcs/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,10 @@
/// From overmap Undock(): (datum/overmap)
#define COMSIG_OVERMAP_UNDOCK "overmap_undock"

// /datum/component/spawner signals
// Called by parent when pausing spawning, returns bool: (datum/source, spawning_started)
#define COMSIG_SPAWNER_TOGGLE_SPAWNING "spawner_toggle"

///Beam Signals
/// Called before beam is redrawn
#define COMSIG_BEAM_BEFORE_DRAW "beam_before_draw"
Expand Down
6 changes: 6 additions & 0 deletions code/__DEFINES/stock_parts.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//Stock part types (like tool behaviour but for stock parts)
#define PART_CAPACITOR "capacitor"
#define PART_SCANNER "scanning module"
#define PART_MANIPULATOR "manipulator"
#define PART_LASER "micro-laser"
#define PART_BIN "matter bin"
22 changes: 22 additions & 0 deletions code/__HELPERS/game.dm
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,28 @@ block( \
//turfs += centerturf
return atoms

/**
* Behaves like the orange() proc, but only looks in the outer range of the function (The "peel" of the orange).
* Credit to ArcaneMusic for this one
*/
/proc/turf_peel(outer_range, inner_range, center, view_based = FALSE)
var/list/peel = list()
var/list/outer
var/list/inner
if(view_based)
outer = circleviewturfs(center, outer_range)
inner = circleviewturfs(center, inner_range)
else
outer = circlerangeturfs(center, outer_range)
inner = circlerangeturfs(center, inner_range)
for(var/turf/possible_spawn in outer)
if(possible_spawn in inner)
continue
if(istype(possible_spawn, /turf/closed))
continue
peel += possible_spawn
return peel

/proc/get_dist_euclidian(atom/Loc1 as turf|mob|obj,atom/Loc2 as turf|mob|obj)
var/dx = Loc1.x - Loc2.x
var/dy = Loc1.y - Loc2.y
Expand Down
101 changes: 85 additions & 16 deletions code/datums/components/spawner.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@
var/list/spawn_text = list("emerges from")
var/list/faction = list("mining")
var/list/spawn_sound = list()
var/spawn_distance_min = 1
var/spawn_distance_max = 1
var/wave_length //Average time until break in spawning
var/wave_downtime //Average time until spawning starts again
var/wave_timer
var/current_timerid


/datum/component/spawner/Initialize(_mob_types, _spawn_time, _faction, _spawn_text, _max_mobs, _spawn_sound)
/datum/component/spawner/Initialize(_mob_types, _spawn_time, _faction, _spawn_text, _max_mobs, _spawn_sound, _spawn_distance_min, _spawn_distance_max, _wave_length, _wave_downtime)
if(_spawn_time)
spawn_time=_spawn_time
if(_mob_types)
Expand All @@ -22,36 +28,99 @@
max_mobs=_max_mobs
if(_spawn_sound)
spawn_sound=_spawn_sound
if(_spawn_distance_min)
spawn_distance_min=_spawn_distance_min
if(_spawn_distance_max)
spawn_distance_max=_spawn_distance_max
if(_wave_length)
wave_length = _wave_length
if(_wave_downtime)
wave_downtime = _wave_downtime

RegisterSignal(parent, list(COMSIG_PARENT_QDELETING), PROC_REF(stop_spawning))
RegisterSignal(parent, list(COMSIG_SPAWNER_TOGGLE_SPAWNING), PROC_REF(toggle_spawning))
START_PROCESSING(SSprocessing, src)

/datum/component/spawner/process()
if(!parent) //Sanity check for instances where the spawner may be sleeping while the parent is destroyed
qdel(src)
return
try_spawn_mob()


/datum/component/spawner/proc/stop_spawning(force)
SIGNAL_HANDLER

STOP_PROCESSING(SSprocessing, src)
deltimer(current_timerid)
for(var/mob/living/simple_animal/L in spawned_mobs)
if(L.nest == src)
L.nest = null
spawned_mobs = null

//Different from stop_spawning() as it doesn't untether all mobs from it and is meant for temporarily stopping spawning
/datum/component/spawner/proc/toggle_spawning(datum/source, spawning_started)
SIGNAL_HANDLER

if(spawning_started)
STOP_PROCESSING(SSprocessing, src)
deltimer(current_timerid) //Otherwise if spawning is paused while the wave timer is loose it'll just unpause on its own
COOLDOWN_RESET(src, wave_timer)
return FALSE
else
START_PROCESSING(SSprocessing, src)
return TRUE

/datum/component/spawner/proc/try_spawn_mob()
var/atom/P = parent
if(spawned_mobs.len >= max_mobs)
return 0
if(spawn_delay > world.time)
return 0
spawn_delay = world.time + spawn_time
var/chosen_mob_type = pickweight(mob_types)
var/mob/living/simple_animal/L = new chosen_mob_type(P.loc)
L.flags_1 |= (P.flags_1 & ADMIN_SPAWNED_1)
spawned_mobs += L
L.nest = src
L.faction = src.faction
P.visible_message("<span class='danger'>[L] [pick(spawn_text)] [P].</span>")
if(length(spawn_sound))
playsound(P, pick(spawn_sound), 50, TRUE)
var/turf/spot = get_turf(P)
//Checks for handling the wave-based pausing and unpausing of spawning
//Almost certainly a better way to do this, but until then this technically works
if(wave_length)
if(!wave_timer)
COOLDOWN_START(src, wave_timer, wave_length)
if(wave_timer && COOLDOWN_FINISHED(src, wave_timer))
COOLDOWN_RESET(src, wave_timer)
STOP_PROCESSING(SSprocessing, src)
current_timerid = addtimer(CALLBACK(src, PROC_REF(toggle_spawning)), wave_downtime, TIMER_STOPPABLE)
return
////////////////////////////////
if(length(spawned_mobs) >= max_mobs)
return
if(!COOLDOWN_FINISHED(src, spawn_delay))
return
COOLDOWN_START(src, spawn_delay, spawn_time)
var/spawn_multiplier = 1
//Avoid using this with spawners that add this component on initialize
//It causes numerous runtime errors during planet generation
if(spawn_distance_max > 1)
var/player_count = 0
for(var/mob/player as anything in GLOB.player_list)
if(player.virtual_z() != spot.virtual_z())
continue
if(!isliving(player))
continue
if(player.stat != CONSCIOUS)
continue
if(get_dist(get_turf(player), spot) > spawn_distance_max)
continue
player_count++
if(player_count > 3)
spawn_multiplier = round(player_count/2)
spawn_multiplier = clamp(spawn_multiplier, 1, max_mobs - length(spawned_mobs))
for(var/mob_index in 1 to spawn_multiplier)
if(spawn_distance_max > 1)
var/origin = spot
var/list/peel = turf_peel(spawn_distance_max, spawn_distance_min, origin, view_based = TRUE)
if(length(peel))
spot = pick(peel)
else
spot = pick(circleviewturfs(origin, spawn_distance_max))
var/chosen_mob_type = pickweight(mob_types)
var/mob/living/simple_animal/L = new chosen_mob_type(spot)
L.flags_1 |= (P.flags_1 & ADMIN_SPAWNED_1)
spawned_mobs += L
L.nest = src
L.faction = src.faction
P.visible_message("<span class='danger'>[L] [pick(spawn_text)] [P].</span>")
if(length(spawn_sound))
playsound(P, pick(spawn_sound), 50, TRUE)
7 changes: 7 additions & 0 deletions code/datums/looping_sounds/machinery_sounds.dm
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,10 @@
volume = 85
vary = TRUE

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/datum/looping_sound/drill
mid_sounds = list('sound/machines/gravgen/gravgen_mid1.ogg'=1, 'sound/machines/gravgen/gravgen_mid2.ogg'=1, 'sound/machines/gravgen/gravgen_mid3.ogg'=1, 'sound/machines/gravgen/gravgen_mid4.ogg'=1)
mid_length = 4
volume = 50
extra_range = 6
20 changes: 13 additions & 7 deletions code/datums/mapgen/planetary/LavaGenerator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,12 @@
)
feature_spawn_chance = 0.3
feature_spawn_list = list(
/obj/structure/flora/rock/hell = 10,
/obj/structure/flora/rock/hell = 14,
/obj/structure/vein = 5,
/obj/structure/vein/classtwo = 2,
/obj/structure/elite_tumor = 2,
/obj/structure/geyser/random = 2,
/obj/structure/vein/classthree = 1,
/obj/effect/spawner/lootdrop/anomaly/lava = 1,

)
Expand All @@ -112,9 +115,9 @@
/mob/living/simple_animal/hostile/asteroid/goliath/beast/ancient/crystal = 1,
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/forgotten = 1,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/crystal = 1,
/obj/structure/spawner/lavaland/low_threat = 12,
/obj/structure/spawner/lavaland/medium_threat = 4,
/obj/structure/spawner/lavaland/high_threat = 2,
/obj/structure/spawner/lavaland/low_threat = 8,
/obj/structure/spawner/lavaland/medium_threat = 3,
/obj/structure/spawner/lavaland/high_threat = 1,
)

/datum/biome/lavaland/forest
Expand Down Expand Up @@ -161,7 +164,10 @@
feature_spawn_list = list(
/obj/structure/flora/tree/dead/barren = 50,
/obj/structure/flora/tree/dead/tall/grey = 45,
/obj/effect/spawner/lootdrop/anomaly/lava = 5
/obj/effect/spawner/lootdrop/anomaly/lava = 10,
/obj/structure/vein = 5,
/obj/structure/vein/classtwo = 2,
/obj/structure/vein/classthree = 1,
)

/datum/biome/lavaland/plains/dense/mixed
Expand Down Expand Up @@ -231,8 +237,8 @@
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random = 40,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 30,
/mob/living/simple_animal/hostile/asteroid/goldgrub = 10,
/obj/structure/spawner/lavaland/low_threat = 12,
/obj/structure/spawner/lavaland/medium_threat = 4,
/obj/structure/spawner/lavaland/low_threat = 8,
/obj/structure/spawner/lavaland/medium_threat = 3,
/obj/structure/spawner/lavaland/high_threat = 2,
/obj/structure/spawner/lavaland/extreme_threat = 1
)
Expand Down
6 changes: 6 additions & 0 deletions code/datums/mapgen/planetary/RockGenerator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,11 @@
feature_spawn_chance = 0.25
feature_spawn_list = list(
/obj/structure/geyser/random = 80,
/obj/structure/vein = 60,
/obj/structure/elite_tumor = 40,
/obj/structure/vein/classtwo = 40,
/obj/effect/spawner/lootdrop/anomaly/rock = 10,
/obj/structure/vein/classthree = 10,
/obj/effect/spawner/lootdrop/anomaly/big = 1 //get out of here stalker
)

Expand Down Expand Up @@ -147,8 +150,11 @@
)
feature_spawn_chance = 0.5
feature_spawn_list = list(
/obj/structure/vein = 3,
/obj/structure/geyser/random = 2,
/obj/structure/vein/classtwo = 2,
/obj/structure/elite_tumor = 1,
/obj/structure/vein/classthree = 1,
/obj/structure/spawner/ice_moon/rockplanet = 4,
/obj/effect/spawner/lootdrop/anomaly/rock/cave = 1,
)
Expand Down
5 changes: 5 additions & 0 deletions code/datums/mapgen/planetary/SandGenerator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@
feature_spawn_chance = 0.1
feature_spawn_list = list(
/obj/structure/geyser/random = 8,
/obj/structure/vein = 8,
/obj/structure/vein/classtwo = 4,
/obj/structure/elite_tumor = 4,
/obj/structure/vein/classthree = 2,
/obj/effect/spawner/lootdrop/anomaly/sand = 1,
)
mob_spawn_chance = 4
Expand Down Expand Up @@ -192,7 +195,9 @@
/obj/structure/flora/ash/puce = 1,
)
feature_spawn_list = list(
/obj/structure/vein = 8,
/obj/structure/geyser/random = 4,
/obj/structure/vein/classtwo = 4,
/obj/structure/elite_tumor = 4,
/obj/effect/spawner/lootdrop/anomaly/sand/cave = 1
)
Expand Down
54 changes: 33 additions & 21 deletions code/datums/mapgen/planetary/SnowGenerator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@
mob_spawn_chance = 1
mob_spawn_list = list(
/mob/living/simple_animal/hostile/asteroid/wolf/random = 30,
/obj/structure/spawner/ice_moon = 3,
/obj/structure/spawner/ice_moon/polarbear = 3,
/obj/structure/spawner/ice_moon = 2,
/obj/structure/spawner/ice_moon/polarbear = 2,
/mob/living/simple_animal/hostile/asteroid/polarbear/random = 30,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50,
/mob/living/simple_animal/hostile/asteroid/goldgrub = 10,
Expand All @@ -116,7 +116,10 @@
/obj/effect/spawner/lootdrop/anomaly/big = 1,
/obj/structure/spawner/ice_moon/demonic_portal/low_threat = 25,
/obj/structure/spawner/ice_moon/demonic_portal/medium_threat = 50,
/obj/structure/spawner/ice_moon/demonic_portal/high_threat = 13
/obj/structure/spawner/ice_moon/demonic_portal/high_threat = 13,
/obj/structure/vein/ice = 25,
/obj/structure/vein/ice/classtwo = 50,
/obj/structure/vein/ice/classthree = 10,
)

/datum/biome/snow/lush
Expand Down Expand Up @@ -164,15 +167,18 @@
)
feature_spawn_chance = 0.1
feature_spawn_list = list(
/obj/structure/spawner/ice_moon = 3,
/obj/structure/spawner/ice_moon/polarbear = 3,
/obj/structure/spawner/ice_moon = 2,
/obj/structure/spawner/ice_moon/polarbear = 2,
/obj/structure/statue/snow/snowman = 3,
/obj/structure/statue/snow/snowlegion = 1
/obj/structure/statue/snow/snowlegion = 1,
/obj/structure/vein/ice = 3,
/obj/structure/vein/ice/classtwo = 4,
/obj/structure/vein/ice/classthree = 1,
)
mob_spawn_list = list(
/mob/living/simple_animal/hostile/asteroid/wolf/random = 30,
/obj/structure/spawner/ice_moon = 3,
/obj/structure/spawner/ice_moon/polarbear = 3,
/obj/structure/spawner/ice_moon = 2,
/obj/structure/spawner/ice_moon/polarbear = 2,
/mob/living/simple_animal/hostile/asteroid/polarbear/random = 30,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50,
/mob/living/simple_animal/hostile/asteroid/goldgrub = 10,
Expand Down Expand Up @@ -209,10 +215,13 @@
feature_spawn_list = list(
/obj/effect/spawner/lootdrop/anomaly/ice = 100,
/obj/effect/spawner/lootdrop/anomaly/big = 1,
/obj/structure/spawner/ice_moon/demonic_portal/low_threat = 300,
/obj/structure/spawner/ice_moon/demonic_portal/medium_threat = 500,
/obj/structure/spawner/ice_moon/demonic_portal/high_threat = 50,
/obj/structure/spawner/ice_moon/demonic_portal/extreme_threat = 1
/obj/structure/spawner/ice_moon/demonic_portal/low_threat = 200,
/obj/structure/spawner/ice_moon/demonic_portal/medium_threat = 400,
/obj/structure/spawner/ice_moon/demonic_portal/high_threat = 40,
/obj/structure/spawner/ice_moon/demonic_portal/extreme_threat = 1,
/obj/structure/vein/ice = 300,
/obj/structure/vein/ice/classtwo = 500,
/obj/structure/vein/ice/classthree = 50,
)


Expand Down Expand Up @@ -249,8 +258,8 @@
mob_spawn_chance = 2
mob_spawn_list = list(
/mob/living/simple_animal/hostile/asteroid/wolf/random = 30,
/obj/structure/spawner/ice_moon = 3,
/obj/structure/spawner/ice_moon/polarbear = 3,
/obj/structure/spawner/ice_moon = 2,
/obj/structure/spawner/ice_moon/polarbear = 2,
/mob/living/simple_animal/hostile/asteroid/polarbear/random = 30,
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50,
/mob/living/simple_animal/hostile/asteroid/goldgrub = 10,
Expand All @@ -260,13 +269,16 @@
)
feature_spawn_chance = 0.2
feature_spawn_list = list(
/obj/structure/spawner/ice_moon/demonic_portal/low_threat = 30,
/obj/structure/spawner/ice_moon/demonic_portal/medium_threat = 50,
/obj/structure/spawner/ice_moon/demonic_portal/high_threat = 6,
/obj/structure/spawner/ice_moon/demonic_portal/extreme_threat = 2,
/obj/structure/spawner/ice_moon = 30,
/obj/structure/spawner/ice_moon/polarbear = 30,
/obj/effect/spawner/lootdrop/anomaly/ice/cave = 10
/obj/structure/spawner/ice_moon/demonic_portal/low_threat = 20,
/obj/structure/spawner/ice_moon/demonic_portal/medium_threat = 40,
/obj/structure/spawner/ice_moon/demonic_portal/high_threat = 5,
/obj/structure/spawner/ice_moon/demonic_portal/extreme_threat = 1,
/obj/structure/spawner/ice_moon = 20,
/obj/structure/spawner/ice_moon/polarbear = 20,
/obj/effect/spawner/lootdrop/anomaly/ice/cave = 10,
/obj/structure/vein/ice = 30,
/obj/structure/vein/ice/classtwo = 50,
/obj/structure/vein/ice/classthree = 6,
)

/datum/biome/cave/snow/thawed
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/pinpointer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
. = ..()
if(!active)
return
if(!target)
if(!target?.loc)
. += "pinon[alert ? "alert" : ""]null[icon_suffix]"
return
var/turf/here = get_turf(src)
Expand Down
Loading

0 comments on commit 961ff1a

Please sign in to comment.