mirror of
https://github.com/CHOMPstation/CHOMPstation.git
synced 2026-08-25 13:06:38 +01:00
Thanks to Razgriz and Dragonhark for coding most of the three plant mobs; piranha plant, spitter and pitcher plant, and Skits for providing the sprites. I have with help finished the mobs with spitter stunning victims for other plants to eat, pitcher heals when having a meal and both it and spitter produces soyelent which can have fture possible uses! If the stars align and a space vine has the carnivorous trait and enough potency, it has a chance to spawn these mobs when spreading! additionally theres now two new variables, one that makes ranged mob stop targeting unconscious victims and another that makes mobs immune to entangling and attacking vines!
175 lines
5.3 KiB
Plaintext
175 lines
5.3 KiB
Plaintext
#define NEIGHBOR_REFRESH_TIME 100
|
|
|
|
/obj/effect/plant/proc/get_cardinal_neighbors()
|
|
var/list/cardinal_neighbors = list()
|
|
for(var/check_dir in cardinal)
|
|
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
|
|
|
|
var/blocked = 0
|
|
for(var/obj/effect/plant/other in floor.contents)
|
|
if(other.seed == src.seed)
|
|
blocked = 1
|
|
break
|
|
if(blocked)
|
|
continue
|
|
|
|
if(floor.density)
|
|
if(!isnull(seed.chems["pacid"]))
|
|
spawn(rand(5,25)) floor.ex_act(3)
|
|
continue
|
|
|
|
if(!Adjacent(floor) || !floor.Enter(src))
|
|
continue
|
|
neighbors |= floor
|
|
|
|
if(neighbors.len)
|
|
plant_controller.add_plant(src) //if we have neighbours again, start processing
|
|
|
|
// Update all of our friends.
|
|
var/turf/T = get_turf(src)
|
|
for(var/obj/effect/plant/neighbor in range(1,src))
|
|
if(neighbor.seed == src.seed)
|
|
neighbor.neighbors -= T
|
|
|
|
/obj/effect/plant/process()
|
|
|
|
// Something is very wrong, kill ourselves.
|
|
if(!seed)
|
|
die_off()
|
|
return 0
|
|
|
|
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
|
|
if(smoke.reagents.has_reagent("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 < max_health)
|
|
health += rand(3,5)
|
|
refresh_icon()
|
|
if(health > max_health)
|
|
health = max_health
|
|
else if(health == max_health && !plant)
|
|
plant = new(T,seed)
|
|
plant.dir = src.dir
|
|
plant.transform = src.transform
|
|
plant.age = seed.get_trait(TRAIT_MATURATION)-1
|
|
plant.update_icon()
|
|
if(growth_type==0) //Vines do not become invisible.
|
|
invisibility = INVISIBILITY_MAXIMUM
|
|
else
|
|
plant.layer = layer + 0.1
|
|
|
|
if(has_buckled_mobs())
|
|
for(var/A in buckled_mobs)
|
|
var/mob/living/L = A
|
|
seed.do_sting(L,src)
|
|
if(seed.get_trait(TRAIT_CARNIVOROUS))
|
|
seed.do_thorns(L,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 = max(1, round(15/seed.get_trait(TRAIT_PRODUCTION)))
|
|
if(prob(chance))
|
|
sampled = 0
|
|
|
|
if(is_mature() && !has_buckled_mobs())
|
|
for(var/turf/neighbor in neighbors)
|
|
for(var/mob/living/M in neighbor)
|
|
if(seed.get_trait(TRAIT_SPREAD) >= 2 && (M.lying || prob(round(seed.get_trait(TRAIT_POTENCY)))))
|
|
entangle(M)
|
|
|
|
if(is_mature() && neighbors.len && prob(spread_chance))
|
|
//spread to 1-3 adjacent turfs depending on yield trait.
|
|
var/max_spread = between(1, round(seed.get_trait(TRAIT_YIELD)*3/14), 3)
|
|
|
|
for(var/i in 1 to max_spread)
|
|
if(prob(spread_chance))
|
|
sleep(rand(3,5))
|
|
if(!neighbors.len)
|
|
break
|
|
spread_to(pick(neighbors))
|
|
|
|
// We shouldn't have spawned if the controller doesn't exist.
|
|
check_health()
|
|
if(has_buckled_mobs() || neighbors.len)
|
|
plant_controller.add_plant(src)
|
|
|
|
//spreading vines aren't created on their final turf.
|
|
//Instead, they are created at their parent and then move to their destination.
|
|
|
|
/obj/effect/plant/proc/spread_to(turf/target_turf)
|
|
var/obj/effect/plant/child = new(get_turf(src),seed,parent)
|
|
|
|
spawn(1) // This should do a little bit of animation.
|
|
if(QDELETED(child))
|
|
return
|
|
|
|
//move out to the destination
|
|
child.anchored = 0
|
|
step_to(child, target_turf)
|
|
child.anchored = 1
|
|
child.update_icon()
|
|
|
|
if((seed.get_trait(TRAIT_POTENCY)) >= 50 && (seed.get_trait(TRAIT_CARNIVOROUS)) && prob(5))
|
|
var/spread_mobspawn = rand(0,2)
|
|
switch(spread_mobspawn)
|
|
if(0) new /mob/living/simple_animal/hostile/piranhaplant(src.loc)
|
|
if(1) new /mob/living/simple_animal/hostile/piranhaplant/spitter(src.loc)
|
|
if(2) new /mob/living/simple_animal/hostile/piranhaplant/pitcher(src.loc)
|
|
|
|
|
|
//see if anything is there
|
|
for(var/thing in child.loc)
|
|
if(thing != child && istype(thing, /obj/effect/plant))
|
|
var/obj/effect/plant/other = thing
|
|
if(other.seed != child.seed)
|
|
other.vine_overrun(child.seed, src) //vine fight
|
|
qdel(child)
|
|
return
|
|
if(istype(thing, /obj/effect/dead_plant))
|
|
qdel(thing)
|
|
qdel(child)
|
|
return
|
|
if(isliving(thing) && (seed.get_trait(TRAIT_CARNIVOROUS) || (seed.get_trait(TRAIT_SPREAD) >= 2 && prob(round(seed.get_trait(TRAIT_POTENCY))))))
|
|
entangle(thing)
|
|
qdel(child)
|
|
return
|
|
|
|
// Update neighboring squares.
|
|
for(var/obj/effect/plant/neighbor in range(1, child.loc)) //can use the actual final child loc now
|
|
if(child.seed == neighbor.seed) //neighbors of different seeds will continue to try to overrun each other
|
|
neighbor.neighbors -= target_turf
|
|
|
|
child.finish_spreading()
|
|
|
|
/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
|
|
plant_controller.add_plant(neighbor)
|
|
spawn(1) if(src) qdel(src)
|
|
|
|
#undef NEIGHBOR_REFRESH_TIME |