[MIRROR] Refactors Gunlight / Helmetlight to be a component [MDB IGNORE] (#14226)

* Refactors Gunlight / Helmetlight to be a component

* wew

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
This commit is contained in:
SkyratBot
2022-06-10 20:49:38 +01:00
committed by GitHub
co-authored by MrMelbert Gandalf
parent a1fd933f8c
commit d2e1be321f
28 changed files with 636 additions and 625 deletions
+17 -126
View File
@@ -56,10 +56,6 @@
var/obj/item/firing_pin/pin = /obj/item/firing_pin //standard firing pin for most guns
/// True if a gun dosen't need a pin, mostly used for abstract guns like tentacles and meathooks
var/pinless = FALSE
var/can_flashlight = FALSE //if a flashlight can be added or removed if it already has one.
var/obj/item/flashlight/seclite/gun_light
var/datum/action/item_action/toggle_gunlight/alight
var/gunlight_state = "flight"
var/can_bayonet = FALSE //if a bayonet can be added or removed if it already has one.
var/obj/item/knife/bayonet
@@ -68,8 +64,6 @@
var/ammo_x_offset = 0 //used for positioning ammo count overlay on sprite
var/ammo_y_offset = 0
var/flight_x_offset = 0
var/flight_y_offset = 0
var/pb_knockback = 0
@@ -77,14 +71,12 @@
. = ..()
if(pin)
pin = new pin(src)
if(gun_light)
alight = new(src)
add_seclight_point()
/obj/item/gun/Destroy()
if(isobj(pin)) //Can still be the initial path, then we skip
QDEL_NULL(pin)
if(gun_light)
QDEL_NULL(gun_light)
if(bayonet)
QDEL_NULL(bayonet)
if(chambered) //Not all guns are chambered (EMP'ed energy guns etc)
@@ -93,6 +85,12 @@
QDEL_NULL(suppressed)
return ..()
/// Handles adding [the seclite mount component][/datum/component/seclite_attachable] to the gun.
/// If the gun shouldn't have a seclight mount, override this with a return.
/// Or, if a child of a gun with a seclite mount has slightly different behavior or icons, extend this.
/obj/item/gun/proc/add_seclight_point()
return
/obj/item/gun/handle_atom_del(atom/A)
if(A == pin)
pin = null
@@ -101,8 +99,6 @@
update_appearance()
if(A == bayonet)
clear_bayonet()
if(A == gun_light)
clear_gunlight()
if(A == suppressed)
clear_suppressor()
return ..()
@@ -123,13 +119,6 @@
else
. += "It doesn't have a <b>firing pin</b> installed, and won't fire."
if(gun_light)
. += "It has \a [gun_light] [can_flashlight ? "" : "permanently "]mounted on it."
if(can_flashlight) //if it has a light and this is false, the light is permanent.
. += span_info("[gun_light] looks like it can be <b>unscrewed</b> from [src].")
else if(can_flashlight)
. += "It has a mounting point for a <b>seclite</b>."
if(bayonet)
. += "It has \a [bayonet] [can_bayonet ? "" : "permanently "]affixed to it."
if(can_bayonet) //if it has a bayonet and this is false, the bayonet is permanent.
@@ -417,19 +406,7 @@
/obj/item/gun/attackby(obj/item/I, mob/living/user, params)
if(user.combat_mode)
return ..()
else if(istype(I, /obj/item/flashlight/seclite))
if(!can_flashlight)
return ..()
var/obj/item/flashlight/seclite/S = I
if(!gun_light)
if(!user.transferItemToLoc(I, src))
return
to_chat(user, span_notice("You click [S] into place on [src]."))
set_gun_light(S)
update_gunlight()
alight = new(src)
if(loc == user)
alight.Grant(user)
else if(istype(I, /obj/item/knife))
var/obj/item/knife/K = I
if(!can_bayonet || !K.bayonet || bayonet) //ensure the gun has an attachment point available, and that the knife is compatible with it.
@@ -449,20 +426,9 @@
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/list/possible_items = list(gun_light, bayonet)
var/obj/item/item_to_remove = tgui_input_list(user, "Attachment to remove", "Attachment Removal", sort_names(possible_items))
if(isnull(item_to_remove))
return
if(!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.
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
return remove_gun_attachment(user, I, bayonet, "unfix")
if(bayonet && can_bayonet) //if it has a bayonet, and the bayonet can be removed
return remove_bayonet(user, I)
else if(pin && user.is_holding(src))
user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [I]."),
@@ -509,19 +475,15 @@
QDEL_NULL(pin)
return TRUE
/obj/item/gun/proc/remove_gun_attachment(mob/living/user, obj/item/tool_item, obj/item/item_to_remove, removal_verb)
if(tool_item)
tool_item.play_tool_sound(src)
to_chat(user, span_notice("You [removal_verb ? removal_verb : "remove"] [item_to_remove] from [src]."))
item_to_remove.forceMove(drop_location())
/obj/item/gun/proc/remove_bayonet(mob/living/user, obj/item/tool_item)
tool_item?.play_tool_sound(src)
to_chat(user, span_notice("You unfix [bayonet] from [src]."))
bayonet.forceMove(drop_location())
if(Adjacent(user) && !issilicon(user))
user.put_in_hands(item_to_remove)
user.put_in_hands(bayonet)
if(item_to_remove == bayonet)
return clear_bayonet()
else if(item_to_remove == gun_light)
return clear_gunlight()
return clear_bayonet()
/obj/item/gun/proc/clear_bayonet()
if(!bayonet)
@@ -530,79 +492,8 @@
update_appearance()
return TRUE
/obj/item/gun/proc/clear_gunlight()
if(!gun_light)
return
var/obj/item/flashlight/seclite/removed_light = gun_light
set_gun_light(null)
update_gunlight()
removed_light.update_brightness()
QDEL_NULL(alight)
return TRUE
/**
* Swaps the gun's seclight, dropping the old seclight if it has not been qdel'd.
*
* Returns the former gun_light that has now been replaced by this proc.
* Arguments:
* * new_light - The new light to attach to the weapon. Can be null, which will mean the old light is removed with no replacement.
*/
/obj/item/gun/proc/set_gun_light(obj/item/flashlight/seclite/new_light)
// Doesn't look like this should ever happen? We're replacing our old light with our old light?
if(gun_light == new_light)
CRASH("Tried to set a new gun light when the old gun light was also the new gun light.")
. = gun_light
// If there's an old gun light that isn't being QDELETED, detatch and drop it to the floor.
if(!QDELETED(gun_light))
gun_light.set_light_flags(gun_light.light_flags & ~LIGHT_ATTACHED)
if(gun_light.loc == src)
gun_light.forceMove(get_turf(src))
// If there's a new gun light to be added, attach and move it to the gun.
if(new_light)
new_light.set_light_flags(new_light.light_flags | LIGHT_ATTACHED)
if(new_light.loc != src)
new_light.forceMove(src)
gun_light = new_light
/obj/item/gun/ui_action_click(mob/user, actiontype)
if(istype(actiontype, alight))
toggle_gunlight()
else
..()
/obj/item/gun/proc/toggle_gunlight()
if(!gun_light)
return
var/mob/living/carbon/human/user = usr
gun_light.on = !gun_light.on
gun_light.update_brightness()
to_chat(user, span_notice("You toggle the gunlight [gun_light.on ? "on":"off"]."))
playsound(user, 'sound/weapons/empty.ogg', 100, TRUE)
update_gunlight()
/obj/item/gun/proc/update_gunlight()
update_appearance()
update_action_buttons()
/obj/item/gun/update_overlays()
. = ..()
if(gun_light)
var/mutable_appearance/flashlight_overlay
var/state = "[gunlight_state][gun_light.on? "_on":""]" //Generic state.
if(gun_light.icon_state in icon_states('icons/obj/guns/flashlights.dmi')) //Snowflake state?
state = gun_light.icon_state
flashlight_overlay = mutable_appearance('icons/obj/guns/flashlights.dmi', state)
flashlight_overlay.pixel_x = flight_x_offset
flashlight_overlay.pixel_y = flight_y_offset
. += flashlight_overlay
if(bayonet)
var/mutable_appearance/knife_overlay
var/state = "bayonet" //Generic state.
+3 -6
View File
@@ -59,6 +59,7 @@
START_PROCESSING(SSobj, src)
update_appearance()
RegisterSignal(src, COMSIG_ITEM_RECHARGED, .proc/instant_recharge)
AddElement(/datum/element/update_icon_updates_onmob)
/obj/item/gun/energy/add_weapon_description()
AddElement(/datum/element/weapon_description, attached_proc = .proc/add_notes_energy)
@@ -92,10 +93,6 @@
return readout.Join("\n") // Sending over the singular string, rather than the whole list
/obj/item/gun/energy/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
/obj/item/gun/energy/proc/update_ammo_types()
var/obj/item/ammo_casing/energy/shot
for (var/i in 1 to ammo_type.len)
@@ -219,8 +216,8 @@
if(modifystate)
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
if(single_shot_type_overlay)
. += "[icon_state]_[shot.select_name]"
overlay_icon_state += "_[shot.select_name]"
. += "[icon_state]_[initial(shot.select_name)]"
overlay_icon_state += "_[initial(shot.select_name)]"
var/ratio = get_charge_ratio()
if(ratio == 0 && display_empty)
@@ -6,12 +6,16 @@
inhand_icon_state = null //so the human update icon uses the icon_state instead.
ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
modifystate = TRUE
can_flashlight = TRUE
ammo_x_offset = 3
flight_x_offset = 15
flight_y_offset = 10
dual_wield_spread = 60
/obj/item/gun/energy/e_gun/add_seclight_point()
AddComponent(/datum/component/seclite_attachable, \
light_overlay_icon = 'icons/obj/guns/flashlights.dmi', \
light_overlay = "flight", \
overlay_x = 15, \
overlay_y = 10)
/obj/item/gun/energy/e_gun/mini
name = "miniature energy gun"
desc = "A small, pistol-sized energy gun with a built-in flashlight. It has two settings: disable and kill."
@@ -21,15 +25,17 @@
cell_type = /obj/item/stock_parts/cell/mini_egun
ammo_x_offset = 2
charge_sections = 3
can_flashlight = FALSE // Can't attach or detach the flashlight, and override it's icon update
gunlight_state = "mini-light"
flight_x_offset = 19
flight_y_offset = 13
single_shot_type_overlay = FALSE
/obj/item/gun/energy/e_gun/mini/Initialize(mapload)
set_gun_light(new /obj/item/flashlight/seclite(src))
return ..()
/obj/item/gun/energy/e_gun/mini/add_seclight_point()
// The mini energy gun's light comes attached but is unremovable.
AddComponent(/datum/component/seclite_attachable, \
starting_light = new /obj/item/flashlight/seclite(src), \
is_light_removable = FALSE, \
light_overlay_icon = 'icons/obj/guns/flashlights.dmi', \
light_overlay = "mini-light", \
overlay_x = 19, \
overlay_y = 13)
/obj/item/gun/energy/e_gun/stun
name = "tactical energy gun"
@@ -76,9 +82,11 @@
ammo_type = list(/obj/item/ammo_casing/energy/net, /obj/item/ammo_casing/energy/trap)
modifystate = FALSE
w_class = WEIGHT_CLASS_NORMAL
can_flashlight = FALSE
ammo_x_offset = 1
/obj/item/gun/energy/e_gun/dragnet/add_seclight_point()
return
/obj/item/gun/energy/e_gun/dragnet/snare
name = "Energy Snare Launcher"
desc = "Fires an energy snare that slows the target down."
@@ -94,11 +102,13 @@
w_class = WEIGHT_CLASS_HUGE
ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
weapon_weight = WEAPON_HEAVY
can_flashlight = FALSE
trigger_guard = TRIGGER_GUARD_NONE
ammo_x_offset = 2
/obj/item/gun/energy/e_gun/nuclear //ICON OVERRIDEN IN SKYRAT AESTHETICS - SEE MODULE
/obj/item/gun/energy/e_gun/turret/add_seclight_point()
return
/obj/item/gun/energy/e_gun/nuclear
name = "advanced energy gun"
desc = "An energy gun with an experimental miniaturized nuclear reactor that automatically charges the internal power cell."
icon_state = "nucgun"
@@ -8,9 +8,6 @@
item_flags = NONE
obj_flags = UNIQUE_RENAME
weapon_weight = WEAPON_LIGHT
can_flashlight = TRUE
flight_x_offset = 15
flight_y_offset = 9
can_bayonet = TRUE
knife_x_offset = 20
knife_y_offset = 12
@@ -18,6 +15,13 @@
var/max_mod_capacity = 100
var/list/modkits = list()
/obj/item/gun/energy/recharge/kinetic_accelerator/add_seclight_point()
AddComponent(/datum/component/seclite_attachable, \
light_overlay_icon = 'icons/obj/guns/flashlights.dmi', \
light_overlay = "flight", \
overlay_x = 15, \
overlay_y = 9)
/obj/item/gun/energy/recharge/kinetic_accelerator/examine(mob/user)
. = ..()
if(max_mod_capacity)
@@ -168,19 +168,23 @@
ammo_type = list(/obj/item/ammo_casing/energy/nanite)
shaded_charge = TRUE
ammo_x_offset = 1
can_flashlight = TRUE
flight_x_offset = 15
flight_y_offset = 9
can_bayonet = TRUE
knife_x_offset = 19
knife_y_offset = 13
w_class = WEIGHT_CLASS_NORMAL
dual_wield_spread = 10 //as intended by the coders
/obj/item/gun/energy/laser/thermal/ComponentInitialize()
/obj/item/gun/energy/laser/thermal/Initialize(mapload)
. = ..()
AddElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_CONTENTS)
/obj/item/gun/energy/laser/thermal/add_seclight_point()
AddComponent(/datum/component/seclite_attachable, \
light_overlay_icon = 'icons/obj/guns/flashlights.dmi', \
light_overlay = "flight", \
overlay_x = 15, \
overlay_y = 9)
/obj/item/gun/energy/laser/thermal/inferno //the magma gun
name = "inferno pistol"
desc = "A modified handcannon with a self-replicating reserve of decommissioned weaponized nanites. Spit globs of molten angry robots into the bad guys. While it doesn't manipulate temperature in of itself, it does cause an violent eruption in anyone who is severely cold."
@@ -7,11 +7,10 @@
display_empty = FALSE
force = 5
selfcharge = 1
can_flashlight = FALSE
trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses neural signals instead
/obj/item/gun/energy/e_gun/advtaser/mounted/dropped()//if somebody manages to drop this somehow...
..()
/obj/item/gun/energy/e_gun/advtaser/mounted/add_seclight_point()
return
/obj/item/gun/energy/laser/mounted
name = "mounted laser"
@@ -23,9 +22,6 @@
selfcharge = 1
trigger_guard = TRIGGER_GUARD_ALLOW_ALL
/obj/item/gun/energy/laser/mounted/dropped()
..()
/obj/item/gun/energy/laser/mounted/augment
icon = 'icons/obj/surgery.dmi'
icon_state = "arm_laser"
@@ -40,9 +40,13 @@
worn_icon_state = "gun"
inhand_icon_state = null
cell_type = "/obj/item/stock_parts/cell/pulse/carbine"
can_flashlight = TRUE
flight_x_offset = 18
flight_y_offset = 12
/obj/item/gun/energy/pulse/carbine/add_seclight_point()
AddComponent(/datum/component/seclite_attachable, \
light_overlay_icon = 'icons/obj/guns/flashlights.dmi', \
light_overlay = "flight", \
overlay_x = 18, \
overlay_y = 12)
/obj/item/gun/energy/pulse/carbine/loyalpin
pin = /obj/item/firing_pin/implant/mindshield
@@ -5,13 +5,17 @@
inhand_icon_state = null //so the human update icon uses the icon_state instead.
worn_icon_state = null
shaded_charge = TRUE
can_flashlight = TRUE
w_class = WEIGHT_CLASS_HUGE
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BACK
ammo_type = list(/obj/item/ammo_casing/energy/ion)
flight_x_offset = 17
flight_y_offset = 9
/obj/item/gun/energy/ionrifle/add_seclight_point()
AddComponent(/datum/component/seclite_attachable, \
light_overlay_icon = 'icons/obj/guns/flashlights.dmi', \
light_overlay = "flight", \
overlay_x = 17, \
overlay_y = 9)
/obj/item/gun/energy/ionrifle/emp_act(severity)
return
@@ -22,8 +26,11 @@
icon_state = "ioncarbine"
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BELT
flight_x_offset = 18
flight_y_offset = 11
/obj/item/gun/energy/ionrifle/carbine/add_seclight_point()
. = ..()
// We use the same overlay as the parent, so we can just let the component inherit the correct offsets here
AddComponent(/datum/component/seclite_attachable, overlay_x = 18, overlay_y = 11)
/obj/item/gun/energy/decloner
name = "biological demolecularisor"
+10 -4
View File
@@ -16,10 +16,12 @@
/obj/item/gun/energy/e_gun/advtaser/cyborg
name = "cyborg taser"
desc = "An integrated hybrid taser that draws directly from a cyborg's power cell. The weapon contains a limiter to prevent the cyborg's power cell from overheating."
can_flashlight = FALSE
can_charge = FALSE
use_cyborg_cell = TRUE
/obj/item/gun/energy/e_gun/advtaser/cyborg/add_seclight_point()
return
/obj/item/gun/energy/e_gun/advtaser/cyborg/emp_act()
return
@@ -30,11 +32,15 @@
inhand_icon_state = null
ammo_type = list(/obj/item/ammo_casing/energy/disabler/skyrat) // SKYRAT EDIT: ammo_type = list(/obj/item/ammo_casing/energy/disabler)
ammo_x_offset = 2
can_flashlight = TRUE
flight_x_offset = 15
flight_y_offset = 10
cell_type = /obj/item/stock_parts/cell/super // SKYRAT EDIT ADDITION
/obj/item/gun/energy/disabler/add_seclight_point()
AddComponent(/datum/component/seclite_attachable, \
light_overlay_icon = 'icons/obj/guns/flashlights.dmi', \
light_overlay = "flight", \
overlay_x = 15, \
overlay_y = 10)
/obj/item/gun/energy/disabler/cyborg
name = "cyborg disabler"
desc = "An integrated disabler that draws from a cyborg's power cell. This weapon contains a limiter to prevent the cyborg's power cell from overheating."