Bane refactor (now uses damage multipliers) (#96003)

This commit is contained in:
MrMelbert
2026-05-16 11:41:29 +10:00
committed by GitHub
parent 15f771dd11
commit ea0859d5fe
26 changed files with 287 additions and 203 deletions
@@ -70,13 +70,6 @@
///from base of element/bane/activate(): (item/weapon, mob/user)
#define COMSIG_LIVING_BANED "living_baned"
///from base of element/bane/activate(): (item/weapon, mob/user)
#define COMSIG_OBJECT_PRE_BANING "obj_pre_baning"
#define COMPONENT_CANCEL_BANING (1<<0)
///from base of element/bane/activate(): (item/weapon, mob/user)
#define COMSIG_OBJECT_ON_BANING "obj_on_baning"
// adjust_x_loss messages sent from /mob/living/proc/adjust[x]Loss
/// Returned from all the following messages if you actually aren't going to apply any change
#define COMPONENT_IGNORE_CHANGE (1<<0)
@@ -686,6 +686,9 @@
/// Sent from /datum/component/reflection when the reflection is updated to the mob reflecting: (atom/movable/reflecting_in, obj/effect/abstract/reflection)
#define COMSIG_REFLECTION_UPDATED "reflection_updated"
/// From /datum/element/weapon_description: (list/readout)
#define COMSIG_ITEM_WEAPON_LABEL_READOUT "item_weapon_label_readout"
/// Send from /datum/element/cuffable_item(): (mob/cuffer, obj/item/cuffs)
#define COMSIG_ITEM_PRE_CUFFED_TO_MOB "item_cuffed_to_mob"
/// Return to stop the cuffing from happening.
+20
View File
@@ -127,6 +127,26 @@
///The mob is all boney
#define MOB_SKELETAL (1 << 15)
/// Readable biotypes, keep this in the same order as the flags are
#define MOB_BIOTYPES_READABLE list(\
"organic", \
"mineral", \
"robotic", \
"undead", \
"humanoid", \
"insectoid", \
"beast", \
"monstrous", \
"reptile", \
"spirit", \
"plant", \
"slime", \
"aquatic", \
"mining", \
"crustacean", \
"skeletal", \
)
//Lung respiration type flags
#define RESPIRATION_OXYGEN (1 << 0)
#define RESPIRATION_N2 (1 << 1)
+199
View File
@@ -0,0 +1,199 @@
/**
* ## Bane component
*
* Applied to items and projectiles that modifies damage dealt to certain things.
* For example a sword that deals 2x damage to specifically skeletons.
*
* For items, you are not limited to only dealing more damage. Supports smaller multipliers or removing flat damage.
* For projectiles, you are limited to only dealing more damage, at least until further refactors are done.
*/
/datum/component/bane
dupe_mode = COMPONENT_DUPE_ALLOWED
/// Callback invoked when checking if a target is valid to be baned (arguments: target)
/// Return a boolean, FALSE to stop the bane effect or TRUE to allow it
VAR_FINAL/datum/callback/should_bane_callback
/// Callback invoked before bane damage is applied, allows for modifying the damage or applying other effects. (arguments: target, attacker, damage_modifiers)
/// Return value doesn't matter, but you can modify the damage_modifiers list to change the attack's values
VAR_FINAL/datum/callback/pre_bane_callback
/// Callback invoked after bane damage is applied, allows for applying other effects. (arguments: target, attacker)
/// Return value doesn't matter
VAR_FINAL/datum/callback/on_bane_callback
/// A bitfield of mob biotypes that this bane component applies to.
///If NONE, applies to all biotypes. Defaults to NONE.
VAR_FINAL/affected_biotypes = NONE
/// Multiplier applied to damage when the bane effect applies. Defaults to 1 (no change).
VAR_FINAL/damage_multiplier = 1
/// Flat damage added when the bane effect applies. Defaults to 0 (no change).
VAR_FINAL/added_damage = 0
/// Optional text to show in the weapon label readout, if not set it will generate a generic one based on the biotypes
VAR_FINAL/label_text = ""
/datum/component/bane/Initialize(
damage_multiplier = 1,
added_damage = 0,
affected_biotypes = NONE,
datum/callback/should_bane_callback,
datum/callback/pre_bane_callback,
datum/callback/on_bane_callback,
label_text = "",
)
if(!isitem(parent) && !isprojectile(parent))
return COMPONENT_INCOMPATIBLE
src.damage_multiplier = damage_multiplier
src.added_damage = added_damage
src.affected_biotypes = affected_biotypes
src.should_bane_callback = should_bane_callback
src.pre_bane_callback = pre_bane_callback
src.on_bane_callback = on_bane_callback
src.label_text = label_text
/datum/component/bane/RegisterWithParent()
if(isitem(parent))
RegisterSignal(parent, COMSIG_ITEM_WEAPON_LABEL_READOUT, PROC_REF(label_readout))
RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(pre_attack))
RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, PROC_REF(after_attack))
RegisterSignal(parent, COMSIG_MOVABLE_IMPACT_ZONE, PROC_REF(on_thrown_hit))
if(isprojectile(parent))
RegisterSignal(parent, COMSIG_PROJECTILE_SELF_ON_HIT, PROC_REF(projectile_hit))
/datum/component/bane/UnregisterFromParent()
if(isitem(parent))
UnregisterSignal(parent, COMSIG_ITEM_WEAPON_LABEL_READOUT)
UnregisterSignal(parent, COMSIG_ITEM_PRE_ATTACK)
UnregisterSignal(parent, COMSIG_ITEM_AFTERATTACK)
UnregisterSignal(parent, COMSIG_MOVABLE_IMPACT_ZONE)
if(isprojectile(parent))
UnregisterSignal(parent, COMSIG_PROJECTILE_SELF_ON_HIT)
/datum/component/bane/proc/is_bane_target(atom/target)
if(!isliving(target))
return FALSE
var/mob/living/living_target = target
if(affected_biotypes && !(living_target.mob_biotypes & affected_biotypes))
return FALSE
return isnull(should_bane_callback) ? TRUE : should_bane_callback.Invoke(target)
/datum/component/bane/proc/label_readout(obj/item/source, list/readout)
SIGNAL_HANDLER
if(damage_multiplier == 1 && added_damage == 0 && !label_text)
return
var/label_line = ""
if(damage_multiplier > 1 || added_damage > 0)
label_line += "It is especially effective against"
else if(damage_multiplier < 1 || added_damage < 0)
label_line += "It is less effective against"
else
label_line += "It interacts uniquely with" // for custom behaviors?
label_line += " "
if(label_text)
label_line += label_text
else if(affected_biotypes)
var/list/affected_biotypes_readable = bitfield_to_list(affected_biotypes, MOB_BIOTYPES_READABLE)
label_line += "[english_list(affected_biotypes_readable)] enemies"
else
label_line += "certain enemies"
if(damage_multiplier > 1 || added_damage > 0)
var/magnitude = ""
switch(max(damage_multiplier, added_damage / 10))
if(3 to INFINITY)
magnitude = "massively increased"
if(2 to 3)
magnitude = "greatly increased"
if(1.5 to 2)
magnitude = "significantly increased"
if(1 to 1.5)
magnitude = "slightly increased"
label_line += ", dealing [span_warning(magnitude)] damage per hit"
else if(damage_multiplier < 1 || added_damage < 0)
var/magnitude = ""
switch(min(damage_multiplier, 10 / abs(added_damage || 1)))
if(-INFINITY to 0)
magnitude = "no"
if(0 to 0.3)
magnitude = "massively reduced"
if(0.3 to 0.6)
magnitude = "greatly reduced"
if(0.6 to 0.9)
magnitude = "significantly reduced"
if(0.9 to 1)
magnitude = "slightly reduced"
label_line += ", dealing [span_warning(magnitude)] damage per hit"
label_line += "."
readout += label_line
// Item attack handling
/datum/component/bane/proc/pre_attack(datum/source, atom/target, mob/living/attacker, list/modifiers, list/attack_modifiers)
SIGNAL_HANDLER
if(!is_bane_target(target))
return
if(added_damage != 0)
MODIFY_ATTACK_FORCE(attack_modifiers, added_damage)
if(damage_multiplier != 1)
MODIFY_ATTACK_FORCE_MULTIPLIER(attack_modifiers, damage_multiplier)
pre_bane_callback?.Invoke(target, attacker, attack_modifiers)
/datum/component/bane/proc/after_attack(datum/source, atom/target, mob/living/attacker, ...)
SIGNAL_HANDLER
if(!is_bane_target(target))
return
SEND_SIGNAL(target, COMSIG_LIVING_BANED, source, attacker)
on_bane_callback?.Invoke(target, attacker)
// Throw impact handling
/datum/component/bane/proc/on_thrown_hit(datum/source, atom/hit_atom, hit_zone, blocked, datum/thrownthing/throwingdatum)
SIGNAL_HANDLER
if(!is_bane_target(hit_atom))
return
var/mob/thrower = throwingdatum?.thrower?.resolve()
var/list/damage_modifiers = list("[FORCE_MULTIPLIER]" = damage_multiplier, "[FORCE_MODIFIER]" = added_damage)
pre_bane_callback?.Invoke(hit_atom, thrower, damage_modifiers)
// We're not modifying the throwforce of the item we're just applying more damage as a separate damage event
// That's why we do damage_multiplier - 1 (so that a 1.5x multiplier would apply 0.5x damage here for a total of 1.5x)
var/obj/item/throwing_item = parent
var/extra_damage = (throwing_item.throwforce * max(0, damage_modifiers[FORCE_MULTIPLIER] - 1)) + damage_modifiers[FORCE_MODIFIER]
if(extra_damage > 0)
var/mob/living/living_target = hit_atom // safe assertion from is_bane_target
living_target.apply_damage(extra_damage, throwing_item.damtype, hit_zone, blocked)
SEND_SIGNAL(hit_atom, COMSIG_LIVING_BANED, thrower, hit_atom)
on_bane_callback?.Invoke(hit_atom, thrower)
// Projectile hit handling
/datum/component/bane/proc/projectile_hit(datum/source, atom/firer, atom/target, angle, hit_zone, blocked, ...)
SIGNAL_HANDLER
if(!is_bane_target(target))
return
var/list/damage_modifiers = list("[FORCE_MULTIPLIER]" = damage_multiplier, "[FORCE_MODIFIER]" = added_damage)
pre_bane_callback?.Invoke(target, firer, damage_modifiers)
// We're not modifying the projectile damage we're just applying more damage as a separate damage event
// That's why we do damage_multiplier - 1 (so that a 1.5x multiplier would apply 0.5x damage here for a total of 1.5x)
var/obj/projectile/projectile_owner = parent
var/extra_damage = (projectile_owner.damage * max(0, damage_modifiers[FORCE_MULTIPLIER] - 1)) + damage_modifiers[FORCE_MODIFIER]
if(extra_damage > 0)
var/mob/living/living_target = target // safe assertion from is_bane_target
living_target.apply_damage(extra_damage, projectile_owner.damage_type, hit_zone, blocked)
SEND_SIGNAL(target, COMSIG_LIVING_BANED, firer, target)
on_bane_callback?.Invoke(target, firer)
+1 -9
View File
@@ -58,7 +58,6 @@
name = "of <mobtype> slaying (random species, carbon or simple animal)"
placement = AFFIX_SUFFIX
alignment = AFFIX_GOOD
var/list/target_types_by_comp = list()
/datum/fantasy_affix/bane/apply(datum/component/fantasy/comp, newName)
. = ..()
@@ -83,16 +82,9 @@
// 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, target_type = picked_mobtype)
target_types_by_comp[comp] = picked_mobtype
comp.appliedComponents += master.AddComponent(/datum/component/bane, affected_biotypes = picked_mobtype, damage_multiplier = 2)
return "[newName] of [initial(picked_mobtype.name)] slaying"
/datum/fantasy_affix/bane/remove(datum/component/fantasy/comp)
var/picked_mobtype = target_types_by_comp[comp]
var/obj/item/master = comp.parent
master.RemoveElement(/datum/element/bane, picked_mobtype)
target_types_by_comp -= comp
/datum/fantasy_affix/summoning
name = "of <mobtype> summoning (dangerous, can pick all but megafauna tier stuff)"
placement = AFFIX_SUFFIX
-93
View File
@@ -1,93 +0,0 @@
/// 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 its own damage separately ON TOP of normal damage
/// ie. a sword that does 10 damage with a bane element attached 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
/// can be a mob or a species.
var/target_type
/// multiplier of the extra damage based on the force of the item.
var/damage_multiplier
/// Added after the above.
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 = /mob/living, mob_biotypes = NONE, damage_multiplier=1, added_damage = 0, requires_combat_mode = TRUE)
. = ..()
if(!ispath(target_type, /mob/living) && !ispath(target_type, /datum/species))
return ELEMENT_INCOMPATIBLE
src.target_type = target_type
src.damage_multiplier = damage_multiplier
src.added_damage = added_damage
src.requires_combat_mode = requires_combat_mode
src.mob_biotypes = mob_biotypes
target.AddElementTrait(TRAIT_ON_HIT_EFFECT, REF(src), /datum/element/on_hit_effect)
RegisterSignal(target, COMSIG_ON_HIT_EFFECT, PROC_REF(do_bane))
/datum/element/bane/Detach(datum/source)
UnregisterSignal(source, COMSIG_ON_HIT_EFFECT)
REMOVE_TRAIT(source, TRAIT_ON_HIT_EFFECT, REF(src))
return ..()
/datum/element/bane/proc/do_bane(datum/element_owner, mob/living/bane_applier, mob/living/baned_target, hit_zone, throw_hit)
if(!check_biotype_path(bane_applier, baned_target))
return
if(SEND_SIGNAL(element_owner, COMSIG_OBJECT_PRE_BANING, baned_target) & COMPONENT_CANCEL_BANING)
return
var/force_boosted
var/applied_dam_type
if(isitem(element_owner))
var/obj/item/item_owner = element_owner
force_boosted = item_owner.force
applied_dam_type = item_owner.damtype
else if(isprojectile(element_owner))
var/obj/projectile/projectile_owner = element_owner
force_boosted = projectile_owner.damage
applied_dam_type = projectile_owner.damage_type
else if (isliving(element_owner))
var/mob/living/living_owner = element_owner
force_boosted = (living_owner.melee_damage_lower + living_owner.melee_damage_upper) / 2
//commence crying. yes, these really are the same check. FUCK.
if(isbasicmob(living_owner))
var/mob/living/basic/basic_owner = living_owner
applied_dam_type = basic_owner.melee_damage_type
else if(isanimal(living_owner))
var/mob/living/simple_animal/simple_owner = living_owner
applied_dam_type = simple_owner.melee_damage_type
else
return
else
return
var/extra_damage = max(0, (force_boosted * damage_multiplier) + added_damage)
baned_target.apply_damage(extra_damage, applied_dam_type, hit_zone)
SEND_SIGNAL(baned_target, COMSIG_LIVING_BANED, bane_applier, baned_target) // for extra effects when baned.
SEND_SIGNAL(element_owner, COMSIG_OBJECT_ON_BANING, baned_target)
/**
* Checks typepaths and the mob's biotype, returning TRUE if correct and FALSE if wrong.
* Additionally checks if combat mode is required, and if so whether it's enabled or not.
*/
/datum/element/bane/proc/check_biotype_path(atom/bane_applier, atom/target)
if(!isliving(target))
return FALSE
var/mob/living/living_target = target
if(isliving(bane_applier) && bane_applier)
var/mob/living/living_bane_applier = bane_applier
if(requires_combat_mode && !living_bane_applier.combat_mode)
return FALSE
var/is_correct_biotype = living_target.mob_biotypes & mob_biotypes
if(mob_biotypes && !(is_correct_biotype))
return FALSE
if(ispath(target_type, /mob/living))
return istype(living_target, target_type)
else //species type
return is_species(living_target, target_type)
+1 -1
View File
@@ -19,7 +19,7 @@
effects_we_clear = list(/obj/effect/rune, /obj/effect/heretic_rune, /obj/effect/cosmic_rune), \
)
target.AddComponent(/datum/component/cult_kill_tracker)
target.AddElement(/datum/element/bane, mob_biotypes = MOB_SPIRIT, damage_multiplier = 0, added_damage = 25, requires_combat_mode = FALSE)
target.AddComponent(/datum/component/bane, affected_biotypes = MOB_SPIRIT, added_damage = 25)
ADD_TRAIT(target, TRAIT_NULLROD_ITEM, ELEMENT_TRAIT(type))
if(!PERFORM_ALL_TESTS(focus_only/nullrod_variants) || !chaplain_spawnable)
@@ -97,6 +97,8 @@
if(attached_proc)
readout += call(source, attached_proc)()
SEND_SIGNAL(source, COMSIG_ITEM_WEAPON_LABEL_READOUT, readout)
// Finally bringing the fields together
return readout.Join("\n")
@@ -41,4 +41,4 @@
/obj/item/storage/toolbox/medical/coroner/Initialize(mapload)
. = ..()
AddElement(/datum/element/bane, mob_biotypes = MOB_UNDEAD, damage_multiplier = 1) //Just in case one of the tennants get uppity
AddComponent(/datum/component/bane, affected_biotypes = MOB_UNDEAD, damage_multiplier = 2) //Just in case one of the tennants get uppity
+12 -1
View File
@@ -488,7 +488,18 @@
/obj/effect/decal/cleanable/ants,
/obj/item/queen_bee,
))
AddElement(/datum/element/bane, mob_biotypes = MOB_BUG, target_type = /mob/living/basic, damage_multiplier = 0, added_damage = 24, requires_combat_mode = FALSE)
AddComponent(/datum/component/bane, affected_biotypes = MOB_BUG, pre_bane_callback = CALLBACK(src, PROC_REF(bane_check)) )
// Different type of bug mobs get different amounts of damage multipliers
/obj/item/melee/flyswatter/proc/bane_check(mob/living/target, mob/living/attacker, list/attack_modifiers)
if(isanimal_or_basicmob(target))
MODIFY_ATTACK_FORCE(attack_modifiers, 24)
else if(isflyperson(target))
MODIFY_ATTACK_FORCE(attack_modifiers, 29)
else if(ismoth(target))
MODIFY_ATTACK_FORCE(attack_modifiers, 9)
else // ?? Whatever
MODIFY_ATTACK_FORCE(attack_modifiers, 14)
/obj/item/melee/flyswatter/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers)
if(is_type_in_typecache(target, splattable))
+16 -22
View File
@@ -34,29 +34,23 @@
bonus_modifier = 5, \
)
// The weight of authority comes down on the tider's crimes.
AddElement(/datum/element/bane, target_type = /mob/living/carbon/human, damage_multiplier = 0.35)
RegisterSignal(src, COMSIG_OBJECT_PRE_BANING, PROC_REF(attempt_bane))
RegisterSignal(src, COMSIG_OBJECT_ON_BANING, PROC_REF(bane_effects))
/**
* If the target reeks of maintenance, the blade can tear through their body with a total of 20 damage.
*/
/obj/item/melee/sabre/proc/attempt_bane(element_owner, mob/living/carbon/criminal)
SIGNAL_HANDLER
var/obj/item/organ/liver/liver = criminal.get_organ_slot(ORGAN_SLOT_LIVER)
if(isnull(liver) || !HAS_TRAIT(liver, TRAIT_MAINTENANCE_METABOLISM))
return COMPONENT_CANCEL_BANING
/**
* Assistants should fear this weapon.
*/
/obj/item/melee/sabre/proc/bane_effects(element_owner, mob/living/carbon/human/baned_target)
SIGNAL_HANDLER
baned_target.visible_message(
span_warning("[src] tears through [baned_target] with unnatural ease!"),
span_userdanger("As [src] tears into your body, you feel the weight of authority collapse into your wounds!"),
AddComponent(/datum/component/bane, \
damage_multiplier = 1.35, \
should_bane_callback = CALLBACK(src, PROC_REF(bane_check)), \
on_bane_callback = CALLBACK(src, PROC_REF(bane_message)), \
label_text = "assistants", \
)
INVOKE_ASYNC(baned_target, TYPE_PROC_REF(/mob/living/carbon/human, emote), "scream")
/obj/item/melee/sabre/proc/bane_check(mob/living/target)
var/obj/item/organ/liver/liver = target.get_organ_slot(ORGAN_SLOT_LIVER)
return !isnull(liver) && HAS_TRAIT(liver, TRAIT_MAINTENANCE_METABOLISM)
/obj/item/melee/sabre/proc/bane_message(mob/living/target, mob/living/attacker)
target.visible_message(
span_warning("[src] tears through [target] with unnatural ease!"),
span_boldwarning("As [src] tears into your body, you feel the weight of authority collapse into your wounds!"),
)
INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, emote), "scream")
/obj/item/melee/sabre/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE)
if(attack_type == PROJECTILE_ATTACK || attack_type == LEAP_ATTACK || attack_type == OVERWHELMING_ATTACK)
@@ -38,7 +38,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)
AddComponent(/datum/component/bane, affected_biotypes = MOB_PLANT, damage_multiplier = 1.5)
/obj/item/soulscythe/examine(mob/user)
. = ..()
@@ -462,7 +462,7 @@
/obj/item/spear/dragonator/Initialize(mapload)
. = ..()
AddElement(/datum/element/bane, mob_biotypes = MOB_MINING, damage_multiplier = 0, added_damage = 80, requires_combat_mode = FALSE) //For killing really big monsters.
AddComponent(/datum/component/bane, affected_biotypes = MOB_MINING, added_damage = 80) //For killing really big monsters.
/*
* Untreated Giantslayer , needs to be thrown into lava
+5 -2
View File
@@ -332,14 +332,17 @@
. = ..()
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, target_type = /mob/living/basic/statue, damage_multiplier = 40)
AddComponent(/datum/component/bane, damage_multiplier = 40, should_bane_callback = CALLBACK(src, PROC_REF(bane_check)), label_text = "statues")
/obj/item/chisel/Destroy()
prepared_block = null
tracked_user = null
return ..()
/// Bane component callback
/obj/item/chisel/proc/bane_check(mob/living/target)
return istype(target, /mob/living/basic/statue)
/*
Hit the block to start
Point with the chisel at the target to choose what to sculpt or hit block to choose from preset statue types.
+12 -16
View File
@@ -92,11 +92,12 @@
set_slot(new line(src), ROD_SLOT_LINE)
update_appearance()
//Bane effect that make it extra-effective against mobs with water adaptation (read: fish infusion)
AddElement(/datum/element/bane, target_type = /mob/living, damage_multiplier = 1.25)
RegisterSignal(src, COMSIG_OBJECT_PRE_BANING, PROC_REF(attempt_bane))
RegisterSignal(src, COMSIG_OBJECT_ON_BANING, PROC_REF(bane_effects))
AddComponent(/datum/component/bane, \
damage_multiplier = 2.25, \
should_bane_callback = CALLBACK(src, PROC_REF(should_bane_fish_infusions)), \
on_bane_callback = CALLBACK(src, PROC_REF(on_bane_fish_infusions)), \
label_text = "fishpeople", \
)
/obj/item/fishing_rod/add_context(atom/source, list/context, obj/item/held_item, mob/user)
if(src == held_item)
@@ -260,18 +261,13 @@
material_chance += user.mind?.get_skill_level(/datum/skill/fishing) * 1.5
return material_chance
///Fishing rodss should only bane fish DNA-infused spessman
/obj/item/fishing_rod/proc/attempt_bane(datum/source, mob/living/fish)
SIGNAL_HANDLER
if(!force || !HAS_TRAIT(fish, TRAIT_WATER_ADAPTATION))
return COMPONENT_CANCEL_BANING
/obj/item/fishing_rod/proc/should_bane_fish_infusions(mob/living/target)
return force > 0 && HAS_TRAIT(target, TRAIT_WATER_ADAPTATION)
///Fishing rods should hard-counter fish DNA-infused spessman
/obj/item/fishing_rod/proc/bane_effects(datum/source, mob/living/fish)
SIGNAL_HANDLER
fish.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 4 SECONDS)
fish.adjust_confusion_up_to(1.5 SECONDS, 3 SECONDS)
fish.adjust_wet_stacks(-4)
/obj/item/fishing_rod/proc/on_bane_fish_infusions(mob/living/target, mob/living/attacker)
target.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 4 SECONDS)
target.adjust_confusion_up_to(1.5 SECONDS, 3 SECONDS)
target.adjust_wet_stacks(-4)
/obj/item/fishing_rod/interact(mob/user)
if(currently_hooked)
+2 -5
View File
@@ -172,11 +172,8 @@
/obj/item/scythe/Initialize(mapload)
. = ..()
AddComponent(/datum/component/butchering, \
speed = 9 SECONDS, \
effectiveness = 105, \
)
AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE)
AddComponent(/datum/component/butchering, speed = 9 SECONDS, effectiveness = 105)
AddComponent(/datum/component/bane, affected_biotypes = MOB_PLANT, damage_multiplier = 1.5)
/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!"))
@@ -79,12 +79,8 @@ If the scythe isn't empowered when you sheath it, you take a heap of damage and
/obj/item/vorpalscythe/Initialize(mapload)
. = ..()
AddElement(/datum/element/nullrod_core, chaplain_spawnable = FALSE, rune_remove_line = "TO DUST WITH YE!! AWAY!!") // The implant is the actual item the chappie can select
AddComponent(
/datum/component/butchering, \
speed = 3 SECONDS, \
effectiveness = 125, \
)
AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) //also good at killing plants
AddComponent(/datum/component/bane, affected_biotypes = MOB_PLANT, damage_multiplier = 1.5) //also good at killing plants
AddComponent(/datum/component/butchering, speed = 3 SECONDS, effectiveness = 125)
/obj/item/vorpalscythe/attack(mob/living/target, mob/living/user, list/modifiers, list/attack_modifiers)
if(ismonkey(target) && !target.mind) //Don't empower from hitting monkeys. Hit a corgi or something, I don't know.
+1 -1
View File
@@ -365,13 +365,13 @@ GLOBAL_LIST_INIT(bibleitemstates, list(
/obj/item/book/bible/syndicate/Initialize(mapload)
. = ..()
AddComponent(/datum/component/anti_magic, MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY)
AddComponent(/datum/component/bane, affected_biotypes = MOB_SPIRIT, added_damage = 25)
AddComponent(/datum/component/effect_remover, \
success_feedback = "You disrupt the magic of %THEEFFECT with %THEWEAPON.", \
success_forcesay = "BEGONE FOUL MAGIKS!!", \
tip_text = "Clear rune", \
effects_we_clear = list(/obj/effect/rune, /obj/effect/heretic_rune, /obj/effect/cosmic_rune), \
)
AddElement(/datum/element/bane, mob_biotypes = MOB_SPIRIT, damage_multiplier = 0, added_damage = 25, requires_combat_mode = FALSE)
/obj/item/book/bible/syndicate/attack_self(mob/living/carbon/human/user, modifiers)
if(!uses || !istype(user))
@@ -34,7 +34,7 @@
register_context()
AddComponent(/datum/component/two_handed, require_twohands = TRUE, force_unwielded = 0, force_wielded = 5) //Heavy as all hell, it's a boulder, dude.
AddComponent(/datum/component/sisyphus_awarder)
AddElement(/datum/element/bane, mob_biotypes = MOB_SPECIAL, added_damage = 20, requires_combat_mode = FALSE)
AddComponent(/datum/component/bane, affected_biotypes = MOB_SPECIAL, added_damage = 20)
/obj/item/boulder/Destroy(force)
SSore_generation.available_boulders -= src
@@ -185,7 +185,7 @@
/obj/item/shovel/serrated/Initialize(mapload)
. = ..()
AddElement(/datum/element/bane, mob_biotypes = MOB_ORGANIC, damage_multiplier = 1) //You may be horridly cursed now, but at least you kill the living a whole lot more easily!
AddComponent(/datum/component/bane, affected_biotypes = MOB_ORGANIC, damage_multiplier = 2) //You may be horridly cursed now, but at least you kill the living a whole lot more easily!
/obj/item/shovel/serrated/examine(mob/user)
. = ..()
@@ -26,20 +26,6 @@
BODY_ZONE_CHEST = /obj/item/bodypart/chest/fly,
)
/datum/species/fly/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load, regenerate_icons)
. = ..()
RegisterSignal(human_who_gained_species, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby))
/datum/species/fly/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
. = ..()
UnregisterSignal(C, COMSIG_ATOM_ATTACKBY)
/datum/species/fly/proc/on_attackby(mob/living/source, obj/item/attacking_item, mob/living/attacker, list/modifiers, list/attack_modifiers)
SIGNAL_HANDLER
if(istype(attacking_item, /obj/item/melee/flyswatter))
MODIFY_ATTACK_FORCE_MULTIPLIER(attack_modifiers, 30) // Yes, a 30x damage modifier
/datum/species/fly/get_physical_attributes()
return "These hideous creatures suffer from pesticide immensely, eat waste, and are incredibly vulnerable to bright lights. They do have wings though."
@@ -29,20 +29,6 @@
BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/moth,
)
/datum/species/moth/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load, regenerate_icons)
. = ..()
RegisterSignal(human_who_gained_species, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby))
/datum/species/moth/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
. = ..()
UnregisterSignal(C, COMSIG_ATOM_ATTACKBY)
/datum/species/moth/proc/on_attackby(mob/living/source, obj/item/attacking_item, mob/living/attacker, list/modifiers, list/attack_modifiers)
SIGNAL_HANDLER
if(istype(attacking_item, /obj/item/melee/flyswatter))
MODIFY_ATTACK_FORCE_MULTIPLIER(attack_modifiers, 10) // Yes, a 10x damage modifier
/datum/species/moth/randomize_features()
var/list/features = ..()
features[FEATURE_MOTH_MARKINGS] = pick(SSaccessories.feature_list[FEATURE_MOTH_MARKINGS])
@@ -117,8 +117,8 @@
/obj/projectile/bullet/arrow/holy/Initialize(mapload)
. = ..()
//50 damage to revenants
AddElement(/datum/element/bane, mob_biotypes = MOB_SPIRIT, damage_multiplier = 0, added_damage = 30)
// 50 damage to revenants
AddComponent(/datum/component/bane, affected_biotypes = MOB_SPIRIT, added_damage = 30)
/// plastic arrows
// completely dogshit quality and they break when they hit something.
@@ -190,5 +190,4 @@
/obj/projectile/bullet/arrow/ashen/Initialize(mapload)
. = ..()
AddElement(/datum/element/bane, mob_biotypes = MOB_MINING, damage_multiplier = 0, added_damage = 40)
AddComponent(/datum/component/bane, affected_biotypes = MOB_MINING, added_damage = 40)
@@ -123,7 +123,7 @@
/obj/projectile/bullet/ballista_spear/dragonator/Initialize(mapload)
. = ..()
AddElement(/datum/element/bane, mob_biotypes = MOB_MINING, damage_multiplier = 2)
AddComponent(/datum/component/bane, affected_biotypes = MOB_MINING, damage_multiplier = 3)
/obj/projectile/bullet/ballista_spear/dragonator/attach_spear(obj/item/spear)
AddComponent(/datum/component/projectile_instance_drop, spear)
+1 -1
View File
@@ -729,7 +729,7 @@
/obj/item/scalpel/cruel/Initialize(mapload)
. = ..()
AddElement(/datum/element/bane, mob_biotypes = MOB_UNDEAD, damage_multiplier = 1) //Just in case one of the tennants get uppity
AddComponent(/datum/component/bane, affected_biotypes = MOB_UNDEAD, damage_multiplier = 2) //Just in case one of the tennants get uppity
/obj/item/surgicaldrill/cruel
name = "tearing drill"
+1 -1
View File
@@ -1131,6 +1131,7 @@
#include "code\datums\components\atom_mounted.dm"
#include "code\datums\components\aura_healing.dm"
#include "code\datums\components\bakeable.dm"
#include "code\datums\components\bane.dm"
#include "code\datums\components\banned_from_space.dm"
#include "code\datums\components\basic_inhands.dm"
#include "code\datums\components\basic_mob_attack_telegraph.dm"
@@ -1539,7 +1540,6 @@
#include "code\datums\elements\attack_equip.dm"
#include "code\datums\elements\attack_zone_randomiser.dm"
#include "code\datums\elements\backblast.dm"
#include "code\datums\elements\bane.dm"
#include "code\datums\elements\basic_allergenic_attack.dm"
#include "code\datums\elements\basic_eating.dm"
#include "code\datums\elements\basic_health_examine.dm"