mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-30 08:29:57 +01:00
- balance: "Buffs gattling laser modifier charge time from 3 to 2 seconds. It took so long to charge multiple people thought it was bugged." This modifier was simply a downgrade, you'd be dead by the time it fired. Often people handed gattling guns would think they are bugged and unable to fire. This might help a bit. - balance: "Tweaks material costs, replacing uranium with silver and gold. Uranium was previously used everywhere." Everything used uranium, even things that really didn't make sense. As uranium spawns on station in engineering and the machinists, this is a slight nerf. - bugfix: "Fixed a bug where energy guns would not properly handle reliability failures when the gun was out of charge." - bugfix: "Fixed improvement potential calculations for ions and slimes. You no longer gain improvement shooting monkeys with ions, or for shooting slimes with lasers." - bugfix: "Fixed a bug with bluespace capacitors teleporting items in teleport inhibitor range. This was due to the EMP happening before the teleport and destroying the inhibitor." - bugfix: "Fixed Ion modulators not correctly decreasing the number of shots." Fixes: #22850
344 lines
11 KiB
Plaintext
344 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/handle_reliability_fail(var/mob/user)
|
|
if(power_supply && power_supply.charge < charge_cost)
|
|
handle_click_empty(user)
|
|
return
|
|
..()
|
|
|
|
/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)
|