mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-11 08:06:33 +01:00
21b4095dfd
Upstream 04/17/2026 fixes https://github.com/Bubberstation/Bubberstation/issues/5549 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com> Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Rhials <28870487+Rhials@users.noreply.github.com> Co-authored-by: rageguy505 <54517726+rageguy505@users.noreply.github.com> Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Co-authored-by: Aliceee2ch <160794176+Aliceee2ch@users.noreply.github.com> Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com> Co-authored-by: Tsar-Salat <62388554+Tsar-Salat@users.noreply.github.com> Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Co-authored-by: Maxipat <108554989+Maxipat112@users.noreply.github.com> Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com> Co-authored-by: SimplyLogan <47579821+loganuk@users.noreply.github.com> Co-authored-by: loganuk <fakeemail123@aol.com> Co-authored-by: Leland Kemble <70413276+lelandkemble@users.noreply.github.com> Co-authored-by: FalloutFalcon <86381784+FalloutFalcon@users.noreply.github.com> Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com> Co-authored-by: Lucy <lucy@absolucy.moe> Co-authored-by: siliconOpossum <138069572+siliconOpossum@users.noreply.github.com> Co-authored-by: Isratosh <Isratosh@hotmail.com> Co-authored-by: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com> Co-authored-by: Neocloudy <88008002+Neocloudy@users.noreply.github.com> Co-authored-by: Alexander V. <volas@ya.ru> Co-authored-by: ElGitificador <168473461+ElGitificador@users.noreply.github.com> Co-authored-by: Twaticus <46540570+Twaticus@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Tim <timothymtorres@gmail.com> Co-authored-by: Iamgoofball <iamgoofball@gmail.com> Co-authored-by: Layzu666 <121319428+Layzu666@users.noreply.github.com> Co-authored-by: Arturlang <24881678+Arturlang@users.noreply.github.com> Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com> Co-authored-by: mrmanlikesbt <99309552+mrmanlikesbt@users.noreply.github.com> Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Co-authored-by: John F. Kennedy <54908920+MacaroniCritter@users.noreply.github.com> Co-authored-by: Cursor <102828457+theselfish@users.noreply.github.com> Co-authored-by: Josh <josh.adam.powell@gmail.com> Co-authored-by: Josh Powell <josh.powell@softwire.com> Co-authored-by: Yobrocharlie <Charliemiller5617@gmail.com> Co-authored-by: Hardly3D <66234359+Hardly3D@users.noreply.github.com> Co-authored-by: shayoki <96078776+shayoki@users.noreply.github.com> Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
168 lines
7.1 KiB
Plaintext
168 lines
7.1 KiB
Plaintext
///A list of the possible mutations for a vine
|
|
GLOBAL_LIST_INIT(vine_mutations_list, init_vine_mutation_list())
|
|
|
|
/proc/init_vine_mutation_list()
|
|
var/list/mutation_list = list()
|
|
|
|
for(var/datum/spacevine_mutation/subtype as anything in valid_subtypesof(/datum/spacevine_mutation))
|
|
var/datum/spacevine_mutation/mutation = new subtype
|
|
mutation_list[mutation] = IDEAL_MAX_SEVERITY - mutation.severity // the ideal maximum potency is used for weighting
|
|
|
|
return mutation_list
|
|
|
|
/datum/spacevine_controller
|
|
///Canonical list of all the vines we "own"
|
|
var/list/obj/structure/spacevine/vines
|
|
///Queue of vines to process
|
|
var/list/growth_queue
|
|
//List of currently processed vines, on this level to prevent runtime tomfoolery
|
|
var/list/obj/structure/spacevine/queue_end
|
|
///Spread multiplier, depends on productivity, affects how often kudzu spreads
|
|
var/spread_multiplier = 5 // corresponds to artificial kudzu with production speed of 1, approaches 10% of total vines will spread per second
|
|
///Maximum spreading limit (ie. how many kudzu can there be) for this controller
|
|
var/spread_cap = 30 // corresponds to artificial kudzu with production speed of 3.5
|
|
///The chance that we will develop a new mutation
|
|
var/mutativeness = 1
|
|
///Maximum sum of mutation severities
|
|
var/max_mutation_severity = 20
|
|
///Minimum spread rate per second
|
|
var/minimum_spread_rate = 1
|
|
|
|
/datum/spacevine_controller/New(turf/location, list/muts, potency, production, datum/round_event/event = null)
|
|
vines = list()
|
|
growth_queue = list()
|
|
queue_end = list()
|
|
var/obj/structure/spacevine/vine = spawn_spacevine_piece(location, null, muts)
|
|
if(event)
|
|
event.announce_to_ghosts(vine)
|
|
START_PROCESSING(SSobj, src)
|
|
if(potency != null)
|
|
mutativeness = potency * MUTATIVENESS_SCALE_FACTOR // If potency is 100, 20 mutativeness; if 1: 0.2 mutativeness
|
|
max_mutation_severity = round(potency * MAX_SEVERITY_LINEAR_COEFF + MAX_SEVERITY_CONSTANT_TERM) // If potency is 100, 25 max mutation severity; if 1, 10 max mutation severity
|
|
if(production != null && production <= MAX_POSSIBLE_PRODUCTIVITY_VALUE) //Prevents runtime in case production is set to 11.
|
|
spread_cap = SPREAD_CAP_LINEAR_COEFF * (MAX_POSSIBLE_PRODUCTIVITY_VALUE + 1 - production) + SPREAD_CAP_CONSTANT_TERM //Best production speed of 1 increases spread_cap to 60, worst production speed of 10 lowers it to 24, even distribution
|
|
spread_multiplier = SPREAD_MULTIPLIER_MAX / (MAX_POSSIBLE_PRODUCTIVITY_VALUE + 1 - production) // Best production speed of 1: 10% of total vines will spread per second, worst production speed of 10: 1% of total vines (with minimum of 1) will spread per second
|
|
if(event != null) // spawned by space vine event
|
|
max_mutation_severity += MAX_SEVERITY_EVENT_BONUS
|
|
minimum_spread_rate = 3
|
|
|
|
/datum/spacevine_controller/vv_get_dropdown()
|
|
. = ..()
|
|
VV_DROPDOWN_OPTION("", "--- /spacevine_controller ---")
|
|
VV_DROPDOWN_OPTION(VV_HK_SPACEVINE_PURGE, "Delete Vines")
|
|
|
|
/datum/spacevine_controller/vv_do_topic(href_list)
|
|
. = ..()
|
|
|
|
if(!.)
|
|
return
|
|
|
|
if(href_list[VV_HK_SPACEVINE_PURGE])
|
|
if(tgui_alert(usr, "Are you sure you want to delete this spacevine cluster?", "Delete Vines", list("Yes", "No")) == "Yes")
|
|
DeleteVines()
|
|
|
|
/datum/spacevine_controller/proc/DeleteVines() //this is kill
|
|
QDEL_LIST(vines) //this will also qdel us
|
|
|
|
/datum/spacevine_controller/Destroy()
|
|
STOP_PROCESSING(SSobj, src)
|
|
vines.Cut()
|
|
growth_queue.Cut()
|
|
queue_end.Cut()
|
|
return ..()
|
|
|
|
/datum/spacevine_controller/proc/spawn_spacevine_piece(turf/location, obj/structure/spacevine/parent, list/muts)
|
|
var/obj/structure/spacevine/vine = new(location)
|
|
growth_queue += vine
|
|
vines += vine
|
|
vine.master = src
|
|
for(var/mutation_type in muts)
|
|
for(var/datum/spacevine_mutation/mutation in GLOB.vine_mutations_list)
|
|
if(istype(mutation, mutation_type))
|
|
mutation.add_mutation_to_vinepiece(vine)
|
|
break
|
|
if(parent)
|
|
vine.mutations |= parent.mutations
|
|
vine.trait_flags |= parent.trait_flags
|
|
var/parentcolor = parent.atom_colours[FIXED_COLOUR_PRIORITY]
|
|
vine.add_atom_colour(parentcolor, FIXED_COLOUR_PRIORITY)
|
|
if(prob(mutativeness))
|
|
var/datum/spacevine_mutation/random_mutate = pick_weight(GLOB.vine_mutations_list - vine.mutations)
|
|
if(!isnull(random_mutate)) //If this vine has every single mutation don't attempt to add a null mutation.
|
|
var/total_severity = random_mutate.severity
|
|
for(var/datum/spacevine_mutation/mutation as anything in vine.mutations)
|
|
total_severity += mutation.severity
|
|
if(total_severity <= max_mutation_severity)
|
|
random_mutate.add_mutation_to_vinepiece(vine)
|
|
|
|
for(var/datum/spacevine_mutation/mutation in vine.mutations)
|
|
mutation.on_birth(vine)
|
|
location.Entered(vine, null)
|
|
return vine
|
|
|
|
/datum/spacevine_controller/proc/VineDestroyed(obj/structure/spacevine/vine)
|
|
vine.master = null
|
|
vines -= vine
|
|
growth_queue -= vine
|
|
queue_end -= vine
|
|
if(length(vines))
|
|
return
|
|
var/obj/item/seeds/kudzu/seed = new(vine.loc)
|
|
seed.mutations |= vine.mutations
|
|
seed.set_potency(mutativeness / MUTATIVENESS_SCALE_FACTOR)
|
|
// Mathematical notes:
|
|
// The formula for spread_multiplier is SPREAD_MULTIPLIER_MAX / (MAX_POSSIBLE_PRODUCTIVITY_VALUE + 1 - production)
|
|
// So (MAX_POSSIBLE_PRODUCTIVITY_VALUE + 1 - production) = SPREAD_MULTIPLIER_MAX / spread_multiplier
|
|
// ie. production = MAX_POSSIBLE_PRODUCTIVITY_VALUE + 1 - SPREAD_MULTIPLIER_MAX / spread_multiplier
|
|
seed.set_production(MAX_POSSIBLE_PRODUCTIVITY_VALUE + 1 - (SPREAD_MULTIPLIER_MAX / spread_multiplier)) //Reverts spread_multiplier formula so resulting seed gets original production stat or equivalent back.
|
|
qdel(src)
|
|
|
|
/// Life cycle of a space vine
|
|
/datum/spacevine_controller/process(seconds_per_tick)
|
|
var/vine_count = length(vines)
|
|
if(!vine_count)
|
|
qdel(src) //space vines exterminated. Remove the controller
|
|
return
|
|
|
|
/// Bonus spread for kudzu that has just started out (ie. with low vine count)
|
|
var/start_spread_bonus = max(5 - spread_multiplier * (vine_count ** 2) / 400, 0)
|
|
/// Base spread rate, depends solely on spread multiplier and vine count
|
|
var/spread_base = 0.5 * vine_count / spread_multiplier
|
|
/// Actual maximum spread rate for this process tick
|
|
var/spread_max = round(clamp(seconds_per_tick * (spread_base + start_spread_bonus), max(seconds_per_tick * minimum_spread_rate, 1), spread_cap))
|
|
var/amount_processed = 0
|
|
for(var/obj/structure/spacevine/vine in growth_queue)
|
|
if(!vine.can_spread)
|
|
continue
|
|
growth_queue -= vine
|
|
queue_end += vine
|
|
for(var/datum/spacevine_mutation/mutation in vine.mutations)
|
|
mutation.process_mutation(vine)
|
|
|
|
if(vine.growth_stage >= 2) //If tile is fully grown
|
|
vine.entangle_mob()
|
|
else if(SPT_PROB(10, seconds_per_tick)) //If tile isn't fully grown
|
|
vine.grow()
|
|
|
|
vine.spread()
|
|
|
|
amount_processed++
|
|
if(amount_processed >= spread_max)
|
|
break
|
|
|
|
//We can only do so much work per process, but we still want to process everything at some point
|
|
//So we shift the queue a bit
|
|
growth_queue += queue_end
|
|
queue_end = list()
|
|
|
|
/**
|
|
* Used to determine whether the mob is immune to actions by the vine.
|
|
* Use cases: Stops vine from attacking itself, other plants.
|
|
*/
|
|
/proc/isvineimmune(atom/target)
|
|
if(isliving(target))
|
|
var/mob/living/victim = target
|
|
if(victim.has_faction(FACTION_VINES, FACTION_PLANTS))
|
|
return TRUE
|
|
return FALSE
|