mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
Now certain weapons can strike faster or slower than usual. No weapons currently do this as this PR just lays the groundwork for that. The click delay can also be modified with traits. The slime agility modifier makes attacks happen 25% sooner. Adds debug test verb to display a weapon's DPS. It's really basic but should be sufficient for future force adjustments I might do in the future.
148 lines
4.8 KiB
Plaintext
148 lines
4.8 KiB
Plaintext
|
|
//---------- actual energy field
|
|
|
|
// Each field object has a strength var (mensured in "Renwicks").
|
|
// Melee weapons do 5% of their normal (force var) damage, so a harmbaton would do 0.75 Renwick.
|
|
// Projectiles do 5% of their structural damage, so a normal laser would do 2 Renwick damage.
|
|
// For meteors, one Renwick is about equal to one layer of r-wall.
|
|
// Meteors will be completely halted by the shield if the shield survives the impact.
|
|
// Explosions do 4 Renwick of damage per severity, at a max of 12.
|
|
|
|
/obj/effect/energy_field
|
|
name = "energy shield field"
|
|
desc = "Impenetrable field of energy, capable of blocking anything as long as it's active."
|
|
icon = 'icons/obj/machines/shielding.dmi'
|
|
icon_state = "shield"
|
|
alpha = 100
|
|
anchored = 1
|
|
layer = 4.1 //just above mobs
|
|
density = 0
|
|
var/obj/machinery/shield_gen/my_gen = null
|
|
var/strength = 0 // in Renwicks
|
|
var/ticks_recovering = 10
|
|
var/max_strength = 10
|
|
|
|
/obj/effect/energy_field/New(var/newloc, var/new_gen)
|
|
..(newloc)
|
|
my_gen = new_gen
|
|
update_nearby_tiles()
|
|
|
|
/obj/effect/energy_field/Destroy()
|
|
update_nearby_tiles()
|
|
my_gen.field.Remove(src)
|
|
my_gen = null
|
|
var/turf/current_loc = get_turf(src)
|
|
. = ..()
|
|
for(var/direction in cardinal)
|
|
var/turf/T = get_step(current_loc, direction)
|
|
if(T)
|
|
for(var/obj/effect/energy_field/F in T)
|
|
F.update_icon()
|
|
|
|
/obj/effect/energy_field/ex_act(var/severity)
|
|
adjust_strength(-(4 - severity) * 4)
|
|
|
|
/obj/effect/energy_field/bullet_act(var/obj/item/projectile/Proj)
|
|
adjust_strength(-Proj.get_structure_damage() / 10)
|
|
|
|
/obj/effect/energy_field/attackby(obj/item/W, mob/user)
|
|
if(W.force)
|
|
adjust_strength(-W.force / 20)
|
|
user.do_attack_animation(src)
|
|
user.setClickCooldown(user.get_attack_speed(W))
|
|
..()
|
|
|
|
/obj/effect/energy_field/attack_hand(var/mob/living/user)
|
|
impact_effect(3) // Harmless, but still produces the 'impact' effect.
|
|
..()
|
|
|
|
/obj/effect/energy_field/Bumped(atom/A)
|
|
..(A)
|
|
impact_effect(2)
|
|
|
|
/obj/effect/energy_field/handle_meteor_impact(var/obj/effect/meteor/meteor)
|
|
var/penetrated = TRUE
|
|
adjust_strength(-max((meteor.wall_power * meteor.hits) / 800, 0)) // One renwick (strength var) equals one r-wall for the purposes of meteor-stopping.
|
|
sleep(1)
|
|
if(density) // Check if we're still up.
|
|
penetrated = FALSE
|
|
explosion(meteor.loc, 0, 0, 0, 0, 0, 0, 0) // For the sound effect.
|
|
|
|
// Returning FALSE will kill the meteor.
|
|
return penetrated // If the shield's still around, the meteor was successfully stopped, otherwise keep going and plow into the station.
|
|
|
|
/obj/effect/energy_field/proc/adjust_strength(amount, impact = 1)
|
|
var/old_density = density
|
|
strength = between(0, strength + amount, max_strength)
|
|
|
|
//maptext = "[round(strength, 0.1)]/[max_strength]"
|
|
|
|
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
|
|
if(amount < 0) // Taking damage.
|
|
if(impact)
|
|
impact_effect(round(abs(amount * 2)))
|
|
|
|
ticks_recovering = min(ticks_recovering + 2, 10)
|
|
if(strength < 1) // We broke
|
|
density = 0
|
|
ticks_recovering = 10
|
|
strength = 0
|
|
|
|
else if(amount > 0) // Healing damage.
|
|
if(strength >= 1)
|
|
density = 1
|
|
|
|
if(density != old_density)
|
|
update_icon()
|
|
update_nearby_tiles()
|
|
|
|
/obj/effect/energy_field/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
|
//Purpose: Determines if the object (or airflow) can pass this atom.
|
|
//Called by: Movement, airflow.
|
|
//Inputs: The moving atom (optional), target turf, "height" and air group
|
|
//Outputs: Boolean if can pass.
|
|
|
|
//return (!density || !height || air_group)
|
|
return !density
|
|
|
|
/obj/effect/energy_field/update_icon(var/update_neightbors = 0)
|
|
overlays.Cut()
|
|
var/list/adjacent_shields_dir = list()
|
|
for(var/direction in cardinal)
|
|
var/turf/T = get_step(src, direction)
|
|
if(T) // Incase we somehow stepped off the map.
|
|
for(var/obj/effect/energy_field/F in T)
|
|
if(update_neightbors)
|
|
F.update_icon(0)
|
|
adjacent_shields_dir |= direction
|
|
break
|
|
// Icon_state and Glow
|
|
if(density)
|
|
icon_state = "shield"
|
|
set_light(3, 3, "#66FFFF")
|
|
else
|
|
icon_state = "shield_broken"
|
|
set_light(3, 5, "#FF9900")
|
|
|
|
// Edge overlays
|
|
for(var/found_dir in adjacent_shields_dir)
|
|
overlays += image(src.icon, src, icon_state = "shield_edge", dir = found_dir)
|
|
|
|
|
|
// Small visual effect, makes the shield tiles brighten up by becoming more opaque for a moment, and spreads to nearby shields.
|
|
/obj/effect/energy_field/proc/impact_effect(var/i, var/list/affected_shields = list())
|
|
i = between(1, i, 10)
|
|
alpha = 200
|
|
animate(src, alpha = initial(alpha), time = 1 SECOND)
|
|
affected_shields |= src
|
|
i--
|
|
if(i)
|
|
spawn(2)
|
|
for(var/direction in cardinal)
|
|
var/turf/T = get_step(src, direction)
|
|
if(T) // Incase we somehow stepped off the map.
|
|
for(var/obj/effect/energy_field/F in T)
|
|
if(!(F in affected_shields))
|
|
F.impact_effect(i, affected_shields) // Spread the effect to them.
|
|
|