mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 20:48:56 +01:00
## About The Pull Request The holy whip no longer arbitrarily does 2x damage to vampires The holy whip is now made out of silver, and thus applies bonus burn damage when hitting vampires The damage amount has gone down slightly (36 brute -> 18 brute + 12 burn) but it's slightly offset by the fact that the silver burn damage is calculated against different armor Silver itself now does more damage on average (from 5 flat to 4-16 based on material volume) and is no longer completely blocked by any form of clothing, instead blocked by wound armor ## Why It's Good For The Game Tying these hardcoded debuffs to more broad game systems is more sandboxy, which I think is more fun. It establishes consistent rules that players can follow without needing niche code knowledge or extra examine tooltips Yeah it's a bit weaker in practice... but the balance doesn't really matter anyways since it's a niche Halloween interaction ## Changelog 🆑 Melbert balance: "Holy whip" null rod no longer arbitrarily does 2x brute damage to vampires balance: "Holy whip" null rod is now made of silver, which does bonus burn damage to vampires (~1.67x damage now) balance: Silver material weapons deal more burn damage to vampires on average now (from 5 flat to 4-16, depending on volume of silver in the weapon) balance: Silver material weapons are no longer completely blocked by any form of clothing, instead now reduced / blocked by wound armor /🆑
218 lines
8.1 KiB
Plaintext
218 lines
8.1 KiB
Plaintext
|
|
// Optional properties, not guaranteed to be present on all materials
|
|
|
|
/// Minimum flammability value required to make an object made out of this material flammable
|
|
#define MINIMUM_FLAMMABILITY 4
|
|
|
|
/// If a material has this property, it is flammable and has reduced fire protection.
|
|
/datum/material_property/flammability
|
|
name = "Flammability"
|
|
id = MATERIAL_FLAMMABILITY
|
|
|
|
/datum/material_property/flammability/get_descriptor(value)
|
|
switch(value)
|
|
if (0)
|
|
return "fireproof"
|
|
if (0 to 1)
|
|
return "nonflammable"
|
|
if (1 to 2)
|
|
return "mostly nonflammable"
|
|
if (2 to 3)
|
|
return "slightly fire-resistant"
|
|
if (3 to 4)
|
|
return "flammable"
|
|
if (4 to 6)
|
|
return "highly flammable"
|
|
if (6 to 8)
|
|
return "extremely flammable"
|
|
if (8 to INFINITY)
|
|
return "insanely flammable"
|
|
|
|
/datum/material_property/flammability/attach_to(datum/material/material)
|
|
. = ..()
|
|
RegisterSignal(material, COMSIG_MATERIAL_APPLIED, PROC_REF(on_applied))
|
|
RegisterSignal(material, COMSIG_MATERIAL_REMOVED, PROC_REF(on_removed))
|
|
|
|
/datum/material_property/flammability/proc/on_applied(datum/material/source, atom/new_atom, mat_amount, multiplier, from_slot)
|
|
SIGNAL_HANDLER
|
|
|
|
if (isobj(new_atom) && (new_atom.material_flags & MATERIAL_AFFECT_STATISTICS) && source.get_property(id) >= MINIMUM_FLAMMABILITY)
|
|
new_atom.resistance_flags |= FLAMMABLE
|
|
|
|
/datum/material_property/flammability/proc/on_removed(datum/material/source, atom/old_atom, mat_amount, multiplier, from_slot)
|
|
SIGNAL_HANDLER
|
|
|
|
if (isobj(old_atom) && (old_atom.material_flags & MATERIAL_AFFECT_STATISTICS) && source.get_property(id) >= MINIMUM_FLAMMABILITY && !(initial(old_atom.resistance_flags) & FLAMMABLE))
|
|
old_atom.resistance_flags &= ~FLAMMABLE
|
|
|
|
#undef MINIMUM_FLAMMABILITY
|
|
|
|
// An average value of 4 would equate to URANIUM_IRRADIATION_CHANCE radioactivity
|
|
#define URANIUM_RADIOACTIVITY 4
|
|
|
|
/datum/material_property/radioactivity
|
|
name = "Radioactivity"
|
|
id = MATERIAL_RADIOACTIVITY
|
|
|
|
/datum/material_property/radioactivity/get_descriptor(value)
|
|
switch(value)
|
|
if (0)
|
|
return null
|
|
if (0 to 2)
|
|
return "slightly radioactive"
|
|
if (2 to 4)
|
|
return "radioactive"
|
|
if (4 to 6)
|
|
return "highly radioactive"
|
|
if (6 to 8)
|
|
return "extremely radioactive"
|
|
if (8 to INFINITY)
|
|
return "insanely radioactive"
|
|
|
|
/datum/material_property/radioactivity/attach_to(datum/material/material)
|
|
. = ..()
|
|
RegisterSignal(material, COMSIG_MATERIAL_APPLIED, PROC_REF(on_applied))
|
|
RegisterSignal(material, COMSIG_MATERIAL_REMOVED, PROC_REF(on_removed))
|
|
|
|
/datum/material_property/radioactivity/proc/on_applied(datum/material/source, atom/new_atom, mat_amount, multiplier, from_slot)
|
|
SIGNAL_HANDLER
|
|
// Uranium structures should irradiate, but not items, because item irradiation is a lot more annoying.
|
|
if (!isitem(new_atom))
|
|
new_atom.AddElement(/datum/element/radioactive, chance = source.get_property(id) / URANIUM_RADIOACTIVITY * URANIUM_IRRADIATION_CHANCE * multiplier)
|
|
|
|
/datum/material_property/radioactivity/proc/on_removed(datum/material/source, atom/old_atom, mat_amount, multiplier, from_slot)
|
|
SIGNAL_HANDLER
|
|
|
|
if (!isitem(old_atom))
|
|
old_atom.RemoveElement(/datum/element/radioactive, chance = source.get_property(id) / URANIUM_RADIOACTIVITY * URANIUM_IRRADIATION_CHANCE * multiplier)
|
|
|
|
#undef URANIUM_RADIOACTIVITY
|
|
|
|
/// Applies firestacks to affected mobs
|
|
/datum/material_property/firestacker
|
|
name = "Igniting"
|
|
id = MATERIAL_FIRESTACKER
|
|
|
|
/datum/material_property/firestacker/get_descriptor(value)
|
|
return "igniting"
|
|
|
|
/datum/material_property/firestacker/get_tooltip(value)
|
|
return "Applies [value] firestacks to affected mobs"
|
|
|
|
/datum/material_property/firestacker/attach_to(datum/material/material)
|
|
. = ..()
|
|
material.track_flags |= MATERIAL_TRACK_CONTACT | MATERIAL_TRACK_IMPACT
|
|
var/static/list/interaction_signals = list(
|
|
COMSIG_MATERIAL_EFFECT_TOUCH,
|
|
COMSIG_MATERIAL_EFFECT_STEP,
|
|
COMSIG_MATERIAL_EFFECT_HIT,
|
|
COMSIG_MATERIAL_EFFECT_THROW_IMPACT,
|
|
)
|
|
RegisterSignals(material, interaction_signals, PROC_REF(on_contact))
|
|
|
|
/datum/material_property/firestacker/proc/on_contact(datum/material/source, atom/object, mob/living/target, mob/living/user, def_zone, skin_contact)
|
|
SIGNAL_HANDLER
|
|
|
|
// Floors don't trigger if you're wearing shoes because it'd be too cancer
|
|
if (isfloorturf(object) && !skin_contact && !source.get_property(MATERIAL_PENETRATING))
|
|
return
|
|
|
|
if (isliving(target))
|
|
target.adjust_fire_stacks(source.get_property(id))
|
|
|
|
/// Deals additional burn damage to vampires, property value times material volume determines damage
|
|
/datum/material_property/vampires_bane
|
|
name = "Vampires' Bane"
|
|
id = MATERIAL_VAMPIRES_BANE
|
|
|
|
/datum/material_property/vampires_bane/get_descriptor(value)
|
|
return "vampires' bane"
|
|
|
|
/datum/material_property/vampires_bane/get_tooltip(value)
|
|
return "Deals [value * 0.5] to [value * 2] additional burn damage to vampires on contact (based on material volume)"
|
|
|
|
/datum/material_property/vampires_bane/attach_to(datum/material/material)
|
|
. = ..()
|
|
material.track_flags |= MATERIAL_TRACK_CONTACT | MATERIAL_TRACK_IMPACT
|
|
var/static/list/interaction_signals = list(
|
|
COMSIG_MATERIAL_EFFECT_TOUCH,
|
|
COMSIG_MATERIAL_EFFECT_STEP,
|
|
COMSIG_MATERIAL_EFFECT_HIT,
|
|
COMSIG_MATERIAL_EFFECT_THROW_IMPACT,
|
|
)
|
|
RegisterSignals(material, interaction_signals, PROC_REF(on_contact))
|
|
|
|
/datum/material_property/vampires_bane/proc/on_contact(datum/material/source, atom/object, mob/living/target, mob/living/user, def_zone, skin_contact)
|
|
SIGNAL_HANDLER
|
|
|
|
if (!isvampire(target))
|
|
return
|
|
|
|
var/burn_damage = source.get_property(id) * clamp((object.custom_materials[source] / (2 * SHEET_MATERIAL_AMOUNT)), 0.5, 2)
|
|
var/armor_block = 0
|
|
if(!skin_contact && !source.get_property(MATERIAL_PENETRATING))
|
|
armor_block = target.run_armor_check(def_zone, WOUND, armour_penetration = astype(object, /obj/item)?.armour_penetration || 0, silent = TRUE, weak_against_armour = TRUE)
|
|
|
|
if(armor_block > 50)
|
|
return
|
|
|
|
to_chat(target, span_userdanger("Contact with [object] sears your undead flesh!"))
|
|
playsound(target, SFX_SIZZLE, 33, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
|
target.apply_damage(burn_damage, BURN, def_zone, armor_block, wound_bonus = 10, attacking_item = object, attack_direction = get_dir(user, target), wound_clothing = FALSE)
|
|
|
|
/// Teleports targets who come into active contact with the material around, property value determines teleport radius and damage taken per teleport
|
|
/datum/material_property/teleporting
|
|
name = "Teleporting"
|
|
id = MATERIAL_TELEPORTING
|
|
|
|
/datum/material_property/teleporting/get_descriptor(value)
|
|
return "dimensionally unstable"
|
|
|
|
/datum/material_property/teleporting/get_tooltip(value)
|
|
return "Randomly teleports whoever comes into contact with it in a [value] tile radius"
|
|
|
|
/datum/material_property/teleporting/attach_to(datum/material/material)
|
|
. = ..()
|
|
material.track_flags |= MATERIAL_TRACK_CONTACT | MATERIAL_TRACK_IMPACT
|
|
var/static/list/interaction_signals = list(
|
|
COMSIG_MATERIAL_EFFECT_TOUCH,
|
|
COMSIG_MATERIAL_EFFECT_STEP,
|
|
COMSIG_MATERIAL_EFFECT_HIT,
|
|
COMSIG_MATERIAL_EFFECT_THROW_IMPACT,
|
|
)
|
|
RegisterSignals(material, interaction_signals, PROC_REF(on_contact))
|
|
|
|
/datum/material_property/teleporting/proc/on_contact(datum/material/source, atom/object, atom/target, mob/living/user, def_zone, skin_contact)
|
|
SIGNAL_HANDLER
|
|
|
|
if (!ismovable(target))
|
|
return
|
|
|
|
var/atom/movable/as_movable = target
|
|
// Don't teleport airlocks around please
|
|
if (as_movable.anchored || as_movable.move_resist >= INFINITY)
|
|
return
|
|
|
|
// Floors don't trigger if you're wearing shoes because it'd be too cancer
|
|
if (isfloorturf(object) && !skin_contact && !source.get_property(MATERIAL_PENETRATING))
|
|
return
|
|
|
|
var/value = source.get_property(id)
|
|
do_teleport(target, get_turf(target), value, channel = TELEPORT_CHANNEL_BLUESPACE)
|
|
if (isstack(object))
|
|
var/obj/item/stack/as_stack = object
|
|
as_stack.use(1)
|
|
else if (object.uses_integrity)
|
|
object.take_damage(object.max_integrity * value * 0.01)
|
|
|
|
/// Makes all contact count as skin contact
|
|
/datum/material_property/penetrating
|
|
name = "Penetrating"
|
|
id = MATERIAL_PENETRATING
|
|
|
|
/datum/material_property/penetrating/get_descriptor(value)
|
|
return "dimensionally penetrating"
|
|
|
|
/datum/material_property/penetrating/get_tooltip(value)
|
|
return "Ignores all means of skin protection when triggering other material effects"
|