Merge pull request #10892 from kevinz000/small_guncode_refactor
Small guncode refactor but it works
This commit is contained in:
@@ -191,7 +191,7 @@
|
||||
else if(istype(I, /obj/item/gun/energy))
|
||||
var/obj/item/gun/energy/EG = I
|
||||
if(EG.cell?.charge < EG.cell.maxcharge)
|
||||
var/obj/item/ammo_casing/energy/S = EG.ammo_type[EG.select]
|
||||
var/obj/item/ammo_casing/energy/S = EG.ammo_type[EG.current_firemode_index]
|
||||
EG.cell.give(S.e_cost * coeff)
|
||||
if(!EG.chambered)
|
||||
EG.recharge_newshot(TRUE)
|
||||
|
||||
@@ -197,8 +197,6 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/ranged
|
||||
var/obj/item/gun/TrueGun = null
|
||||
var/obj/item/gun/magic/Zapstick
|
||||
@@ -229,14 +227,13 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
|
||||
casingtype = initial(M.ammo_type)
|
||||
if(istype(G, /obj/item/gun/energy))
|
||||
Zapgun = G
|
||||
var/selectfiresetting = Zapgun.select
|
||||
var/obj/item/ammo_casing/energy/E = Zapgun.ammo_type[selectfiresetting]
|
||||
var/obj/item/ammo_casing/energy/E = Zapgun.ammo_type[Zapgun.current_firemode_index]
|
||||
projectiletype = initial(E.projectile_type)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/ranged/OpenFire(the_target)
|
||||
if(Zapgun)
|
||||
if(Zapgun.cell)
|
||||
var/obj/item/ammo_casing/energy/shot = Zapgun.ammo_type[Zapgun.select]
|
||||
var/obj/item/ammo_casing/energy/shot = Zapgun.ammo_type[Zapgun.current_firemode_index]
|
||||
if(Zapgun.cell.charge >= shot.e_cost)
|
||||
Zapgun.cell.use(shot.e_cost)
|
||||
Zapgun.update_icon()
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
|
||||
/obj/item/ammo_casing/energy/plasma/weak
|
||||
projectile_type = /obj/item/projectile/plasma/weak
|
||||
e_cost = 100
|
||||
e_cost = 100
|
||||
|
||||
@@ -28,10 +28,19 @@
|
||||
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
|
||||
var/fire_delay = 0 //rate of fire for burst firing and semi auto
|
||||
var/firing_burst = 0 //Prevent the weapon from firing again while already firing
|
||||
var/semicd = 0 //cooldown handler
|
||||
|
||||
/// Weapon is burst fire if this is above 1
|
||||
var/burst_size = 1
|
||||
/// The time between shots in burst.
|
||||
var/burst_shot_delay = 3
|
||||
/// The time between firing actions, this means between bursts if this is burst weapon. The reason this is 0 is because you are still, by default, limited by clickdelay.
|
||||
var/fire_delay = 0
|
||||
/// Last world.time this was fired
|
||||
var/last_fire = 0
|
||||
/// Currently firing, whether or not it's a burst or not.
|
||||
var/firing = FALSE
|
||||
/// Used in gun-in-mouth execution/suicide and similar, while TRUE nothing should work on this like firing or modification and so on and so forth.
|
||||
var/busy_action = FALSE
|
||||
var/weapon_weight = WEAPON_LIGHT //currently only used for inaccuracy
|
||||
var/spread = 0 //Spread induced by the gun itself.
|
||||
var/burst_spread = 0 //Spread induced by the gun itself during burst fire per iteration. Only checked if spread is 0.
|
||||
@@ -117,13 +126,12 @@
|
||||
to_chat(user, "<span class='danger'>*click*</span>")
|
||||
playsound(src, "gun_dry_fire", 30, 1)
|
||||
|
||||
|
||||
/obj/item/gun/proc/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1)
|
||||
if(recoil)
|
||||
shake_camera(user, recoil + 1, recoil)
|
||||
|
||||
if(isliving(user)) //CIT CHANGE - makes gun recoil cause staminaloss
|
||||
user.adjustStaminaLossBuffered(getstamcost(user)*(firing_burst && burst_size >= 2 ? 1/burst_size : 1)) //CIT CHANGE - ditto
|
||||
user.adjustStaminaLossBuffered(getstamcost(user)*(firing && burst_size >= 2 ? 1/burst_size : 1)) //CIT CHANGE - ditto
|
||||
|
||||
if(suppressed)
|
||||
playsound(user, fire_sound, 10, 1)
|
||||
@@ -143,9 +151,12 @@
|
||||
|
||||
/obj/item/gun/afterattack(atom/target, mob/living/user, flag, params)
|
||||
. = ..()
|
||||
process_afterattack(target, user, flag, params)
|
||||
|
||||
/obj/item/gun/proc/process_afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(!target)
|
||||
return
|
||||
if(firing_burst)
|
||||
if(firing)
|
||||
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.
|
||||
@@ -169,7 +180,6 @@
|
||||
handle_suicide(user, target, params)
|
||||
return
|
||||
|
||||
|
||||
//Exclude lasertag guns from the TRAIT_CLUMSY check.
|
||||
if(clumsy_check)
|
||||
if(istype(user))
|
||||
@@ -201,8 +211,6 @@
|
||||
|
||||
process_fire(target, user, TRUE, params, null, bonus_spread)
|
||||
|
||||
|
||||
|
||||
/obj/item/gun/can_trigger_gun(mob/living/user)
|
||||
. = ..()
|
||||
if(!.)
|
||||
@@ -227,54 +235,29 @@
|
||||
/obj/item/gun/proc/recharge_newshot()
|
||||
return
|
||||
|
||||
/obj/item/gun/proc/process_burst(mob/living/user, atom/target, message = TRUE, params=null, zone_override = "", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0)
|
||||
if(!user || !firing_burst)
|
||||
firing_burst = FALSE
|
||||
return FALSE
|
||||
if(!issilicon(user))
|
||||
if(iteration > 1 && !(user.is_holding(src))) //for burst firing
|
||||
firing_burst = FALSE
|
||||
return FALSE
|
||||
if(chambered && chambered.BB)
|
||||
if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal.
|
||||
if(chambered.harmful) // Is the bullet chambered harmful?
|
||||
to_chat(user, "<span class='notice'> [src] is lethally chambered! You don't want to risk harming anyone...</span>")
|
||||
return
|
||||
if(randomspread)
|
||||
sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread), 1)
|
||||
else //Smart spread
|
||||
sprd = round((((rand_spr/burst_size) * iteration) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread), 1)
|
||||
before_firing(target,user)
|
||||
if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, sprd, src))
|
||||
shoot_with_empty_chamber(user)
|
||||
firing_burst = FALSE
|
||||
return FALSE
|
||||
else
|
||||
if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot
|
||||
shoot_live_shot(user, 1, target, message)
|
||||
else
|
||||
shoot_live_shot(user, 0, target, message)
|
||||
if (iteration >= burst_size)
|
||||
firing_burst = FALSE
|
||||
else
|
||||
shoot_with_empty_chamber(user)
|
||||
firing_burst = FALSE
|
||||
return FALSE
|
||||
process_chamber()
|
||||
update_icon()
|
||||
return TRUE
|
||||
/obj/item/gun/proc/on_cooldown()
|
||||
return busy_action || firing || (last_fire + fire_delay > world.time)
|
||||
|
||||
/obj/item/gun/proc/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
|
||||
add_fingerprint(user)
|
||||
|
||||
if(semicd)
|
||||
if(on_cooldown())
|
||||
return
|
||||
firing = TRUE
|
||||
. = do_fire(target, user, message, params, zone_override, bonus_spread)
|
||||
firing = FALSE
|
||||
last_fire = world.time
|
||||
|
||||
if(user)
|
||||
user.update_inv_hands()
|
||||
SEND_SIGNAL(user, COMSIG_LIVING_GUN_PROCESS_FIRE, target, params, zone_override)
|
||||
|
||||
/obj/item/gun/proc/do_fire(atom/target, mob/living/user, message = TRUE, params, zone_override = "", bonus_spread = 0)
|
||||
var/sprd = 0
|
||||
var/randomized_gun_spread = 0
|
||||
var/rand_spr = rand()
|
||||
if(spread)
|
||||
randomized_gun_spread = rand(0, spread)
|
||||
randomized_gun_spread = rand(0, spread)
|
||||
else if(burst_size > 1 && burst_spread)
|
||||
randomized_gun_spread = rand(0, burst_spread)
|
||||
if(HAS_TRAIT(user, TRAIT_POOR_AIM)) //nice shootin' tex
|
||||
@@ -282,9 +265,12 @@
|
||||
var/randomized_bonus_spread = rand(0, bonus_spread)
|
||||
|
||||
if(burst_size > 1)
|
||||
firing_burst = TRUE
|
||||
for(var/i = 1 to burst_size)
|
||||
addtimer(CALLBACK(src, .proc/process_burst, user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i), fire_delay * (i - 1))
|
||||
do_burst_shot(user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, 1)
|
||||
for(var/i in 2 to burst_size)
|
||||
sleep(burst_shot_delay)
|
||||
if(QDELETED(src))
|
||||
break
|
||||
do_burst_shot(user, target, message, params, zone_override, sprd, randomized_gun_spread, randomized_bonus_spread, rand_spr, i)
|
||||
else
|
||||
if(chambered)
|
||||
sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
|
||||
@@ -302,21 +288,46 @@
|
||||
return
|
||||
process_chamber()
|
||||
update_icon()
|
||||
semicd = TRUE
|
||||
addtimer(CALLBACK(src, .proc/reset_semicd), fire_delay)
|
||||
|
||||
if(user)
|
||||
user.update_inv_hands()
|
||||
SEND_SIGNAL(user, COMSIG_LIVING_GUN_PROCESS_FIRE, target, params, zone_override)
|
||||
SSblackbox.record_feedback("tally", "gun_fired", 1, type)
|
||||
return TRUE
|
||||
|
||||
/obj/item/gun/update_icon()
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/gun/proc/reset_semicd()
|
||||
semicd = FALSE
|
||||
/obj/item/gun/proc/do_burst_shot(mob/living/user, atom/target, message = TRUE, params=null, zone_override = "", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0)
|
||||
if(!user || !firing)
|
||||
firing = FALSE
|
||||
return FALSE
|
||||
if(!issilicon(user))
|
||||
if(iteration > 1 && !(user.is_holding(src))) //for burst firing
|
||||
firing = FALSE
|
||||
return FALSE
|
||||
if(chambered && chambered.BB)
|
||||
if(HAS_TRAIT(user, TRAIT_PACIFISM)) // If the user has the pacifist trait, then they won't be able to fire [src] if the round chambered inside of [src] is lethal.
|
||||
if(chambered.harmful) // Is the bullet chambered harmful?
|
||||
to_chat(user, "<span class='notice'> [src] is lethally chambered! You don't want to risk harming anyone...</span>")
|
||||
return
|
||||
if(randomspread)
|
||||
sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread), 1)
|
||||
else //Smart spread
|
||||
sprd = round((((rand_spr/burst_size) * iteration) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread), 1)
|
||||
before_firing(target,user)
|
||||
if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, sprd, src))
|
||||
shoot_with_empty_chamber(user)
|
||||
firing = FALSE
|
||||
return FALSE
|
||||
else
|
||||
if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot
|
||||
shoot_live_shot(user, 1, target, message)
|
||||
else
|
||||
shoot_live_shot(user, 0, target, message)
|
||||
if (iteration >= burst_size)
|
||||
firing = FALSE
|
||||
else
|
||||
shoot_with_empty_chamber(user)
|
||||
firing = FALSE
|
||||
return FALSE
|
||||
process_chamber()
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/item/gun/attack(mob/M as mob, mob/user)
|
||||
if(user.a_intent == INTENT_HARM) //Flogging
|
||||
@@ -437,7 +448,7 @@
|
||||
if(!ishuman(user) || !ishuman(target))
|
||||
return
|
||||
|
||||
if(semicd)
|
||||
if(on_cooldown())
|
||||
return
|
||||
|
||||
if(user == target)
|
||||
@@ -447,7 +458,7 @@
|
||||
target.visible_message("<span class='warning'>[user] points [src] at [target]'s head, ready to pull the trigger...</span>", \
|
||||
"<span class='userdanger'>[user] points [src] at your head, ready to pull the trigger...</span>")
|
||||
|
||||
semicd = TRUE
|
||||
busy_action = TRUE
|
||||
|
||||
if(!bypass_timer && (!do_mob(user, target, 120) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH))
|
||||
if(user)
|
||||
@@ -455,10 +466,10 @@
|
||||
user.visible_message("<span class='notice'>[user] decided not to shoot.</span>")
|
||||
else if(target && target.Adjacent(user))
|
||||
target.visible_message("<span class='notice'>[user] has decided to spare [target]</span>", "<span class='notice'>[user] has decided to spare your life!</span>")
|
||||
semicd = FALSE
|
||||
busy_action = FALSE
|
||||
return
|
||||
|
||||
semicd = FALSE
|
||||
busy_action = FALSE
|
||||
|
||||
target.visible_message("<span class='warning'>[user] pulls the trigger!</span>", "<span class='userdanger'>[user] pulls the trigger!</span>")
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
var/automatic_burst_overlay = TRUE
|
||||
can_suppress = TRUE
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
burst_shot_delay = 2
|
||||
actions_types = list(/datum/action/item_action/toggle_firemode)
|
||||
|
||||
/obj/item/gun/ballistic/automatic/proto
|
||||
@@ -77,11 +77,9 @@
|
||||
|
||||
/obj/item/gun/ballistic/automatic/proc/enable_burst()
|
||||
burst_size = initial(burst_size)
|
||||
fire_delay = initial(fire_delay)
|
||||
|
||||
/obj/item/gun/ballistic/automatic/proc/disable_burst()
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
|
||||
/obj/item/gun/ballistic/automatic/can_shoot()
|
||||
return get_ammo()
|
||||
@@ -100,7 +98,7 @@
|
||||
item_state = "c20r"
|
||||
mag_type = /obj/item/ammo_box/magazine/smgm45
|
||||
fire_sound = 'sound/weapons/gunshot_smg.ogg'
|
||||
fire_delay = 2
|
||||
burst_shot_delay = 2
|
||||
burst_size = 2
|
||||
pin = /obj/item/firing_pin/implant/pindicate
|
||||
can_bayonet = TRUE
|
||||
@@ -130,7 +128,7 @@
|
||||
mag_type = /obj/item/ammo_box/magazine/wt550m9
|
||||
can_suppress = FALSE
|
||||
burst_size = 2
|
||||
fire_delay = 1
|
||||
burst_shot_delay = 1
|
||||
can_bayonet = TRUE
|
||||
knife_x_offset = 25
|
||||
knife_y_offset = 12
|
||||
@@ -165,7 +163,7 @@
|
||||
can_suppress = FALSE
|
||||
var/obj/item/gun/ballistic/revolver/grenadelauncher/underbarrel
|
||||
burst_size = 3
|
||||
fire_delay = 2
|
||||
burst_shot_delay = 2
|
||||
pin = /obj/item/firing_pin/implant/pindicate
|
||||
|
||||
/obj/item/gun/ballistic/automatic/m90/Initialize()
|
||||
@@ -212,7 +210,6 @@
|
||||
if(0)
|
||||
select = 1
|
||||
burst_size = initial(burst_size)
|
||||
fire_delay = initial(fire_delay)
|
||||
to_chat(user, "<span class='notice'>You switch to [burst_size]-rnd burst.</span>")
|
||||
if(1)
|
||||
select = 2
|
||||
@@ -220,7 +217,6 @@
|
||||
if(2)
|
||||
select = 0
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
to_chat(user, "<span class='notice'>You switch to semi-auto.</span>")
|
||||
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
|
||||
update_icon()
|
||||
@@ -237,7 +233,7 @@
|
||||
fire_sound = 'sound/weapons/gunshot_smg.ogg'
|
||||
can_suppress = FALSE
|
||||
burst_size = 4
|
||||
fire_delay = 1
|
||||
burst_shot_delay = 1
|
||||
|
||||
/obj/item/gun/ballistic/automatic/ar
|
||||
name = "\improper NT-ARG 'Boarder'"
|
||||
@@ -249,7 +245,7 @@
|
||||
fire_sound = 'sound/weapons/gunshot_smg.ogg'
|
||||
can_suppress = FALSE
|
||||
burst_size = 3
|
||||
fire_delay = 1
|
||||
burst_shot_delay = 1
|
||||
|
||||
// Bulldog shotgun //
|
||||
|
||||
@@ -264,7 +260,6 @@
|
||||
fire_sound = 'sound/weapons/gunshot.ogg'
|
||||
can_suppress = FALSE
|
||||
burst_size = 1
|
||||
fire_delay = 0
|
||||
pin = /obj/item/firing_pin/implant/pindicate
|
||||
actions_types = list()
|
||||
|
||||
@@ -301,7 +296,7 @@
|
||||
var/cover_open = FALSE
|
||||
can_suppress = FALSE
|
||||
burst_size = 3
|
||||
fire_delay = 1
|
||||
burst_shot_delay = 1
|
||||
spread = 7
|
||||
pin = /obj/item/firing_pin/implant/pindicate
|
||||
|
||||
@@ -421,7 +416,7 @@
|
||||
mag_type = /obj/item/ammo_box/magazine/recharge
|
||||
fire_delay = 2
|
||||
can_suppress = FALSE
|
||||
burst_size = 0
|
||||
burst_size = 1
|
||||
actions_types = list()
|
||||
fire_sound = 'sound/weapons/laser.ogg'
|
||||
casing_ejector = FALSE
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
/*
|
||||
* Energy guns that draw from a cell to fire.
|
||||
*
|
||||
* This is a bit weird but this is how it currently works:
|
||||
* When switching shots, it clears the chamber, and loads the correct energy ammo casing if there is enough energy to fire it.
|
||||
* If there's no projectile in the casing, it creates it now.
|
||||
* Otherwise the chamber stays null.
|
||||
* After firing, it actually deducts the energy and then clears the chamber and does the above again.
|
||||
* It detects if a successful fire is done by checking if the chambered energy ammo casing still has its projectile intact.
|
||||
*
|
||||
* It might be good in the future to move away from ammo casinsgs and instead use a datum-firemode system, but that would make handling firing,
|
||||
* which the casing does as of now, a little interesting to implement.
|
||||
*/
|
||||
/obj/item/gun/energy
|
||||
icon_state = "energy"
|
||||
name = "energy gun"
|
||||
@@ -7,8 +20,10 @@
|
||||
var/obj/item/stock_parts/cell/cell //What type of power cell this uses
|
||||
var/cell_type = /obj/item/stock_parts/cell
|
||||
var/modifystate = 0
|
||||
var/list/ammo_type = list(/obj/item/ammo_casing/energy)
|
||||
var/select = 1 //The state of the select fire switch. Determines from the ammo_type list what kind of shot is fired next.
|
||||
/// = TRUE/FALSE decides if the user can switch to it of their own accord
|
||||
var/list/ammo_type = list(/obj/item/ammo_casing/energy = TRUE)
|
||||
/// The index of the ammo_types/firemodes which we're using right now
|
||||
var/current_firemode_index = 1
|
||||
var/can_charge = 1 //Can it be charged in a recharger?
|
||||
var/automatic_charge_overlays = TRUE //Do we handle overlays with base update_icon()?
|
||||
var/charge_sections = 4
|
||||
@@ -21,6 +36,9 @@
|
||||
var/use_cyborg_cell = FALSE //whether the gun drains the cyborg user's cell instead, not to be confused with EGUN_SELFCHARGE_BORG
|
||||
var/dead_cell = FALSE //set to true so the gun is given an empty cell
|
||||
|
||||
/// SET THIS TO TRUE IF YOU OVERRIDE altafterattack() or ANY right click action! If this is FALSE, the gun will show in examine its default right click behavior, which is to switch modes.
|
||||
var/right_click_overridden = FALSE
|
||||
|
||||
/obj/item/gun/energy/emp_act(severity)
|
||||
. = ..()
|
||||
if(!(. & EMP_PROTECT_CONTENTS))
|
||||
@@ -46,16 +64,6 @@
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/energy/proc/update_ammo_types()
|
||||
var/obj/item/ammo_casing/energy/shot
|
||||
for (var/i = 1, i <= ammo_type.len, i++)
|
||||
var/shottype = ammo_type[i]
|
||||
shot = new shottype(src)
|
||||
ammo_type[i] = shot
|
||||
shot = ammo_type[select]
|
||||
fire_sound = shot.fire_sound
|
||||
fire_delay = shot.delay
|
||||
|
||||
/obj/item/gun/energy/Destroy()
|
||||
if(flags_1 & INITIALIZED_1)
|
||||
QDEL_NULL(cell)
|
||||
@@ -63,6 +71,11 @@
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/examine(mob/user)
|
||||
. = ..()
|
||||
if(!right_click_overridden)
|
||||
. += "<span class='notice'>Right click in combat mode to switch modes.</span>"
|
||||
|
||||
/obj/item/gun/energy/process()
|
||||
if(selfcharge && cell?.charge < cell.maxcharge)
|
||||
charge_tick++
|
||||
@@ -83,13 +96,14 @@
|
||||
recharge_newshot(TRUE)
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/energy/attack_self(mob/living/user as mob)
|
||||
if(ammo_type.len > 1)
|
||||
// ATTACK SELF IGNORING PARENT RETURN VALUE
|
||||
/obj/item/gun/energy/attack_self(mob/living/user)
|
||||
. = ..()
|
||||
if(can_select_fire(user))
|
||||
select_fire(user)
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/energy/can_shoot()
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
|
||||
return !QDELETED(cell) ? (cell.charge >= shot.e_cost) : FALSE
|
||||
|
||||
/obj/item/gun/energy/recharge_newshot(no_cyborg_drain)
|
||||
@@ -99,11 +113,11 @@
|
||||
if(iscyborg(loc))
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
if(R.cell)
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select] //Necessary to find cost of shot
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index] //Necessary to find cost of shot
|
||||
if(R.cell.use(shot.e_cost)) //Take power from the borg...
|
||||
cell.give(shot.e_cost) //... to recharge the shot
|
||||
if(!chambered)
|
||||
var/obj/item/ammo_casing/energy/AC = ammo_type[select]
|
||||
var/obj/item/ammo_casing/energy/AC = ammo_type[current_firemode_index]
|
||||
if(cell.charge >= AC.e_cost) //if there's enough power in the cell cell...
|
||||
chambered = AC //...prepare a new shot based on the current ammo type selected
|
||||
if(!chambered.BB)
|
||||
@@ -116,29 +130,104 @@
|
||||
chambered = null //either way, released the prepared shot
|
||||
recharge_newshot() //try to charge a new shot
|
||||
|
||||
/obj/item/gun/energy/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
|
||||
/obj/item/gun/energy/do_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
|
||||
if(!chambered && can_shoot())
|
||||
process_chamber() // If the gun was drained and then recharged, load a new shot.
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/process_burst(mob/living/user, atom/target, message = TRUE, params = null, zone_override="", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0)
|
||||
/obj/item/gun/energy/do_burst_shot(mob/living/user, atom/target, message = TRUE, params = null, zone_override="", sprd = 0, randomized_gun_spread = 0, randomized_bonus_spread = 0, rand_spr = 0, iteration = 0)
|
||||
if(!chambered && can_shoot())
|
||||
process_chamber() // Ditto.
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/energy/proc/select_fire(mob/living/user)
|
||||
select++
|
||||
if (select > ammo_type.len)
|
||||
select = 1
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
fire_sound = shot.fire_sound
|
||||
fire_delay = shot.delay
|
||||
if (shot.select_name)
|
||||
to_chat(user, "<span class='notice'>[src] is now set to [shot.select_name].</span>")
|
||||
chambered = null
|
||||
recharge_newshot(TRUE)
|
||||
// Firemodes/Ammotypes
|
||||
|
||||
/obj/item/gun/energy/proc/update_ammo_types()
|
||||
var/obj/item/ammo_casing/energy/C
|
||||
for(var/i in 1 to length(ammo_type))
|
||||
var/v = ammo_type[i]
|
||||
var/user_can_select = ammo_type[v]
|
||||
if(istype(v, /obj/item/ammo_casing/energy)) //already set
|
||||
ammo_type[v] = isnull(user_can_select)? TRUE : user_can_select
|
||||
else
|
||||
C = new v //if you put non energycasing/type stuff in here you deserve the runtime
|
||||
ammo_type[i] = C
|
||||
ammo_type[C] = isnull(user_can_select)? TRUE : user_can_select
|
||||
set_firemode_index(initial(current_firemode_index))
|
||||
|
||||
/obj/item/gun/energy/proc/set_firemode_index(index, mob/user_for_feedback)
|
||||
chambered = null //unchamber whatever we have chambered
|
||||
if(index > length(ammo_type))
|
||||
index = 1
|
||||
else if(index < 1)
|
||||
index = length(ammo_type)
|
||||
var/obj/item/ammo_casing/energy/C = ammo_type[index] //energy weapons should not have no casings, if it does you deserve the runtime.
|
||||
current_firemode_index = index
|
||||
fire_sound = C.fire_sound
|
||||
fire_delay = C.delay
|
||||
if(user_for_feedback)
|
||||
to_chat(user_for_feedback, "<span class='notice'>[src] is now set to [C.select_name || C].</span>")
|
||||
post_set_firemode()
|
||||
update_icon(TRUE)
|
||||
return
|
||||
|
||||
/obj/item/gun/energy/proc/post_set_firemode(recharge_newshot = TRUE)
|
||||
if(recharge_newshot)
|
||||
recharge_newshot(TRUE)
|
||||
|
||||
/obj/item/gun/energy/proc/set_firemode_to_next(mob/user_for_feedback)
|
||||
return set_firemode_index(++current_firemode_index, user_for_feedback)
|
||||
|
||||
/obj/item/gun/energy/proc/set_firemode_to_prev(mob/user_for_feedback)
|
||||
return set_firemode_index(--current_firemode_index, user_for_feedback)
|
||||
|
||||
/obj/item/gun/energy/proc/get_firemode_index(casing_type)
|
||||
var/obj/item/ammo_casing/energy/E = locate(casing_type) in ammo_type
|
||||
if(E)
|
||||
return ammo_type.Find(E)
|
||||
|
||||
/obj/item/gun/energy/proc/set_firemode_to_type(casing_type)
|
||||
var/index = get_firemode_index(casing_type)
|
||||
if(index)
|
||||
set_firemode_index(index)
|
||||
|
||||
/// This is the proc used in general for when a user switches firemodes. Just goes to next firemode by default.
|
||||
/obj/item/gun/energy/proc/select_fire(mob/living/user)
|
||||
return user_set_firemode_to_next(user)
|
||||
|
||||
/obj/item/gun/energy/proc/can_select_fire(mob/living/user)
|
||||
return TRUE
|
||||
|
||||
#define INCREMENT_OR_WRAP(i) i = (i >= length(ammo_type))? 1 : (i + 1)
|
||||
#define DECREMENT_OR_WRAP(i) i = (i <= 1)? length(ammo_type) : (i - 1)
|
||||
#define IS_VALID_INDEX(i) (ammo_type[ammo_type[i]])
|
||||
/obj/item/gun/energy/proc/user_set_firemode_to_next(mob/user_for_feedback)
|
||||
var/current_index = current_firemode_index
|
||||
var/new_index = current_index
|
||||
INCREMENT_OR_WRAP(new_index)
|
||||
if(!IS_VALID_INDEX(new_index))
|
||||
var/initial_index = new_index
|
||||
while(!IS_VALID_INDEX(new_index) && (new_index != initial_index))
|
||||
new_index = INCREMENT_OR_WRAP(new_index)
|
||||
if(initial_index == new_index) //cycled through without finding another
|
||||
new_index = current_index
|
||||
|
||||
set_firemode_index(new_index, user_for_feedback)
|
||||
|
||||
/obj/item/gun/energy/proc/user_set_firemode_to_prev(mob/user_for_feedback)
|
||||
var/current_index = current_firemode_index
|
||||
var/new_index = current_index
|
||||
DECREMENT_OR_WRAP(new_index)
|
||||
if(!IS_VALID_INDEX(new_index))
|
||||
var/initial_index = new_index
|
||||
while(!IS_VALID_INDEX(new_index) && (new_index != initial_index))
|
||||
new_index = DECREMENT_OR_WRAP(new_index)
|
||||
if(initial_index == new_index) //cycled through without finding another
|
||||
new_index = current_index
|
||||
|
||||
set_firemode_index(new_index, user_for_feedback)
|
||||
#undef INCREMENT_OR_WRAP
|
||||
#undef DECREMENT_OR_WRAP
|
||||
#undef IS_VALID_INDEX
|
||||
|
||||
/obj/item/gun/energy/update_icon(force_update)
|
||||
if(QDELETED(src))
|
||||
@@ -158,7 +247,7 @@
|
||||
if(!initial(item_state))
|
||||
itemState = icon_state
|
||||
if (modifystate)
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
|
||||
add_overlay("[icon_state]_[shot.select_name]")
|
||||
iconState += "_[shot.select_name]"
|
||||
if(itemState)
|
||||
@@ -177,6 +266,9 @@
|
||||
if(itemState)
|
||||
itemState += "[ratio]"
|
||||
item_state = itemState
|
||||
if(ismob(loc)) //forces inhands to update
|
||||
var/mob/M = loc
|
||||
M.update_inv_hands()
|
||||
|
||||
/obj/item/gun/energy/suicide_act(mob/living/user)
|
||||
if (istype(user) && can_shoot() && can_trigger_gun(user) && user.get_bodypart(BODY_ZONE_HEAD))
|
||||
@@ -186,7 +278,7 @@
|
||||
user.visible_message("<span class='suicide'>[user] melts [user.p_their()] face off with [src]!</span>")
|
||||
playsound(loc, fire_sound, 50, 1, -1)
|
||||
playsound(src, 'sound/weapons/dink.ogg', 30, 1)
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
|
||||
cell.use(shot.e_cost)
|
||||
update_icon()
|
||||
return(FIRELOSS)
|
||||
@@ -208,13 +300,12 @@
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
|
||||
/obj/item/gun/energy/ignition_effect(atom/A, mob/living/user)
|
||||
if(!can_shoot() || !ammo_type[select])
|
||||
if(!can_shoot() || !ammo_type[current_firemode_index])
|
||||
shoot_with_empty_chamber()
|
||||
. = ""
|
||||
else
|
||||
var/obj/item/ammo_casing/energy/E = ammo_type[select]
|
||||
var/obj/item/ammo_casing/energy/E = ammo_type[current_firemode_index]
|
||||
var/obj/item/projectile/energy/BB = E.BB
|
||||
if(!BB)
|
||||
. = ""
|
||||
@@ -236,3 +327,9 @@
|
||||
playsound(user, BB.hitsound, 50, 1)
|
||||
cell.use(E.e_cost)
|
||||
. = "<span class='danger'>[user] casually lights their [A.name] with [src]. Damn.</span>"
|
||||
|
||||
/obj/item/gun/energy/altafterattack(atom/target, mob/user, proximity_flags, params)
|
||||
if(!right_click_overridden)
|
||||
select_fire(user)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
@@ -202,7 +202,7 @@
|
||||
if(!ishuman(user) || !ishuman(target))
|
||||
return
|
||||
|
||||
if(semicd)
|
||||
if(on_cooldown())
|
||||
return
|
||||
|
||||
if(user == target)
|
||||
@@ -212,7 +212,7 @@
|
||||
target.visible_message("<span class='warning'>[user] points [src] at [target]'s head, ready to pull the trigger...</span>", \
|
||||
"<span class='userdanger'>[user] points [src] at your head, ready to pull the trigger...</span>")
|
||||
|
||||
semicd = TRUE
|
||||
busy_action = TRUE
|
||||
|
||||
if(!bypass_timer && (!do_mob(user, target, 120) || user.zone_selected != BODY_ZONE_PRECISE_MOUTH))
|
||||
if(user)
|
||||
@@ -220,10 +220,10 @@
|
||||
user.visible_message("<span class='notice'>[user] decided not to shoot.</span>")
|
||||
else if(target && target.Adjacent(user))
|
||||
target.visible_message("<span class='notice'>[user] has decided to spare [target]</span>", "<span class='notice'>[user] has decided to spare your life!</span>")
|
||||
semicd = FALSE
|
||||
busy_action = FALSE
|
||||
return
|
||||
|
||||
semicd = FALSE
|
||||
busy_action = FALSE
|
||||
|
||||
target.visible_message("<span class='warning'>[user] pulls the trigger!</span>", "<span class='userdanger'>[user] pulls the trigger!</span>")
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
/obj/item/gun/energy/decloner/update_icon()
|
||||
..()
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
|
||||
if(!QDELETED(cell) && (cell.charge > shot.e_cost))
|
||||
add_overlay("decloner_spin")
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
var/atmos_link = FALSE
|
||||
|
||||
/obj/item/gun/energy/wormhole_projector/update_icon()
|
||||
icon_state = "[initial(icon_state)][select]"
|
||||
icon_state = "[initial(icon_state)][current_firemode_index]"
|
||||
item_state = icon_state
|
||||
|
||||
/obj/item/gun/energy/wormhole_projector/update_ammo_types()
|
||||
@@ -320,7 +320,7 @@
|
||||
|
||||
/obj/item/gun/energy/emitter/update_icon()
|
||||
..()
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
|
||||
var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
|
||||
if(!QDELETED(cell) && (cell.charge > shot.e_cost))
|
||||
add_overlay("emitter_carbine_empty")
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user