/
ranged_armour.dm
61 lines (56 loc) · 2.58 KB
/
ranged_armour.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/// Reduces or nullifies damage from ranged weaponry with force below a certain value
/datum/element/ranged_armour
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2
/// The minimum force a projectile must have to ignore our armour
var/minimum_projectile_force
/// Projectile damage below the minimum is multiplied by this value
var/below_projectile_multiplier
/// Projectile damage types which work regardless of force
var/list/vulnerable_projectile_types
/// The minimum force a thrown object must have to ignore our armour
var/minimum_thrown_force
/// Message to output if throwing damage is absorbed
var/throw_blocked_message
/datum/element/ranged_armour/Attach(
atom/target,
minimum_projectile_force = 0,
below_projectile_multiplier = 0,
list/vulnerable_projectile_types = list(),
minimum_thrown_force = 0,
throw_blocked_message = "bounces off",
)
. = ..()
if (!isatom(target))
return ELEMENT_INCOMPATIBLE
src.minimum_projectile_force = minimum_projectile_force
src.below_projectile_multiplier = below_projectile_multiplier
src.vulnerable_projectile_types = vulnerable_projectile_types
src.minimum_thrown_force = minimum_thrown_force
src.throw_blocked_message = throw_blocked_message
if (minimum_projectile_force > 0)
RegisterSignal(target, COMSIG_PROJECTILE_PREHIT, PROC_REF(pre_bullet_impact))
if (minimum_thrown_force > 0)
RegisterSignal(target, COMSIG_ATOM_PREHITBY, PROC_REF(pre_thrown_impact))
/datum/element/ranged_armour/Detach(datum/target)
UnregisterSignal(target, list(COMSIG_PROJECTILE_PREHIT, COMSIG_ATOM_PREHITBY))
return ..()
/// Modify or ignore bullet damage based on projectile properties
/datum/element/ranged_armour/proc/pre_bullet_impact(atom/parent, list/signal_args, obj/projectile/bullet)
SIGNAL_HANDLER
if (bullet.damage >= minimum_projectile_force || (bullet.damage_type in vulnerable_projectile_types))
return
if (below_projectile_multiplier == 0)
parent.visible_message(span_danger("[parent] seems unharmed by [bullet]!"))
return PROJECTILE_INTERRUPT_HIT
bullet.damage *= below_projectile_multiplier
parent.visible_message(span_danger("[parent] seems resistant to [bullet]!"))
/// Ignore thrown damage based on projectile properties. There's no elegant way to multiply the damage because throwforce is persistent.
/datum/element/ranged_armour/proc/pre_thrown_impact(atom/parent, obj/item/hit_atom, datum/thrownthing/throwingdatum)
SIGNAL_HANDLER
if (!isitem(hit_atom))
return
if (hit_atom.throwforce >= minimum_thrown_force)
return
parent.visible_message(span_danger("[hit_atom] [throw_blocked_message] [parent]!"))
return COMSIG_HIT_PREVENTED