mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-27 06:54:18 +01:00
https://www.youtube.com/watch?v=ZpUYjpKg9KY As per title. The goal is to add health to most objects in the game and thus allow them to be dynamically destructible, while also avoiding shitcode like each structure having its own snowflake health update proc. --------- Signed-off-by: Matt Atlas <mattiathebest2000@hotmail.it> Co-authored-by: Matt Atlas <liermattia@gmail.com> Co-authored-by: SleepyGemmy <99297919+SleepyGemmy@users.noreply.github.com>
130 lines
3.8 KiB
Plaintext
130 lines
3.8 KiB
Plaintext
#define NEIGHBOR_REFRESH_TIME 100
|
|
|
|
/obj/effect/plant/proc/get_cardinal_neighbors()
|
|
var/list/cardinal_neighbors = list()
|
|
for(var/check_dir in GLOB.cardinals)
|
|
var/turf/simulated/T = get_step(get_turf(src), check_dir)
|
|
if(istype(T))
|
|
cardinal_neighbors |= T
|
|
return cardinal_neighbors
|
|
|
|
/obj/effect/plant/proc/update_neighbors()
|
|
// Update our list of valid neighboring turfs.
|
|
neighbors = list()
|
|
for(var/turf/simulated/floor in get_cardinal_neighbors())
|
|
if(get_dist(parent, floor) > spread_distance)
|
|
continue
|
|
if((locate(/obj/effect/plant) in floor.contents) || (locate(/obj/effect/dead_plant) in floor.contents) )
|
|
continue
|
|
if(floor.density)
|
|
if(seed && seed.chems[/singleton/reagent/acid/polyacid])
|
|
addtimer(CALLBACK(floor, TYPE_PROC_REF(/atom, ex_act), 3), rand(5, 25))
|
|
continue
|
|
if(!Adjacent(floor) || !floor.Enter(src))
|
|
continue
|
|
neighbors |= floor
|
|
|
|
if (neighbors.len)
|
|
SSplants.add_plant(src)
|
|
|
|
// Update all of our friends.
|
|
var/turf/T = get_turf(src)
|
|
for(var/obj/effect/plant/neighbor in range(1,src))
|
|
neighbor.neighbors -= T
|
|
|
|
/obj/effect/plant/process()
|
|
// Something is very wrong, kill ourselves.
|
|
if(!seed)
|
|
die_off()
|
|
return 0
|
|
|
|
for(var/obj/effect/smoke/chem/smoke in view(1, src))
|
|
if(smoke.reagents.has_reagent(/singleton/reagent/toxin/plantbgone))
|
|
die_off()
|
|
return
|
|
|
|
// Handle life.
|
|
var/turf/simulated/T = get_turf(src)
|
|
if(istype(T))
|
|
health -= seed.handle_environment(T,T.return_air(),null,1)
|
|
if(health < maxhealth)
|
|
health += rand(3,5)
|
|
refresh_icon()
|
|
if(health > maxhealth)
|
|
health = maxhealth
|
|
else if(health == maxhealth && !plant)
|
|
plant = new(T,seed)
|
|
plant.dir = src.dir
|
|
plant.transform = src.transform
|
|
plant.age = GET_SEED_TRAIT(seed, TRAIT_MATURATION)-1
|
|
plant.update_icon()
|
|
if(growth_type==0) //Vines do not become invisible.
|
|
set_invisibility(INVISIBILITY_MAXIMUM)
|
|
else
|
|
plant.layer = layer + 0.1
|
|
|
|
if(buckled)
|
|
seed.do_sting(buckled,src)
|
|
if(GET_SEED_TRAIT(seed, TRAIT_CARNIVOROUS))
|
|
seed.do_thorns(buckled,src)
|
|
|
|
if(world.time >= last_tick+NEIGHBOR_REFRESH_TIME)
|
|
last_tick = world.time
|
|
update_neighbors()
|
|
|
|
if(sampled)
|
|
//Should be between 2-7 for given the default range of values for TRAIT_PRODUCTION
|
|
var/chance
|
|
if(!GET_SEED_TRAIT(seed, TRAIT_PRODUCTION))
|
|
chance = 1
|
|
else
|
|
chance = max(1, round(30/GET_SEED_TRAIT(seed, TRAIT_PRODUCTION)))
|
|
if(prob(chance))
|
|
sampled = 0
|
|
|
|
if(is_mature() && neighbors.len && prob(spread_chance))
|
|
//spread to 1-3 adjacent turfs depending on yield trait.
|
|
var/max_spread = between(1, round(GET_SEED_TRAIT(seed, TRAIT_YIELD)*3/14), 3)
|
|
|
|
do_spread(spread_chance, max_spread)
|
|
|
|
// We shouldn't have spawned if the controller doesn't exist.
|
|
check_health()
|
|
if(neighbors.len || health != maxhealth || buckled || !is_mature())
|
|
SSplants.add_plant(src)
|
|
|
|
/obj/effect/plant/proc/do_spread(spread_chance, max_spread)
|
|
set waitfor = FALSE
|
|
for(var/i in 1 to max_spread)
|
|
if(prob(spread_chance))
|
|
sleep(rand(3,5))
|
|
if(!neighbors.len)
|
|
return
|
|
|
|
var/turf/target_turf = pick(neighbors)
|
|
var/obj/effect/plant/child = new(get_turf(src),seed,parent)
|
|
// This should do a little bit of animation.
|
|
addtimer(CALLBACK(src, PROC_REF(do_move), target_turf, child), 1)
|
|
// Update neighboring squares.
|
|
for(var/obj/effect/plant/neighbor in range(1,target_turf))
|
|
neighbor.neighbors -= target_turf
|
|
|
|
/obj/effect/plant/proc/do_move(turf/target, obj/effect/plant/child)
|
|
child.forceMove(target)
|
|
child.queue_icon_update()
|
|
|
|
/obj/effect/plant/proc/die_off()
|
|
// Kill off our plant.
|
|
if(plant) plant.die()
|
|
// This turf is clear now, let our buddies know.
|
|
for(var/turf/simulated/check_turf in get_cardinal_neighbors())
|
|
if(!istype(check_turf))
|
|
continue
|
|
for(var/obj/effect/plant/neighbor in check_turf.contents)
|
|
neighbor.neighbors |= check_turf
|
|
SSplants.add_plant(neighbor)
|
|
|
|
qdel(src)
|
|
|
|
#undef NEIGHBOR_REFRESH_TIME
|