Moves projectile processing to a subsystem
This commit is contained in:
committed by
CitadelStationBot
parent
be2dc49384
commit
ed96224d3a
@@ -1,3 +1,4 @@
|
||||
<<<<<<< HEAD
|
||||
/obj/item/ammo_casing/proc/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread)
|
||||
distro += variance
|
||||
for (var/i = max(1, pellets), i > 0, i--)
|
||||
@@ -60,3 +61,67 @@
|
||||
var/dx = abs(target.x - current.x)
|
||||
var/dy = abs(target.y - current.y)
|
||||
return locate(target.x + round(gaussian(0, distro) * (dy+2)/8, 1), target.y + round(gaussian(0, distro) * (dx+2)/8, 1), target.z)
|
||||
=======
|
||||
/obj/item/ammo_casing/proc/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread)
|
||||
distro += variance
|
||||
for (var/i = max(1, pellets), i > 0, i--)
|
||||
var/targloc = get_turf(target)
|
||||
ready_proj(target, user, quiet, zone_override)
|
||||
if(distro) //We have to spread a pixel-precision bullet. throw_proj was called before so angles should exist by now...
|
||||
if(randomspread)
|
||||
spread = round((rand() - 0.5) * distro)
|
||||
else //Smart spread
|
||||
spread = round((i / pellets - 0.5) * distro)
|
||||
if(!throw_proj(target, targloc, user, params, spread))
|
||||
return 0
|
||||
if(i > 1)
|
||||
newshot()
|
||||
if(click_cooldown_override)
|
||||
user.changeNext_move(click_cooldown_override)
|
||||
else
|
||||
user.changeNext_move(CLICK_CD_RANGE)
|
||||
user.newtonian_move(get_dir(target, user))
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/item/ammo_casing/proc/ready_proj(atom/target, mob/living/user, quiet, zone_override)
|
||||
if (!BB)
|
||||
return
|
||||
BB.original = target
|
||||
BB.firer = user
|
||||
if (zone_override)
|
||||
BB.def_zone = zone_override
|
||||
else
|
||||
BB.def_zone = user.zone_selected
|
||||
BB.suppressed = quiet
|
||||
|
||||
if(reagents && BB.reagents)
|
||||
reagents.trans_to(BB, reagents.total_volume) //For chemical darts/bullets
|
||||
qdel(reagents)
|
||||
|
||||
/obj/item/ammo_casing/proc/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread)
|
||||
var/turf/curloc = get_turf(user)
|
||||
if (!istype(targloc) || !istype(curloc) || !BB)
|
||||
return 0
|
||||
|
||||
var/firing_dir
|
||||
if(BB.firer)
|
||||
firing_dir = BB.firer.dir
|
||||
if(!BB.suppressed && firing_effect_type)
|
||||
new firing_effect_type(get_turf(src), firing_dir)
|
||||
|
||||
var/direct_target
|
||||
if(targloc == curloc)
|
||||
if(target) //if the target is right on our location we'll skip the travelling code in the proj's fire()
|
||||
direct_target = target
|
||||
if(!direct_target)
|
||||
BB.preparePixelProjectile(target, user, params, spread)
|
||||
BB.fire(null, direct_target)
|
||||
BB = null
|
||||
return 1
|
||||
|
||||
/obj/item/ammo_casing/proc/spread(turf/target, turf/current, distro)
|
||||
var/dx = abs(target.x - current.x)
|
||||
var/dy = abs(target.y - current.y)
|
||||
return locate(target.x + round(gaussian(0, distro) * (dy+2)/8, 1), target.y + round(gaussian(0, distro) * (dx+2)/8, 1), target.z)
|
||||
>>>>>>> 64851d8... Moves projectile processing to a subsystem (#30599)
|
||||
|
||||
@@ -38,9 +38,14 @@
|
||||
var/aiming_time = 12
|
||||
var/aiming_time_fire_threshold = 5
|
||||
var/aiming_time_left = 12
|
||||
<<<<<<< HEAD
|
||||
var/aiming_time_increase_user_movement = 6
|
||||
=======
|
||||
var/aiming_time_increase_user_movement = 3
|
||||
>>>>>>> 64851d8... Moves projectile processing to a subsystem (#30599)
|
||||
var/scoped_slow = 1
|
||||
var/aiming_time_increase_angle_multiplier = 0.3
|
||||
var/last_process = 0
|
||||
|
||||
var/lastangle = 0
|
||||
var/aiming_lastangle = 0
|
||||
@@ -204,7 +209,7 @@
|
||||
|
||||
/obj/item/gun/energy/beam_rifle/Initialize()
|
||||
. = ..()
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
START_PROCESSING(SSprojectiles, src)
|
||||
zoom_speed_action = new(src)
|
||||
zoom_lock_action = new(src)
|
||||
|
||||
@@ -240,7 +245,7 @@
|
||||
if(!istype(curloc))
|
||||
return
|
||||
targloc = get_turf_in_angle(lastangle, curloc, 10)
|
||||
P.preparePixelProjectile(targloc, targloc, current_user, current_user.client.mouseParams, 0)
|
||||
P.preparePixelProjectile(targloc, current_user, current_user.client.mouseParams, 0)
|
||||
P.fire(lastangle)
|
||||
|
||||
/obj/item/gun/energy/beam_rifle/process()
|
||||
@@ -248,9 +253,15 @@
|
||||
return
|
||||
check_user()
|
||||
handle_zooming()
|
||||
<<<<<<< HEAD
|
||||
aiming_time_left = min(0, aiming_time_left - (world.time - lastprocess))
|
||||
aiming_beam(TRUE)
|
||||
lastprocess = world.time
|
||||
=======
|
||||
aiming_time_left = max(0, aiming_time_left - (world.time - last_process))
|
||||
aiming_beam(TRUE)
|
||||
last_process = world.time
|
||||
>>>>>>> 64851d8... Moves projectile processing to a subsystem (#30599)
|
||||
|
||||
/obj/item/gun/energy/beam_rifle/proc/check_user(automatic_cleanup = TRUE)
|
||||
if(!istype(current_user) || !isturf(current_user.loc) || !(src in current_user.held_items) || current_user.incapacitated()) //Doesn't work if you're not holding it!
|
||||
@@ -442,7 +453,7 @@
|
||||
firing_dir = BB.firer.dir
|
||||
if(!BB.suppressed && firing_effect_type)
|
||||
new firing_effect_type(get_turf(src), firing_dir)
|
||||
BB.preparePixelProjectile(target, targloc, user, params, spread)
|
||||
BB.preparePixelProjectile(target, user, params, spread)
|
||||
BB.fire(gun? gun.lastangle : null, null)
|
||||
BB = null
|
||||
return TRUE
|
||||
@@ -638,10 +649,6 @@
|
||||
while(loc)
|
||||
if(++safety > (range * 3)) //If it's looping for way, way too long...
|
||||
return //Kill!
|
||||
if((!( current ) || loc == current))
|
||||
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
|
||||
if(!Angle)
|
||||
Angle=round(Get_Angle(src,current))
|
||||
if(spread)
|
||||
Angle += (rand() - 0.5) * spread
|
||||
var/matrix/M = new
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
|
||||
#define MOVES_HITSCAN -1 //Not actually hitscan but close as we get.
|
||||
|
||||
/obj/item/projectile
|
||||
name = "projectile"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
@@ -16,18 +19,31 @@
|
||||
var/suppressed = FALSE //Attack message
|
||||
var/yo = null
|
||||
var/xo = null
|
||||
var/current = null
|
||||
var/atom/original = null // the original target clicked
|
||||
var/turf/starting = null // the projectile's starting turf
|
||||
var/list/permutated = list() // we've passed through these atoms, don't try to hit them again
|
||||
var/paused = FALSE //for suspending the projectile midair
|
||||
var/p_x = 16
|
||||
var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center
|
||||
|
||||
//Fired processing vars
|
||||
var/fired = FALSE //Have we been fired yet
|
||||
var/paused = FALSE //for suspending the projectile midair
|
||||
var/last_projectile_move = 0
|
||||
var/last_process = 0
|
||||
var/time_offset = 0
|
||||
var/old_pixel_x = 0
|
||||
var/old_pixel_y = 0
|
||||
var/pixel_x_increment = 0
|
||||
var/pixel_y_increment = 0
|
||||
var/pixel_x_offset = 0
|
||||
var/pixel_y_offset = 0
|
||||
var/new_x = 0
|
||||
var/new_y = 0
|
||||
|
||||
var/speed = 0.8 //Amount of deciseconds it takes for projectile to travel
|
||||
var/Angle = 0
|
||||
var/nondirectional_sprite = FALSE //Set TRUE to prevent projectiles from having their sprites rotated based on firing angle
|
||||
var/spread = 0 //amount (in degrees) of projectile spread
|
||||
var/legacy = 0 //legacy projectile system
|
||||
animate_movement = 0 //Use SLIDE_STEPS in conjunction with legacy
|
||||
var/ricochets = 0
|
||||
var/ricochets_max = 2
|
||||
@@ -146,7 +162,7 @@
|
||||
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
|
||||
|
||||
/obj/item/projectile/Collide(atom/A)
|
||||
if(check_ricochet() && check_ricochet_flag(A) && ricochets < ricochets_max)
|
||||
if(check_ricochet(A) && check_ricochet_flag(A) && ricochets < ricochets_max)
|
||||
ricochets++
|
||||
if(A.handle_ricochet(src))
|
||||
ignore_source_check = TRUE
|
||||
@@ -218,9 +234,33 @@
|
||||
return FALSE
|
||||
|
||||
/obj/item/projectile/Process_Spacemove(var/movement_dir = 0)
|
||||
return 1 //Bullets don't drift in space
|
||||
return TRUE //Bullets don't drift in space
|
||||
|
||||
/obj/item/projectile/proc/fire(setAngle, atom/direct_target)
|
||||
/obj/item/projectile/process()
|
||||
last_process = world.time
|
||||
if(!loc || !fired)
|
||||
fired = FALSE
|
||||
return PROCESS_KILL
|
||||
if(paused || !isturf(loc))
|
||||
last_projectile_move += world.time - last_process //Compensates for pausing, so it doesn't become a hitscan projectile when unpaused from charged up ticks.
|
||||
return
|
||||
var/elapsed_time_deciseconds = (world.time - last_projectile_move) + time_offset
|
||||
time_offset = 0
|
||||
var/required_moves = speed > 0? Floor(elapsed_time_deciseconds / speed) : MOVES_HITSCAN //Would be better if a 0 speed made hitscan but everyone hates those so I can't make it a universal system :<
|
||||
if(required_moves == MOVES_HITSCAN)
|
||||
required_moves = SSprojectiles.global_max_tick_moves
|
||||
else
|
||||
if(required_moves > SSprojectiles.global_max_tick_moves)
|
||||
var/overrun = required_moves - SSprojectiles.global_max_tick_moves
|
||||
required_moves = SSprojectiles.global_max_tick_moves
|
||||
time_offset += overrun * speed
|
||||
time_offset += Modulus(elapsed_time_deciseconds, speed)
|
||||
|
||||
for(var/i in 1 to required_moves)
|
||||
pixel_move(required_moves)
|
||||
|
||||
/obj/item/projectile/proc/fire(angle, atom/direct_target)
|
||||
//If no angle needs to resolve it from xo/yo!
|
||||
if(!log_override && firer && original)
|
||||
add_logs(firer, original, "fired at", src, " [get_area(src)]")
|
||||
if(direct_target)
|
||||
@@ -228,84 +268,70 @@
|
||||
direct_target.bullet_act(src, def_zone)
|
||||
qdel(src)
|
||||
return
|
||||
if(isnum(setAngle))
|
||||
Angle = setAngle
|
||||
var/old_pixel_x = pixel_x
|
||||
var/old_pixel_y = pixel_y
|
||||
if(!legacy) //new projectiles
|
||||
set waitfor = 0
|
||||
var/next_run = world.time
|
||||
while(loc)
|
||||
if(paused)
|
||||
next_run = world.time
|
||||
stoplag(1)
|
||||
continue
|
||||
if(isnum(angle))
|
||||
setAngle(angle)
|
||||
if(spread)
|
||||
setAngle(Angle + ((rand() - 0.5) * spread))
|
||||
if(isnull(Angle)) //Try to resolve through offsets if there's no angle set.
|
||||
var/turf/starting = get_turf(src)
|
||||
var/turf/target = locate(Clamp(starting + xo, 1, world.maxx), Clamp(starting + yo, 1, world.maxy), starting.z)
|
||||
setAngle(Get_Angle(src, target))
|
||||
if(!nondirectional_sprite)
|
||||
var/matrix/M = new
|
||||
M.Turn(Angle)
|
||||
transform = M
|
||||
old_pixel_x = pixel_x
|
||||
old_pixel_y = pixel_y
|
||||
last_projectile_move = world.time
|
||||
fired = TRUE
|
||||
if(!isprocessing)
|
||||
START_PROCESSING(SSprojectiles, src)
|
||||
|
||||
if((!( current ) || loc == current))
|
||||
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
|
||||
/obj/item/projectile/proc/setAngle(new_angle) //wrapper for overrides.
|
||||
Angle = new_angle
|
||||
return TRUE
|
||||
|
||||
if(!Angle)
|
||||
Angle=round(Get_Angle(src,current))
|
||||
if(spread)
|
||||
Angle += (rand() - 0.5) * spread
|
||||
if(!nondirectional_sprite)
|
||||
var/matrix/M = new
|
||||
M.Turn(Angle)
|
||||
transform = M
|
||||
/obj/item/projectile/proc/pixel_move(moves)
|
||||
if(!nondirectional_sprite)
|
||||
var/matrix/M = new
|
||||
M.Turn(Angle)
|
||||
transform = M
|
||||
|
||||
var/Pixel_x=round((sin(Angle)+16*sin(Angle)*2), 1) //round() is a floor operation when only one argument is supplied, we don't want that here
|
||||
var/Pixel_y=round((cos(Angle)+16*cos(Angle)*2), 1)
|
||||
var/pixel_x_offset = old_pixel_x + Pixel_x
|
||||
var/pixel_y_offset = old_pixel_y + Pixel_y
|
||||
var/new_x = x
|
||||
var/new_y = y
|
||||
pixel_x_increment=round((sin(Angle)+16*sin(Angle)*2), 1) //round() is a floor operation when only one argument is supplied, we don't want that here
|
||||
pixel_y_increment=round((cos(Angle)+16*cos(Angle)*2), 1)
|
||||
pixel_x_offset = old_pixel_x + pixel_x_increment
|
||||
pixel_y_offset = old_pixel_y + pixel_y_increment
|
||||
new_x = x
|
||||
new_y = y
|
||||
|
||||
while(pixel_x_offset > 16)
|
||||
pixel_x_offset -= 32
|
||||
old_pixel_x -= 32
|
||||
new_x++// x++
|
||||
while(pixel_x_offset < -16)
|
||||
pixel_x_offset += 32
|
||||
old_pixel_x += 32
|
||||
new_x--
|
||||
while(pixel_y_offset > 16)
|
||||
pixel_y_offset -= 32
|
||||
old_pixel_y -= 32
|
||||
new_y++
|
||||
while(pixel_y_offset < -16)
|
||||
pixel_y_offset += 32
|
||||
old_pixel_y += 32
|
||||
new_y--
|
||||
while(pixel_x_offset > 16)
|
||||
pixel_x_offset -= 32
|
||||
old_pixel_x -= 32
|
||||
new_x++// x++
|
||||
while(pixel_x_offset < -16)
|
||||
pixel_x_offset += 32
|
||||
old_pixel_x += 32
|
||||
new_x--
|
||||
while(pixel_y_offset > 16)
|
||||
pixel_y_offset -= 32
|
||||
old_pixel_y -= 32
|
||||
new_y++
|
||||
while(pixel_y_offset < -16)
|
||||
pixel_y_offset += 32
|
||||
old_pixel_y += 32
|
||||
new_y--
|
||||
|
||||
pixel_x = old_pixel_x
|
||||
pixel_y = old_pixel_y
|
||||
step_towards(src, locate(new_x, new_y, z))
|
||||
next_run += max(world.tick_lag, speed)
|
||||
var/delay = next_run - world.time
|
||||
if(delay <= world.tick_lag*2)
|
||||
pixel_x = pixel_x_offset
|
||||
pixel_y = pixel_y_offset
|
||||
else
|
||||
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (delay <= 3 ? delay - 1 : delay)), flags = ANIMATION_END_NOW)
|
||||
old_pixel_x = pixel_x_offset
|
||||
old_pixel_y = pixel_y_offset
|
||||
if(can_hit_target(original, permutated))
|
||||
Collide(original)
|
||||
Range()
|
||||
if (delay > 0)
|
||||
sleep(delay)
|
||||
|
||||
else //old projectile system
|
||||
set waitfor = 0
|
||||
while(loc)
|
||||
if(!paused)
|
||||
if((!( current ) || loc == current))
|
||||
current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z)
|
||||
step_towards(src, current)
|
||||
if(can_hit_target(original, permutated))
|
||||
Collide(original)
|
||||
Range()
|
||||
sleep(CONFIG_GET(number/run_delay) * 0.9)
|
||||
step_towards(src, locate(new_x, new_y, z))
|
||||
pixel_x = old_pixel_x
|
||||
pixel_y = old_pixel_y
|
||||
//var/animation_time = ((SSprojectiles.flags & SS_TICKER? (SSprojectiles.wait * world.tick_lag) : SSprojectiles.wait) / moves)
|
||||
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = 1, flags = ANIMATION_END_NOW)
|
||||
old_pixel_x = pixel_x_offset
|
||||
old_pixel_y = pixel_y_offset
|
||||
if(can_hit_target(original, permutated))
|
||||
Collide(original)
|
||||
Range()
|
||||
last_projectile_move = world.time
|
||||
|
||||
//Returns true if the target atom is on our current turf and above the right layer
|
||||
/obj/item/projectile/proc/can_hit_target(atom/target, var/list/passthrough)
|
||||
@@ -315,21 +341,26 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/projectile/proc/preparePixelProjectile(atom/target, var/turf/targloc, mob/living/user, params, spread)
|
||||
var/turf/curloc = get_turf(user)
|
||||
forceMove(get_turf(user))
|
||||
starting = get_turf(user)
|
||||
current = curloc
|
||||
/obj/item/projectile/proc/preparePixelProjectile(atom/target, atom/source, params, spread = 0)
|
||||
var/turf/curloc = get_turf(source)
|
||||
var/turf/targloc = get_turf(target)
|
||||
forceMove(get_turf(source))
|
||||
starting = get_turf(source)
|
||||
original = target
|
||||
yo = targloc.y - curloc.y
|
||||
xo = targloc.x - curloc.x
|
||||
|
||||
var/list/calculated = calculate_projectile_angle_and_pixel_offsets(user, params)
|
||||
Angle = calculated[1]
|
||||
p_x = calculated[2]
|
||||
p_y = calculated[3]
|
||||
if(isliving(source) && params)
|
||||
var/list/calculated = calculate_projectile_angle_and_pixel_offsets(source, params)
|
||||
p_x = calculated[2]
|
||||
p_y = calculated[3]
|
||||
|
||||
if(spread)
|
||||
src.Angle += spread
|
||||
if(spread)
|
||||
setAngle(calculated[1] + spread)
|
||||
else
|
||||
setAngle(calculated[1])
|
||||
else
|
||||
setAngle(Get_Angle(src, targloc))
|
||||
|
||||
/proc/calculate_projectile_angle_and_pixel_offsets(mob/user, params)
|
||||
var/list/mouse_control = params2list(params)
|
||||
@@ -366,6 +397,7 @@
|
||||
Collide(AM)
|
||||
|
||||
/obj/item/projectile/Destroy()
|
||||
STOP_PROCESSING(SSprojectiles, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/experience_pressure_difference()
|
||||
|
||||
@@ -95,8 +95,6 @@
|
||||
name = "emitter beam"
|
||||
icon_state = "emitter"
|
||||
damage = 30
|
||||
legacy = 1
|
||||
animate_movement = SLIDE_STEPS
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
|
||||
@@ -8,12 +8,6 @@
|
||||
hitsound_wall = "ricochet"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect
|
||||
|
||||
/obj/item/projectile/bullet/pellet/shotgun_buckshot/Range()
|
||||
..()
|
||||
damage -= 0.75
|
||||
if(damage < 0)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/bullet/incendiary
|
||||
damage = 20
|
||||
var/fire_stacks = 4
|
||||
@@ -39,7 +33,7 @@
|
||||
damage = 60
|
||||
|
||||
// 7.62 (Nagant Rifle)
|
||||
|
||||
|
||||
/obj/item/projectile/bullet/a762
|
||||
name = "7.62 bullet"
|
||||
damage = 60
|
||||
@@ -156,7 +150,7 @@
|
||||
|
||||
/obj/item/projectile/bullet/p50
|
||||
name =".50 bullet"
|
||||
speed = 0 //360 alwaysscope.
|
||||
speed = 0.4
|
||||
damage = 70
|
||||
knockdown = 100
|
||||
dismemberment = 50
|
||||
@@ -272,15 +266,30 @@
|
||||
explosion(target, -1, 0, 1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/projectile/bullet/pellet
|
||||
var/tile_dropoff = 0.75
|
||||
var/tile_dropoff_s = 1.25
|
||||
|
||||
/obj/item/projectile/bullet/pellet/shotgun_buckshot
|
||||
name = "buckshot pellet"
|
||||
damage = 12.5
|
||||
|
||||
/obj/item/projectile/bullet/pellet/shotgun_rubbershot
|
||||
name = "rubbershot pellet"
|
||||
damage = 3
|
||||
stamina = 25
|
||||
|
||||
/obj/item/projectile/bullet/pellet/Range()
|
||||
..()
|
||||
if(damage > 0)
|
||||
damage -= tile_dropoff
|
||||
if(stamina > 0)
|
||||
stamina -= tile_dropoff_s
|
||||
if(damage < 0 && stamina < 0)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/bullet/pellet/shotgun_improvised
|
||||
tile_dropoff = 0.55 //Come on it does 6 damage don't be like that.
|
||||
damage = 6
|
||||
|
||||
/obj/item/projectile/bullet/pellet/shotgun_improvised/Initialize()
|
||||
|
||||
Reference in New Issue
Block a user