Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slightly optimize shroom spreading code #53652

Merged
merged 1 commit into from
Sep 18, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
77 changes: 52 additions & 25 deletions code/game/objects/effects/glowshroom.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
var/spreadIntoAdjacentChance = 75
/// Internal seed of the glowshroom, stats are stored here
var/obj/item/seeds/myseed = /obj/item/seeds/glowshroom

/// If we fail to spread this many times we stop trying to spread
var/max_failed_spreads = 5
/// Turfs where the glowshroom cannot spread to
var/static/list/blacklisted_glowshroom_turfs = typecacheof(list(
/turf/open/lava,
Expand Down Expand Up @@ -92,39 +95,59 @@
else //if on the floor, glowshroom on-floor sprite
icon_state = base_icon_state

addtimer(CALLBACK(src, .proc/Spread), delay_spread)
addtimer(CALLBACK(src, .proc/Decay), delay_decay, FALSE) // Start decaying the plant

addtimer(CALLBACK(src, .proc/Spread), delay_spread, TIMER_UNIQUE|TIMER_NO_HASH_WAIT)
addtimer(CALLBACK(src, .proc/Decay), delay_decay, TIMER_UNIQUE|TIMER_NO_HASH_WAIT)

/**
* Causes glowshroom spreading across the floor/walls.
*/

/obj/structure/glowshroom/proc/Spread()

//We could be deleted at any point and the timers might not be cleaned up
if(QDELETED(src))
return

var/turf/ownturf = get_turf(src)
var/shrooms_planted = 0
var/list/possibleLocs = list()
SpaceManiac marked this conversation as resolved.
Show resolved Hide resolved
//Lets collect a list of possible viewable turfs BEFORE we iterate for yield so we don't call view multiple
//times when there's no real chance of the viewable range changing, really you could do this once on item
//spawn and most people probably would not notice.
for(var/turf/open/floor/earth in view(3,src))
if(is_type_in_typecache(earth, blacklisted_glowshroom_turfs))
continue
if(!ownturf.CanAtmosPass(earth))
continue
possibleLocs += earth

//Lets not even try to spawn again if somehow we have ZERO possible locations
if(!possibleLocs.len)
return

for(var/i in 1 to myseed.yield)
var/chance_stats = ((myseed.potency + myseed.endurance * 2) * 0.2) // Chance of generating a new mushroom based on stats
var/chance_generation = (100 / (generation * generation)) // This formula gives you diminishing returns based on generation. 100% with 1st gen, decreasing to 25%, 11%, 6, 4, 2...
if(prob(max(chance_stats, chance_generation))) // Whatever is the higher chance we use it
var/list/possibleLocs = list()
var/spreadsIntoAdjacent = FALSE

if(prob(spreadIntoAdjacentChance))
spreadsIntoAdjacent = TRUE

for(var/turf/open/floor/earth in view(3,src))
if(is_type_in_typecache(earth, blacklisted_glowshroom_turfs))
continue
if(!ownturf.CanAtmosPass(earth))
continue
if(spreadsIntoAdjacent || !locate(/obj/structure/glowshroom) in view(1,earth))
possibleLocs += earth
CHECK_TICK
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will note I have removed this.

If this causes server lag I will delete glowshrooms

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

based


if(!possibleLocs.len)
break

var/turf/newLoc = pick(possibleLocs)
// Whatever is the higher chance we use it (this is really stupid as the diminishing returns are effectively pointless???)
if(prob(max(chance_stats, chance_generation)))
var/spreadsIntoAdjacent = prob(spreadIntoAdjacentChance)
var/turf/newLoc = null
SpaceManiac marked this conversation as resolved.
Show resolved Hide resolved

//Try three random locations to spawn before giving up tradeoff
//between running view(1, earth) on every single collected possibleLoc
//and failing to spread if we get 3 bad picks, which should only be a problem
//if there's a lot of glow shroom clustered about
for(var/Potato in 1 to 3)
SpaceManiac marked this conversation as resolved.
Show resolved Hide resolved
var/turf/possibleLoc = pick(possibleLocs)
if(spreadsIntoAdjacent || !locate(/obj/structure/glowshroom) in view(1,possibleLoc))
newLoc = possibleLoc
break

//We failed to find any location, skip trying to yield
if(newLoc == null)
break

var/shroomCount = 0 //hacky
var/placeCount = 1
Expand All @@ -144,10 +167,14 @@
child.generation = generation + 1
shrooms_planted++

CHECK_TICK
if(shrooms_planted <= myseed.yield) //if we didn't get all possible shrooms planted, try again later
if(!shrooms_planted)
max_failed_spreads--

//if we didn't get all possible shrooms planted or we haven't failed to spread at least 5 times then try to spread again later
if( (shrooms_planted <= myseed.yield) && (max_failed_spreads >= 0) )
myseed.adjust_yield(-shrooms_planted)
addtimer(CALLBACK(src, .proc/Spread), delay_spread)
//Lets make this a unique hash
addtimer(CALLBACK(src, .proc/Spread), delay_spread, TIMER_UNIQUE|TIMER_NO_HASH_WAIT)

/obj/structure/glowshroom/proc/CalcDir(turf/location = loc)
var/direction = 16
Expand Down Expand Up @@ -194,7 +221,7 @@
else // Timed decay
myseed.endurance -= 1
if (myseed.endurance > 0)
addtimer(CALLBACK(src, .proc/Decay), delay_decay, FALSE) // Recall decay timer
addtimer(CALLBACK(src, .proc/Decay), delay_decay, TIMER_UNIQUE|TIMER_NO_HASH_WAIT) // Recall decay timer
return
if (myseed.endurance < 1) // Plant is gone
qdel(src)
Expand Down