Merge pull request #14903 from silicons/spray_fix
fixes and rewrites sprays
This commit is contained in:
@@ -24,55 +24,86 @@
|
||||
var/range = 3
|
||||
var/hits_left = 3
|
||||
var/range_left = 3
|
||||
var/firstmove = TRUE
|
||||
var/list/hit
|
||||
|
||||
/obj/effect/decal/chempuff/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
|
||||
/obj/effect/decal/chempuff/Initialize(mapload, stream_mode, speed, range, hits_left)
|
||||
/obj/effect/decal/chempuff/Initialize(mapload, stream_mode, speed, range, hits_left, size)
|
||||
. = ..()
|
||||
create_reagents(size, NONE, NO_REAGENTS_VALUE)
|
||||
stream = stream_mode
|
||||
src.speed = speed
|
||||
src.range = src.range_left = range
|
||||
src.hits_left = hits_left
|
||||
hit = list()
|
||||
|
||||
/obj/effect/decal/chempuff/proc/hit_thing(atom/A)
|
||||
/obj/effect/decal/chempuff/Destroy()
|
||||
hit = null
|
||||
return ..()
|
||||
|
||||
/// proc called to handle us hitting something
|
||||
/obj/effect/decal/chempuff/proc/hit_thing(atom/A, bump_hit)
|
||||
// if the thing is invisible it usually is abstract/underfloor. also, don't hit ourselves.
|
||||
if(A == src || A.invisibility)
|
||||
return
|
||||
if(!hits_left)
|
||||
// don't hit anything on the first move unless overridden (see: we're colliding a wall blocking our move out of the first tile)
|
||||
if(firstmove && !bump_hit)
|
||||
return
|
||||
if(stream)
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
if(!M.lying || !range_left)
|
||||
reagents.reaction(M, VAPOR)
|
||||
hits_left--
|
||||
else
|
||||
if(!range_left)
|
||||
reagents.reaction(A, VAPOR)
|
||||
else
|
||||
reagents.reaction(A)
|
||||
if(ismob(A))
|
||||
hits_left--
|
||||
// we're out of hits or we already hit it
|
||||
if(!hits_left || hit[A])
|
||||
return
|
||||
var/living = isliving(A)
|
||||
// if it's not dense and we're a stream instead of a mist, and we're not out of range
|
||||
if(!A.density && stream && range_left && !bump_hit)
|
||||
return
|
||||
// non living mobs are effectively abstract
|
||||
if(ismob(A) && !living)
|
||||
return
|
||||
hit[A] = TRUE
|
||||
reagents.reaction(A, VAPOR)
|
||||
// mobs absorb enough to decrement hits_left, as well as stuff blocking us.
|
||||
if(ismob(A) || bump_hit)
|
||||
hits_left--
|
||||
|
||||
/obj/effect/decal/chempuff/Crossed(atom/movable/AM, oldloc)
|
||||
. = ..()
|
||||
// bump things moving into us as long as we're not on our first move/moving out of origin tile
|
||||
hit_thing(AM)
|
||||
|
||||
/obj/effect/decal/chempuff/Bump(atom/A)
|
||||
. = ..()
|
||||
// if we hit something blocking our movement, collide it regardless even if we're still on our origin tile
|
||||
hit_thing(A, TRUE)
|
||||
|
||||
/obj/effect/decal/chempuff/proc/run_puff(atom/target)
|
||||
set waitfor = FALSE
|
||||
for(var/i in 1 to range)
|
||||
var/safety = 255
|
||||
while(range_left)
|
||||
if(!safety--)
|
||||
CRASH("Spray ran out of safety.")
|
||||
// move towards new turf
|
||||
step_towards(src, target)
|
||||
if(firstmove)
|
||||
// mark first movement so future Cross()es result in collisions
|
||||
firstmove = FALSE
|
||||
// decrement range
|
||||
range_left--
|
||||
// if we got nullspaced, exit
|
||||
if(!isturf(loc))
|
||||
break
|
||||
// hit everything in it
|
||||
for(var/atom/T in loc)
|
||||
hit_thing(T)
|
||||
// if we got deleted or ran out of hits, stop
|
||||
if(!hits_left || !isturf(loc))
|
||||
break
|
||||
if(hits_left && isturf(loc) && (!stream || !range_left))
|
||||
reagents.reaction(loc, VAPOR)
|
||||
hits_left--
|
||||
if(!hits_left)
|
||||
if(!hits_left || !isturf(loc))
|
||||
// yeah yeah sue me it's copypasted code but I don't want to declare a var.
|
||||
break
|
||||
// hit the turf
|
||||
hit_thing(loc)
|
||||
sleep(speed)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/decal/fakelattice
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
var/stream_mode = 0 //whether we use the more focused mode
|
||||
var/current_range = 3 //the range of tiles the sprayer will reach.
|
||||
var/spray_range = 3 //the range of tiles the sprayer will reach when in spray mode.
|
||||
var/stream_range = 1 //the range of tiles the sprayer will reach when in stream mode.
|
||||
var/stream_range = 3 //the range of tiles the sprayer will reach when in stream mode.
|
||||
var/stream_amount = 10 //the amount of reagents transfered when in stream mode.
|
||||
/// Amount of time it takes for a spray to completely travel.
|
||||
var/spray_delay = 8
|
||||
@@ -74,19 +74,18 @@
|
||||
return
|
||||
var/range = clamp(get_dist(src, A), 1, current_range)
|
||||
var/wait_step = CEILING(spray_delay * INVERSE(range), world.tick_lag)
|
||||
var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src), stream_mode, wait_step, range, stream_mode? 1 : range)
|
||||
var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src), stream_mode, wait_step, range, stream_mode? 1 : range, amount_per_transfer_from_this)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return
|
||||
log_reagent("SPRAY: [key_name(usr)] fired [src] ([REF(src)]) [COORD(T)] at [A] ([REF(A)]) [COORD(A)] (chempuff: [D.reagents.log_list()])")
|
||||
D.create_reagents(amount_per_transfer_from_this, NONE, NO_REAGENTS_VALUE)
|
||||
if(stream_mode)
|
||||
reagents.trans_to(D, amount_per_transfer_from_this)
|
||||
else
|
||||
reagents.trans_to(D, amount_per_transfer_from_this, 1/range)
|
||||
D.color = mix_color_from_reagents(D.reagents.reagent_list)
|
||||
D.add_atom_colour(mix_color_from_reagents(D.reagents.reagent_list), TEMPORARY_COLOUR_PRIORITY)
|
||||
last_spray = world.time
|
||||
D.run_puff(A)
|
||||
INVOKE_ASYNC(D, /obj/effect/decal/chempuff/proc/run_puff, A)
|
||||
|
||||
/obj/item/reagent_containers/spray/attack_self(mob/user)
|
||||
stream_mode = !stream_mode
|
||||
|
||||
Reference in New Issue
Block a user