Merge pull request #11990 from Trilbyspaceclone/patch-357
Test merge maybe - Buffs space vines
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
|
||||
if(turfs.len) //Pick a turf to spawn at if we can
|
||||
var/turf/T = pick(turfs)
|
||||
new /datum/spacevine_controller(T) //spawn a controller at turf
|
||||
new /datum/spacevine_controller(T, pick(subtypesof(/datum/spacevine_mutation)), rand(30,100), rand(5,10), src) //spawn a controller at turf with randomized stats and a single random mutation
|
||||
|
||||
|
||||
/datum/spacevine_mutation
|
||||
@@ -227,13 +227,13 @@
|
||||
quality = NEGATIVE
|
||||
|
||||
/datum/spacevine_mutation/thorns/on_cross(obj/structure/spacevine/holder, mob/living/crosser)
|
||||
if(prob(severity) && istype(crosser) && !isvineimmune(holder))
|
||||
if(prob(severity) && istype(crosser) && !isvineimmune(crosser))
|
||||
var/mob/living/M = crosser
|
||||
M.adjustBruteLoss(5)
|
||||
to_chat(M, "<span class='alert'>You cut yourself on the thorny vines.</span>")
|
||||
|
||||
/datum/spacevine_mutation/thorns/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage)
|
||||
if(prob(severity) && istype(hitter) && !isvineimmune(holder))
|
||||
if(prob(severity) && istype(hitter) && !isvineimmune(hitter))
|
||||
var/mob/living/M = hitter
|
||||
M.adjustBruteLoss(5)
|
||||
to_chat(M, "<span class='alert'>You cut yourself on the thorny vines.</span>")
|
||||
@@ -251,7 +251,7 @@
|
||||
holder.obj_integrity = holder.max_integrity
|
||||
|
||||
/datum/spacevine_mutation/woodening/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage)
|
||||
if(I.get_sharpness())
|
||||
if(I?.get_sharpness())
|
||||
. = expected_damage * 0.5
|
||||
else
|
||||
. = expected_damage
|
||||
@@ -344,16 +344,17 @@
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
if(damage_amount)
|
||||
playsound(src, 'sound/weapons/slash.ogg', 50, 1)
|
||||
playsound(src, 'sound/weapons/slash.ogg', 50, TRUE)
|
||||
else
|
||||
playsound(src, 'sound/weapons/tap.ogg', 50, 1)
|
||||
playsound(src, 'sound/weapons/tap.ogg', 50, TRUE)
|
||||
if(BURN)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, 1)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, TRUE)
|
||||
|
||||
/obj/structure/spacevine/Crossed(mob/crosser)
|
||||
if(isliving(crosser))
|
||||
for(var/datum/spacevine_mutation/SM in mutations)
|
||||
SM.on_cross(src, crosser)
|
||||
/obj/structure/spacevine/Crossed(atom/movable/AM)
|
||||
if(!isliving(AM))
|
||||
return
|
||||
for(var/datum/spacevine_mutation/SM in mutations)
|
||||
SM.on_cross(src, AM)
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/structure/spacevine/attack_hand(mob/user)
|
||||
@@ -378,10 +379,9 @@
|
||||
var/list/vine_mutations_list
|
||||
var/mutativeness = 1
|
||||
|
||||
/datum/spacevine_controller/New(turf/location, list/muts, potency, production)
|
||||
/datum/spacevine_controller/New(turf/location, list/muts, potency, production, datum/round_event/event = null)
|
||||
vines = list()
|
||||
growth_queue = list()
|
||||
spawn_spacevine_piece(location, null, muts)
|
||||
START_PROCESSING(SSobj, src)
|
||||
vine_mutations_list = list()
|
||||
init_subtypes(/datum/spacevine_mutation/, vine_mutations_list)
|
||||
@@ -428,6 +428,7 @@
|
||||
for(var/datum/spacevine_mutation/SM in SV.mutations)
|
||||
SM.on_birth(SV)
|
||||
location.Entered(SV)
|
||||
return SV
|
||||
|
||||
/datum/spacevine_controller/proc/VineDestroyed(obj/structure/spacevine/S)
|
||||
S.master = null
|
||||
@@ -531,14 +532,13 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/spacevine/CanPass(atom/movable/mover, turf/target)
|
||||
. = ..()
|
||||
if(isvineimmune(mover))
|
||||
. = TRUE
|
||||
else
|
||||
. = ..()
|
||||
return TRUE
|
||||
|
||||
/proc/isvineimmune(atom/A)
|
||||
. = FALSE
|
||||
if(isliving(A))
|
||||
var/mob/living/M = A
|
||||
if(("vines" in M.faction) || ("plants" in M.faction))
|
||||
. = TRUE
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -1,5 +1,13 @@
|
||||
|
||||
|
||||
/**
|
||||
* Kudzu Flower Bud
|
||||
*
|
||||
* A flower created by flowering kudzu which spawns a venus human trap after a certain amount of time has passed.
|
||||
*
|
||||
* A flower created by kudzu with the flowering mutation. Spawns a venus human trap after 2 minutes under normal circumstances.
|
||||
* Also spawns 4 vines going out in diagonal directions from the bud. Any living creature not aligned with plants is damaged by these vines.
|
||||
* Once it grows a venus human trap, the bud itself will destroy itself.
|
||||
*
|
||||
*/
|
||||
/obj/structure/alien/resin/flower_bud_enemy //inheriting basic attack/damage stuff from alien structures
|
||||
name = "flower bud"
|
||||
desc = "A large pulsating plant..."
|
||||
@@ -9,9 +17,9 @@
|
||||
opacity = 0
|
||||
canSmoothWith = list()
|
||||
smooth = SMOOTH_FALSE
|
||||
/// The amount of time it takes to create a venus human trap, in deciseconds
|
||||
var/growth_time = 1200
|
||||
|
||||
|
||||
/obj/structure/alien/resin/flower_bud_enemy/Initialize()
|
||||
. = ..()
|
||||
var/list/anchors = list()
|
||||
@@ -25,36 +33,49 @@
|
||||
B.sleep_time = 10 //these shouldn't move, so let's slow down updates to 1 second (any slower and the deletion of the vines would be too slow)
|
||||
addtimer(CALLBACK(src, .proc/bear_fruit), growth_time)
|
||||
|
||||
/**
|
||||
* Spawns a venus human trap, then qdels itself.
|
||||
*
|
||||
* Displays a message, spawns a human venus trap, then qdels itself.
|
||||
*/
|
||||
/obj/structure/alien/resin/flower_bud_enemy/proc/bear_fruit()
|
||||
visible_message("<span class='danger'>the plant has borne fruit!</span>")
|
||||
visible_message("<span class='danger'>The plant has borne fruit!</span>")
|
||||
new /mob/living/simple_animal/hostile/venus_human_trap(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/effect/ebeam/vine
|
||||
name = "thick vine"
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
desc = "A thick vine, painful to the touch."
|
||||
|
||||
|
||||
/obj/effect/ebeam/vine/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!("vines" in L.faction))
|
||||
if(!isvineimmune(L))
|
||||
L.adjustBruteLoss(5)
|
||||
to_chat(L, "<span class='alert'>You cut yourself on the thorny vines.</span>")
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Venus Human Trap
|
||||
*
|
||||
* The result of a kudzu flower bud, these enemies use vines to drag prey close to them for attack.
|
||||
*
|
||||
* A carnivorious plant which uses vines to catch and ensnare prey. Spawns from kudzu flower buds.
|
||||
* Each one has a maximum of four vines, which can be attached to a variety of things. Carbons are stunned when a vine is attached to them, and movable entities are pulled closer over time.
|
||||
* Attempting to attach a vine to something with a vine already attached to it will pull all movable targets closer on command.
|
||||
* Once the prey is in melee range, melee attacks from the venus human trap heals itself for 10% of its max health, assuming the target is alive.
|
||||
* Akin to certain spiders, venus human traps can also be possessed and controlled by ghosts.
|
||||
*
|
||||
*/
|
||||
/mob/living/simple_animal/hostile/venus_human_trap
|
||||
name = "venus human trap"
|
||||
desc = "Now you know how the fly feels."
|
||||
icon_state = "venus_human_trap"
|
||||
threat = 1
|
||||
layer = SPACEVINE_MOB_LAYER
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
ranged = 1
|
||||
ranged = TRUE
|
||||
harm_intent_damage = 5
|
||||
obj_damage = 60
|
||||
melee_damage_lower = 25
|
||||
@@ -63,65 +84,110 @@
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
unsuitable_atmos_damage = 0
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
faction = list("hostile","vines","plants")
|
||||
var/list/grasping = list()
|
||||
var/max_grasps = 4
|
||||
var/grasp_chance = 20
|
||||
var/grasp_pull_chance = 85
|
||||
var/grasp_range = 4
|
||||
del_on_death = 1
|
||||
initial_language_holder = /datum/language_holder/venus
|
||||
del_on_death = TRUE
|
||||
/// A list of all the plant's vines
|
||||
var/list/vines = list()
|
||||
/// The maximum amount of vines a plant can have at one time
|
||||
var/max_vines = 4
|
||||
/// How far away a plant can attach a vine to something
|
||||
var/vine_grab_distance = 5
|
||||
/// Whether or not this plant is ghost possessable
|
||||
var/playable_plant = FALSE //Normal plants can **not** have players.
|
||||
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/Destroy()
|
||||
for(var/L in grasping)
|
||||
var/datum/beam/B = grasping[L]
|
||||
if(B)
|
||||
qdel(B)
|
||||
grasping = null
|
||||
return ..()
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/ghost_playable
|
||||
playable_plant = TRUE //For admins that want to buss some harmless plants
|
||||
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/handle_automated_action()
|
||||
if(..())
|
||||
for(var/mob/living/L in grasping)
|
||||
if(L.stat == DEAD)
|
||||
var/datum/beam/B = grasping[L]
|
||||
if(B)
|
||||
B.End()
|
||||
grasping -= L
|
||||
|
||||
//Can attack+pull multiple times per cycle
|
||||
if(L.Adjacent(src))
|
||||
L.attack_animal(src)
|
||||
else
|
||||
if(prob(grasp_pull_chance))
|
||||
setDir(get_dir(src,L) )//staaaare
|
||||
step(L,get_dir(L,src)) //reel them in
|
||||
L.DefaultCombatKnockdown(60) //you can't get away now~
|
||||
|
||||
if(grasping.len < max_grasps)
|
||||
grasping:
|
||||
for(var/mob/living/L in view(grasp_range, src))
|
||||
if(L == src || faction_check_mob(L) || (L in grasping) || L == target)
|
||||
continue
|
||||
for(var/t in getline(src,L))
|
||||
for(var/a in t)
|
||||
var/atom/A = a
|
||||
if(A.density && A != L)
|
||||
continue grasping
|
||||
if(prob(grasp_chance))
|
||||
to_chat(L, "<span class='userdanger'>\The [src] has you entangled!</span>")
|
||||
grasping[L] = Beam(L, "vine", time=INFINITY, maxdistance=5, beam_type=/obj/effect/ebeam/vine)
|
||||
|
||||
break //only take 1 new victim per cycle
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/Life()
|
||||
. = ..()
|
||||
pull_vines()
|
||||
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/AttackingTarget()
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.stat != DEAD)
|
||||
adjustHealth(-maxHealth * 0.1)
|
||||
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/OpenFire(atom/the_target)
|
||||
var/dist = get_dist(src,the_target)
|
||||
Beam(the_target, "vine", time=dist*2, maxdistance=dist+2, beam_type=/obj/effect/ebeam/vine)
|
||||
the_target.attack_animal(src)
|
||||
for(var/datum/beam/B in vines)
|
||||
if(B.target == the_target)
|
||||
pull_vines()
|
||||
ranged_cooldown = world.time + (ranged_cooldown_time * 0.5)
|
||||
return
|
||||
if(get_dist(src,the_target) > vine_grab_distance || vines.len == max_vines)
|
||||
return
|
||||
for(var/turf/T in getline(src,target))
|
||||
if (T.density)
|
||||
return
|
||||
for(var/obj/O in T)
|
||||
if(O.density)
|
||||
return
|
||||
|
||||
var/datum/beam/newVine = Beam(the_target, "vine", time=INFINITY, maxdistance = vine_grab_distance, beam_type=/obj/effect/ebeam/vine)
|
||||
RegisterSignal(newVine, COMSIG_PARENT_QDELETING, .proc/remove_vine, newVine)
|
||||
vines += newVine
|
||||
if(isliving(the_target))
|
||||
var/mob/living/L = the_target
|
||||
L.Paralyze(20)
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/CanAttack(atom/the_target)
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/Login()
|
||||
. = ..()
|
||||
to_chat(src, "<span class='boldwarning'>You a venus human trap! Protect the kudzu at all costs, and feast on those who oppose you!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/attack_ghost(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(the_target in grasping)
|
||||
return 0
|
||||
return
|
||||
humanize_plant(user)
|
||||
|
||||
/**
|
||||
* Sets a ghost to control the plant if the plant is eligible
|
||||
*
|
||||
* Asks the interacting ghost if they would like to control the plant.
|
||||
* If they answer yes, and another ghost hasn't taken control, sets the ghost to control the plant.
|
||||
* Arguments:
|
||||
* * mob/user - The ghost to possibly control the plant
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/proc/humanize_plant(mob/user)
|
||||
if(key || !playable_plant || stat)
|
||||
return
|
||||
var/plant_ask = alert("Become a venus human trap?", "Are you reverse vegan?", "Yes", "No")
|
||||
if(plant_ask == "No" || QDELETED(src))
|
||||
return
|
||||
if(key)
|
||||
to_chat(user, "<span class='warning'>Someone else already took this plant!</span>")
|
||||
return
|
||||
key = user.key
|
||||
log_game("[key_name(src)] took control of [name].")
|
||||
|
||||
/**
|
||||
* Manages how the vines should affect the things they're attached to.
|
||||
*
|
||||
* Pulls all movable targets of the vines closer to the plant
|
||||
* If the target is on the same tile as the plant, destroy the vine
|
||||
* Removes any QDELETED vines from the vines list.
|
||||
*/
|
||||
/mob/living/simple_animal/hostile/venus_human_trap/proc/pull_vines()
|
||||
for(var/datum/beam/B in vines)
|
||||
if(istype(B.target, /atom/movable))
|
||||
var/atom/movable/AM = B.target
|
||||
if(!AM.anchored)
|
||||
step(AM,get_dir(AM,src))
|
||||
if(get_dist(src,B.target) == 0)
|
||||
B.End()
|
||||
|
||||
/**
|
||||
* Removes a vine from the list.
|
||||
*
|
||||
* Removes the vine from our list.
|
||||
* Called specifically when the vine is about to be destroyed, so we don't have any null references.
|
||||
* Arguments:
|
||||
* * datum/beam/vine - The vine to be removed from the list.
|
||||
*/
|
||||
mob/living/simple_animal/hostile/venus_human_trap/proc/remove_vine(datum/beam/vine, force)
|
||||
vines -= vine
|
||||
|
||||
Reference in New Issue
Block a user