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

The Particlening #3239

Merged
merged 34 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
0ab1695
first off
rye-rice Sep 24, 2023
b231f33
this shit dont work
rye-rice Sep 28, 2023
aba18b3
Merge remote-tracking branch 'upstream/master' into particlening
rye-rice Dec 3, 2023
438e76e
Merge remote-tracking branch 'upstream/master' into particlening
rye-rice Mar 6, 2024
c0d5245
Revert "this shit dont work"
rye-rice Mar 6, 2024
08eea5f
Revert "Revert "this shit dont work""
rye-rice Mar 6, 2024
1930851
The failed particle editor port, this is to revert and reviver when i…
rye-rice Mar 6, 2024
bd7cc65
Revert "The failed particle editor port, this is to revert and revive…
rye-rice Mar 6, 2024
3221f27
works
rye-rice Mar 6, 2024
0d6004a
progress
rye-rice Mar 6, 2024
d7f097c
feedback
rye-rice Mar 7, 2024
0a7a5e6
blood changes
rye-rice Mar 7, 2024
e2f24ee
steam vents
rye-rice Mar 7, 2024
1608d3a
revert after done
rye-rice Mar 7, 2024
21b35f2
x
rye-rice Apr 29, 2024
39594f5
Merge remote-tracking branch 'upstream/master' into particlening
rye-rice Jun 11, 2024
6af47f0
Merge remote-tracking branch 'upstream/master' into particlening
rye-rice Jun 17, 2024
9c7940f
Merge remote-tracking branch 'upstream/master' into particlening
rye-rice Jun 17, 2024
474a66b
waga
rye-rice Jun 17, 2024
089fdef
we balll
rye-rice Jun 24, 2024
a3ced96
Merge remote-tracking branch 'upstream/master' into particlening
rye-rice Jun 24, 2024
26c2124
fixes
rye-rice Jun 30, 2024
55c7d83
Merge remote-tracking branch 'upstream/master' into particlening
rye-rice Jun 30, 2024
7be6dea
test
rye-rice Jul 1, 2024
f8580ba
Merge remote-tracking branch 'upstream/master' into particlening
rye-rice Jul 4, 2024
8d8b82e
fix
rye-rice Jul 6, 2024
c4cd2fa
Merge remote-tracking branch 'upstream/master' into particlening
rye-rice Jul 23, 2024
f1b788d
cleanup
rye-rice Jul 23, 2024
7e4c281
linters
rye-rice Jul 24, 2024
2dbd844
Fuck
rye-rice Jul 25, 2024
e93ed81
Fuck(2)
rye-rice Jul 25, 2024
a919d82
Merge remote-tracking branch 'upstream/master' into particlening
rye-rice Aug 22, 2024
abf068a
Merge remote-tracking branch 'upstream/master' into particlening
rye-rice Aug 22, 2024
8a6937d
fdakljhouliya908u7y6
rye-rice Aug 26, 2024
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"
2 changes: 2 additions & 0 deletions code/__DEFINES/is_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#define isweakref(D) (istype(D, /datum/weakref))

#define isgenerator(A) (istype(A, /generator))

//Turfs
//#define isturf(A) (istype(A, /turf)) This is actually a byond built-in. Added here for completeness sake.

Expand Down
5 changes: 5 additions & 0 deletions code/__DEFINES/particles.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// /obj/effect/abstract/particle_holder/var/particle_flags
// Flags that effect how a particle holder displays something

/// If we're inside something inside a mob, display off that mob too
#define PARTICLE_ATTACH_MOB (1<<0)
1 change: 1 addition & 0 deletions code/__DEFINES/vv.dm
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
#define VV_HK_AUTO_RENAME "auto_rename"
#define VV_HK_RADIATE "radiate"
#define VV_HK_EDIT_FILTERS "edit_filters"
#define VV_HK_EDIT_PARTICLES "edit_particles"

// /obj
#define VV_HK_OSAY "osay"
Expand Down
11 changes: 11 additions & 0 deletions code/__HELPERS/generators.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* returns the arguments given to a generator and manually extracts them from the internal byond object
* returns:
* * flat list of strings for args given to the generator.
* * Note: this means things like "list(1,2,3)" will need to be processed
*/
/proc/return_generator_args(generator/target)
var/string_repr = "[target]" //the name of the generator is the string representation of it's _binobj, which also contains it's args
string_repr = copytext(string_repr, 11, length(string_repr)) // strips extraneous data
string_repr = replacetext(string_repr, "\"", "") // removes the " around the type
return splittext(string_repr, ", ")
17 changes: 17 additions & 0 deletions code/datums/looping_sounds/weather.dm
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,20 @@

/datum/looping_sound/weather/rain/indoors
volume = 30

/datum/looping_sound/weather/rain/storm
mid_sounds = list(
'sound/ambience/storm_outdoors.ogg' = 1
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
'sound/ambience/storm_outdoors.ogg' = 1
'sound/ambience/storm_outdoors.ogg' = 1,

)
mid_length = 20.03 SECONDS // The lengths for the files vary, but the longest is ten seconds, so this will make it sound like intermittent wind.
start_sound = 'sound/ambience/acidrain_start.ogg'
start_length = null
end_sound = null
volume = 50

/datum/looping_sound/weather/rain/storm/indoors
volume = 30
mid_sounds = list(
'sound/ambience/storm_indoors.ogg' = 1
)
mid_length = 20.03 SECONDS // The lengths for the files vary, but the longest is ten seconds, so this will make it sound like intermittent wind.
14 changes: 14 additions & 0 deletions code/datums/weather/weather_types/rain.dm
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,17 @@
desc = "Storm with rain and lightning."
weather_message = "<span class='warning'>The clouds blacken and the sky starts to flash as thunder strikes down!</span>"
thunder_chance = 10

/datum/weather/rain/heavy/storm_intense
name = "storm"
desc = "Storm with rain and lightning."
weather_overlay = "storm_very"
thunder_chance = 20
weather_color = "#a3daf7"
weather_duration_lower = 420690
weather_duration_upper = 420690

sound_active_outside = /datum/looping_sound/weather/rain/storm/indoors
sound_active_inside = /datum/looping_sound/weather/rain/storm
sound_weak_outside = /datum/looping_sound/weather/rain/storm/indoors
sound_weak_inside = /datum/looping_sound/weather/rain/storm
131 changes: 131 additions & 0 deletions code/game/objects/effects/decals/cleanable/humans.dm
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
random_icon_states = list("gibbl1", "gibbl2", "gibbl3", "gibbl4", "gibbl5")
dryname = "dried tracks"
drydesc = "Some old bloody tracks left by wheels. Machines are evil, perhaps."
///Absorb the /squirt subtype when it exists on the turf
var/absorb_squirts = TRUE

/obj/effect/decal/cleanable/blood/tracks
icon_state = "tracks"
Expand Down Expand Up @@ -278,3 +280,132 @@
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
return 1
return 0

/obj/effect/decal/cleanable/blood/hitsplatter
name = "blood splatter"
pass_flags = PASSTABLE | PASSGRILLE
icon_state = "hitsplatter1"
random_icon_states = list("hitsplatter1", "hitsplatter2", "hitsplatter3")
/// The turf we just came from, so we can back up when we hit a wall
var/turf/prev_loc
/// The cached info about the blood
var/list/blood_dna_info
/// Skip making the final blood splatter when we're done, like if we're not in a turf
var/skip = FALSE
/// How many tiles/items/people we can paint red
var/splatter_strength = 3
/// Insurance so that we don't keep moving once we hit a stoppoint
var/hit_endpoint = FALSE
// ///Absorb the /squirt subtype when it exists on the turf
// var/absorb_squirts = TRUE

/obj/effect/decal/cleanable/blood/hitsplatter/Initialize(mapload, splatter_strength)
. = ..()
prev_loc = loc //Just so we are sure prev_loc exists
if(splatter_strength)
src.splatter_strength = splatter_strength

/obj/effect/decal/cleanable/blood/hitsplatter/Destroy()
if(isturf(loc) && !skip)
playsound(src, 'sound/effects/splatter.ogg', 60, TRUE, -1)
if(blood_dna_info)
loc.add_blood_DNA(blood_dna_info)
return ..()

/// Set the splatter up to fly through the air until it rounds out of steam or hits something. Contains sleep() pending imminent moveloop rework, don't call without async'ing it
/obj/effect/decal/cleanable/blood/hitsplatter/proc/fly_towards(turf/target_turf, range)
splatter_strength = range
for(var/i in 1 to range)
step_towards(src,target_turf)
sleep(2) // Will be resolved pending Potato's moveloop rework
for(var/atom/iter_atom in get_turf(src))
if(hit_endpoint)
return
if(splatter_strength <= 0)
break

if(isitem(iter_atom))
iter_atom.add_blood_DNA(blood_dna_info)
splatter_strength--
else if(ishuman(iter_atom))
var/mob/living/carbon/human/splashed_human = iter_atom
if(splashed_human.wear_suit)
splashed_human.wear_suit.add_blood_DNA(blood_dna_info)
splashed_human.update_inv_wear_suit() //updates mob overlays to show the new blood (no refresh)
if(splashed_human.w_uniform)
splashed_human.w_uniform.add_blood_DNA(blood_dna_info)
splashed_human.update_inv_w_uniform() //updates mob overlays to show the new blood (no refresh)
splatter_strength--

if(splatter_strength <= 0) // we used all the puff so we delete it.
qdel(src)
return

var/obj/effect/decal/cleanable/blood/newsplatter
if(splatter_strength <= 3.5)
newsplatter = new /obj/effect/decal/cleanable/blood/squirt(get_turf(src), get_dir(prev_loc, loc), blood_dna_info)
else
newsplatter = new /obj/effect/decal/cleanable/blood/splatter(get_turf(src))
newsplatter.add_blood_DNA(blood_dna_info)
prev_loc = loc

qdel(src)
return

/obj/effect/decal/cleanable/blood/hitsplatter/Bump(atom/bumped_atom)
if(!iswallturf(bumped_atom) && !istype(bumped_atom, /obj/structure/window))
qdel(src)
return

if(istype(bumped_atom, /obj/structure/window))
var/obj/structure/window/bumped_window = bumped_atom
if(!bumped_window.fulltile)
qdel(src)
return

hit_endpoint = TRUE
if(isturf(prev_loc))
abstract_move(bumped_atom)
skip = TRUE
//Adjust pixel offset to make splatters appear on the wall
if(istype(bumped_atom, /obj/structure/window))
land_on_window(bumped_atom)
else
var/obj/effect/decal/cleanable/blood/splatter/over_window/final_splatter = new(prev_loc)
final_splatter.pixel_x = (dir == EAST ? 32 : (dir == WEST ? -32 : 0))
final_splatter.pixel_y = (dir == NORTH ? 32 : (dir == SOUTH ? -32 : 0))
else // This will only happen if prev_loc is not even a turf, which is highly unlikely.
abstract_move(bumped_atom)
qdel(src)

/// A special case for hitsplatters hitting windows, since those can actually be moved around, store it in the window and slap it in the vis_contents
/obj/effect/decal/cleanable/blood/hitsplatter/proc/land_on_window(obj/structure/window/the_window)
if(!the_window.fulltile)
return
var/obj/effect/decal/cleanable/blood/splatter/over_window/final_splatter = new
final_splatter.forceMove(the_window)
the_window.vis_contents += final_splatter
the_window.bloodied = TRUE
qdel(src)

/obj/effect/decal/cleanable/blood/squirt
name = "blood trail"
icon_state = "squirt"
random_icon_states = null

/obj/effect/decal/cleanable/blood/squirt/Initialize(mapload, direction, list/blood_dna)
. = ..()
dir = direction
var/obj/effect/decal/cleanable/blood/splatter/existing_blood = locate() in get_turf(src)
if(existing_blood?.absorb_squirts)
if(blood_dna)
existing_blood.add_blood_DNA(blood_dna)
existing_blood.bloodiness = min((existing_blood.bloodiness + bloodiness), BLOOD_AMOUNT_PER_DECAL)
return INITIALIZE_HINT_QDEL

/obj/effect/decal/cleanable/blood/splatter/over_window // special layer/plane set to appear on windows
layer = ABOVE_WINDOW_LAYER
plane = GAME_PLANE
turf_loc_check = FALSE
alpha = 180
absorb_squirts = FALSE
71 changes: 67 additions & 4 deletions code/game/objects/effects/particle_emitter.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,70 @@
/obj/effect/particle_emitter
name = ""
///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
name = "particle holder"
desc = "How are you reading this? Please make a bug report :)"
appearance_flags = KEEP_APART|KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE|LONG_GLIDE //movable appearance_flags plus KEEP_APART and KEEP_TOGETHER
vis_flags = VIS_INHERIT_PLANE
layer = ABOVE_ALL_MOB_LAYER
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
anchored = TRUE
mouse_opacity = 0
/// Holds info about how this particle emitter works
/// See \code\__DEFINES\particles.dm
var/particle_flags = NONE

/obj/effect/particle_emitter/Initialize(mapload, time)
var/atom/parent

/obj/effect/abstract/particle_holder/Initialize(mapload, particle_path = /particles/smoke, particle_flags = NONE)
. = ..()
if(!loc)
stack_trace("particle holder was created with no loc!")
return INITIALIZE_HINT_QDEL
// We nullspace ourselves because some objects use their contents (e.g. storage) and some items may drop everything in their contents on deconstruct.
parent = loc
loc = null

// Mouse opacity can get set to opaque by some objects when placed into the object's contents (storage containers).
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
src.particle_flags = particle_flags
particles = new particle_path()
// /atom doesn't have vis_contents, /turf and /atom/movable do
var/atom/movable/lie_about_areas = parent
lie_about_areas.vis_contents += src
RegisterSignal(parent, COMSIG_PARENT_QDELETING, PROC_REF(parent_deleted))

if(particle_flags & PARTICLE_ATTACH_MOB)
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
on_move(parent, null, NORTH)

/obj/effect/abstract/particle_holder/Destroy(force)
QDEL_NULL(particles)
parent = null
return ..()

/// Non movables don't delete contents on destroy, so we gotta do this
/obj/effect/abstract/particle_holder/proc/parent_deleted(datum/source)
SIGNAL_HANDLER
qdel(src)

/// signal called when a parent that's been hooked into this moves
/// does a variety of checks to ensure overrides work out properly
/obj/effect/abstract/particle_holder/proc/on_move(atom/movable/attached, atom/oldloc, direction)
SIGNAL_HANDLER

if(!(particle_flags & PARTICLE_ATTACH_MOB))
return

//remove old
if(ismob(oldloc))
var/mob/particle_mob = oldloc
particle_mob.vis_contents -= src

// If we're sitting in a mob, we want to emit from it too, for vibes and shit
if(ismob(attached.loc))
var/mob/particle_mob = attached.loc
particle_mob.vis_contents += src

/// Sets the particles position to the passed coordinate list (X, Y, Z)
/// See [https://www.byond.com/docs/ref/#/{notes}/particles] for position documentation
/obj/effect/abstract/particle_holder/proc/set_particle_position(list/pos)
particles.position = pos
15 changes: 15 additions & 0 deletions code/game/objects/effects/particles/acid.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Acid related particles.
/particles/acid
icon = 'icons/effects/particles/goop.dmi'
icon_state = list("goop_1" = 6, "goop_2" = 2, "goop_3" = 1)
width = 100
height = 100
count = 100
spawning = 0.5
color = "#00ea2b80" //to get 96 alpha
lifespan = 1.5 SECONDS
fade = 1 SECONDS
grow = -0.025
gravity = list(0, 0.15)
position = generator(GEN_SPHERE, 0, 16, NORMAL_RAND)
spin = generator(GEN_NUM, -15, 15, NORMAL_RAND)
55 changes: 55 additions & 0 deletions code/game/objects/effects/particles/fire.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Fire related particles.
/particles/bonfire
icon = 'icons/effects/particles/bonfire.dmi'
icon_state = "bonfire"
width = 100
height = 100
count = 1000
spawning = 4
lifespan = 0.7 SECONDS
fade = 1 SECONDS
grow = -0.01
velocity = list(0, 0)
position = generator(GEN_CIRCLE, 0, 16, NORMAL_RAND)
drift = generator(GEN_VECTOR, list(0, -0.2), list(0, 0.2))
gravity = list(0, 0.95)
scale = generator(GEN_VECTOR, list(0.3, 0.3), list(1,1), NORMAL_RAND)
rotation = 30
spin = generator(GEN_NUM, -20, 20)

/particles/embers
icon = 'icons/effects/particles/generic.dmi'
icon_state = list("dot" = 4,"cross" = 1,"curl" = 1)
width = 64
height = 96
count = 500
spawning = 5
lifespan = 3 SECONDS
fade = 1 SECONDS
color = 0
color_change = 0.05
gradient = list("#FBAF4D", "#FCE6B6", "#FD481C")
position = generator(GEN_BOX, list(-12,-16,0), list(12,16,0), NORMAL_RAND)
drift = generator(GEN_VECTOR, list(-0.1,0), list(0.1,0.025))
spin = generator(GEN_NUM, list(-15,15), NORMAL_RAND)
scale = generator(GEN_VECTOR, list(0.5,0.5), list(2,2), NORMAL_RAND)

/particles/embers/lava
width = 700
height = 700
gradient = list(LIGHT_COLOR_FLARE, LIGHT_COLOR_FLARE , COLOR_ALMOST_BLACK)
spawning = 1

/particles/lava
width = 700
height = 700
count = 500
spawning = 1
lifespan = 4 SECONDS
fade = 2 SECONDS
position = generator(GEN_CIRCLE, 16, 24, NORMAL_RAND)
drift = generator(GEN_VECTOR, list(-0.2, -0.2), list(0.6, 0.6))
velocity = generator(GEN_CIRCLE, -6, 6, NORMAL_RAND)
friction = 0.15
gradient = list(0,LIGHT_COLOR_FLARE , 0.75, COLOR_ALMOST_BLACK)
color_change = 0.125
Loading
Loading