|
|
|
@@ -4,9 +4,6 @@
|
|
|
|
|
#define ZOOM_LOCK_CENTER_VIEW 2
|
|
|
|
|
#define ZOOM_LOCK_OFF 3
|
|
|
|
|
|
|
|
|
|
#define ZOOM_SPEED_STEP 0
|
|
|
|
|
#define ZOOM_SPEED_INSTANT 1
|
|
|
|
|
|
|
|
|
|
#define AUTOZOOM_PIXEL_STEP_FACTOR 48
|
|
|
|
|
|
|
|
|
|
#define AIMING_BEAM_ANGLE_CHANGE_THRESHOLD 0.1
|
|
|
|
@@ -45,7 +42,7 @@
|
|
|
|
|
var/lastangle = 0
|
|
|
|
|
var/aiming_lastangle = 0
|
|
|
|
|
var/mob/current_user = null
|
|
|
|
|
var/obj/effect/projectile_beam/current_tracer
|
|
|
|
|
var/list/obj/effect/projectile_beam/current_tracers
|
|
|
|
|
|
|
|
|
|
var/structure_piercing = 2 //Amount * 2. For some reason structures aren't respecting this unless you have it doubled. Probably with the objects in question's Bump() code instead of this but I'll deal with this later.
|
|
|
|
|
var/structure_bleed_coeff = 0.7
|
|
|
|
@@ -64,14 +61,11 @@
|
|
|
|
|
var/delay = 65
|
|
|
|
|
var/lastfire = 0
|
|
|
|
|
|
|
|
|
|
var/lastprocess = 0
|
|
|
|
|
|
|
|
|
|
//ZOOMING
|
|
|
|
|
var/zoom_current_view_increase = 0
|
|
|
|
|
var/zoom_target_view_increase = 10
|
|
|
|
|
var/zoom_speed = ZOOM_SPEED_STEP
|
|
|
|
|
var/zooming = FALSE
|
|
|
|
|
var/zoom_lock = ZOOM_LOCK_AUTOZOOM_FREEMOVE
|
|
|
|
|
var/zoom_lock = ZOOM_LOCK_OFF
|
|
|
|
|
var/zooming_angle
|
|
|
|
|
var/current_zoom_x = 0
|
|
|
|
|
var/current_zoom_y = 0
|
|
|
|
@@ -80,7 +74,6 @@
|
|
|
|
|
var/static/image/charged_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_charged")
|
|
|
|
|
var/static/image/drained_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_empty")
|
|
|
|
|
|
|
|
|
|
var/datum/action/item_action/zoom_speed_action/zoom_speed_action
|
|
|
|
|
var/datum/action/item_action/zoom_lock_action/zoom_lock_action
|
|
|
|
|
|
|
|
|
|
/obj/item/gun/energy/beam_rifle/debug
|
|
|
|
@@ -103,15 +96,6 @@
|
|
|
|
|
. = ..()
|
|
|
|
|
|
|
|
|
|
/obj/item/gun/energy/beam_rifle/ui_action_click(owner, action)
|
|
|
|
|
if(istype(action, /datum/action/item_action/zoom_speed_action))
|
|
|
|
|
zoom_speed++
|
|
|
|
|
if(zoom_speed > 1)
|
|
|
|
|
zoom_speed = ZOOM_SPEED_STEP
|
|
|
|
|
switch(zoom_speed)
|
|
|
|
|
if(ZOOM_SPEED_STEP)
|
|
|
|
|
to_chat(owner, "<span class='boldnotice'>You switch [src]'s digital zoom to stepper mode.</span>")
|
|
|
|
|
if(ZOOM_SPEED_INSTANT)
|
|
|
|
|
to_chat(owner, "<span class='boldnotice'>You switch [src]'s digital zoom to instant mode.</span>")
|
|
|
|
|
if(istype(action, /datum/action/item_action/zoom_lock_action))
|
|
|
|
|
zoom_lock++
|
|
|
|
|
if(zoom_lock > 3)
|
|
|
|
@@ -135,8 +119,6 @@
|
|
|
|
|
var/total_time = SSfastprocess.wait
|
|
|
|
|
if(delay_override)
|
|
|
|
|
total_time = delay_override
|
|
|
|
|
if(zoom_speed == ZOOM_SPEED_INSTANT)
|
|
|
|
|
total_time = 0
|
|
|
|
|
zoom_animating = total_time
|
|
|
|
|
animate(current_user.client, pixel_x = current_zoom_x, pixel_y = current_zoom_y , total_time, SINE_EASING, ANIMATION_PARALLEL)
|
|
|
|
|
zoom_animating = 0
|
|
|
|
@@ -150,18 +132,10 @@
|
|
|
|
|
/obj/item/gun/energy/beam_rifle/proc/handle_zooming()
|
|
|
|
|
if(!zooming || !check_user())
|
|
|
|
|
return
|
|
|
|
|
if(zoom_speed == ZOOM_SPEED_INSTANT)
|
|
|
|
|
current_user.client.change_view(world.view + zoom_target_view_increase)
|
|
|
|
|
zoom_current_view_increase = zoom_target_view_increase
|
|
|
|
|
set_autozoom_pixel_offsets_immediate(zooming_angle)
|
|
|
|
|
smooth_zooming()
|
|
|
|
|
return
|
|
|
|
|
if(zoom_current_view_increase > zoom_target_view_increase)
|
|
|
|
|
return
|
|
|
|
|
zoom_current_view_increase++
|
|
|
|
|
current_user.client.change_view(zoom_current_view_increase + world.view)
|
|
|
|
|
current_user.client.change_view(world.view + zoom_target_view_increase)
|
|
|
|
|
zoom_current_view_increase = zoom_target_view_increase
|
|
|
|
|
set_autozoom_pixel_offsets_immediate(zooming_angle)
|
|
|
|
|
smooth_zooming(SSfastprocess.wait * zoom_target_view_increase * zoom_speed)
|
|
|
|
|
smooth_zooming()
|
|
|
|
|
|
|
|
|
|
/obj/item/gun/energy/beam_rifle/proc/start_zooming()
|
|
|
|
|
if(zoom_lock == ZOOM_LOCK_OFF)
|
|
|
|
@@ -169,8 +143,9 @@
|
|
|
|
|
zooming = TRUE
|
|
|
|
|
|
|
|
|
|
/obj/item/gun/energy/beam_rifle/proc/stop_zooming()
|
|
|
|
|
zooming = FALSE
|
|
|
|
|
reset_zooming()
|
|
|
|
|
if(zooming)
|
|
|
|
|
zooming = FALSE
|
|
|
|
|
reset_zooming()
|
|
|
|
|
|
|
|
|
|
/obj/item/gun/energy/beam_rifle/proc/reset_zooming()
|
|
|
|
|
if(!check_user(FALSE))
|
|
|
|
@@ -204,14 +179,14 @@
|
|
|
|
|
|
|
|
|
|
/obj/item/gun/energy/beam_rifle/Initialize()
|
|
|
|
|
. = ..()
|
|
|
|
|
current_tracers = list()
|
|
|
|
|
START_PROCESSING(SSprojectiles, src)
|
|
|
|
|
zoom_speed_action = new(src)
|
|
|
|
|
zoom_lock_action = new(src)
|
|
|
|
|
|
|
|
|
|
/obj/item/gun/energy/beam_rifle/Destroy()
|
|
|
|
|
STOP_PROCESSING(SSfastprocess, src)
|
|
|
|
|
set_user(null)
|
|
|
|
|
QDEL_NULL(current_tracer)
|
|
|
|
|
QDEL_LIST(current_tracers)
|
|
|
|
|
return ..()
|
|
|
|
|
|
|
|
|
|
/obj/item/gun/energy/beam_rifle/emp_act(severity)
|
|
|
|
@@ -245,6 +220,7 @@
|
|
|
|
|
|
|
|
|
|
/obj/item/gun/energy/beam_rifle/process()
|
|
|
|
|
if(!aiming)
|
|
|
|
|
last_process = world.time
|
|
|
|
|
return
|
|
|
|
|
check_user()
|
|
|
|
|
handle_zooming()
|
|
|
|
@@ -299,7 +275,7 @@
|
|
|
|
|
set waitfor = FALSE
|
|
|
|
|
aiming_time_left = aiming_time
|
|
|
|
|
aiming = FALSE
|
|
|
|
|
QDEL_NULL(current_tracer)
|
|
|
|
|
QDEL_LIST(current_tracers)
|
|
|
|
|
stop_zooming()
|
|
|
|
|
|
|
|
|
|
/obj/item/gun/energy/beam_rifle/proc/set_user(mob/user)
|
|
|
|
@@ -341,7 +317,7 @@
|
|
|
|
|
sync_ammo()
|
|
|
|
|
afterattack(M.client.mouseObject, M, FALSE, M.client.mouseParams, passthrough = TRUE)
|
|
|
|
|
stop_aiming()
|
|
|
|
|
QDEL_NULL(current_tracer)
|
|
|
|
|
QDEL_LIST(current_tracers)
|
|
|
|
|
return ..()
|
|
|
|
|
|
|
|
|
|
/obj/item/gun/energy/beam_rifle/afterattack(atom/target, mob/living/user, flag, params, passthrough = FALSE)
|
|
|
|
@@ -555,136 +531,103 @@
|
|
|
|
|
handle_impact(target)
|
|
|
|
|
|
|
|
|
|
/obj/item/projectile/beam/beam_rifle/Collide(atom/target)
|
|
|
|
|
paused = TRUE
|
|
|
|
|
if(check_pierce(target))
|
|
|
|
|
permutated += target
|
|
|
|
|
return FALSE
|
|
|
|
|
if(!QDELETED(target))
|
|
|
|
|
cached = get_turf(target)
|
|
|
|
|
paused = FALSE
|
|
|
|
|
. = ..()
|
|
|
|
|
|
|
|
|
|
/obj/item/projectile/beam/beam_rifle/on_hit(atom/target, blocked = FALSE)
|
|
|
|
|
paused = TRUE
|
|
|
|
|
if(!QDELETED(target))
|
|
|
|
|
cached = get_turf(target)
|
|
|
|
|
handle_hit(target)
|
|
|
|
|
paused = FALSE
|
|
|
|
|
. = ..()
|
|
|
|
|
|
|
|
|
|
/obj/item/projectile/beam/beam_rifle/hitscan
|
|
|
|
|
icon_state = ""
|
|
|
|
|
var/tracer_type = /obj/effect/projectile_beam/tracer
|
|
|
|
|
var/starting_z
|
|
|
|
|
var/starting_p_x
|
|
|
|
|
var/starting_p_y
|
|
|
|
|
var/list/beam_segments //assoc list of datum/point or datum/point/vector, start = end.
|
|
|
|
|
var/constant_tracer = FALSE
|
|
|
|
|
var/travelled_p_x = 0
|
|
|
|
|
var/travelled_p_y = 0
|
|
|
|
|
var/tracer_spawned = FALSE
|
|
|
|
|
var/beam_index
|
|
|
|
|
|
|
|
|
|
/obj/item/projectile/beam/beam_rifle/hitscan/Destroy()
|
|
|
|
|
paused = TRUE //STOP HITTING WHEN YOU'RE ALREADY BEING DELETED!
|
|
|
|
|
spawn_tracer(constant_tracer)
|
|
|
|
|
if(loc)
|
|
|
|
|
var/datum/point/pcache = trajectory.copy_to()
|
|
|
|
|
beam_segments[beam_index] = pcache
|
|
|
|
|
generate_tracers(constant_tracer)
|
|
|
|
|
return ..()
|
|
|
|
|
|
|
|
|
|
/obj/item/projectile/beam/beam_rifle/hitscan/proc/spawn_tracer(put_in_rifle = FALSE)
|
|
|
|
|
if(tracer_spawned)
|
|
|
|
|
return
|
|
|
|
|
tracer_spawned = TRUE
|
|
|
|
|
//Remind me to port baystation trajectories so this shit isn't needed...
|
|
|
|
|
var/pixels_travelled = round(sqrt(travelled_p_x**2 + travelled_p_y**2),1)
|
|
|
|
|
var/scaling = pixels_travelled/world.icon_size
|
|
|
|
|
var/midpoint_p_x = round(starting_p_x + (travelled_p_x / 2))
|
|
|
|
|
var/midpoint_p_y = round(starting_p_y + (travelled_p_y / 2))
|
|
|
|
|
var/tracer_px = midpoint_p_x % world.icon_size
|
|
|
|
|
var/tracer_py = midpoint_p_y % world.icon_size
|
|
|
|
|
var/tracer_lx = (midpoint_p_x - tracer_px) / world.icon_size
|
|
|
|
|
var/tracer_ly = (midpoint_p_y - tracer_py) / world.icon_size
|
|
|
|
|
var/obj/effect/projectile_beam/PB = new tracer_type(src)
|
|
|
|
|
PB.apply_vars(Angle, tracer_px, tracer_py, color, scaling, locate(tracer_lx,tracer_ly,starting_z))
|
|
|
|
|
if(put_in_rifle && istype(gun))
|
|
|
|
|
if(gun.current_tracer)
|
|
|
|
|
QDEL_NULL(gun.current_tracer)
|
|
|
|
|
gun.current_tracer = PB
|
|
|
|
|
else
|
|
|
|
|
QDEL_IN(PB, 5)
|
|
|
|
|
/obj/item/projectile/beam/beam_rifle/hitscan/Collide(atom/target)
|
|
|
|
|
var/datum/point/pcache = trajectory.copy_to()
|
|
|
|
|
. = ..()
|
|
|
|
|
if(. && !QDELETED(src)) //successful touch and not destroyed.
|
|
|
|
|
beam_segments[beam_index] = pcache
|
|
|
|
|
beam_index = pcache
|
|
|
|
|
beam_segments[beam_index] = null
|
|
|
|
|
|
|
|
|
|
/obj/item/projectile/beam/beam_rifle/hitscan/proc/check_for_turf_edge(turf/T)
|
|
|
|
|
if(!istype(T))
|
|
|
|
|
return TRUE
|
|
|
|
|
var/tx = T.x
|
|
|
|
|
var/ty = T.y
|
|
|
|
|
if(tx < 10 || tx > (world.maxx - 10) || ty < 10 || ty > (world.maxy-10))
|
|
|
|
|
return TRUE
|
|
|
|
|
return FALSE
|
|
|
|
|
/obj/item/projectile/beam/beam_rifle/hitscan/before_z_change(turf/oldloc, turf/newloc)
|
|
|
|
|
var/datum/point/pcache = trajectory.copy_to()
|
|
|
|
|
beam_segments[beam_index] = pcache
|
|
|
|
|
beam_index = RETURN_PRECISE_POINT(newloc)
|
|
|
|
|
beam_segments[beam_index] = null
|
|
|
|
|
return ..()
|
|
|
|
|
|
|
|
|
|
/obj/item/projectile/beam/beam_rifle/hitscan/proc/generate_tracers(highlander = FALSE, cleanup = TRUE)
|
|
|
|
|
set waitfor = FALSE
|
|
|
|
|
if(highlander && istype(gun))
|
|
|
|
|
QDEL_LIST(gun.current_tracers)
|
|
|
|
|
for(var/datum/point/p in beam_segments)
|
|
|
|
|
gun.current_tracers += generate_projectile_beam_between_points(p, beam_segments[p], tracer_type, color, 0)
|
|
|
|
|
else
|
|
|
|
|
for(var/datum/point/p in beam_segments)
|
|
|
|
|
generate_projectile_beam_between_points(p, beam_segments[p], tracer_type, color, 5)
|
|
|
|
|
if(cleanup)
|
|
|
|
|
QDEL_LIST(beam_segments)
|
|
|
|
|
beam_segments = null
|
|
|
|
|
QDEL_NULL(beam_index)
|
|
|
|
|
|
|
|
|
|
/obj/item/projectile/beam/beam_rifle/hitscan/fire(setAngle, atom/direct_target) //oranges didn't let me make this a var the first time around so copypasta time
|
|
|
|
|
set waitfor = 0
|
|
|
|
|
set waitfor = FALSE
|
|
|
|
|
var/turf/starting = get_turf(src)
|
|
|
|
|
trajectory = new(starting.x, starting.y, starting.z, 0, 0, setAngle? setAngle : Angle, 33)
|
|
|
|
|
if(!log_override && firer && original)
|
|
|
|
|
add_logs(firer, original, "fired at", src, " [get_area(src)]")
|
|
|
|
|
fired = TRUE
|
|
|
|
|
if(setAngle)
|
|
|
|
|
Angle = setAngle
|
|
|
|
|
var/next_run = world.time
|
|
|
|
|
var/old_pixel_x = pixel_x
|
|
|
|
|
var/old_pixel_y = pixel_y
|
|
|
|
|
var/safety = 0 //The code works fine, but... just in case...
|
|
|
|
|
var/turf/c2
|
|
|
|
|
var/starting_x = loc.x
|
|
|
|
|
var/starting_y = loc.y
|
|
|
|
|
starting_z = loc.z
|
|
|
|
|
starting_p_x = starting_x * world.icon_size + pixel_x
|
|
|
|
|
starting_p_y = starting_y * world.icon_size + pixel_y
|
|
|
|
|
beam_segments = list() //initialize segment list with the list for the first segment
|
|
|
|
|
beam_index = RETURN_PRECISE_POINT(src)
|
|
|
|
|
beam_segments[beam_index] = null //record start.
|
|
|
|
|
if(spread)
|
|
|
|
|
Angle += (rand() - 0.5) * spread
|
|
|
|
|
while(loc)
|
|
|
|
|
if(paused || QDELETED(src))
|
|
|
|
|
return
|
|
|
|
|
if(++safety > (range * 3)) //If it's looping for way, way too long...
|
|
|
|
|
qdel(src)
|
|
|
|
|
stack_trace("WARNING: [type] projectile encountered infinite recursion in [__FILE__]/[__LINE__]!")
|
|
|
|
|
return //Kill!
|
|
|
|
|
if(spread)
|
|
|
|
|
Angle += (rand() - 0.5) * spread
|
|
|
|
|
var/matrix/M = new
|
|
|
|
|
M.Turn(Angle)
|
|
|
|
|
transform = M
|
|
|
|
|
var/Pixel_x=sin(Angle)+16*sin(Angle)*2
|
|
|
|
|
var/Pixel_y=cos(Angle)+16*cos(Angle)*2
|
|
|
|
|
travelled_p_x += Pixel_x
|
|
|
|
|
travelled_p_y += Pixel_y
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
trajectory.increment()
|
|
|
|
|
var/turf/T = trajectory.return_turf()
|
|
|
|
|
if(T.z != loc.z)
|
|
|
|
|
before_z_change(loc, T)
|
|
|
|
|
trajectory_ignore_forcemove = TRUE
|
|
|
|
|
forceMove(T)
|
|
|
|
|
trajectory_ignore_forcemove = FALSE
|
|
|
|
|
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
|
|
|
|
|
step_towards(src, T)
|
|
|
|
|
animate(src, pixel_x = trajectory.return_px(), pixel_y = trajectory.return_py(), time = 1, flags = ANIMATION_END_NOW)
|
|
|
|
|
|
|
|
|
|
if(can_hit_target(original, permutated))
|
|
|
|
|
Collide(original)
|
|
|
|
|
c2 = loc
|
|
|
|
|
Range()
|
|
|
|
|
if(check_for_turf_edge(loc))
|
|
|
|
|
spawn_tracer(constant_tracer)
|
|
|
|
|
c2 = get_turf(src)
|
|
|
|
|
if(istype(c2))
|
|
|
|
|
cached = c2
|
|
|
|
|
|
|
|
|
@@ -704,38 +647,3 @@
|
|
|
|
|
/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/on_hit()
|
|
|
|
|
qdel(src)
|
|
|
|
|
return FALSE
|
|
|
|
|
|
|
|
|
|
/obj/effect/projectile_beam
|
|
|
|
|
icon = 'icons/obj/projectiles.dmi'
|
|
|
|
|
layer = ABOVE_MOB_LAYER
|
|
|
|
|
anchored = TRUE
|
|
|
|
|
light_power = 1
|
|
|
|
|
light_range = 2
|
|
|
|
|
light_color = "#00ffff"
|
|
|
|
|
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
|
|
|
|
flags_1 = ABSTRACT_1
|
|
|
|
|
appearance_flags = 0
|
|
|
|
|
|
|
|
|
|
/obj/effect/projectile_beam/tracer
|
|
|
|
|
icon_state = "tracer_beam"
|
|
|
|
|
|
|
|
|
|
/obj/effect/projectile_beam/tracer/aiming
|
|
|
|
|
icon_state = "gbeam"
|
|
|
|
|
|
|
|
|
|
/datum/action/item_action/zoom_speed_action
|
|
|
|
|
name = "Toggle Zooming Speed"
|
|
|
|
|
icon_icon = 'icons/mob/actions/actions_spells.dmi'
|
|
|
|
|
button_icon_state = "projectile"
|
|
|
|
|
background_icon_state = "bg_tech"
|
|
|
|
|
|
|
|
|
|
/datum/action/item_action/zoom_lock_action
|
|
|
|
|
name = "Switch Zoom Mode"
|
|
|
|
|
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
|
|
|
|
button_icon_state = "zoom_mode"
|
|
|
|
|
background_icon_state = "bg_tech"
|
|
|
|
|
|
|
|
|
|
/obj/effect/projectile_beam/singularity_pull()
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
/obj/effect/projectile_beam/singularity_act()
|
|
|
|
|
return
|
|
|
|
|