diff --git a/code/datums/components/fantasy/suffixes.dm b/code/datums/components/fantasy/suffixes.dm index 1c49bace23e..4e38d61b0d1 100644 --- a/code/datums/components/fantasy/suffixes.dm +++ b/code/datums/components/fantasy/suffixes.dm @@ -76,7 +76,7 @@ // This works even with the species picks since we're only accessing the name var/obj/item/master = comp.parent - master.AddElement(/datum/element/bane, picked_mobtype) + master.AddElement(/datum/element/bane, target_type = picked_mobtype) target_types_by_comp[comp] = picked_mobtype return "[newName] of [initial(picked_mobtype.name)] slaying" diff --git a/code/datums/elements/bane.dm b/code/datums/elements/bane.dm index ce149e98dca..e050c41b61c 100644 --- a/code/datums/elements/bane.dm +++ b/code/datums/elements/bane.dm @@ -1,4 +1,7 @@ -/// Deals extra damage to mobs of a certain type or species. +/// Deals extra damage to mobs of a certain type, species, or biotype. +/// This doesn't directly modify the normal damage of the weapon, instead it applies it's own damage seperatedly ON TOP of normal damage +/// ie. a sword that does 10 damage with a bane elment attacthed that has a 0.5 damage_multiplier will do: +/// 10 damage from the swords normal attack + 5 damage (50%) from the bane element /datum/element/bane element_flags = ELEMENT_BESPOKE argument_hash_start_idx = 2 @@ -10,8 +13,10 @@ var/added_damage /// If it requires combat mode on to deal the extra damage or not. var/requires_combat_mode + /// if we want it to only affect a certain mob biotype + var/mob_biotypes -/datum/element/bane/Attach(datum/target, target_type, damage_multiplier=1, added_damage = 0, requires_combat_mode = TRUE) +/datum/element/bane/Attach(datum/target, target_type = /mob/living, mob_biotypes = NONE, damage_multiplier=1, added_damage = 0, requires_combat_mode = TRUE) . = ..() if(!isitem(target)) return ELEMENT_INCOMPATIBLE @@ -27,23 +32,34 @@ src.damage_multiplier = damage_multiplier src.added_damage = added_damage src.requires_combat_mode = requires_combat_mode + src.mob_biotypes = mob_biotypes /datum/element/bane/Detach(datum/source) UnregisterSignal(source, COMSIG_ITEM_AFTERATTACK) return ..() -/datum/element/bane/proc/species_check(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) +/datum/element/bane/proc/species_check(obj/item/source, mob/living/target, mob/user, proximity_flag, click_parameters) SIGNAL_HANDLER - if(!proximity_flag || !is_species(target, target_type)) + if(!proximity_flag || !istype(target) || !is_species(target, target_type)) return + + var/is_correct_biotype = target.mob_biotypes & mob_biotypes + if(mob_biotypes && !(is_correct_biotype)) + return + activate(source, target, user) -/datum/element/bane/proc/mob_check(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) +/datum/element/bane/proc/mob_check(obj/item/source, mob/living/target, mob/user, proximity_flag, click_parameters) SIGNAL_HANDLER if(!proximity_flag || !istype(target, target_type)) return + + var/is_correct_biotype = target.mob_biotypes & mob_biotypes + if(mob_biotypes && !(is_correct_biotype)) + return + activate(source, target, user) /datum/element/bane/proc/activate(obj/item/source, mob/living/target, mob/living/attacker) diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 073bfdbefab..aadffa0e431 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -254,7 +254,7 @@ speed = 7 SECONDS, \ effectiveness = 110, \ ) - //the harvest gives a high bonus chance + AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) /obj/item/nullrod/scythe/vibro name = "high frequency blade" diff --git a/code/modules/art/statues.dm b/code/modules/art/statues.dm index c29c9957774..639234f27a7 100644 --- a/code/modules/art/statues.dm +++ b/code/modules/art/statues.dm @@ -298,7 +298,7 @@ AddElement(/datum/element/eyestab) AddElement(/datum/element/wall_engraver) //deals 200 damage to statues, meaning you can actually kill one in ~250 hits - AddElement(/datum/element/bane, /mob/living/simple_animal/hostile/netherworld/statue, damage_multiplier = 40) + AddElement(/datum/element/bane, target_type = /mob/living/simple_animal/hostile/netherworld/statue, damage_multiplier = 40) /obj/item/chisel/Destroy() prepared_block = null diff --git a/code/modules/cargo/packs/emergency.dm b/code/modules/cargo/packs/emergency.dm index 6150fd6d5e4..78ddc28bbb8 100644 --- a/code/modules/cargo/packs/emergency.dm +++ b/code/modules/cargo/packs/emergency.dm @@ -170,11 +170,12 @@ /datum/supply_pack/emergency/weedcontrol name = "Weed Control Crate" - desc = "Keep those invasive species OUT. Contains a scythe, gasmask, and two anti-weed chemical grenades. \ - Warranty void if used on ambrosia. Requires Hydroponics access to open." + desc = "Keep those invasive species OUT. Contains a scythe, leather gloves, gasmask, and two anti-weed chemical grenades. \ + Warranty void if used on ambrosia." cost = CARGO_CRATE_VALUE * 2.5 access = ACCESS_HYDROPONICS contains = list(/obj/item/scythe, + /obj/item/clothing/gloves/botanic_leather, /obj/item/clothing/mask/gas, /obj/item/grenade/chem_grenade/antiweed = 2, ) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index d4c702f629c..c848f83b5cf 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -256,7 +256,7 @@ var/obj/item/bodypart/limb = victim.get_bodypart(victim.get_random_valid_zone(even_weights = TRUE)) //Picks a random bodypart. var/armor = victim.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/thorn = locate() in vine.mutations //Searches for the thorns mutation in the "mutations"-list inside obj/structure/spacevine, and defines T if it finds it. - if(thorn && (prob(40))) //If we found the thorns mutation there is now a chance to get stung instead of lashed or smashed. + if(thorn && prob(40) && !HAS_TRAIT(victim, TRAIT_PIERCEIMMUNE)) //If we found the thorns mutation there is now a chance to get stung instead of lashed or smashed. victim.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. victim.Stun(1 SECONDS) //Stopped in place for a moment. playsound(living_mob, 'sound/weapons/pierce.ogg', 50, TRUE, -1) @@ -264,7 +264,7 @@ span_userdanger("You are nailed by a sharp thorn!")) log_combat(vine, living_mob, "aggressively pierced") //"Aggressively" for easy ctrl+F'ing in the attack logs. else - if(prob(80)) + if(prob(80) && !HAS_TRAIT(victim, TRAIT_PIERCEIMMUNE)) victim.apply_damage(60, BRUTE, def_zone = limb, blocked = armor, wound_bonus = rand(-20,10), sharpness = SHARP_EDGED) victim.Knockdown(2 SECONDS) playsound(victim, 'sound/weapons/whip.ogg', 50, TRUE, -1) @@ -364,17 +364,30 @@ quality = NEGATIVE /datum/spacevine_mutation/thorns/on_cross(obj/structure/spacevine/holder, mob/living/crosser) + if(istype(crosser) && HAS_TRAIT(crosser, TRAIT_PIERCEIMMUNE)) + return + if(prob(THORN_MUTATION_CUT_PROB) && istype(crosser) && !isvineimmune(crosser)) var/mob/living/victim = crosser victim.adjustBruteLoss(15) to_chat(victim, span_danger("You cut yourself on the thorny vines.")) /datum/spacevine_mutation/thorns/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/item, expected_damage) + if(iscarbon(hitter)) + var/mob/living/carbon/carbon_victim = hitter + for(var/obj/item/clothing/worn_item in carbon_victim.get_equipped_items()) + if((worn_item.body_parts_covered & HANDS) && (worn_item.clothing_flags & THICKMATERIAL)) + return expected_damage + + if(HAS_TRAIT(hitter, TRAIT_PIERCEIMMUNE) || HAS_TRAIT(hitter, TRAIT_PLANT_SAFE)) + return expected_damage + if(prob(THORN_MUTATION_CUT_PROB) && istype(hitter) && !isvineimmune(hitter)) var/mob/living/victim = hitter victim.adjustBruteLoss(15) to_chat(victim, span_danger("You cut yourself on the thorny vines.")) - . = expected_damage + + return expected_damage /datum/spacevine_mutation/woodening name = "Hardened" @@ -486,7 +499,7 @@ for(var/datum/spacevine_mutation/mutation in mutations) override += mutation.on_chem(src, chem) if(!override && istype(chem, /datum/reagent/toxin/plantbgone)) - if(prob(50)) + if(prob(75)) qdel(src) /obj/structure/spacevine/proc/eat(mob/eater) @@ -656,7 +669,7 @@ /// Actual maximum spread rate for this process tick var/spread_max = round(clamp(delta_time * (spread_base + start_spread_bonus), max(delta_time * minimum_spread_rate, 1), spread_cap)) var/amount_processed = 0 - for(var/obj/structure/spacevine/vine as anything in growth_queue) + for(var/obj/structure/spacevine/vine in growth_queue) if(!vine.can_spread) continue growth_queue -= vine @@ -714,6 +727,9 @@ /obj/structure/spacevine/proc/spread() var/direction = pick(GLOB.cardinals) var/turf/stepturf = get_step(src, direction) + if(!istype(stepturf)) + return + 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/eating = locate() in mutations //Locates the vine eating trait in our own seed and calls it E. diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index 655c5a86d8a..28d43ad8446 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -522,6 +522,7 @@ attack_verb_continuous = list("chops", "slices", "cuts", "reaps") attack_verb_simple = list("chop", "slice", "cut", "reap") hitsound = 'sound/weapons/bladeslice.ogg' + sharpness = SHARP_EDGED var/swiping = FALSE /obj/item/scythe/Initialize(mapload) @@ -530,6 +531,7 @@ speed = 9 SECONDS, \ effectiveness = 105, \ ) + AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) /obj/item/scythe/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is beheading [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) @@ -541,18 +543,23 @@ playsound(src, SFX_DESECRATION ,50, TRUE, -1) return BRUTELOSS -/obj/item/scythe/pre_attack(atom/A, mob/living/user, params) - if(swiping || !istype(A, /obj/structure/spacevine) || get_turf(A) == get_turf(user)) +/obj/item/scythe/pre_attack(atom/target, mob/living/user, params) + if(!istype(target, /obj/structure/alien/resin/flower_bud) && !istype(target, /obj/structure/spacevine)) + return ..() + if(swiping || get_turf(target) == get_turf(user)) return ..() var/turf/user_turf = get_turf(user) - var/dir_to_target = get_dir(user_turf, get_turf(A)) + var/dir_to_target = get_dir(user_turf, get_turf(target)) swiping = TRUE var/static/list/scythe_slash_angles = list(0, 45, 90, -45, -90) for(var/i in scythe_slash_angles) - var/turf/T = get_step(user_turf, turn(dir_to_target, i)) - for(var/obj/structure/spacevine/V in T) - if(user.Adjacent(V)) - melee_attack_chain(user, V) + var/turf/adjacent_turf = get_step(user_turf, turn(dir_to_target, i)) + for(var/obj/structure/spacevine/vine in adjacent_turf) + if(user.Adjacent(vine)) + melee_attack_chain(user, vine) + for(var/obj/structure/alien/resin/flower_bud/flower in adjacent_turf) + if(user.Adjacent(flower)) + melee_attack_chain(user, flower) swiping = FALSE return TRUE */ diff --git a/code/modules/mining/lavaland/megafauna_loot.dm b/code/modules/mining/lavaland/megafauna_loot.dm index 001e9f37e85..3b113912064 100644 --- a/code/modules/mining/lavaland/megafauna_loot.dm +++ b/code/modules/mining/lavaland/megafauna_loot.dm @@ -387,6 +387,7 @@ RegisterSignal(soul, COMSIG_MOB_ATTACK_RANGED, PROC_REF(on_attack)) RegisterSignal(soul, COMSIG_MOB_ATTACK_RANGED_SECONDARY, PROC_REF(on_secondary_attack)) RegisterSignal(src, COMSIG_ATOM_INTEGRITY_CHANGED, PROC_REF(on_integrity_change)) + AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) /obj/item/soulscythe/examine(mob/user) . = ..() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 714cd314837..a2e7c101993 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -590,6 +590,7 @@ return if(new_resting == resting) return + . = resting resting = new_resting if(new_resting) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 9cf65380fc4..b17ffcf33e6 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -60,8 +60,16 @@ return for(var/direction in shuffle(list(1,2,4,8,5,6,9,10))) - var/step = get_step(src, direction) - if(step && ((locate(/obj/structure/spacevine) in step) || (locate(/obj/structure/glowshroom) in step))) + var/turf/step = get_step(src, direction) + + if(!istype(step)) + return + + var/vine = locate(/obj/structure/spacevine) in step + var/mushroom = locate(/obj/structure/glowshroom) in step + var/flower = locate(/obj/structure/alien/resin/flower_bud) in step + + if(vine || mushroom || flower) Move(step, get_dir(src, step)) /mob/living/simple_animal/hostile/retaliate/goat/Retaliate() @@ -74,29 +82,44 @@ eat_plants() /mob/living/simple_animal/hostile/retaliate/goat/proc/eat_plants() - var/eaten = FALSE - var/obj/structure/spacevine/SV = locate(/obj/structure/spacevine) in loc - if(SV) - SV.eat(src) - eaten = TRUE + var/obj/structure/spacevine/vine = locate(/obj/structure/spacevine) in loc + if(vine) + vine.eat(src) - var/obj/structure/glowshroom/GS = locate(/obj/structure/glowshroom) in loc - if(GS) - qdel(GS) - eaten = TRUE + var/obj/structure/alien/resin/flower_bud/flower = locate(/obj/structure/alien/resin/flower_bud) in loc + if(flower) + flower.take_damage(rand(30, 50), BRUTE, 0) - if(eaten && prob(10)) - say("Nom") + var/obj/structure/glowshroom/mushroom = locate(/obj/structure/glowshroom) in loc + if(mushroom) + qdel(mushroom) + + if((vine || flower || mushroom) && prob(10)) + say("Nom") // bon appetit + playsound(src, 'sound/items/eatfood.ogg', rand(30, 50), TRUE) /mob/living/simple_animal/hostile/retaliate/goat/AttackingTarget() . = ..() - if(. && ishuman(target)) - var/mob/living/carbon/human/H = target - if(istype(H.dna.species, /datum/species/pod)) - var/obj/item/bodypart/NB = pick(H.bodyparts) - H.visible_message(span_warning("[src] takes a big chomp out of [H]!"), \ - span_userdanger("[src] takes a big chomp out of your [NB]!")) - NB.dismember() + + if(!. || !isliving(target)) + return + + var/mob/living/plant_target = target + if(!(plant_target.mob_biotypes & MOB_PLANT)) + return + + plant_target.adjustBruteLoss(20) + playsound(src, 'sound/items/eatfood.ogg', rand(30, 50), TRUE) + var/obj/item/bodypart/edible_bodypart + + if(ishuman(plant_target)) + var/mob/living/carbon/human/plant_man = target + edible_bodypart = pick(plant_man.bodyparts) + edible_bodypart.dismember() + + plant_target.visible_message(span_warning("[src] takes a big chomp out of [plant_target]!"), \ + span_userdanger("[src] takes a big chomp out of your [edible_bodypart || "body"]!")) + /mob/living/simple_animal/chick name = "\improper chick" diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index 5500b4bfd29..740416547d1 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -20,6 +20,7 @@ opacity = FALSE canSmoothWith = null smoothing_flags = NONE + density = FALSE /// The amount of time it takes to create a venus human trap. var/growth_time = 1 MINUTES //SKYRAT EDIT CHANGE var/growth_icon = 0 @@ -59,6 +60,15 @@ damage_amount = 0 . = ..() +/obj/structure/alien/resin/flower_bud/attacked_by(obj/item/item, mob/living/user) + var/damage_dealt = item.force + if(item.damtype == BURN) + damage_dealt *= 4 + if(item.get_sharpness()) + damage_dealt *= 16 // alien resin applies 75% reduction to brute damage so this actually x4 damage + + take_damage(damage_dealt, item.damtype, MELEE, 1) + /obj/structure/alien/resin/flower_bud/Destroy() QDEL_LIST(vines) QDEL_NULL(countdown) diff --git a/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm b/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm index 6d1e0b9e438..0a8329128d9 100644 --- a/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm +++ b/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm @@ -5,6 +5,7 @@ icon = 'icons/effects/spacevines.dmi' icon_state = "bud0" mob_type = /mob/living/simple_animal/hostile/venus_human_trap + density = FALSE prompt_name = "venus human trap" you_are_text = "You are a venus human trap." flavour_text = "You are a venus human trap! Protect the kudzu at all costs, and feast on those who oppose you!" diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 10253811caf..1b9ff451c83 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -73,7 +73,7 @@ return mytray.mutation_roll(user) - + mytray.adjust_toxic(3) //It is still toxic, mind you, but not to the same degree. #define LIQUID_PLASMA_BP (50+T0C) @@ -363,7 +363,10 @@ . = ..() if(istype(exposed_obj, /obj/structure/alien/weeds)) var/obj/structure/alien/weeds/alien_weeds = exposed_obj - alien_weeds.take_damage(rand(15,35), BRUTE, 0) // Kills alien weeds pretty fast + alien_weeds.take_damage(rand(15, 35), BRUTE, 0) // Kills alien weeds pretty fast + if(istype(exposed_obj, /obj/structure/alien/resin/flower_bud)) + var/obj/structure/alien/resin/flower_bud/flower = exposed_obj + flower.take_damage(rand(30, 50), BRUTE, 0) else if(istype(exposed_obj, /obj/structure/glowshroom)) //even a small amount is enough to kill it qdel(exposed_obj) else if(istype(exposed_obj, /obj/structure/spacevine)) @@ -374,9 +377,13 @@ . = ..() var/damage = min(round(0.4 * reac_volume, 0.1), 10) if(exposed_mob.mob_biotypes & MOB_PLANT) - exposed_mob.adjustToxLoss(damage, required_biotype = affected_biotype) + // spray bottle emits 5u so it's dealing ~15 dmg per spray + exposed_mob.adjustToxLoss(damage * 20, required_biotype = affected_biotype) + return + if(!(methods & VAPOR) || !iscarbon(exposed_mob)) return + var/mob/living/carbon/exposed_carbon = exposed_mob if(!exposed_carbon.wear_mask) exposed_carbon.adjustToxLoss(damage, required_biotype = affected_biotype)