diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 0ad1658a1c0..c1e2eb225b1 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -71,6 +71,8 @@ /datum/spacevine_mutation/proc/on_explosion(severity, target, obj/structure/spacevine/holder) return +/datum/spacevine_mutation/aggressive_spread/proc/aggrospread_act(obj/structure/spacevine/S, mob/living/M) + return /datum/spacevine_mutation/light name = "light" @@ -134,9 +136,9 @@ hue = "#ff7700" quality = MINOR_NEGATIVE +/// Destroys any vine on spread-target's tile. The checks for if this should be done are in the spread() proc. /datum/spacevine_mutation/vine_eating/on_spread(obj/structure/spacevine/holder, turf/target) - var/obj/structure/spacevine/prey = locate() in target - if(prey && !prey.mutations.Find(src)) //Eat all vines that are not of the same origin + for(var/obj/structure/spacevine/prey in target) qdel(prey) /datum/spacevine_mutation/aggressive_spread //very OP, but im out of other ideas currently @@ -145,17 +147,53 @@ severity = 3 quality = NEGATIVE -/datum/spacevine_mutation/aggressive_spread/on_spread(obj/structure/spacevine/holder, turf/target) - switch(severity) - if(EXPLODE_DEVASTATE) - SSexplosions.highturf += target - if(EXPLODE_HEAVY) - SSexplosions.medturf += target - if(EXPLODE_LIGHT) - SSexplosions.lowturf += target +/// Checks mobs on spread-target's turf to see if they should be hit by a damaging proc or not. +/datum/spacevine_mutation/aggressive_spread/on_spread(obj/structure/spacevine/holder, turf/target, mob/living) + for(var/mob/living/M in target) + if(!isvineimmune(M) && M.stat != DEAD) // Don't kill immune creatures. Dead check to prevent log spam when a corpse is trapped between vine eaters. + aggrospread_act(holder, M) +/// What happens if an aggr spreading vine buckles a mob. /datum/spacevine_mutation/aggressive_spread/on_buckle(obj/structure/spacevine/holder, mob/living/buckled) - buckled.ex_act(severity, null, src) + aggrospread_act(holder, buckled) + +/// Hurts mobs. To be used when a vine with aggressive spread mutation spreads into the mob's tile or buckles them. +/datum/spacevine_mutation/aggressive_spread/aggrospread_act(obj/structure/spacevine/S, mob/living/M) + var/mob/living/carbon/C = M //If the mob is carbon then it now also exists as a "C", and not just an M. + if(istype(C)) //If the mob (M) is a carbon subtype (C) we move on to pick a more complex damage proc, with damage zones, wounds and armor mitigation. + var/obj/item/bodypart/limb = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD, BODY_ZONE_CHEST) //Picks a random bodypart. Does not runtime even if it's missing. + var/armor = C.run_armor_check(limb, "melee", null, null) //armor = the armor value of that randomly chosen bodypart. Nulls to not print a message, because it would still print on pierce. + var/datum/spacevine_mutation/thorns/T = locate() in S.mutations //Searches for the thorns mutation in the "mutations"-list inside obj/structure/spacevine, and defines T if it finds it. + if(T && (prob(40))) //If we found the thorns mutation there is now a chance to get stung instead of lashed or smashed. + C.apply_damage(50, BRUTE, def_zone = limb, wound_bonus = rand(-20,10), sharpness = SHARP_POINTY) //This one gets a bit lower damage because it ignores armor. + C.Stun(1 SECONDS) //Stopped in place for a moment. + playsound(M, 'sound/weapons/pierce.ogg', 50, TRUE, -1) + M.visible_message("[M] is nailed by a sharp thorn!", \ + "You are nailed by a sharp thorn!") + log_combat(S, M, "aggressively pierced") //"Aggressively" for easy ctrl+F'ing in the attack logs. + else + if(prob(80)) + C.apply_damage(60, BRUTE, def_zone = limb, blocked = armor, wound_bonus = rand(-20,10), sharpness = SHARP_EDGED) + C.Knockdown(2 SECONDS) + playsound(M, 'sound/weapons/whip.ogg', 50, TRUE, -1) + M.visible_message("[M] is lacerated by an outburst of vines!", \ + "You are lacerated by an outburst of vines!") + log_combat(S, M, "aggressively lacerated") + else + C.apply_damage(60, BRUTE, def_zone = limb, blocked = armor, wound_bonus = rand(-20,10), sharpness = SHARP_NONE) + C.Knockdown(3 SECONDS) + var/atom/throw_target = get_edge_target_turf(C, get_dir(S, get_step_away(C, S))) + C.throw_at(throw_target, 3, 6) + playsound(M, 'sound/effects/hit_kick.ogg', 50, TRUE, -1) + M.visible_message("[M] is smashed by a large vine!", \ + "You are smashed by a large vine!") + log_combat(S, M, "aggressively smashed") + else //Living but not a carbon? Maybe a silicon? Can't be wounded so have a big chunk of simple bruteloss with no special effects. They can be entangled. + M.adjustBruteLoss(75) + playsound(M, 'sound/weapons/whip.ogg', 50, TRUE, -1) + M.visible_message("[M] is brutally threshed by [S]!", \ + "You are brutally threshed by [S]!") + log_combat(S, M, "aggressively spread into") //You aren't being attacked by the vines. You just happen to stand in their way. /datum/spacevine_mutation/transparency name = "transparent" @@ -503,7 +541,6 @@ if(has_buckled_mobs()) break //only capture one mob at a time - /obj/structure/spacevine/proc/entangle(mob/living/V) if(!V || isvineimmune(V)) return @@ -513,20 +550,21 @@ to_chat(V, "The vines [pick("wind", "tangle", "tighten")] around you!") buckle_mob(V, 1) +/// Finds a target tile to spread to. If checks pass it will spread to it and also proc on_spread on target. /obj/structure/spacevine/proc/spread() var/direction = pick(GLOB.cardinals) var/turf/stepturf = get_step(src,direction) - if (!isspaceturf(stepturf) && stepturf.Enter(src)) - for(var/datum/spacevine_mutation/SM in mutations) - SM.on_spread(src, stepturf) - stepturf = get_step(src,direction) //in case turf changes, to make sure no runtimes happen - if(!locate(/obj/structure/spacevine, stepturf)) + if(!isspaceturf(stepturf) && stepturf.Enter(src)) + var/obj/structure/spacevine/spot_taken = locate() in stepturf //Locates any vine on target turf. Calls that vine "spot_taken". + var/datum/spacevine_mutation/vine_eating/E = locate() in mutations //Locates the vine eating trait in our own seed and calls it E. + if(!spot_taken || (E && (spot_taken && !spot_taken.mutations.Find(E)))) //Proceed if there isn't a vine on the target turf, OR we have vine eater AND target vine is from our seed and doesn't. Vines from other seeds are eaten regardless. if(master) + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_spread(src, stepturf) //Only do the on_spread proc if it actually spreads. + stepturf = get_step(src,direction) //in case turf changes, to make sure no runtimes happen master.spawn_spacevine_piece(stepturf, src) /obj/structure/spacevine/ex_act(severity, target) - if(istype(target, type)) //if its agressive spread vine dont do anything - return var/i for(var/datum/spacevine_mutation/SM in mutations) i += SM.on_explosion(severity, target, src)