mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-07-19 04:08:55 +01:00
[MIRROR] Turf Cascade Subsystem (#12348)
Co-authored-by: Will <7099514+Willburd@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
153c095b14
commit
a49b18dacc
@@ -0,0 +1,98 @@
|
||||
// Defaults are tuned for bluespace cascade
|
||||
#define DEFAULT_CONVERSION_RATE 350
|
||||
#define DEFAULT_CONVERSION_PROB 60
|
||||
#define DEFAULT_CONVERSION_DELAY 2.5 SECONDS
|
||||
|
||||
SUBSYSTEM_DEF(turf_cascade)
|
||||
name = "Turf Cascade"
|
||||
wait = 2
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
VAR_PRIVATE/last_group_time = 0
|
||||
VAR_PRIVATE/next_group_delay = DEFAULT_CONVERSION_DELAY
|
||||
|
||||
VAR_PRIVATE/list/currentrun = list()
|
||||
VAR_PRIVATE/list/remaining_turf = list()
|
||||
VAR_PRIVATE/turf_iterations = 0
|
||||
|
||||
VAR_PRIVATE/turf_replace_type = null // Turf path that turfs will be replaced with
|
||||
VAR_PRIVATE/conversion_probability = DEFAULT_CONVERSION_PROB // Randomized rate of conversion, 0 to 100
|
||||
VAR_PRIVATE/conversion_rate = DEFAULT_CONVERSION_RATE // Maximum number of turfs converted in each batch
|
||||
|
||||
/datum/controller/subsystem/turf_cascade/stat_entry(msg)
|
||||
msg = "C: [length(currentrun)] | R: [length(remaining_turf)] | R: [conversion_rate] | P: [turf_replace_type]"
|
||||
. = ..()
|
||||
|
||||
/datum/controller/subsystem/turf_cascade/fire(resumed = FALSE)
|
||||
if(!resumed)
|
||||
if(world.time < (last_group_time + next_group_delay)) // Wait for next expansion
|
||||
return
|
||||
if(!turf_replace_type || (!length(remaining_turf) && !length(currentrun)))
|
||||
stop_cascade()
|
||||
return
|
||||
last_group_time = world.time
|
||||
|
||||
if(!length(currentrun) && length(remaining_turf) && turf_iterations <= 0)
|
||||
// Create a random list of tiles to expand with instead of doing it in order
|
||||
var/subtractive_rand_max = conversion_rate * (1 - (conversion_probability / 100))
|
||||
var/i = 10 // Always do at least a handful of the oldest, to avoid spots that linger unfilled
|
||||
while(i-- > 0)
|
||||
var/turf/next = remaining_turf[1]
|
||||
remaining_turf -= next
|
||||
currentrun += next
|
||||
if(!length(remaining_turf))
|
||||
break
|
||||
|
||||
// Now for randomized growth. If we still have any left to grow into!
|
||||
if(length(remaining_turf))
|
||||
turf_iterations = max(1, conversion_rate - rand(0, subtractive_rand_max)) // Allows for slower rates and more messy growth, min 1, max conversion_rate
|
||||
|
||||
while(turf_iterations-- > 0)
|
||||
var/turf/next = pick(remaining_turf)
|
||||
remaining_turf -= next
|
||||
currentrun += next
|
||||
if(!length(remaining_turf))
|
||||
break
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
while(length(currentrun))
|
||||
var/turf/changing = currentrun[1]
|
||||
currentrun -= changing
|
||||
|
||||
// Convert turf if we are not the replacement type already
|
||||
if(changing.type != turf_replace_type)
|
||||
changing.ChangeTurf(turf_replace_type)
|
||||
remaining_turf += changing.conversion_cascade_act(remaining_turf)
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/// Starts the turf cascade and boots up the subsystem. If a cascade is already in process, it will not allow another another to start.
|
||||
/datum/controller/subsystem/turf_cascade/proc/start_cascade(turf/start_turf, turf_path, max_per_fire = DEFAULT_CONVERSION_RATE, time_delay = DEFAULT_CONVERSION_DELAY, convert_probability = DEFAULT_CONVERSION_PROB)
|
||||
if(turf_replace_type)
|
||||
return
|
||||
if(!isturf(start_turf) || !max_per_fire)
|
||||
return
|
||||
turf_replace_type = turf_path
|
||||
remaining_turf.Add(start_turf)
|
||||
conversion_rate = max_per_fire
|
||||
conversion_probability = convert_probability
|
||||
// Configure subsystem for the cascade... Doing it with tick delays is uglier than just making the subsystem slower or faster. Considering this will end the round anyway.
|
||||
can_fire = TRUE
|
||||
next_group_delay = DEFAULT_CONVERSION_DELAY
|
||||
|
||||
/// Called when we have no more turfs to convert, or an admin wants to emergency stop
|
||||
/datum/controller/subsystem/turf_cascade/proc/stop_cascade()
|
||||
turf_replace_type = null
|
||||
remaining_turf.Cut()
|
||||
currentrun.Cut()
|
||||
conversion_rate = DEFAULT_CONVERSION_RATE
|
||||
conversion_probability = DEFAULT_CONVERSION_PROB
|
||||
next_group_delay = DEFAULT_CONVERSION_DELAY
|
||||
can_fire = FALSE
|
||||
|
||||
#undef DEFAULT_CONVERSION_RATE
|
||||
#undef DEFAULT_CONVERSION_PROB
|
||||
#undef DEFAULT_CONVERSION_DELAY
|
||||
@@ -10,55 +10,19 @@
|
||||
//l_color="#0066FF"
|
||||
plane = PLANE_LIGHTING_ABOVE
|
||||
|
||||
var/spawned=0 // DIR mask
|
||||
var/next_check=0
|
||||
var/list/avail_dirs = list(NORTH,SOUTH,EAST,WEST)
|
||||
|
||||
/turf/unsimulated/wall/supermatter/Initialize(mapload)
|
||||
/turf/unsimulated/wall/supermatter/conversion_cascade_act(list/already_marked_turfs)
|
||||
// Do pretty fadeout animation for the new turf
|
||||
. = ..()
|
||||
START_PROCESSING(SSturfs, src)
|
||||
next_check = world.time+5 SECONDS
|
||||
|
||||
/turf/unsimulated/wall/supermatter/Destroy()
|
||||
STOP_PROCESSING(SSturfs, src)
|
||||
return ..()
|
||||
|
||||
/turf/unsimulated/wall/supermatter/process()
|
||||
// Only check infrequently.
|
||||
if(next_check>world.time) return
|
||||
|
||||
// No more available directions? Shut down process().
|
||||
if(avail_dirs.len==0)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return 1
|
||||
|
||||
// We're checking, reset the timer.
|
||||
next_check = world.time+5 SECONDS
|
||||
|
||||
// Choose a direction.
|
||||
var/pdir = pick(avail_dirs)
|
||||
avail_dirs -= pdir
|
||||
var/turf/T=get_step(src,pdir)
|
||||
|
||||
// EXPAND
|
||||
if(!istype(T,type))
|
||||
// Do pretty fadeout animation for 1s.
|
||||
new /obj/effect/overlay/bluespacify(T)
|
||||
spawn(10)
|
||||
// Nom.
|
||||
for(var/atom/movable/A in T)
|
||||
if(A)
|
||||
if(isliving(A))
|
||||
qdel(A)
|
||||
else if(istype(A,/mob)) // Observers, AI cameras.
|
||||
continue
|
||||
else
|
||||
qdel(A)
|
||||
T.ChangeTurf(type)
|
||||
|
||||
if((spawned & (NORTH|SOUTH|EAST|WEST)) == (NORTH|SOUTH|EAST|WEST))
|
||||
STOP_PROCESSING(SSturfs, src)
|
||||
return
|
||||
for(var/turf/valid_turf in .)
|
||||
new /obj/effect/overlay/bluespacify(valid_turf)
|
||||
// Consume everything in our turf
|
||||
for(var/atom/movable/A in src)
|
||||
if(isliving(A))
|
||||
qdel(A)
|
||||
continue
|
||||
if(istype(A,/mob)) // Observers, AI cameras.
|
||||
continue
|
||||
qdel(A)
|
||||
|
||||
/turf/unsimulated/wall/supermatter/attack_generic(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
@@ -117,3 +81,7 @@
|
||||
return
|
||||
|
||||
qdel(user)
|
||||
|
||||
|
||||
/turf/unsimulated/wall/supermatter/ex_act(severity)
|
||||
return
|
||||
|
||||
@@ -58,7 +58,9 @@ GLOBAL_VAR_INIT(universe_has_ended, 0)
|
||||
|
||||
PlayerSet()
|
||||
|
||||
new /obj/singularity/narsie/large/exit(pick(GLOB.endgame_exits))
|
||||
if(GLOB.endgame_exits?.len)
|
||||
new /obj/singularity/narsie/large/exit(pick(GLOB.endgame_exits))
|
||||
|
||||
spawn(rand(30,60) SECONDS)
|
||||
var/txt = {"
|
||||
There's been a galaxy-wide electromagnetic pulse. All of our systems are heavily damaged and many personnel are dead or dying. We are seeing increasing indications of the universe itself beginning to unravel.
|
||||
|
||||
@@ -531,3 +531,14 @@
|
||||
if(!ismopable(movable_content))
|
||||
continue
|
||||
movable_content.wash(clean_types)
|
||||
|
||||
/// Used during turf_cascade subsystem to determine additional effects when spreading, and directions it may spread
|
||||
/turf/proc/conversion_cascade_act(list/already_marked_turfs)
|
||||
var/list/expanding_turfs = list()
|
||||
|
||||
for(var/expand_dir in GLOB.cardinalz)
|
||||
var/turf/next_turf = get_step(src, expand_dir)
|
||||
if(next_turf && next_turf.type != type && !(next_turf in already_marked_turfs)) // Yes in already_marked_turfs is expensive, but less expensive than 6 dupes per turf potentially in the loop
|
||||
expanding_turfs += next_turf
|
||||
|
||||
return expanding_turfs
|
||||
|
||||
@@ -427,8 +427,8 @@ ADMIN_VERB(secrets, R_HOLDER, "Secrets", "Abuse harder than you ever have before
|
||||
if("supermatter_cascade")
|
||||
var/choice = tgui_alert(holder, "You sure you want to destroy the universe and create a large explosion at your location? Misuse of this could result in removal of flags or hilarity.","WARNING!", list("NO TIME TO EXPLAIN", "Cancel"))
|
||||
if(choice == "NO TIME TO EXPLAIN")
|
||||
explosion(get_turf(holder), 8, 16, 24, 32, 1)
|
||||
new /turf/unsimulated/wall/supermatter(get_turf(holder))
|
||||
explosion(get_turf(holder.mob), 8, 16, 24, 32, 1)
|
||||
SSturf_cascade.start_cascade(get_turf(holder.mob), /turf/unsimulated/wall/supermatter)
|
||||
SetUniversalState(/datum/universal_state/supermatter_cascade)
|
||||
message_admins("[key_name_admin(holder)] has managed to destroy the universe with a supermatter cascade. Good job, [key_name_admin(holder)]")
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
if(forensic_data?.get_hiddenprints())
|
||||
prints = ", all touchers : " + forensic_data?.get_hiddenprints()
|
||||
|
||||
SSturf_cascade.start_cascade(get_turf(src), /turf/unsimulated/wall/supermatter)
|
||||
SetUniversalState(/datum/universal_state/supermatter_cascade)
|
||||
log_admin("New super singularity made by eating a SM crystal [prints]. Last touched by [forensic_data?.get_lastprint()].")
|
||||
message_admins("New super singularity made by eating a SM crystal [prints]. Last touched by [forensic_data?.get_lastprint()].")
|
||||
|
||||
@@ -42,7 +42,7 @@ export const SORTING_TYPES: readonly SortType[] = [
|
||||
},
|
||||
{
|
||||
label: 'Subsystem Overtime',
|
||||
propName: 'overtime',
|
||||
propName: 'tick_overrun',
|
||||
inDeciseconds: true,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -636,6 +636,7 @@
|
||||
#include "code\controllers\subsystems\time_track.dm"
|
||||
#include "code\controllers\subsystems\timer.dm"
|
||||
#include "code\controllers\subsystems\transcore_vr.dm"
|
||||
#include "code\controllers\subsystems\turf_cascade.dm"
|
||||
#include "code\controllers\subsystems\verb_manager.dm"
|
||||
#include "code\controllers\subsystems\vis_overlays.dm"
|
||||
#include "code\controllers\subsystems\vote.dm"
|
||||
|
||||
Reference in New Issue
Block a user