mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-19 03:49:10 +01:00
d8e02149e0
Human_defense was calling it's parent, which also EMP'd all carried items, so carried items were taking two EMP acts. This mean that PDAs always exploded from light EMPs. Energy guns used sleep() in their EMP act and didn't multiply by * SECONDS. EMP_LIGHT is 2 and EMP_HEAVY is 1, previous implementation was multiplying where it should divide. Also added some feedback about why the gun won't fire. Now decrements a timer in process, 10 seconds for a light EMP, 20 seconds for a heavy EMP.
338 lines
11 KiB
Plaintext
338 lines
11 KiB
Plaintext
ABSTRACT_TYPE(/obj/item/gun/energy)
|
|
name = "energy gun"
|
|
desc = "A basic energy-based gun."
|
|
icon = 'icons/obj/guns/faction/nanotrasen_corporation/ecarbine.dmi'
|
|
icon_state = "energykill100"
|
|
item_state = "energykill100"
|
|
fire_sound = 'sound/weapons/Taser.ogg'
|
|
fire_sound_text = "laser blast"
|
|
update_icon_on_init = TRUE
|
|
|
|
safetyon_sound = 'sound/weapons/laser_safetyon.ogg'
|
|
safetyoff_sound = 'sound/weapons/laser_safetyoff.ogg'
|
|
|
|
/// Does this gun use the ratio system to modify its icon_state?
|
|
var/has_icon_ratio = TRUE
|
|
/// Does this gun use the ratio system to paint its item_states?
|
|
var/has_item_ratio = TRUE
|
|
|
|
/// What type of power cell this uses.
|
|
var/obj/item/cell/power_supply
|
|
/// How much energy is needed to fire.
|
|
var/charge_cost = 200
|
|
/// Determines the capacity of the weapon's power cell. Specifying a cell_type overrides this value.
|
|
var/max_shots = 10
|
|
var/cell_type = null
|
|
/// Also passed to turrets.
|
|
var/projectile_type = /obj/projectile/beam/practice
|
|
var/modifystate
|
|
/// If set, the icon state will be chosen based on the current charge.
|
|
var/charge_meter = 1
|
|
/// This list matches with firemode index, used to determine which firemodes get unlocked with what level of authorization.
|
|
var/list/required_firemode_auth
|
|
///How long the gun is disabled for after an emp, is set in emp_act and counted down in process.
|
|
var/emp_disable_time
|
|
///Initial charge
|
|
var/initial_charge
|
|
//self-recharging
|
|
/// If set, the weapon will recharge itself.
|
|
var/self_recharge = FALSE
|
|
/// If set, the weapon will look for an external power source to draw from, otherwise it recharges magically
|
|
var/use_external_power = FALSE
|
|
var/recharge_time = 4
|
|
/// Multiplies by charge cost to determine how much charge should be returned
|
|
var/recharge_multiplier = 1
|
|
var/charge_tick = 0
|
|
|
|
/// External power source for the gun. Checked by get_external_power_supply()
|
|
var/obj/item/recharger
|
|
|
|
// Vars passed to turrets
|
|
/// If TRUE, allows you to attach the gun on a turret.
|
|
var/can_turret = FALSE
|
|
/// If null, turret defaults to projectile_type.
|
|
var/secondary_projectile_type = null
|
|
/// If null, turret defaults to fire_sound.
|
|
var/secondary_fire_sound = null
|
|
/// If TRUE, allows switching lethal and stun modes.
|
|
var/can_switch_modes = FALSE
|
|
/// Set of sprites to use for the turret gun.
|
|
var/turret_sprite_set = "carbine"
|
|
/// Is the gun in lethal (secondary) mode by default?
|
|
var/turret_is_lethal = TRUE
|
|
|
|
/obj/item/gun/energy/mechanics_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
. += "This is an energy weapon. Most energy weapons can fire through windows harmlessly. Energy weapons must be recharged once depleted."
|
|
if(can_turret)
|
|
. += "This weapon can be installed on a turret mount."
|
|
|
|
/obj/item/gun/energy/feedback_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
if(distance > 1)
|
|
return
|
|
var/shots_remaining = round(power_supply.charge / charge_cost)
|
|
. += "It has [shots_remaining] shot\s remaining."
|
|
|
|
/obj/item/gun/energy/switch_firemodes()
|
|
. = ..()
|
|
if(.)
|
|
update_icon()
|
|
|
|
/obj/item/gun/energy/emp_act(severity)
|
|
. = ..()
|
|
|
|
if(!power_supply)
|
|
return
|
|
|
|
if(!emp_disable_time)
|
|
var/mob/M
|
|
if(ismob(loc))
|
|
M = loc
|
|
if(power_supply.charge > 0)
|
|
to_chat(M, SPAN_DANGER("\The [src] locks up as the EMP scrambles it!"))
|
|
playsound(M, 'sound/weapons/smg_empty_alarm.ogg', 30)
|
|
initial_charge = power_supply.charge
|
|
power_supply.charge = 0
|
|
SSicon_update.add_to_queue(src)
|
|
START_PROCESSING(SSprocessing, src)
|
|
|
|
emp_disable_time = max(emp_disable_time, 20 / severity)
|
|
|
|
/obj/item/gun/energy/process(seconds_per_tick)
|
|
|
|
emp_disable_time = max(0, emp_disable_time - seconds_per_tick)
|
|
|
|
if (!emp_disable_time)
|
|
STOP_PROCESSING(SSprocessing, src)
|
|
restore_gun_charge()
|
|
|
|
/obj/item/gun/energy/proc/restore_gun_charge()
|
|
power_supply.give(initial_charge)
|
|
var/mob/M
|
|
if(ismob(loc))
|
|
M = loc
|
|
if (power_supply.charge > charge_cost)
|
|
playsound(M, 'sound/weapons/laser_safetyoff.ogg', 30)
|
|
to_chat(M, SPAN_NOTICE("\The [src] clicks as it resets, ready to fire again!"))
|
|
update_maptext()
|
|
update_icon()
|
|
|
|
/obj/item/gun/energy/get_cell()
|
|
return power_supply
|
|
|
|
/obj/item/gun/energy/Initialize()
|
|
. = ..()
|
|
if(cell_type)
|
|
power_supply = new cell_type(src)
|
|
else
|
|
power_supply = new /obj/item/cell/device/variable(src, max_shots*charge_cost)
|
|
update_maptext()
|
|
|
|
/obj/item/gun/energy/Destroy()
|
|
if(recharger)
|
|
disconnect()
|
|
QDEL_NULL(power_supply)
|
|
return ..()
|
|
|
|
/obj/item/gun/energy/proc/try_recharge()
|
|
. = 1
|
|
if (!power_supply || power_supply.charge >= power_supply.maxcharge || !self_recharge)
|
|
return 0 // check if we actually need to recharge
|
|
|
|
if (use_external_power)
|
|
var/obj/item/cell/external = get_external_power_supply()
|
|
if(!external || !external.use(charge_cost)) //Take power from the borg...
|
|
return 0
|
|
|
|
power_supply.give(charge_cost * recharge_multiplier) //... to recharge the shot
|
|
update_maptext()
|
|
update_icon()
|
|
|
|
addtimer(CALLBACK(src, PROC_REF(try_recharge)), recharge_time * 2 SECONDS, TIMER_UNIQUE)
|
|
|
|
/obj/item/gun/energy/consume_next_projectile()
|
|
if(!power_supply)
|
|
return null
|
|
if(!ispath(projectile_type))
|
|
return null
|
|
if(!power_supply.checked_use(charge_cost))
|
|
return null
|
|
if(self_recharge)
|
|
addtimer(CALLBACK(src, PROC_REF(try_recharge)), recharge_time * 2 SECONDS, TIMER_UNIQUE)
|
|
return new projectile_type(src)
|
|
|
|
/obj/item/gun/energy/proc/get_external_power_supply()
|
|
if(isrobot(src.loc))
|
|
var/mob/living/silicon/robot/R = src.loc
|
|
return R.cell
|
|
if(isrobot(src.loc.loc)) // for things inside a robot's module
|
|
var/mob/living/silicon/robot/R = src.loc.loc
|
|
return R.cell
|
|
if(recharger)
|
|
return recharger.get_cell()
|
|
if(istype(src.loc, /obj/item/rig_module))
|
|
var/obj/item/rig_module/module = src.loc
|
|
if(module.holder && module.holder.wearer)
|
|
var/mob/living/carbon/human/H = module.holder.wearer
|
|
if(istype(H) && H.back)
|
|
var/obj/item/rig/suit = H.back
|
|
if(istype(suit))
|
|
return suit.cell
|
|
if(istype(loc, /obj/item/mecha_equipment))
|
|
return loc.get_cell()
|
|
|
|
return null
|
|
|
|
/**
|
|
* Connects the energy gun to an external power supply
|
|
*
|
|
* * powersource - the power supply in question. Can either be `/obj/item/rig_module/recharger` or `/obj/item/recharger_backpack`.
|
|
*
|
|
* Returns `TRUE` if the connection was successful, `FALSE` otherwise
|
|
*/
|
|
/obj/item/gun/energy/proc/connect(obj/item/powersource)
|
|
SHOULD_NOT_SLEEP(TRUE)
|
|
|
|
//Validate that the type is allowed first of all
|
|
if(!is_type_in_list(powersource, list(/obj/item/rig_module/recharger, /obj/item/recharger_backpack)))
|
|
stack_trace("Wrong type to connect the energy gun to!")
|
|
return FALSE
|
|
|
|
//If we're already connected with something, we can't connect with something else
|
|
if(recharger)
|
|
to_chat(usr, SPAN_WARNING("\The [src] is already connected to \the [recharger]!"))
|
|
return FALSE
|
|
|
|
if(istype(powersource, /obj/item/rig_module/recharger))
|
|
var/obj/item/rig_module/recharger/rigcharge = powersource
|
|
|
|
if(!rigcharge.holder || !rigcharge.holder.wearer)
|
|
to_chat(usr, SPAN_WARNING("\The [rigcharge] must be installed in a rig and active!"))
|
|
return FALSE
|
|
|
|
to_chat(usr, SPAN_NOTICE("You neatly plug \the [src] into \the [powersource]."))
|
|
playsound(get_turf(src), 'sound/machines/click.ogg', 30, 0)
|
|
rigcharge.connected = src
|
|
recharger = rigcharge.holder
|
|
self_recharge = TRUE
|
|
use_external_power = TRUE
|
|
|
|
else if(istype(powersource, /obj/item/recharger_backpack))
|
|
var/obj/item/recharger_backpack/back_charge = powersource
|
|
|
|
if(!ismob(loc))
|
|
to_chat(usr, SPAN_WARNING("\The [back_charge] must be worn on the back before a weapon can be connected!"))
|
|
return FALSE
|
|
|
|
to_chat(usr, SPAN_NOTICE("You neatly plug \the [src] into \the [powersource]."))
|
|
playsound(get_turf(src), 'sound/machines/click.ogg', 30, 0)
|
|
back_charge.connect(src)
|
|
recharger = back_charge
|
|
self_recharge = TRUE
|
|
use_external_power = TRUE
|
|
|
|
return TRUE
|
|
|
|
|
|
///Disconnects the energy gun from its external power source if one exists.
|
|
/obj/item/gun/energy/proc/disconnect()
|
|
SHOULD_NOT_SLEEP(TRUE)
|
|
if(!recharger)
|
|
to_chat(usr, SPAN_WARNING("\The [src] lacks an external power source to disconnect!"))
|
|
return
|
|
|
|
if(istype(recharger, /obj/item/rig))
|
|
var/obj/item/rig/rig = recharger
|
|
var/obj/item/rig_module/recharger/rigcharger = locate() in rig.installed_modules
|
|
to_chat(usr, SPAN_NOTICE("With a snap, \the [src] is disconnected from \the [recharger]."))
|
|
playsound(get_turf(src), 'sound/machines/click.ogg', 30, 0)
|
|
if(rigcharger.active)
|
|
rigcharger.deactivate()
|
|
|
|
rigcharger.connected = null
|
|
|
|
else if(istype(recharger, /obj/item/recharger_backpack))
|
|
var/obj/item/recharger_backpack/backcharger = recharger
|
|
to_chat(usr, SPAN_NOTICE("With a snap, \the [src] is disconnected from \the [recharger]."))
|
|
playsound(get_turf(src), 'sound/machines/click.ogg', 30, 0)
|
|
backcharger.disconnect(src)
|
|
|
|
recharger = null
|
|
self_recharge = initial(self_recharge)
|
|
use_external_power = initial(use_external_power)
|
|
|
|
/obj/item/gun/energy/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params)
|
|
. = ..()
|
|
|
|
|
|
if(istype(over, /obj/item/rig))
|
|
var/obj/item/rig/rig = over
|
|
var/obj/item/rig_module/recharger/rigcharge = locate() in rig.installed_modules
|
|
if(rigcharge)
|
|
connect(rigcharge)
|
|
|
|
else if(istype(over, /obj/item/recharger_backpack))
|
|
var/obj/item/recharger_backpack/backcharge = over
|
|
connect(backcharge)
|
|
|
|
|
|
/obj/item/gun/energy/dropped(mob/user)
|
|
. = ..()
|
|
|
|
if(recharger)
|
|
disconnect()
|
|
|
|
/obj/item/gun/energy/update_icon()
|
|
if(charge_meter && power_supply && power_supply.maxcharge)
|
|
var/ratio = power_supply.charge / power_supply.maxcharge
|
|
var/icon_state_ratio = ""
|
|
var/item_state_ratio = ""
|
|
|
|
//make sure that rounding down will not give us the empty state even if we have charge for a shot left.
|
|
if(power_supply.charge < charge_cost)
|
|
ratio = 0
|
|
else
|
|
ratio = max(round(ratio, 0.25) * 100, 25)
|
|
|
|
if(has_icon_ratio)
|
|
icon_state_ratio = ratio
|
|
if(has_item_ratio)
|
|
item_state_ratio = ratio
|
|
|
|
if(modifystate)
|
|
icon_state = "[modifystate][icon_state_ratio]"
|
|
item_state = "[modifystate][item_state_ratio]"
|
|
else
|
|
icon_state = "[initial(icon_state)][icon_state_ratio]"
|
|
item_state = "[initial(item_state)][item_state_ratio]"
|
|
|
|
..()
|
|
|
|
/obj/item/gun/energy/handle_post_fire()
|
|
..()
|
|
update_maptext()
|
|
|
|
/obj/item/gun/energy/get_ammo()
|
|
if(!power_supply)
|
|
return 0
|
|
return round(power_supply.charge / charge_cost)
|
|
|
|
/obj/item/gun/energy/get_print_info()
|
|
. = ""
|
|
. += "Max Shots: [initial(max_shots)]<br>"
|
|
. += "Recharge Type: [initial(self_recharge) ? "self recharging" : "not self recharging"]<br>"
|
|
if(initial(self_recharge))
|
|
. += "Recharge Time: [initial(recharge_time)]<br>"
|
|
. += "<br><b>Primary Projectile</b><br>"
|
|
var/obj/projectile/P = new projectile_type
|
|
. += P.get_print_info()
|
|
|
|
if(secondary_projectile_type)
|
|
. += "<br><b>Secondary Projectile</b><br>"
|
|
var/obj/projectile/P_second = new secondary_projectile_type
|
|
. += P_second.get_print_info()
|
|
. += "<br>"
|
|
|
|
. += ..(FALSE)
|