diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm index 72ea3d18623..942706689e8 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -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) diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 716069b6843..c41304f11b1 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -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. diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index bcc17a7dca1..0ea199845b4 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -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) diff --git a/code/datums/components/bane.dm b/code/datums/components/bane.dm new file mode 100644 index 00000000000..08d3feac17b --- /dev/null +++ b/code/datums/components/bane.dm @@ -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) diff --git a/code/datums/components/fantasy/suffixes.dm b/code/datums/components/fantasy/suffixes.dm index 2b25e442b23..20a55c04e29 100644 --- a/code/datums/components/fantasy/suffixes.dm +++ b/code/datums/components/fantasy/suffixes.dm @@ -58,7 +58,6 @@ name = "of 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 summoning (dangerous, can pick all but megafauna tier stuff)" placement = AFFIX_SUFFIX diff --git a/code/datums/elements/bane.dm b/code/datums/elements/bane.dm deleted file mode 100644 index 769cf8d361d..00000000000 --- a/code/datums/elements/bane.dm +++ /dev/null @@ -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) diff --git a/code/datums/elements/nullrod_core.dm b/code/datums/elements/nullrod_core.dm index fa48e421f8e..6b4a309ba35 100644 --- a/code/datums/elements/nullrod_core.dm +++ b/code/datums/elements/nullrod_core.dm @@ -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) diff --git a/code/datums/elements/weapon_description.dm b/code/datums/elements/weapon_description.dm index 022318abfcf..23acb72960c 100644 --- a/code/datums/elements/weapon_description.dm +++ b/code/datums/elements/weapon_description.dm @@ -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") diff --git a/code/game/objects/items/storage/toolboxes/medical.dm b/code/game/objects/items/storage/toolboxes/medical.dm index 0c9323212b6..26630831aef 100644 --- a/code/game/objects/items/storage/toolboxes/medical.dm +++ b/code/game/objects/items/storage/toolboxes/medical.dm @@ -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 diff --git a/code/game/objects/items/weaponry/melee/misc.dm b/code/game/objects/items/weaponry/melee/misc.dm index 11d951f22a9..b79ff035f20 100644 --- a/code/game/objects/items/weaponry/melee/misc.dm +++ b/code/game/objects/items/weaponry/melee/misc.dm @@ -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)) diff --git a/code/game/objects/items/weaponry/melee/sabre.dm b/code/game/objects/items/weaponry/melee/sabre.dm index 0cc90020800..1507193e3e8 100644 --- a/code/game/objects/items/weaponry/melee/sabre.dm +++ b/code/game/objects/items/weaponry/melee/sabre.dm @@ -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) diff --git a/code/game/objects/items/weaponry/melee/soulscythe.dm b/code/game/objects/items/weaponry/melee/soulscythe.dm index 35b27736e13..a0430b34ce9 100644 --- a/code/game/objects/items/weaponry/melee/soulscythe.dm +++ b/code/game/objects/items/weaponry/melee/soulscythe.dm @@ -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) . = ..() diff --git a/code/game/objects/items/weaponry/melee/spear.dm b/code/game/objects/items/weaponry/melee/spear.dm index c3a87f4f0d6..39ca04c5017 100644 --- a/code/game/objects/items/weaponry/melee/spear.dm +++ b/code/game/objects/items/weaponry/melee/spear.dm @@ -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 diff --git a/code/modules/art/statues.dm b/code/modules/art/statues.dm index 2bb49122747..e86b53d68ea 100644 --- a/code/modules/art/statues.dm +++ b/code/modules/art/statues.dm @@ -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. diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm index 8f21acb8829..ce2abbc6b99 100644 --- a/code/modules/fishing/fishing_rod.dm +++ b/code/modules/fishing/fishing_rod.dm @@ -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) diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index 51100267572..a35b938fcf6 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -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!")) diff --git a/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm b/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm index 91823a073c8..c06f8993b53 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm @@ -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. diff --git a/code/modules/library/bibles.dm b/code/modules/library/bibles.dm index 07a83912f00..597c245a7c3 100644 --- a/code/modules/library/bibles.dm +++ b/code/modules/library/bibles.dm @@ -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)) diff --git a/code/modules/mining/boulder_processing/boulder.dm b/code/modules/mining/boulder_processing/boulder.dm index 96ed8878e71..3969c555180 100644 --- a/code/modules/mining/boulder_processing/boulder.dm +++ b/code/modules/mining/boulder_processing/boulder.dm @@ -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 diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm index 73ebdf10a71..d16be7e4b4c 100644 --- a/code/modules/mining/equipment/mining_tools.dm +++ b/code/modules/mining/equipment/mining_tools.dm @@ -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) . = ..() diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm index eca9383698f..93d054d5344 100644 --- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm @@ -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." diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm index 4b410f52ee7..9660b2d2e4c 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -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]) diff --git a/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm b/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm index d1d5a977de8..84b5a216732 100644 --- a/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm +++ b/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm @@ -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) diff --git a/code/modules/projectiles/projectile/bullets/cannonball.dm b/code/modules/projectiles/projectile/bullets/cannonball.dm index bfc781e6fac..41277bc9559 100644 --- a/code/modules/projectiles/projectile/bullets/cannonball.dm +++ b/code/modules/projectiles/projectile/bullets/cannonball.dm @@ -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) diff --git a/code/modules/surgery/surgery_tools.dm b/code/modules/surgery/surgery_tools.dm index 69f97210b30..f07c53b8117 100644 --- a/code/modules/surgery/surgery_tools.dm +++ b/code/modules/surgery/surgery_tools.dm @@ -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" diff --git a/tgstation.dme b/tgstation.dme index 8df27166a3e..af524133cbe 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -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"