mirror of
https://github.com/CHOMPstation/CHOMPstation.git
synced 2026-07-18 10:32:32 +01:00
2f7db506eb
Now certain weapons can strike faster or slower than usual. No weapons currently do this as this PR just lays the groundwork for that. The click delay can also be modified with traits. The slime agility modifier makes attacks happen 25% sooner. Adds debug test verb to display a weapon's DPS. It's really basic but should be sufficient for future force adjustments I might do in the future.
316 lines
8.5 KiB
Plaintext
316 lines
8.5 KiB
Plaintext
#define DEFAULT_SEED "glowshroom"
|
|
#define VINE_GROWTH_STAGES 5
|
|
|
|
/proc/spacevine_infestation(var/potency_min=70, var/potency_max=100, var/maturation_min=5, var/maturation_max=15)
|
|
spawn() //to stop the secrets panel hanging
|
|
var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas
|
|
for(var/areapath in typesof(/area/hallway))
|
|
var/area/A = locate(areapath)
|
|
for(var/turf/simulated/floor/F in A.contents)
|
|
if(turf_clear(F))
|
|
turfs += F
|
|
|
|
if(turfs.len) //Pick a turf to spawn at if we can
|
|
var/turf/simulated/floor/T = pick(turfs)
|
|
var/datum/seed/seed = plant_controller.create_random_seed(1)
|
|
seed.set_trait(TRAIT_SPREAD,2) // So it will function properly as vines.
|
|
seed.set_trait(TRAIT_POTENCY,rand(potency_min, potency_max)) // 70-100 potency will help guarantee a wide spread and powerful effects.
|
|
seed.set_trait(TRAIT_MATURATION,rand(maturation_min, maturation_max))
|
|
seed.display_name = "strange plants" //more thematic for the vine infestation event
|
|
|
|
//make vine zero start off fully matured
|
|
var/obj/effect/plant/vine = new(T,seed)
|
|
vine.health = vine.max_health
|
|
vine.mature_time = 0
|
|
vine.process()
|
|
|
|
message_admins("<span class='notice'>Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])</span>")
|
|
return
|
|
message_admins("<span class='notice'>Event: Spacevines failed to find a viable turf.</span>")
|
|
|
|
/obj/effect/dead_plant
|
|
anchored = 1
|
|
opacity = 0
|
|
density = 0
|
|
color = DEAD_PLANT_COLOUR
|
|
|
|
/obj/effect/dead_plant/attack_hand()
|
|
qdel(src)
|
|
|
|
/obj/effect/dead_plant/attackby()
|
|
..()
|
|
for(var/obj/effect/plant/neighbor in range(1))
|
|
neighbor.update_neighbors()
|
|
qdel(src)
|
|
|
|
/obj/effect/plant
|
|
name = "plant"
|
|
anchored = 1
|
|
can_buckle = 1
|
|
opacity = 0
|
|
density = 0
|
|
icon = 'icons/obj/hydroponics_growing.dmi'
|
|
icon_state = "bush4-1"
|
|
layer = 3
|
|
pass_flags = PASSTABLE
|
|
mouse_opacity = 2
|
|
|
|
var/health = 10
|
|
var/max_health = 100
|
|
var/growth_threshold = 0
|
|
var/growth_type = 0
|
|
var/max_growth = 0
|
|
var/list/neighbors = list()
|
|
var/obj/effect/plant/parent
|
|
var/datum/seed/seed
|
|
var/sampled = 0
|
|
var/floor = 0
|
|
var/spread_chance = 40
|
|
var/spread_distance = 3
|
|
var/evolve_chance = 2
|
|
var/mature_time //minimum maturation time
|
|
var/last_tick = 0
|
|
var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/plant
|
|
|
|
/obj/effect/plant/Destroy()
|
|
if(plant_controller)
|
|
plant_controller.remove_plant(src)
|
|
for(var/obj/effect/plant/neighbor in range(1,src))
|
|
plant_controller.add_plant(neighbor)
|
|
return ..()
|
|
|
|
/obj/effect/plant/single
|
|
spread_chance = 0
|
|
|
|
/obj/effect/plant/New(var/newloc, var/datum/seed/newseed, var/obj/effect/plant/newparent)
|
|
..()
|
|
|
|
if(!newparent)
|
|
parent = src
|
|
else
|
|
parent = newparent
|
|
|
|
if(!plant_controller)
|
|
sleep(250) // ugly hack, should mean roundstart plants are fine. TODO initialize perhaps?
|
|
if(!plant_controller)
|
|
world << "<span class='danger'>Plant controller does not exist and [src] requires it. Aborting.</span>"
|
|
qdel(src)
|
|
return
|
|
|
|
if(!istype(newseed))
|
|
newseed = plant_controller.seeds[DEFAULT_SEED]
|
|
seed = newseed
|
|
if(!seed)
|
|
qdel(src)
|
|
return
|
|
|
|
name = seed.display_name
|
|
max_health = round(seed.get_trait(TRAIT_ENDURANCE)/2)
|
|
if(seed.get_trait(TRAIT_SPREAD)==2)
|
|
max_growth = VINE_GROWTH_STAGES
|
|
growth_threshold = max_health/VINE_GROWTH_STAGES
|
|
icon = 'icons/obj/hydroponics_vines.dmi'
|
|
growth_type = 2 // Vines by default.
|
|
if(seed.get_trait(TRAIT_CARNIVOROUS) >= 2)
|
|
growth_type = 1 // WOOOORMS.
|
|
else if(!(seed.seed_noun in list("seeds","pits")))
|
|
if(seed.seed_noun == "nodes")
|
|
growth_type = 3 // Biomass
|
|
else
|
|
growth_type = 4 // Mold
|
|
else
|
|
max_growth = seed.growth_stages
|
|
growth_threshold = max_health/seed.growth_stages
|
|
|
|
if(max_growth > 2 && prob(50))
|
|
max_growth-- //Ensure some variation in final sprite, makes the carpet of crap look less wonky.
|
|
|
|
mature_time = world.time + seed.get_trait(TRAIT_MATURATION) + 15 //prevent vines from maturing until at least a few seconds after they've been created.
|
|
spread_chance = seed.get_trait(TRAIT_POTENCY)
|
|
spread_distance = ((growth_type>0) ? round(spread_chance*0.6) : round(spread_chance*0.3))
|
|
update_icon()
|
|
|
|
// Plants will sometimes be spawned in the turf adjacent to the one they need to end up in, for the sake of correct dir/etc being set.
|
|
/obj/effect/plant/proc/finish_spreading()
|
|
set_dir(calc_dir())
|
|
update_icon()
|
|
plant_controller.add_plant(src)
|
|
//Some plants eat through plating.
|
|
if(islist(seed.chems) && !isnull(seed.chems["pacid"]))
|
|
var/turf/T = get_turf(src)
|
|
T.ex_act(prob(80) ? 3 : 2)
|
|
|
|
/obj/effect/plant/update_icon()
|
|
//TODO: should really be caching this.
|
|
refresh_icon()
|
|
if(growth_type == 0 && !floor)
|
|
src.transform = null
|
|
var/matrix/M = matrix()
|
|
// should make the plant flush against the wall it's meant to be growing from.
|
|
M.Translate(0,-(rand(12,14)))
|
|
switch(dir)
|
|
if(WEST)
|
|
M.Turn(90)
|
|
if(NORTH)
|
|
M.Turn(180)
|
|
if(EAST)
|
|
M.Turn(270)
|
|
src.transform = M
|
|
var/icon_colour = seed.get_trait(TRAIT_PLANT_COLOUR)
|
|
if(icon_colour)
|
|
color = icon_colour
|
|
// Apply colour and light from seed datum.
|
|
if(seed.get_trait(TRAIT_BIOLUM))
|
|
var/clr
|
|
if(seed.get_trait(TRAIT_BIOLUM_COLOUR))
|
|
clr = seed.get_trait(TRAIT_BIOLUM_COLOUR)
|
|
set_light(1+round(seed.get_trait(TRAIT_POTENCY)/20), l_color = clr)
|
|
return
|
|
else
|
|
set_light(0)
|
|
|
|
/obj/effect/plant/proc/refresh_icon()
|
|
var/growth = min(max_growth,round(health/growth_threshold))
|
|
var/at_fringe = get_dist(src,parent)
|
|
if(spread_distance > 5)
|
|
if(at_fringe >= (spread_distance-3))
|
|
max_growth--
|
|
if(at_fringe >= (spread_distance-2))
|
|
max_growth--
|
|
max_growth = max(1,max_growth)
|
|
if(growth_type > 0)
|
|
switch(growth_type)
|
|
if(1)
|
|
icon_state = "worms"
|
|
if(2)
|
|
icon_state = "vines-[growth]"
|
|
if(3)
|
|
icon_state = "mass-[growth]"
|
|
if(4)
|
|
icon_state = "mold-[growth]"
|
|
else
|
|
icon_state = "[seed.get_trait(TRAIT_PLANT_ICON)]-[growth]"
|
|
|
|
if(growth>2 && growth == max_growth)
|
|
layer = 5
|
|
set_opacity(1)
|
|
if(!isnull(seed.chems["woodpulp"]))
|
|
density = 1
|
|
else
|
|
layer = 3
|
|
density = 0
|
|
|
|
/obj/effect/plant/proc/calc_dir()
|
|
set background = 1
|
|
var/turf/T = get_turf(src)
|
|
if(!istype(T)) return
|
|
|
|
var/direction = 16
|
|
|
|
for(var/wallDir in cardinal)
|
|
var/turf/newTurf = get_step(T,wallDir)
|
|
if(newTurf.density)
|
|
direction |= wallDir
|
|
|
|
for(var/obj/effect/plant/shroom in T.contents)
|
|
if(shroom == src)
|
|
continue
|
|
if(shroom.floor) //special
|
|
direction &= ~16
|
|
else
|
|
direction &= ~shroom.dir
|
|
|
|
var/list/dirList = list()
|
|
|
|
for(var/i=1,i<=16,i <<= 1)
|
|
if(direction & i)
|
|
dirList += i
|
|
|
|
if(dirList.len)
|
|
var/newDir = pick(dirList)
|
|
if(newDir == 16)
|
|
floor = 1
|
|
newDir = 1
|
|
return newDir
|
|
|
|
floor = 1
|
|
return 1
|
|
|
|
/obj/effect/plant/attackby(var/obj/item/weapon/W, var/mob/user)
|
|
|
|
user.setClickCooldown(user.get_attack_speed(W))
|
|
plant_controller.add_plant(src)
|
|
|
|
if(istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/weapon/surgical/scalpel))
|
|
if(sampled)
|
|
user << "<span class='warning'>\The [src] has already been sampled recently.</span>"
|
|
return
|
|
if(!is_mature())
|
|
user << "<span class='warning'>\The [src] is not mature enough to yield a sample yet.</span>"
|
|
return
|
|
if(!seed)
|
|
user << "<span class='warning'>There is nothing to take a sample from.</span>"
|
|
return
|
|
if(sampled)
|
|
user << "<span class='danger'>You cannot take another sample from \the [src].</span>"
|
|
return
|
|
if(prob(70))
|
|
sampled = 1
|
|
seed.harvest(user,0,1)
|
|
health -= (rand(3,5)*5)
|
|
sampled = 1
|
|
else
|
|
..()
|
|
if(W.force)
|
|
health -= W.force
|
|
check_health()
|
|
|
|
//handles being overrun by vines - note that attacker_parent may be null in some cases
|
|
/obj/effect/plant/proc/vine_overrun(datum/seed/attacker_seed, obj/effect/plant/attacker_parent)
|
|
var/aggression = 0
|
|
aggression += (attacker_seed.get_trait(TRAIT_CARNIVOROUS) - seed.get_trait(TRAIT_CARNIVOROUS))
|
|
aggression += (attacker_seed.get_trait(TRAIT_SPREAD) - seed.get_trait(TRAIT_SPREAD))
|
|
|
|
var/resiliance
|
|
if(is_mature())
|
|
resiliance = 0
|
|
switch(seed.get_trait(TRAIT_ENDURANCE))
|
|
if(30 to 70)
|
|
resiliance = 1
|
|
if(70 to 95)
|
|
resiliance = 2
|
|
if(95 to INFINITY)
|
|
resiliance = 3
|
|
else
|
|
resiliance = -2
|
|
if(seed.get_trait(TRAIT_ENDURANCE) >= 50)
|
|
resiliance = -1
|
|
aggression -= resiliance
|
|
|
|
if(aggression > 0)
|
|
health -= aggression*5
|
|
check_health()
|
|
|
|
/obj/effect/plant/ex_act(severity)
|
|
switch(severity)
|
|
if(1.0)
|
|
die_off()
|
|
return
|
|
if(2.0)
|
|
if (prob(50))
|
|
die_off()
|
|
return
|
|
if(3.0)
|
|
if (prob(5))
|
|
die_off()
|
|
return
|
|
else
|
|
return
|
|
|
|
/obj/effect/plant/proc/check_health()
|
|
if(health <= 0)
|
|
die_off()
|
|
|
|
/obj/effect/plant/proc/is_mature()
|
|
return (health >= (max_health/3) && world.time > mature_time)
|