mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Firearms rework again [Modular Attachments] (#16028)
* initial modular attachment commit * fix bitflags * Update code/modules/projectiles/gun.dm Co-authored-by: tattax <71668564+tattax@users.noreply.github.com> * Update code/modules/projectiles/attachments/laser_sight.dm Co-authored-by: tattax <71668564+tattax@users.noreply.github.com> * Update code/modules/projectiles/attachments/_attachment.dm Co-authored-by: tattax <71668564+tattax@users.noreply.github.com> * Update code/datums/action.dm Co-authored-by: tattax <71668564+tattax@users.noreply.github.com> * Update code/datums/action.dm Co-authored-by: tattax <71668564+tattax@users.noreply.github.com> * Update code/datums/action.dm Co-authored-by: tattax <71668564+tattax@users.noreply.github.com> * Update code/datums/action.dm Co-authored-by: tattax <71668564+tattax@users.noreply.github.com> * Update code/modules/projectiles/attachments/_attachment.dm Co-authored-by: tattax <71668564+tattax@users.noreply.github.com> * Update code/modules/projectiles/attachments/_attachment.dm Co-authored-by: tattax <71668564+tattax@users.noreply.github.com> * use better names * fix tatax breaking my pr Co-authored-by: tattax <71668564+tattax@users.noreply.github.com>
This commit is contained in:
107
code/modules/projectiles/attachments/_attachment.dm
Normal file
107
code/modules/projectiles/attachments/_attachment.dm
Normal file
@@ -0,0 +1,107 @@
|
||||
// Attachment space bitflags.
|
||||
// Attachments that are not exclusive i.e. attaches to the barrel should have an attachment_type of 0.
|
||||
#define TYPE_SIGHT (1<<0) // Scopes, sights
|
||||
#define TYPE_BARREL (1<<1) // Shorter, longer, or otherwise modified barrel
|
||||
#define TYPE_TRIGGER (1<<2) // Modified trigger
|
||||
#define TYPE_FOREGRIP (1<<3) // Foregrip
|
||||
|
||||
/// Base attachment.
|
||||
/// "_a" icons should be 5x5 pixels.
|
||||
/// See icons/obj/guns/attachment.dmi.
|
||||
/obj/item/attachment
|
||||
name = "attachment"
|
||||
desc = "It's an attachment."
|
||||
icon = 'icons/obj/guns/attachment.dmi'
|
||||
|
||||
/// Attached sprite adds "_a" e.g. "iconname_a"
|
||||
icon_state = "_error"
|
||||
|
||||
var/obj/item/gun/attached_gun
|
||||
|
||||
/// If the attachment can be "turned on", it will use "_on" e.g. "iconname_on_a" and "iconname_on".
|
||||
/// It is important to note that not all attachments can be turned on, so you don't have to worry about this most of the time.
|
||||
var/is_on = FALSE
|
||||
|
||||
/// Attachments that are not exclusive i.e. attaches to the side of the barrel should have an attachment_type of 0.
|
||||
/// Otherwise, use one or many bitflags to represent the exclusive space this attachment should occuy.
|
||||
var/attachment_type = 0
|
||||
|
||||
/// "You slide the attachment into place on gun."
|
||||
var/attach_verb = "slide"
|
||||
|
||||
var/mob/current_user = null
|
||||
|
||||
/// List of actions to add to the gun when attached.
|
||||
/// See code/modules/projectiles/attachments/laser_sight.dm for example.
|
||||
var/list/actions_list = list()
|
||||
|
||||
/obj/item/attachment/update_icon()
|
||||
icon_state = initial(icon_state) + is_on ? "_on" : ""
|
||||
. = ..()
|
||||
attached_gun?.update_attachments()
|
||||
|
||||
/obj/item/attachment/Destroy()
|
||||
if(attached_gun)
|
||||
on_detach(attached_gun)
|
||||
. = ..()
|
||||
|
||||
/// Called when the attacment is attached to a weapon
|
||||
/obj/item/attachment/proc/on_attach(obj/item/gun/G, mob/user = null)
|
||||
attached_gun = G
|
||||
|
||||
for(var/act in actions_list)
|
||||
var/datum/action/attachment_action = new act(G)
|
||||
G.attachment_actions += attachment_action
|
||||
if(user && G.loc == user)
|
||||
attachment_action.Grant(user)
|
||||
|
||||
if(G.loc == user)
|
||||
set_user(user)
|
||||
G.attachment_flags |= attachment_type
|
||||
G.current_attachments += src
|
||||
G.update_attachments()
|
||||
forceMove(G)
|
||||
|
||||
if(user)
|
||||
current_user = user
|
||||
|
||||
/// Called when the attachment is detached from a weapon
|
||||
/obj/item/attachment/proc/on_detach(obj/item/gun/G, mob/living/user = null)
|
||||
for(var/act_type in actions_list)
|
||||
for(var/stored_attachment in G.attachment_actions)
|
||||
if(istype(stored_attachment, act_type))
|
||||
var/datum/action/typed_attachment = stored_attachment
|
||||
typed_attachment.Remove(user)
|
||||
G.attachment_actions -= stored_attachment
|
||||
QDEL_NULL(stored_attachment)
|
||||
break
|
||||
|
||||
attached_gun = null
|
||||
set_user()
|
||||
G.attachment_flags ^= attachment_type
|
||||
G.current_attachments -= src
|
||||
G.update_attachments()
|
||||
if(user)
|
||||
user.put_in_hands(src)
|
||||
else
|
||||
forceMove(get_turf(G))
|
||||
|
||||
/obj/item/attachment/proc/on_gun_fire(obj/item/gun/G)
|
||||
|
||||
/obj/item/attachment/proc/set_user(mob/user = null)
|
||||
if(user == current_user)
|
||||
return
|
||||
if(istype(current_user))
|
||||
current_user = null
|
||||
if(istype(user))
|
||||
current_user = user
|
||||
|
||||
/obj/item/attachment/proc/check_user()
|
||||
if(!istype(current_user))
|
||||
if(ismob(loc))
|
||||
set_user(loc)
|
||||
else if(ismob(loc.loc))
|
||||
set_user(loc.loc)
|
||||
if(!istype(current_user) || !isturf(current_user.loc) || !( (src in current_user.held_items)||(loc in current_user.held_items) ) || current_user.incapacitated()) //Doesn't work if you're not holding it!
|
||||
return FALSE
|
||||
return TRUE
|
||||
20
code/modules/projectiles/attachments/grips.dm
Normal file
20
code/modules/projectiles/attachments/grips.dm
Normal file
@@ -0,0 +1,20 @@
|
||||
/// Base grip
|
||||
/obj/item/attachment/grip
|
||||
name = "grip"
|
||||
desc = "It's a grip."
|
||||
attachment_type = TYPE_FOREGRIP
|
||||
var/steady = 0
|
||||
|
||||
/obj/item/attachment/grip/on_attach(obj/item/gun/G, mob/user = null)
|
||||
. = ..()
|
||||
G.recoil -= steady
|
||||
|
||||
/obj/item/attachment/grip/on_detach(obj/item/gun/G, mob/living/user = null)
|
||||
. = ..()
|
||||
G.recoil += steady
|
||||
|
||||
/obj/item/attachment/grip/vertical
|
||||
name = "vertical grip"
|
||||
desc = "A tactile grip that increases the control and steadiness of your weapon."
|
||||
icon_state = "vert_grip"
|
||||
steady = 0.5
|
||||
139
code/modules/projectiles/attachments/laser_sight.dm
Normal file
139
code/modules/projectiles/attachments/laser_sight.dm
Normal file
@@ -0,0 +1,139 @@
|
||||
/obj/item/attachment/laser_sight
|
||||
name = "laser sight"
|
||||
desc = "A glorified laser pointer. Good for knowing what you're aiming at."
|
||||
icon_state = "laser_sight"
|
||||
var/lastangle = 0
|
||||
var/aiming_lastangle = 0
|
||||
var/aiming_time = 12
|
||||
var/aiming_time_left = 12
|
||||
var/laser_color = rgb(255,0,0)
|
||||
var/listeningTo = null
|
||||
var/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/last_beam
|
||||
actions_list = list(/datum/action/item_action/toggle_laser_sight, /datum/action/item_action/change_laser_sight_color)
|
||||
|
||||
/obj/item/attachment/laser_sight/examine(mob/user)
|
||||
. = ..()
|
||||
. += span_notice("You can <b>alt-click</b> it to change its color.")
|
||||
|
||||
/obj/item/attachment/laser_sight/AltClick(mob/user)
|
||||
. = ..()
|
||||
var/C = input(user, "Select Laser Color", "Select laser color", laser_color) as null|color
|
||||
if(!C || QDELETED(src))
|
||||
return
|
||||
laser_color = C
|
||||
|
||||
/obj/item/attachment/laser_sight/on_attach(obj/item/gun/G, mob/user = null)
|
||||
. = ..()
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
if(is_on)
|
||||
G.spread -= 6
|
||||
|
||||
/obj/item/attachment/laser_sight/on_detach(obj/item/gun/G, mob/living/user = null)
|
||||
. = ..()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
if(is_on)
|
||||
G.spread += 6
|
||||
QDEL_LIST(attached_gun.current_tracers)
|
||||
|
||||
/obj/item/attachment/laser_sight/attack_self(mob/user)
|
||||
. = ..()
|
||||
toggle_on()
|
||||
|
||||
/obj/item/attachment/laser_sight/proc/toggle_on()
|
||||
is_on = !is_on
|
||||
playsound(loc, is_on ? 'sound/weapons/magin.ogg' : 'sound/weapons/magout.ogg', 40, 1)
|
||||
if(attached_gun)
|
||||
if(is_on)
|
||||
attached_gun.spread -= 6
|
||||
else
|
||||
attached_gun.spread += 6
|
||||
QDEL_LIST(attached_gun.current_tracers)
|
||||
update_icon()
|
||||
|
||||
/obj/item/attachment/laser_sight/process()
|
||||
return aiming_beam(TRUE)
|
||||
|
||||
/obj/item/attachment/laser_sight/proc/aiming_beam(force_update = FALSE)
|
||||
if(!is_on)
|
||||
return
|
||||
if(!attached_gun)
|
||||
return PROCESS_KILL
|
||||
if(!check_user())
|
||||
// Doesn't need to be optimized, runs nothing if the list is already empty
|
||||
QDEL_LIST(attached_gun.current_tracers)
|
||||
return
|
||||
process_aim()
|
||||
var/diff = abs(aiming_lastangle - lastangle)
|
||||
if(diff < 0.1 && !force_update)
|
||||
return
|
||||
aiming_lastangle = lastangle
|
||||
var/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/P = new
|
||||
P.gun = attached_gun
|
||||
P.color = laser_color
|
||||
var/turf/curloc = get_turf(src)
|
||||
var/turf/targloc = get_turf(current_user.client.mouseObject)
|
||||
if(!istype(targloc))
|
||||
if(!istype(curloc))
|
||||
return
|
||||
targloc = get_turf_in_angle(lastangle, curloc, 10)
|
||||
P.preparePixelProjectile(targloc, current_user, current_user.client.mouseParams, 0)
|
||||
P.fire(lastangle)
|
||||
last_beam = P
|
||||
|
||||
/obj/item/attachment/laser_sight/equipped(mob/user)
|
||||
set_user(user)
|
||||
return ..()
|
||||
|
||||
/obj/item/attachment/laser_sight/pickup(mob/user)
|
||||
set_user(user)
|
||||
return ..()
|
||||
|
||||
/obj/item/attachment/laser_sight/dropped(mob/user)
|
||||
set_user()
|
||||
return ..()
|
||||
|
||||
/obj/item/attachment/laser_sight/set_user(mob/user = null)
|
||||
if(user == current_user)
|
||||
return
|
||||
aiming_time_left = aiming_time
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
listeningTo = null
|
||||
if(istype(current_user))
|
||||
LAZYREMOVE(current_user.mousemove_intercept_objects, src)
|
||||
current_user = null
|
||||
if(istype(user))
|
||||
current_user = user
|
||||
LAZYOR(current_user.mousemove_intercept_objects, src)
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/on_mob_move)
|
||||
listeningTo = user
|
||||
|
||||
/obj/item/attachment/laser_sight/proc/on_mob_move()
|
||||
if(!check_user())
|
||||
return
|
||||
if(is_on)
|
||||
delay_penalty(3)
|
||||
aiming_beam(TRUE)
|
||||
|
||||
/obj/item/attachment/laser_sight/onMouseMove(object, location, control, params)
|
||||
. = ..()
|
||||
if(is_on)
|
||||
aiming_beam()
|
||||
|
||||
/obj/item/attachment/laser_sight/proc/process_aim()
|
||||
if(istype(current_user) && current_user.client && current_user.client.mouseParams)
|
||||
var/angle = mouse_angle_from_client(current_user.client)
|
||||
current_user.setDir(angle2dir_cardinal(angle))
|
||||
var/difference = abs(closer_angle_difference(lastangle, angle))
|
||||
delay_penalty(difference * 0.3)
|
||||
lastangle = angle
|
||||
|
||||
/obj/item/attachment/laser_sight/proc/delay_penalty(amount)
|
||||
aiming_time_left = clamp(aiming_time_left + amount, 0, aiming_time)
|
||||
|
||||
/obj/item/attachment/laser_sight/Destroy()
|
||||
set_user(null)
|
||||
listeningTo = null
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
QDEL_LIST(attached_gun?.current_tracers)
|
||||
return ..()
|
||||
26
code/modules/projectiles/attachments/scopes.dm
Normal file
26
code/modules/projectiles/attachments/scopes.dm
Normal file
@@ -0,0 +1,26 @@
|
||||
/// Base sight
|
||||
/obj/item/attachment/scope
|
||||
name = "sight"
|
||||
desc = "It's a sight."
|
||||
attachment_type = TYPE_SIGHT
|
||||
var/accuracy = 0
|
||||
|
||||
/obj/item/attachment/scope/on_attach(obj/item/gun/G, mob/user = null)
|
||||
. = ..()
|
||||
G.spread -= accuracy
|
||||
|
||||
/obj/item/attachment/scope/on_detach(obj/item/gun/G, mob/living/user = null)
|
||||
. = ..()
|
||||
G.spread += accuracy
|
||||
|
||||
/obj/item/attachment/scope/simple
|
||||
name = "simple sight"
|
||||
desc = "A simple yet elegant scope. Better than ironsights."
|
||||
icon_state = "simple_sight"
|
||||
accuracy = 3
|
||||
|
||||
/obj/item/attachment/scope/holo
|
||||
name = "holographic sight"
|
||||
desc = "A highly advanced sight that projects a holographic design onto its lens, providing unobscured and precise view of your target."
|
||||
icon_state = "holo_sight"
|
||||
accuracy = 6
|
||||
@@ -29,10 +29,10 @@
|
||||
var/suppressed_sound = 'sound/weapons/gunshot_silenced.ogg'
|
||||
var/suppressed_volume = 10
|
||||
var/can_unsuppress = TRUE
|
||||
var/recoil = 0 //boom boom shake the room
|
||||
var/recoil = 0 //boom boom shake the room
|
||||
var/clumsy_check = TRUE
|
||||
var/obj/item/ammo_casing/chambered = null
|
||||
trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers
|
||||
trigger_guard = TRIGGER_GUARD_NORMAL//trigger guard on the weapon, hulks can't fire them with their big meaty fingers
|
||||
var/sawn_desc = null //description change if weapon is sawn-off
|
||||
var/sawn_off = FALSE
|
||||
var/burst_size = 1 //how large a burst is
|
||||
@@ -40,7 +40,7 @@
|
||||
var/firing_burst = 0 //Prevent the weapon from firing again while already firing
|
||||
var/semicd = 0 //cooldown handler
|
||||
var/weapon_weight = WEAPON_LIGHT
|
||||
var/spread = 0 //Spread induced by the gun itself.
|
||||
var/spread = 5 //Spread induced by the gun itself.
|
||||
var/randomspread = 1 //Set to 0 for shotguns. This is used for weapons that don't fire all their bullets at once.
|
||||
|
||||
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
|
||||
@@ -60,6 +60,14 @@
|
||||
var/knife_x_offset = 0
|
||||
var/knife_y_offset = 0
|
||||
|
||||
var/list/available_attachments = list() // What attachments can this gun have
|
||||
var/max_attachments = 0 // How many attachments can this gun hold, recommend not going over 5
|
||||
|
||||
var/list/current_attachments = list()
|
||||
var/list/attachment_overlays = list()
|
||||
var/attachment_flags = 0
|
||||
var/attachment_actions = list()
|
||||
|
||||
var/ammo_x_offset = 0 //used for positioning ammo count overlay on sprite
|
||||
var/ammo_y_offset = 0
|
||||
var/flight_x_offset = 0
|
||||
@@ -73,6 +81,8 @@
|
||||
var/datum/action/toggle_scope_zoom/azoom
|
||||
var/recent_shoot = null //time of the last shot with the gun. Used to track if firing happened for feedback out of all things
|
||||
|
||||
var/list/obj/effect/projectile/tracer/current_tracers
|
||||
|
||||
/obj/item/gun/Initialize()
|
||||
. = ..()
|
||||
if(pin)
|
||||
@@ -82,6 +92,7 @@
|
||||
pin = new pin(src)
|
||||
if(gun_light)
|
||||
alight = new(src)
|
||||
current_tracers = list()
|
||||
build_zooming()
|
||||
|
||||
/obj/item/gun/Destroy()
|
||||
@@ -112,6 +123,10 @@
|
||||
clear_bayonet()
|
||||
if(A == gun_light)
|
||||
clear_gunlight()
|
||||
if(A in current_attachments)
|
||||
var/obj/item/attachment/T = A
|
||||
T.on_detach(src)
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/CheckParts(list/parts_list)
|
||||
@@ -148,9 +163,14 @@
|
||||
. += span_info("[bayonet] looks like it can be <b>unscrewed</b> from [src].")
|
||||
else if(can_bayonet)
|
||||
. += "It has a <b>bayonet</b> lug on it."
|
||||
|
||||
for(var/obj/item/attachment/A in current_attachments)
|
||||
. += "It has \a [A] affixed to it."
|
||||
|
||||
/obj/item/gun/equipped(mob/living/user, slot)
|
||||
. = ..()
|
||||
for(var/obj/item/attachment/A in current_attachments)
|
||||
A.set_user(user)
|
||||
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!!
|
||||
|
||||
@@ -169,7 +189,7 @@
|
||||
|
||||
|
||||
/obj/item/gun/proc/shoot_live_shot(mob/living/user, pointblank = 0, atom/pbtarget = null, message = 1)
|
||||
if(recoil)
|
||||
if(recoil > 0)
|
||||
shake_camera(user, recoil + 1, recoil)
|
||||
|
||||
if(suppressed)
|
||||
@@ -331,6 +351,9 @@
|
||||
if(user)
|
||||
SEND_SIGNAL(user, COMSIG_MOB_FIRED_GUN, user, target, params, zone_override)
|
||||
|
||||
for(var/obj/item/attachment/A in current_attachments)
|
||||
A.on_gun_fire(src)
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
if(semicd)
|
||||
@@ -339,7 +362,7 @@
|
||||
var/sprd = 0
|
||||
var/randomized_gun_spread = 0
|
||||
var/rand_spr = rand()
|
||||
if(spread)
|
||||
if(spread > 0)
|
||||
randomized_gun_spread = rand(0,spread)
|
||||
if(ishuman(user)) //nice shootin' tex
|
||||
var/mob/living/carbon/human/H = user
|
||||
@@ -406,6 +429,41 @@
|
||||
/obj/item/gun/attackby(obj/item/I, mob/user, params)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
else if (istype(I, /obj/item/attachment))
|
||||
var/support = FALSE
|
||||
|
||||
for(var/n in available_attachments)
|
||||
if(istype(I, n))
|
||||
support = TRUE
|
||||
break
|
||||
|
||||
if(!support)
|
||||
to_chat(user, span_warning("\The [src] does not support \the [I]!"))
|
||||
return ..()
|
||||
|
||||
var/already_has = FALSE
|
||||
for(var/n in current_attachments)
|
||||
if(istype(I, n))
|
||||
already_has = TRUE
|
||||
break
|
||||
|
||||
if(already_has)
|
||||
to_chat(user, span_warning("\The [src] already has \a [I]!"))
|
||||
return ..()
|
||||
|
||||
if(LAZYLEN(current_attachments) >= max_attachments)
|
||||
to_chat(user, span_warning("\The [src] has no more room for any more attachments!"))
|
||||
return ..()
|
||||
|
||||
var/obj/item/attachment/A = I
|
||||
|
||||
if(A.attachment_type != 0 && ((attachment_flags &= A.attachment_type) != 0))
|
||||
to_chat(user, span_warning("\The [src] does not have any available places to attach \the [I] onto!"))
|
||||
return ..()
|
||||
|
||||
to_chat(user, span_notice("You [A.attach_verb] \the [I] into place on [src]."))
|
||||
A.on_attach(src, user)
|
||||
|
||||
else if(istype(I, /obj/item/flashlight/seclite))
|
||||
if(!can_flashlight)
|
||||
return ..()
|
||||
@@ -446,17 +504,31 @@
|
||||
return
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
if((can_flashlight && gun_light) && (can_bayonet && bayonet)) //give them a choice instead of removing both
|
||||
|
||||
var/has_fl = FALSE
|
||||
var/has_bayo = FALSE
|
||||
var/amt_modular = LAZYLEN(current_attachments)
|
||||
if(can_flashlight && gun_light)
|
||||
has_fl = TRUE
|
||||
if(bayonet && can_bayonet)
|
||||
has_bayo = TRUE
|
||||
|
||||
var/attachments_amt = amt_modular + has_fl + has_bayo
|
||||
if(attachments_amt > 1) //give them a choice instead of removing both
|
||||
var/list/possible_items = list(gun_light, bayonet)
|
||||
possible_items += current_attachments
|
||||
var/obj/item/item_to_remove = input(user, "Select an attachment to remove", "Attachment Removal") as null|obj in possible_items
|
||||
if(!item_to_remove || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
return remove_gun_attachment(user, I, item_to_remove)
|
||||
|
||||
else if(gun_light && can_flashlight) //if it has a gun_light and can_flashlight is false, the flashlight is permanently attached.
|
||||
else if(amt_modular == 1)
|
||||
return remove_gun_attachment(user, I, current_attachments[1], "unscrewed")
|
||||
|
||||
else if(has_fl) //if it has a gun_light and can_flashlight is false, the flashlight is permanently attached.
|
||||
return remove_gun_attachment(user, I, gun_light, "unscrewed")
|
||||
|
||||
else if(bayonet && can_bayonet) //if it has a bayonet, and the bayonet can be removed
|
||||
else if(has_bayo) //if it has a bayonet, and the bayonet can be removed
|
||||
return remove_gun_attachment(user, I, bayonet, "unfix")
|
||||
|
||||
/obj/item/gun/proc/remove_gun_attachment(mob/living/user, obj/item/tool_item, obj/item/item_to_remove, removal_verb)
|
||||
@@ -468,6 +540,10 @@
|
||||
if(Adjacent(user) && !issilicon(user))
|
||||
user.put_in_hands(item_to_remove)
|
||||
|
||||
if(istype(item_to_remove, /obj/item/attachment))
|
||||
var/obj/item/attachment/A = item_to_remove
|
||||
return A.on_detach(src, user)
|
||||
|
||||
if(item_to_remove == bayonet)
|
||||
return clear_bayonet()
|
||||
else if(item_to_remove == gun_light)
|
||||
@@ -532,13 +608,38 @@
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/gun/proc/update_attachments()
|
||||
for(var/mutable_appearance/M in attachment_overlays)
|
||||
cut_overlay(M, TRUE)
|
||||
attachment_overlays = list()
|
||||
|
||||
var/att_position = 0
|
||||
for(var/obj/item/attachment/A in current_attachments)
|
||||
var/mutable_appearance/M = mutable_appearance('icons/obj/guns/attachment.dmi', "[A.icon_state]_a")
|
||||
M.pixel_x = att_position * 6
|
||||
add_overlay(M, TRUE)
|
||||
attachment_overlays += M
|
||||
att_position += 1
|
||||
|
||||
update_icon(TRUE)
|
||||
for(var/datum/action/A as anything in actions)
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/gun/pickup(mob/user)
|
||||
..()
|
||||
for(var/obj/item/attachment/A in current_attachments)
|
||||
A.set_user(user)
|
||||
for(var/datum/action/att_act in attachment_actions)
|
||||
att_act.Grant(user)
|
||||
if(azoom)
|
||||
azoom.Grant(user)
|
||||
|
||||
/obj/item/gun/dropped(mob/user)
|
||||
. = ..()
|
||||
for(var/obj/item/attachment/A in current_attachments)
|
||||
A.set_user()
|
||||
for(var/datum/action/att_act in attachment_actions)
|
||||
att_act.Remove(user)
|
||||
if(azoom)
|
||||
azoom.Remove(user)
|
||||
if(zoomed)
|
||||
|
||||
@@ -110,6 +110,15 @@
|
||||
var/feedback_recoil_reverse = FALSE // TRUE for clockwise , FALSE for anti-clockwise
|
||||
var/feedback_slide_close_move = TRUE // does the slide closing cause the gun to twist clockwise?
|
||||
|
||||
available_attachments = list(
|
||||
/obj/item/attachment/scope/simple,
|
||||
/obj/item/attachment/scope/holo,
|
||||
/obj/item/attachment/laser_sight,
|
||||
/obj/item/attachment/grip/vertical,
|
||||
)
|
||||
max_attachments = 4
|
||||
recoil = 0.3
|
||||
|
||||
/obj/item/gun/ballistic/proc/feedback(type) // checks to see if gun has that feedback type enabled then commences the animation
|
||||
if(feedback_types[type])
|
||||
feedback_commence(type, feedback_types[type])
|
||||
|
||||
@@ -22,6 +22,15 @@
|
||||
var/use_cyborg_cell = FALSE //whether the gun's cell drains the cyborg user's cell to recharge
|
||||
var/dead_cell = FALSE //set to true so the gun is given an empty cell
|
||||
|
||||
available_attachments = list(
|
||||
/obj/item/attachment/scope/simple,
|
||||
/obj/item/attachment/scope/holo,
|
||||
/obj/item/attachment/laser_sight,
|
||||
/obj/item/attachment/grip/vertical,
|
||||
)
|
||||
max_attachments = 4
|
||||
recoil = 0.1
|
||||
|
||||
/obj/item/gun/energy/emp_act(severity)
|
||||
. = ..()
|
||||
if(!(. & EMP_PROTECT_CONTENTS))
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
var/can_charge = TRUE
|
||||
var/ammo_type
|
||||
var/no_den_usage
|
||||
recoil = 0
|
||||
spread = 0
|
||||
clumsy_check = 0
|
||||
trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses magic instead
|
||||
pin = /obj/item/firing_pin/magic
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
var/lastangle = 0
|
||||
var/aiming_lastangle = 0
|
||||
var/mob/current_user = null
|
||||
var/list/obj/effect/projectile/tracer/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
|
||||
@@ -170,7 +169,6 @@
|
||||
/obj/item/gun/energy/beam_rifle/Initialize()
|
||||
. = ..()
|
||||
fire_delay = delay
|
||||
current_tracers = list()
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
zoom_lock_action = new(src)
|
||||
|
||||
@@ -425,7 +423,7 @@
|
||||
flag = ENERGY
|
||||
range = 150
|
||||
jitter = 10
|
||||
var/obj/item/gun/energy/beam_rifle/gun
|
||||
var/obj/item/gun/gun
|
||||
var/structure_pierce_amount = 0 //All set to 0 so the gun can manually set them during firing.
|
||||
var/structure_bleed_coeff = 0
|
||||
var/structure_pierce = 0
|
||||
|
||||
Reference in New Issue
Block a user