Skip to content

Commit

Permalink
Impact Particle Effects (#12752)
Browse files Browse the repository at this point in the history
* doneso

* complete the sentence

* remove var

* /

* fix args

* cleanup

* blooom

* requests

* stuff

* elementify

* how

* remove filter add scaling

* adjust fix sound

* remove sparks from resin
  • Loading branch information
tyeagg authored May 7, 2023
1 parent 34731a0 commit dda014a
Show file tree
Hide file tree
Showing 25 changed files with 266 additions and 66 deletions.
6 changes: 6 additions & 0 deletions code/__DEFINES/particles.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#define DEBRIS_SPARKS "spark"
#define DEBRIS_WOOD "wood"
#define DEBRIS_ROCK "rock"
#define DEBRIS_GLASS "glass"
#define DEBRIS_LEAF "leaf"
#define DEBRIS_SNOW "snow"
94 changes: 94 additions & 0 deletions code/datums/elements/debris.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@

/particles/debris
icon = 'icons/effects/particles/generic_particles.dmi'
width = 500
height = 500
count = 10
spawning = 10
lifespan = 0.7 SECONDS
fade = 0.4 SECONDS
drift = generator(GEN_CIRCLE, 0, 7)
scale = 0.7
velocity = list(50, 0)
friction = generator(GEN_NUM, 0.1, 0.15)
spin = generator(GEN_NUM, -20, 20)

/particles/impact_smoke
icon = 'icons/effects/effects.dmi'
icon_state = "smoke"
width = 500
height = 500
count = 20
spawning = 20
lifespan = 0.7 SECONDS
fade = 8 SECONDS
grow = 0.1
scale = 0.2
spin = generator(GEN_NUM, -20, 20)
velocity = list(50, 0)
friction = generator(GEN_NUM, 0.1, 0.5)

/datum/element/debris
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2

///Icon state of debris when impacted by a projectile
var/debris = null
///Velocity of debris particles
var/debris_velocity = -15
///Amount of debris particles
var/debris_amount = 8
///Scale of particle debris
var/debris_scale = 0.7

/datum/element/debris/Attach(datum/target, _debris_icon_state, _debris_velocity = -15, _debris_amount = 8, _debris_scale = 0.7)
. = ..()
debris = _debris_icon_state
debris_velocity = _debris_velocity
debris_amount = _debris_amount
debris_scale = _debris_scale
RegisterSignal(target, COMSIG_ATOM_BULLET_ACT, PROC_REF(register_for_impact))

/datum/element/debris/Detach(datum/source, force)
. = ..()
UnregisterSignal(source, COMSIG_ATOM_BULLET_ACT)

/datum/element/debris/proc/register_for_impact(datum/source, obj/projectile/proj)
SIGNAL_HANDLER
INVOKE_ASYNC(src, PROC_REF(on_impact), source, proj)

/datum/element/debris/proc/on_impact(datum/source, obj/projectile/P)
if(!P.ammo.ping)
return
var/angle = !isnull(P.dir_angle) ? P.dir_angle : round(Get_Angle(P.starting_turf, source), 1)
var/x_component = sin(angle) * debris_velocity
var/y_component = cos(angle) * debris_velocity
var/x_component_smoke = sin(angle) * -15
var/y_component_smoke = cos(angle) * -15
var/obj/effect/abstract/particle_holder/debris_visuals
var/obj/effect/abstract/particle_holder/smoke_visuals
var/position_offset = rand(-6,6)
smoke_visuals = new(source, /particles/impact_smoke)
smoke_visuals.particles.position = list(position_offset, position_offset)
smoke_visuals.particles.velocity = list(x_component_smoke, y_component_smoke)
if(debris && !(P.ammo.flags_ammo_behavior & AMMO_ENERGY || P.ammo.flags_ammo_behavior & AMMO_XENO))
debris_visuals = new(source, /particles/debris)
debris_visuals.particles.position = generator(GEN_CIRCLE, position_offset, position_offset)
debris_visuals.particles.velocity = list(x_component, y_component)
debris_visuals.layer = ABOVE_OBJ_LAYER + 0.02
debris_visuals.particles.icon_state = debris
debris_visuals.particles.count = debris_amount
debris_visuals.particles.spawning = debris_amount
debris_visuals.particles.scale = debris_scale
smoke_visuals.layer = ABOVE_OBJ_LAYER + 0.01
if(P.ammo.sound_bounce)
var/pitch = 0
if(P.ammo.flags_ammo_behavior & AMMO_SOUND_PITCH)
pitch = 55000
playsound(source, P.ammo.sound_bounce, 50, 1, frequency = pitch)
addtimer(CALLBACK(src, PROC_REF(remove_ping), src, smoke_visuals, debris_visuals), 0.7 SECONDS)

/datum/element/debris/proc/remove_ping(hit, obj/effect/abstract/particle_holder/smoke_visuals, obj/effect/abstract/particle_holder/debris_visuals)
QDEL_NULL(smoke_visuals)
if(debris_visuals)
QDEL_NULL(debris_visuals)
4 changes: 4 additions & 0 deletions code/game/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1000,3 +1000,7 @@ Proc for attack log creation, because really why not

/atom/proc/can_slip()
return TRUE

///Adds the debris element for projectile impacts
/atom/proc/add_debris_element()
AddElement(/datum/element/debris, null, -15, 8, 0.7)
112 changes: 81 additions & 31 deletions code/game/objects/effects/temporary_visuals/miscellaneous.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,50 +21,100 @@
overlays += I //we use an overlay so the explosion and light source are both in the correct location
icon_state = null

GLOBAL_LIST_EMPTY(blood_particles)
/particles/splatter
icon = 'icons/effects/effects.dmi'
icon_state = "smoke"
width = 500
height = 500
count = 20
spawning = 20
lifespan = 0.5 SECONDS
fade = 0.7 SECONDS
grow = 0.1
scale = 0.2
spin = generator(GEN_NUM, -20, 20)
velocity = list(50, 0)
friction = generator(GEN_NUM, 0.1, 0.5)
position = generator(GEN_CIRCLE, 6, 6)

/particles/splatter/New(set_color)
..()
if(set_color != "red") // we're already red colored by default
color = set_color

//unsorted miscellaneous temporary visuals
/obj/effect/temp_visual/dir_setting/bloodsplatter
icon = 'icons/effects/blood.dmi'
duration = 0.5 SECONDS
randomdir = FALSE
layer = BELOW_MOB_LAYER
layer = ABOVE_MOB_LAYER
alpha = 175
var/splatter_type = "splatter"

/obj/effect/temp_visual/dir_setting/bloodsplatter/Initialize(mapload, set_dir, blood_color)
/obj/effect/temp_visual/dir_setting/bloodsplatter/Initialize(mapload, angle, blood_color)
if(!blood_color)
CRASH("Tried to create a blood splatter without a blood_color")

var/x_component = sin(angle) * -15
var/y_component = cos(angle) * -15
if(!GLOB.blood_particles[blood_color])
GLOB.blood_particles[blood_color] = new /particles/splatter(blood_color)
particles = GLOB.blood_particles[blood_color]
particles.velocity = list(x_component, y_component)
color = blood_color
if(ISDIAGONALDIR(set_dir))
icon_state = "[splatter_type][pick(1, 2, 6)]"
else
icon_state = "[splatter_type][pick(3, 4, 5)]"
icon_state = "[splatter_type][pick(1, 2, 3, 4, 5, 6)]"
. = ..()
var/target_pixel_x = 0
var/target_pixel_y = 0
switch(set_dir)
if(NORTH)
target_pixel_y = 16
if(SOUTH)
target_pixel_y = -16
layer = ABOVE_MOB_LAYER
if(EAST)
target_pixel_x = 16
if(WEST)
target_pixel_x = -16
if(NORTHEAST)
target_pixel_x = 16
target_pixel_y = 16
if(NORTHWEST)
target_pixel_x = -16
target_pixel_y = 16
if(SOUTHEAST)
target_pixel_x = 16
target_pixel_y = -16
layer = ABOVE_MOB_LAYER
if(SOUTHWEST)
target_pixel_x = -16
target_pixel_y = -16
layer = ABOVE_MOB_LAYER
switch(angle)
if(0, 360)
target_pixel_x = 0
target_pixel_y = 8
if(1 to 44)
target_pixel_x = round(4 * ((angle) / 45))
target_pixel_y = 8
if(45)
target_pixel_x = 8
target_pixel_y = 8
if(46 to 89)
target_pixel_x = 8
target_pixel_y = round(4 * ((90 - angle) / 45))
if(90)
target_pixel_x = 8
target_pixel_y = 0
if(91 to 134)
target_pixel_x = 8
target_pixel_y = round(-3 * ((angle - 90) / 45))
if(135)
target_pixel_x = 8
target_pixel_y = -6
if(136 to 179)
target_pixel_x = round(4 * ((180 - angle) / 45))
target_pixel_y = -6
if(180)
target_pixel_x = 0
target_pixel_y = -6
if(181 to 224)
target_pixel_x = round(-6 * ((angle - 180) / 45))
target_pixel_y = -6
if(225)
target_pixel_x = -6
target_pixel_y = -6
if(226 to 269)
target_pixel_x = -6
target_pixel_y = round(-6 * ((270 - angle) / 45))
if(270)
target_pixel_x = -6
target_pixel_y = 0
if(271 to 314)
target_pixel_x = -6
target_pixel_y = round(8 * ((angle - 270) / 45))
if(315)
target_pixel_x = -6
target_pixel_y = 8
if(316 to 359)
target_pixel_x = round(-6 * ((360 - angle) / 45))
target_pixel_y = 8
animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration)

/obj/effect/temp_visual/transfer_plasma
Expand Down
1 change: 0 additions & 1 deletion code/game/objects/obj_defense.dm
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@
return
playsound(loc, P.hitsound, 50, 1)
visible_message(span_warning("\the [src] is damaged by \the [P]!"), visible_message_flags = COMBAT_MESSAGE)
bullet_ping(P)
take_damage(P.damage, P.ammo.damage_type, P.ammo.armor_type, 0, turn(P.dir, 180), P.ammo.penetration)


Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/objs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
GLOB.all_req_one_access[txt_access] = req_one_access
else
req_one_access = GLOB.all_req_one_access[txt_access]

add_debris_element()

/obj/Destroy()
hard_armor = null
Expand Down
10 changes: 9 additions & 1 deletion code/game/objects/structures/barricade.dm
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,9 @@
barricade_type = "wooden"
can_wire = FALSE

/obj/structure/barricade/wooden/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_WOOD, -10, 5)

/obj/structure/barricade/wooden/attackby(obj/item/I, mob/user, params)
. = ..()

Expand Down Expand Up @@ -441,6 +444,9 @@
///The type of upgrade and corresponding overlay we have attached
var/barricade_upgrade_type

/obj/structure/barricade/metal/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_SPARKS, -15, 8, 1)

/obj/structure/barricade/metal/update_overlays()
. = ..()
if(!barricade_upgrade_type)
Expand Down Expand Up @@ -747,14 +753,16 @@
closed = TRUE
can_wire = TRUE
climbable = TRUE

///What state is our barricade in for construction steps?
var/build_state = BARRICADE_PLASTEEL_FIRM
var/busy = FALSE //Standard busy check
///ehther we react with other cades next to us ie when opening or so
var/linked = FALSE
COOLDOWN_DECLARE(tool_cooldown) //Delay to apply tools to prevent spamming

/obj/structure/barricade/plasteel/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_SPARKS, -15, 8, 1)

/obj/structure/barricade/plasteel/handle_barrier_chance(mob/living/M)
if(closed)
return ..()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
icon_closed = "cabinet_closed"
icon_opened = "cabinet_open"

/obj/structure/closet/cabinet/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_WOOD, -10, 5)

/obj/structure/closet/cabinet/update_icon_state()
if(!opened)
icon_state = icon_closed
Expand Down
4 changes: 4 additions & 0 deletions code/game/objects/structures/crates_lockers/largecrate.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
var/spawn_type
var/spawn_amount

/obj/structure/largecrate/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_WOOD, -10, 5)

/obj/structure/largecrate/deconstruct(disassembled = TRUE)
spawn_stuff()
Expand Down Expand Up @@ -156,6 +158,8 @@
. = ..()
. += span_notice("You need a blowtorch to weld this open!")

/obj/structure/largecrate/random/barrel/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_SPARKS, -15, 8, 1)

/obj/structure/largecrate/random/barrel
name = "blue barrel"
Expand Down
6 changes: 6 additions & 0 deletions code/game/objects/structures/flora.dm
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
layer = ABOVE_FLY_LAYER
var/log_amount = 10

/obj/structure/flora/tree/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_WOOD, -10, 5)

/obj/structure/flora/tree/Initialize(mapload)
. = ..()
AddTransparencyComponent()
Expand Down Expand Up @@ -718,6 +721,9 @@
coverage = 100
icon_state = "basalt"

/obj/structure/flora/rock/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_ROCK, -10, 5, 1)

/obj/structure/flora/rock/alt
name = "volcanic rock"
icon_state = "basalt1"
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/structures/girders.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
var/reinforcement = null
var/icon_prefix = "girder"

/obj/structure/girder/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_SPARKS, -15, 8, 1)

#define GIRDER_DECONSTRUCTING (new_state < girder_state)

Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/structures/mineral_doors.dm
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,5 @@
trigger_sound = 'sound/effects/doorcreaky.ogg'
max_integrity = 100

/obj/structure/mineral_door/wood/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_WOOD, -10, 5)
2 changes: 2 additions & 0 deletions code/game/objects/structures/supports.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
/// The type of debris to spawn when the ceiling collaspses
var/collapsed_type = /turf/closed/mineral

/obj/structure/support/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_WOOD, -10, 5)

/obj/structure/support/deconstruct(disassembled)
collapse()
Expand Down
9 changes: 9 additions & 0 deletions code/game/objects/structures/tables_racks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,9 @@
hit_sound = 'sound/effects/woodhit.ogg'
max_integrity = 20

/obj/structure/table/woodentable/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_WOOD, -10, 5)

/obj/structure/table/fancywoodentable
name = "fancy wooden table"
desc = "An expensive fancy wood surface resting on four legs. Useful to put stuff on. Can be flipped in emergencies to act as cover."
Expand All @@ -376,6 +379,9 @@
table_prefix = "fwood"
parts = /obj/item/frame/table/fancywood

/obj/structure/table/fancywoodentable/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_WOOD, -10, 5)

/obj/structure/table/rusticwoodentable
name = "rustic wooden table"
desc = "A rustic wooden surface resting on four legs. Useful to put stuff on. Can be flipped in emergencies to act as cover."
Expand All @@ -385,6 +391,9 @@
table_prefix = "pwood"
parts = /obj/item/frame/table/rusticwood

/obj/structure/table/rusticwoodentable/add_debris_element()
AddElement(/datum/element/debris, DEBRIS_WOOD, -10, 5)

/obj/structure/table/black
name = "black metal table"
desc = "A sleek black metallic surface resting on four legs. Useful to put stuff on. Can be flipped in emergencies to act as cover."
Expand Down
Loading

0 comments on commit dda014a

Please sign in to comment.