Merge pull request #15402 from Linzolle/pinremoval

finally change pin removal from crafting to tools
This commit is contained in:
silicons
2021-12-19 18:54:50 -08:00
committed by GitHub
4 changed files with 228 additions and 94 deletions
-2
View File
@@ -21,8 +21,6 @@
var/active_sound = null
var/toggle_cooldown = null
var/cooldown = 0
var/obj/item/flashlight/F = null
var/can_flashlight = 0
var/blocks_shove_knockdown = FALSE //Whether wearing the clothing item blocks the ability for shove to knock down.
+70 -40
View File
@@ -16,17 +16,47 @@
dog_fashion = /datum/dog_fashion/head/helmet
var/can_flashlight = FALSE //if a flashlight can be mounted. if it has a flashlight and this is false, it is permanently attached.
var/obj/item/flashlight/seclite/attached_light
var/datum/action/item_action/toggle_helmet_flashlight/alight
/obj/item/clothing/head/helmet/Initialize(mapload)
. = ..()
if(attached_light)
alight = new(src)
/obj/item/clothing/head/helmet/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_HEAD))
/obj/item/clothing/head/helmet/examine(mob/user)
. = ..()
if(attached_light)
. += "It has \a [attached_light] [can_flashlight ? "" : "permanently "]mounted on it."
if(can_flashlight)
. += "<span class='info'>[attached_light] looks like it can be <b>unscrewed</b> from [src].</span>"
else if(can_flashlight)
. += "It has a mounting point for a <b>seclite</b>."
/obj/item/clothing/head/helmet/Destroy()
QDEL_NULL(attached_light)
return ..()
/obj/item/clothing/head/helmet/handle_atom_del(atom/A)
if(A == attached_light)
attached_light = null
update_helmlight()
update_icon()
QDEL_NULL(alight)
return ..()
/obj/item/clothing/head/helmet/sec
can_flashlight = 1
/obj/item/clothing/head/helmet/sec/attackby(obj/item/I, mob/user, params)
if(issignaler(I))
var/obj/item/assembly/signaler/S = I
if(F) //Has a flashlight. Player must remove it, else it will be lost forever.
if(attached_light) //Has a flashlight. Player must remove it, else it will be lost forever.
to_chat(user, "<span class='warning'>The mounted flashlight is in the way, remove it first!</span>")
return
@@ -280,8 +310,8 @@
/obj/item/clothing/head/helmet/update_icon_state()
var/state = "[initial(icon_state)]"
if(F)
if(F.on)
if(attached_light)
if(attached_light.on)
state += "-flight-on" //"helmet-flight-on" // "helmet-cam-flight-on"
else
state += "-flight" //etc.
@@ -289,7 +319,7 @@
icon_state = state
/obj/item/clothing/head/helmet/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/toggle_helmet_flashlight))
if(istype(action, alight))
toggle_helmlight()
else
..()
@@ -297,60 +327,60 @@
/obj/item/clothing/head/helmet/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/flashlight/seclite))
var/obj/item/flashlight/seclite/S = I
if(can_flashlight)
if(!F)
if(!user.transferItemToLoc(S, src))
return
to_chat(user, "<span class='notice'>You click [S] into place on [src].</span>")
if(S.on)
set_light(0)
F = S
update_icon()
update_helmlight(user)
verbs += /obj/item/clothing/head/helmet/proc/toggle_helmlight
var/datum/action/A = new /datum/action/item_action/toggle_helmet_flashlight(src)
if(loc == user)
A.Grant(user)
if(can_flashlight && !attached_light)
if(!user.transferItemToLoc(S, src))
return
to_chat(user, "<span class='notice'>You click [S] into place on [src].</span>")
if(S.on)
set_light(0)
attached_light = S
update_icon()
update_helmlight()
alight = new(src)
if(loc == user)
alight.Grant(user)
return
if(I.tool_behaviour == TOOL_SCREWDRIVER)
if(F)
for(var/obj/item/flashlight/seclite/S in src)
to_chat(user, "<span class='notice'>You unscrew the seclite from [src].</span>")
F = null
S.forceMove(user.drop_location())
update_helmlight(user)
S.update_brightness(user)
update_icon()
usr.update_inv_head()
verbs -= /obj/item/clothing/head/helmet/proc/toggle_helmlight
for(var/datum/action/item_action/toggle_helmet_flashlight/THL in actions)
qdel(THL)
return
return ..()
/obj/item/clothing/head/helmet/screwdriver_act(mob/living/user, obj/item/I)
..()
if(can_flashlight && attached_light) //if it has a light but can_flashlight is false, the light is permanently attached.
I.play_tool_sound(src)
to_chat(user, "<span class='notice'>You unscrew [attached_light] from [src].</span>")
attached_light.forceMove(drop_location())
if(Adjacent(user) && !issilicon(user))
user.put_in_hands(attached_light)
var/obj/item/flashlight/removed_light = attached_light
attached_light = null
update_helmlight()
removed_light.update_brightness(user)
update_icon()
user.update_inv_head()
QDEL_NULL(alight)
return TRUE
/obj/item/clothing/head/helmet/proc/toggle_helmlight()
set name = "Toggle Helmetlight"
set category = "Object"
set desc = "Click to toggle your helmet's attached flashlight."
if(!F)
if(!attached_light)
return
var/mob/user = usr
if(user.incapacitated())
return
F.on = !F.on
to_chat(user, "<span class='notice'>You toggle the helmetlight [F.on ? "on":"off"].</span>")
attached_light.on = !attached_light.on
to_chat(user, "<span class='notice'>You toggle the helmet-light [attached_light.on ? "on":"off"].</span>")
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
update_helmlight(user)
/obj/item/clothing/head/helmet/proc/update_helmlight(mob/user = null)
if(F)
if(F.on)
set_light(F.brightness_on, F.flashlight_power, F.light_color)
if(attached_light)
if(attached_light.on)
set_light(attached_light.brightness_on, attached_light.flashlight_power, attached_light.light_color)
else
set_light(0)
update_icon()
+158 -36
View File
@@ -1,5 +1,6 @@
#define DUALWIELD_PENALTY_EXTRA_MULTIPLIER 1.4
#define FIRING_PIN_REMOVAL_DELAY 50
/obj/item/gun
name = "gun"
@@ -63,7 +64,7 @@
var/obj/item/firing_pin/pin = /obj/item/firing_pin //standard firing pin for most guns
var/no_pin_required = FALSE //whether the gun can be fired without a pin
var/obj/item/flashlight/gun_light
var/obj/item/flashlight/seclite/gun_light
var/can_flashlight = FALSE
var/gunlight_state = "flight"
var/obj/item/kitchen/knife/bayonet
@@ -115,23 +116,28 @@
QDEL_NULL(chambered)
return ..()
/obj/item/gun/CheckParts(list/parts_list)
..()
var/obj/item/gun/G = locate(/obj/item/gun) in contents
if(G)
G.forceMove(loc)
QDEL_NULL(G.pin)
visible_message("[G] can now fit a new pin, but the old one was destroyed in the process.", null, null, 3)
qdel(src)
/obj/item/gun/examine(mob/user)
. = ..()
if(no_pin_required)
return
if(pin)
. += "It has \a [pin] installed."
else
. += "It doesn't have a firing pin installed, and won't fire."
if(!no_pin_required)
if(pin)
. += "It has \a [pin] installed."
. += "<span class='info'>[pin] looks like it could be removed with some <b>tools</b>.</span>"
else
. += "It doesn't have a firing pin 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 class='info'>[gun_light] looks like it can be <b>unscrewed</b> from [src].</span>"
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.
. += "<span class='info'>[bayonet] looks like it can be <b>unscrewed</b> from [src].</span>"
else if(can_bayonet)
. += "It has a <b>bayonet</b> lug on it."
/obj/item/gun/equipped(mob/living/user, slot)
. = ..()
@@ -239,7 +245,7 @@
return
if(weapon_weight == WEAPON_HEAVY && user.get_inactive_held_item())
to_chat(user, "<span class='userdanger'>You need both hands free to fire \the [src]!</span>")
to_chat(user, "<span class='userdanger'>You need both hands free to fire [src]!</span>")
return
user.DelayNextAction()
@@ -417,12 +423,12 @@
if(!gun_light)
if(!user.transferItemToLoc(I, src))
return
to_chat(user, "<span class='notice'>You click \the [S] into place on \the [src].</span>")
to_chat(user, "<span class='notice'>You click [S] into place on [src].</span>")
if(S.on)
set_light(0)
gun_light = S
set_gun_light(S)
update_gunlight(user)
alight = new /datum/action/item_action/toggle_gunlight(src)
alight = new(src)
if(loc == user)
alight.Grant(user)
else if(istype(I, /obj/item/kitchen/knife))
@@ -431,27 +437,133 @@
return ..()
if(!user.transferItemToLoc(I, src))
return
to_chat(user, "<span class='notice'>You attach \the [K] to the front of \the [src].</span>")
to_chat(user, "<span class='notice'>You attach [K] to [src]'s bayonet lug.</span>")
bayonet = K
update_icon()
else if(I.tool_behaviour == TOOL_SCREWDRIVER)
if(gun_light)
var/obj/item/flashlight/seclite/S = gun_light
to_chat(user, "<span class='notice'>You unscrew the seclite from \the [src].</span>")
gun_light = null
S.forceMove(get_turf(user))
update_gunlight(user)
S.update_brightness(user)
QDEL_NULL(alight)
if(bayonet)
to_chat(user, "<span class='notice'>You unscrew the bayonet from \the [src].</span>")
var/obj/item/kitchen/knife/K = bayonet
K.forceMove(get_turf(user))
bayonet = null
update_icon()
else
return ..()
/obj/item/gun/screwdriver_act(mob/living/user, obj/item/I)
. = ..()
if(.)
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 = 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.
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")
else if(pin && user.is_holding(src))
user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [I]."),
span_notice("You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)"), null, 3)
if(I.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, volume = 50))
if(!pin) //check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay
return
user.visible_message(span_notice("[pin] is pried out of [src] by [user], destroying the pin in the process."),
span_warning("You pry [pin] out with [I], destroying the pin in the process."), null, 3)
QDEL_NULL(pin)
return TRUE
/obj/item/gun/welder_act(mob/living/user, obj/item/I)
. = ..()
if(.)
return
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
if(pin && user.is_holding(src))
user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [I]."),
span_notice("You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)"), null, 3)
if(I.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, 5, volume = 50))
if(!pin) //check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay
return
user.visible_message(span_notice("[pin] is spliced out of [src] by [user], melting part of the pin in the process."),
span_warning("You splice [pin] out of [src] with [I], melting part of the pin in the process."), null, 3)
QDEL_NULL(pin)
return TRUE
/obj/item/gun/wirecutter_act(mob/living/user, obj/item/I)
. = ..()
if(.)
return
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
if(pin && user.is_holding(src))
user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [I]."),
span_notice("You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)"), null, 3)
if(I.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, volume = 50))
if(!pin) //check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay
return
user.visible_message(span_notice("[pin] is ripped out of [src] by [user], mangling the pin in the process."),
span_warning("You rip [pin] out of [src] with [I], mangling the pin in the process."), null, 3)
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())
if(Adjacent(user) && !issilicon(user))
user.put_in_hands(item_to_remove)
if(item_to_remove == bayonet)
return clear_bayonet()
else if(item_to_remove == gun_light)
return clear_gunlight()
/obj/item/gun/proc/clear_bayonet()
if(!bayonet)
return
bayonet = null
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))
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)
if(new_light.loc != src)
new_light.forceMove(src)
gun_light = new_light
/obj/item/gun/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/toggle_scope_zoom))
zoom(user, user.dir)
@@ -606,9 +718,16 @@
user.client.view_size.zoomIn()
/obj/item/gun/handle_atom_del(atom/A)
if(A == pin)
pin = null
if(A == chambered)
chambered = null
update_icon()
if(A == bayonet)
clear_bayonet()
if(A == gun_light)
clear_gunlight()
return ..()
/obj/item/gun/proc/getinaccuracy(mob/living/user, bonus_spread, stamloss)
return 0 // Replacement TBD: Exponential curved aim instability system.
@@ -642,3 +761,6 @@
. = recoil
if(user && !user.has_gravity())
. = recoil*5
#undef FIRING_PIN_REMOVAL_DELAY
#undef DUALWIELD_PENALTY_EXTRA_MULTIPLIER