Adds a scope component, removes old zooming and adds sniper marksman ammo. (#66218)

Removes the old sniper rifle zoom, replaces it with a scope component. the scope activates on right click and lets your camera follow your mouse.
https://streamable.com/2c63u4 (due to byond rounding some shots were weirdly missed in that video, its fixed now)
Also adds sniper marksman ammo to the nukie uplink. It does slightly less damage, but it is hitscan and has one guaranteed ricochet shot, so you can shoot a wall and it could still hit someone.
This commit is contained in:
Fikou
2022-04-25 15:03:49 -07:00
committed by GitHub
parent a156d7e3d0
commit 742b272f52
20 changed files with 247 additions and 94 deletions
@@ -18,3 +18,8 @@
name = ".50 penetrator round bullet casing"
desc = "A .50 caliber penetrator round casing."
projectile_type = /obj/projectile/bullet/p50/penetrator
/obj/item/ammo_casing/p50/marksman
name = ".50 marksman round bullet casing"
desc = "A .50 caliber marksman round casing."
projectile_type = /obj/projectile/bullet/p50/marksman
@@ -23,3 +23,9 @@
desc = "An extremely powerful round capable of passing straight through cover and anyone unfortunate enough to be behind it."
ammo_type = /obj/item/ammo_casing/p50/penetrator
max_ammo = 5
/obj/item/ammo_box/magazine/sniper_rounds/marksman
name = "sniper rounds (marksman)"
desc = "An extremely fast sniper round able to pretty much instantly shoot through something."
ammo_type = /obj/item/ammo_casing/p50/marksman
max_ammo = 5
+2 -87
View File
@@ -71,12 +71,6 @@
var/flight_x_offset = 0
var/flight_y_offset = 0
//Zooming
var/zoomable = FALSE //whether the gun generates a Zoom action on creation
var/zoomed = FALSE //Zoom toggle
var/zoom_amt = 3 //Distance in TURFs to move the user's screen forward (the "zoom" effect)
var/zoom_out_amt = 0
var/datum/action/toggle_scope_zoom/azoom
var/pb_knockback = 0
/obj/item/gun/Initialize(mapload)
@@ -85,7 +79,6 @@
pin = new pin(src)
if(gun_light)
alight = new(src)
build_zooming()
/obj/item/gun/Destroy()
if(isobj(pin)) //Can still be the initial path, then we skip
@@ -96,8 +89,6 @@
QDEL_NULL(bayonet)
if(chambered) //Not all guns are chambered (EMP'ed energy guns etc)
QDEL_NULL(chambered)
if(azoom)
QDEL_NULL(azoom)
if(isatom(suppressed)) //SUPPRESSED IS USED AS BOTH A TRUE/FALSE AND AS A REF, WHAT THE FUCKKKKKKKKKKKKKKKKK
QDEL_NULL(suppressed)
return ..()
@@ -146,11 +137,6 @@
if(can_bayonet)
. += "It has a <b>bayonet</b> lug on it."
/obj/item/gun/equipped(mob/living/user, slot)
. = ..()
if(zoomed && user.get_active_held_item() != src)
zoom(user, user.dir, FALSE) //we can only stay zoomed in if it's in our hands //yeah and we only unzoom if we're actually zoomed using the gun!!
//called after the gun has successfully fired its chambered ammo.
/obj/item/gun/proc/process_chamber(empty_chamber = TRUE, from_firing = TRUE, chamber_next_round = TRUE)
handle_chamber(empty_chamber, from_firing, chamber_next_round)
@@ -225,6 +211,8 @@
return
if(firing_burst)
return
if(SEND_SIGNAL(src, COMSIG_GUN_TRY_FIRE, user, target, flag, params) & COMPONENT_CANCEL_GUN_FIRE)
return
if(flag) //It's adjacent, is the user, or is on the user's person
if(target in user.contents) //can't shoot stuff inside us.
return
@@ -603,18 +591,6 @@
update_appearance()
update_action_buttons()
/obj/item/gun/pickup(mob/user)
..()
if(azoom)
azoom.Grant(user)
/obj/item/gun/dropped(mob/user)
. = ..()
if(azoom)
azoom.Remove(user)
if(zoomed)
zoom(user, user.dir, FALSE)
/obj/item/gun/update_overlays()
. = ..()
if(gun_light)
@@ -687,66 +663,5 @@
/obj/item/gun/proc/before_firing(atom/target,mob/user)
return
/////////////
// ZOOMING //
/////////////
/datum/action/toggle_scope_zoom
name = "Toggle Scope"
check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_LYING
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "sniper_zoom"
var/obj/item/gun/gun = null
/datum/action/toggle_scope_zoom/Trigger(trigger_flags)
. = ..()
if(!.)
return
gun.zoom(owner, owner.dir)
/datum/action/toggle_scope_zoom/IsAvailable()
. = ..()
if(owner.get_active_held_item() != gun)
. = FALSE
if(!. && gun)
gun.zoom(owner, owner.dir, FALSE)
/datum/action/toggle_scope_zoom/Remove(mob/living/L)
gun.zoom(L, L.dir, FALSE)
..()
/obj/item/gun/proc/rotate(atom/thing, old_dir, new_dir)
SIGNAL_HANDLER
if(ismob(thing))
var/mob/lad = thing
lad.client.view_size.zoomOut(zoom_out_amt, zoom_amt, new_dir)
/obj/item/gun/proc/zoom(mob/living/user, direc, forced_zoom)
if(!user || !user.client)
return
if(isnull(forced_zoom))
zoomed = !zoomed
else
zoomed = forced_zoom
if(zoomed)
RegisterSignal(user, COMSIG_ATOM_DIR_CHANGE, .proc/rotate)
user.client.view_size.zoomOut(zoom_out_amt, zoom_amt, direc)
else
UnregisterSignal(user, COMSIG_ATOM_DIR_CHANGE)
user.client.view_size.zoomIn()
return zoomed
//Proc, so that gun accessories/scopes/etc. can easily add zooming.
/obj/item/gun/proc/build_zooming()
if(azoom)
return
if(zoomable)
azoom = new()
azoom.gun = src
#undef FIRING_PIN_REMOVAL_DELAY
#undef DUALWIELD_PENALTY_EXTRA_MULTIPLIER
@@ -350,15 +350,16 @@
fire_delay = 40
burst_size = 1
w_class = WEIGHT_CLASS_NORMAL
zoomable = TRUE
zoom_amt = 10 //Long range, enough to see in front of you, but no tiles behind you.
zoom_out_amt = 5
slot_flags = ITEM_SLOT_BACK
actions_types = list()
mag_display = TRUE
suppressor_x_offset = 3
suppressor_y_offset = 3
/obj/item/gun/ballistic/automatic/sniper_rifle/Initialize(mapload)
. = ..()
AddComponent(/datum/component/scope, range_modifier = 2)
/obj/item/gun/ballistic/automatic/sniper_rifle/syndicate
name = "syndicate sniper rifle"
desc = "An illegally modified .50 cal sniper rifle with suppression compatibility. Quickscoping still doesn't work."
+3 -1
View File
@@ -94,6 +94,8 @@
var/ricochet_auto_aim_angle = 30
/// the angle of impact must be within this many degrees of the struck surface, set to 0 to allow any angle
var/ricochet_incidence_leeway = 40
/// Can our ricochet autoaim hit our firer?
var/ricochet_shoots_firer = TRUE
///If the object being hit can pass ths damage on to something else, it should not do it for this bullet
var/force_hit = FALSE
@@ -325,7 +327,7 @@
if(firer && HAS_TRAIT(firer, TRAIT_NICE_SHOT))
best_angle += NICE_SHOT_RICOCHET_BONUS
for(var/mob/living/L in range(ricochet_auto_aim_range, src.loc))
if(L.stat == DEAD || !is_in_sight(src, L))
if(L.stat == DEAD || !is_in_sight(src, L) || (!ricochet_shoots_firer && L == firer))
continue
var/our_angle = abs(closer_angle_difference(Angle, get_angle(src.loc, L.loc)))
if(our_angle < best_angle)
@@ -47,3 +47,29 @@
damage = 25
speed = 0.3
range = 16
/obj/projectile/bullet/p50/marksman
name = ".50 marksman round"
damage = 50
paralyze = 0
tracer_type = /obj/effect/projectile/tracer/sniper
impact_type = /obj/effect/projectile/impact/sniper
muzzle_type = /obj/effect/projectile/muzzle/sniper
hitscan = TRUE
impact_effect_type = null
hitscan_light_intensity = 3
hitscan_light_range = 0.75
hitscan_light_color_override = LIGHT_COLOR_YELLOW
muzzle_flash_intensity = 5
muzzle_flash_range = 1
muzzle_flash_color_override = LIGHT_COLOR_YELLOW
impact_light_intensity = 5
impact_light_range = 1
impact_light_color_override = LIGHT_COLOR_YELLOW
ricochets_max = 1
ricochet_chance = 100
ricochet_auto_aim_angle = 45
ricochet_auto_aim_range = 15
ricochet_incidence_leeway = 90
ricochet_decay_damage = 1
ricochet_shoots_firer = FALSE