Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ports various implementations of particle effects from TGMC #2454

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions code/__DEFINES/generators.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//generator types
#define GEN_NUM "num"
#define GEN_VECTOR "vector"
#define GEN_BOX "box"
#define GEN_COLOR "color"
#define GEN_CIRCLE "circle"
#define GEN_SPHERE "sphere"
#define GEN_SQUARE "square"
#define GEN_CUBE "cube"

///particle editor var modifiers
#define P_DATA_GENERATOR "generator"
#define P_DATA_ICON_ADD "icon_add"
#define P_DATA_ICON_REMOVE "icon_remove"
#define P_DATA_ICON_WEIGHT "icon_edit"
11 changes: 11 additions & 0 deletions code/controllers/subsystem/explosions.dm
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ SUBSYSTEM_DEF(explosions)
if(!silent)
shake_the_room(epicenter, orig_max_distance, far_dist, devastation_range, heavy_impact_range)

//MOJAVE EDIT ADDITION BEGIN: Ported TGMC visual explosion particles
/*
if(heavy_impact_range > 1)
var/datum/effect_system/explosion/E
if(smoke)
Expand All @@ -372,7 +374,16 @@ SUBSYSTEM_DEF(explosions)
E = new
E.set_up(epicenter)
E.start()
*/
if(devastation_range > 0)
new /obj/effect/temp_visual/explosion(epicenter, max_range, LIGHT_COLOR_LAVA, FALSE, TRUE)
else if(heavy_impact_range > 0)
new /obj/effect/temp_visual/explosion(epicenter, max_range, LIGHT_COLOR_LAVA, FALSE, FALSE)
else if(light_impact_range > 0)
new /obj/effect/temp_visual/explosion(epicenter, max_range, LIGHT_COLOR_LAVA, TRUE, FALSE)


//MOJAVE EDIT ADDITION END
//flash mobs
if(flash_range)
for(var/mob/living/L in viewers(flash_range, epicenter))
Expand Down
4 changes: 4 additions & 0 deletions code/game/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2208,3 +2208,7 @@
new /datum/merger(id, allowed_types, src)
candidate = mergers[id]
return candidate

//Mojave Edit
/atom/proc/add_debris_element()
AddElement(/datum/element/debris, null, -15, 8, 0.7)
67 changes: 67 additions & 0 deletions code/game/objects/effects/particle_holder.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
///objects can only have one particle on them at a time, so we use these abstract effects to hold and display the effects. You know, so multiple particle effects can exist at once.
///also because some objects do not display particles due to how their visuals are built
/obj/effect/abstract/particle_holder
anchored = TRUE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = ABOVE_ALL_MOB_LAYER
vis_flags = VIS_INHERIT_PLANE
///typepath of the last location we're in, if it's different when moved then we need to update vis contents
var/last_attached_location_type
///the main item we're attached to at the moment, particle holders hold particles for something
var/datum/weakref/weak_attached
///besides the item we're also sometimes attached to other stuff! (items held emitting particles on a mob)
var/datum/weakref/weak_additional

/obj/effect/abstract/particle_holder/Initialize(mapload, particle_path = null)
. = ..()
if(!loc)
stack_trace("particle holder was created with no loc!")
return INITIALIZE_HINT_QDEL
if(ismovable(loc))
RegisterSignal(loc, COMSIG_MOVABLE_MOVED, .proc/on_move)
RegisterSignal(loc, COMSIG_PARENT_QDELETING, .proc/on_qdel)
weak_attached = WEAKREF(loc)
particles = new particle_path
update_visual_contents(loc)

/obj/effect/abstract/particle_holder/Destroy(force)
var/atom/movable/attached = weak_attached.resolve()
var/atom/movable/additional_attached
if(weak_additional)
additional_attached = weak_additional.resolve()
if(attached)
attached.vis_contents -= src
UnregisterSignal(loc, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING))
if(additional_attached)
additional_attached.vis_contents -= src
QDEL_NULL(particles)
return ..()

///signal called when parent is moved
/obj/effect/abstract/particle_holder/proc/on_move(atom/movable/attached, atom/oldloc, direction)
SIGNAL_HANDLER
if(attached.loc.type != last_attached_location_type)
update_visual_contents(attached)

///signal called when parent is deleted
/obj/effect/abstract/particle_holder/proc/on_qdel(atom/movable/attached, force)
SIGNAL_HANDLER
qdel(src)//our parent is gone and we need to be as well

///logic proc for particle holders, aka where they move.
///subtypes of particle holders can override this for particles that should always be turf level or do special things when repositioning.
///this base subtype has some logic for items, as the loc of items becomes mobs very often hiding the particles
/obj/effect/abstract/particle_holder/proc/update_visual_contents(atom/movable/attached_to)
//remove old
if(weak_additional)
var/atom/movable/resolved_location = weak_additional.resolve()
if(resolved_location)
resolved_location.vis_contents -= src
//add to new
if(isitem(attached_to) && ismob(attached_to.loc)) //special case we want to also be emitting from the mob
var/mob/particle_mob = attached_to.loc
last_attached_location_type = attached_to.loc
weak_additional = WEAKREF(particle_mob)
particle_mob.vis_contents += src
//readd to ourselves
attached_to.vis_contents |= src
3 changes: 3 additions & 0 deletions code/game/objects/effects/temporary_visuals/miscellaneous.dm
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@
plane = ABOVE_GAME_PLANE
duration = 4

//MOJAVE EDIT: Using TGMC explosion visual
/*
/obj/effect/temp_visual/explosion
name = "explosion"
icon = 'icons/effects/96x96.dmi'
Expand All @@ -336,6 +338,7 @@
/obj/effect/temp_visual/explosion/fast
icon_state = "explosionfast"
duration = 4
*/

/obj/effect/temp_visual/blob
name = "blob"
Expand Down
2 changes: 2 additions & 0 deletions code/game/objects/objs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
AddComponent(/datum/component/ntnet_interface, network_id, id_tag)
/// Needs to run before as ComponentInitialize runs after this statement...why do we have ComponentInitialize again?

//Mojave Edit
add_debris_element()

/obj/Destroy(force)
if(!ismachinery(src))
Expand Down
2 changes: 2 additions & 0 deletions code/game/turfs/closed/_closed.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
. = ..()
if(frill_icon)
AddElement(/datum/element/frill, frill_icon) //MOJAVE SUN EDIT - Wallening Testmerge
add_debris_element()


/turf/closed/AfterChange()
. = ..()
Expand Down
33 changes: 33 additions & 0 deletions code/modules/projectiles/gun.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@
#define DUALWIELD_PENALTY_EXTRA_MULTIPLIER 1.4
#define FIRING_PIN_REMOVAL_DELAY 50

//MOJAVE EDIT ADDITION BEGIN: Ported TGMC gun smoke particles
/particles/firing_smoke
icon = 'mojave/icons/effects/96x96.dmi'
icon_state = "smoke5"
width = 500
height = 500
count = 5
spawning = 15
lifespan = 0.5 SECONDS
fade = 2.4 SECONDS
grow = 0.12
drift = generator(GEN_CIRCLE, 8, 8)
scale = 0.1
spin = generator(GEN_NUM, -20, 20)
velocity = list(50, 0)
friction = generator(GEN_NUM, 0.3, 0.6)
//MOJAVE EDIT ADDITION END

/obj/item/gun
name = "gun"
desc = "It's a gun. It's pretty terrible, though."
Expand All @@ -24,6 +42,10 @@
attack_verb_continuous = list("strikes", "hits", "bashes")
attack_verb_simple = list("strike", "hit", "bash")

//MOJAVE EDIT ADDITION BEGIN: Ported TGMC gun smoke particles
var/barrel_smoke_on_shoot = FALSE
//MOJAVE EDIT ADDITION END

var/gun_flags = NONE
var/fire_sound = 'sound/weapons/gun/pistol/shot.ogg'
var/vary_fire_sound = TRUE
Expand Down Expand Up @@ -204,6 +226,17 @@
span_danger("You fire [src]!"), \
span_hear("You hear a gunshot!"), COMBAT_MESSAGE_RANGE)

//MOJAVE EDIT BEGIN
if(barrel_smoke_on_shoot)
var/x_component = sin(get_angle(user, pbtarget)) * 40
var/y_component = cos(get_angle(user, pbtarget)) * 40
var/obj/effect/abstract/particle_holder/gun_smoke = new(get_turf(src), /particles/firing_smoke)
gun_smoke.particles.velocity = list(x_component, y_component)
addtimer(VARSET_CALLBACK(gun_smoke.particles, count, 0), 5)
addtimer(VARSET_CALLBACK(gun_smoke.particles, drift, 0), 3)
QDEL_IN(gun_smoke, 0.6 SECONDS)
//MOJAVE EDIT CHANGE END

/obj/item/gun/emp_act(severity)
. = ..()
if(!(. & EMP_PROTECT_CONTENTS))
Expand Down
5 changes: 4 additions & 1 deletion code/modules/projectiles/guns/ballistic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
icon_state = "pistol"
w_class = WEIGHT_CLASS_NORMAL

//MOJAVE EDIT ADDITION BEGIN: Ported TGMC gun smoke particles
barrel_smoke_on_shoot = TRUE
//MOJAVE EDIT ADDITION END

///sound when inserting magazine
var/load_sound = 'sound/weapons/gun/general/magazine_insert_full.ogg'
///sound when inserting an empty magazine
Expand Down Expand Up @@ -392,7 +396,6 @@
if(can_misfire)
misfire_probability += misfire_percentage_increment
misfire_probability = clamp(misfire_probability, 0, misfire_probability_cap)

. = ..()

///Installs a new suppressor, assumes that the suppressor is already in the contents of src
Expand Down
6 changes: 6 additions & 0 deletions mojave/__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"
102 changes: 102 additions & 0 deletions mojave/code/datums/elements/debris.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#define DEBRIS_SPARKS "spark"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mojave/code/datums/elements/debris.dm, line 1, column [9](https://github.com/Mojave-Sun/mojave-sun-13/actions/runs/6320722331/job/17163641058?pr=2454#step:7:10):
warning: macro redefined: DEBRIS_SPARKS
- code/__DEFINES/particles.dm:1:9: previous definition of DEBRIS_SPARKS

mojave/code/datums/elements/debris.dm, line 2, column 9:
warning: macro redefined: DEBRIS_WOOD
- code/__DEFINES/particles.dm:2:9: previous definition of DEBRIS_WOOD

mojave/code/datums/elements/debris.dm, line 3, column 9:
warning: macro redefined: DEBRIS_ROCK
- code/__DEFINES/particles.dm:3:9: previous definition of DEBRIS_ROCK

mojave/code/datums/elements/debris.dm, line 4, column 9:
warning: macro redefined: DEBRIS_GLASS
- code/__DEFINES/particles.dm:4:9: previous definition of DEBRIS_GLASS

mojave/code/datums/elements/debris.dm, line 5, column 9:
warning: macro redefined: DEBRIS_LEAF
- code/__DEFINES/particles.dm:5:9: previous definition of DEBRIS_LEAF

mojave/code/datums/elements/debris.dm, line 6, column 9:
warning: macro redefined: DEBRIS_SNOW
- code/__DEFINES/particles.dm:6:9: previous definition of DEBRIS_SNOW

Anyway to reasonably clean this up?

#define DEBRIS_WOOD "wood"
#define DEBRIS_ROCK "rock"
#define DEBRIS_GLASS "glass"
#define DEBRIS_LEAF "leaf"
#define DEBRIS_SNOW "snow"

/particles/debris
icon = 'mojave/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
id_arg_index = 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/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/on_impact, source, proj)

/datum/element/debris/proc/on_impact(datum/source, obj/projectile/P)
//if(!P.ammo.ping)
// return
var/angle = !isnull(P.Angle) ? P.Angle : round(get_angle(P.starting, 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/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)
Loading