mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-26 22:42:26 +01:00
Recharger QoL Tweaks (#3826)
changes: Rechargers now briefly show a progress bar showing the current charge level of the device currently charging. Examining a recharger will now specify what is in the charger. Atoms can now mark themselves as requiring an icon update on initialize instead of overriding Initialize() just to call update_icon(). Charger code is now slightly more modular, using proc/get_cell() to get a ref to the power cell instead of hard-coded if-else chains for each supported type.
This commit is contained in:
@@ -57,7 +57,6 @@
|
||||
#include "code\_helpers\global_lists.dm"
|
||||
#include "code\_helpers\icon_smoothing.dm"
|
||||
#include "code\_helpers\icons.dm"
|
||||
#include "code\_helpers\items.dm"
|
||||
#include "code\_helpers\lists.dm"
|
||||
#include "code\_helpers\logging.dm"
|
||||
#include "code\_helpers\maths.dm"
|
||||
|
||||
@@ -452,3 +452,5 @@ Define for getting a bitfield of adjacent turfs that meet a condition.
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DEVICE_NO_CELL "no_cell"
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
//Prevents robots dropping their modules.
|
||||
/proc/dropsafety(var/atom/movable/A)
|
||||
if (istype(A.loc, /mob/living/silicon))
|
||||
return 0
|
||||
|
||||
else if (istype(A.loc, /obj/item/rig_module))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/obj/proc/animate_shake()
|
||||
var/init_px = pixel_x
|
||||
var/shake_dir = pick(-1, 1)
|
||||
animate(src, transform = turn(matrix(), 8*shake_dir), pixel_x = init_px + 2*shake_dir, time = 1)
|
||||
animate(transform = null, pixel_x = init_px, time = 6, easing = ELASTIC_EASING)
|
||||
@@ -1163,3 +1163,12 @@ var/list/wall_items = typecacheof(list(
|
||||
|
||||
#undef NOT_FLAG
|
||||
#undef HAS_FLAG
|
||||
|
||||
//Prevents robots dropping their modules.
|
||||
/proc/dropsafety(var/atom/movable/A)
|
||||
if (istype(A.loc, /mob/living/silicon))
|
||||
return 0
|
||||
|
||||
else if (istype(A.loc, /obj/item/rig_module))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
/atom
|
||||
var/initialized = FALSE
|
||||
var/update_icon_on_init // Default to 'no'.
|
||||
|
||||
/atom/New(loc, ...)
|
||||
// For the DMM Suite.
|
||||
if(use_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New()
|
||||
if(use_preloader && (type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New()
|
||||
_preloader.load(src)
|
||||
|
||||
//. = ..() //uncomment if you are dumb enough to add a /datum/New() proc
|
||||
@@ -36,6 +37,9 @@
|
||||
T.regenerate_ao()
|
||||
#endif
|
||||
|
||||
if (update_icon_on_init)
|
||||
queue_icon_update()
|
||||
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
//called if Initialize returns INITIALIZE_HINT_LATELOAD
|
||||
|
||||
@@ -8,16 +8,39 @@
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 4
|
||||
active_power_usage = 30000 //15 kW
|
||||
active_power_usage = 30 KILOWATTS
|
||||
var/charging_efficiency = 0.85
|
||||
//Entropy. The charge put into the cell is multiplied by this
|
||||
var/obj/item/charging = null
|
||||
var/obj/item/charging
|
||||
|
||||
var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/weapon/cell, /obj/item/modular_computer/, /obj/item/weapon/computer_hardware/battery_module)
|
||||
var/list/allowed_devices = list(
|
||||
/obj/item/weapon/gun/energy,
|
||||
/obj/item/weapon/melee/baton,
|
||||
/obj/item/weapon/cell,
|
||||
/obj/item/modular_computer,
|
||||
/obj/item/weapon/computer_hardware/battery_module
|
||||
)
|
||||
var/icon_state_charged = "recharger2"
|
||||
var/icon_state_charging = "recharger1"
|
||||
var/icon_state_idle = "recharger0" //also when unpowered
|
||||
var/portable = 1
|
||||
var/list/chargebars
|
||||
|
||||
/obj/machinery/recharger/examine(mob/user)
|
||||
. = ..(user, 3)
|
||||
user << "There is [charging ? "\a [charging]" : "nothing"] in [src]."
|
||||
if (charging && .)
|
||||
var/obj/item/weapon/cell/C = charging.get_cell()
|
||||
if (istype(C) && user.client && (!user.progressbars || !user.progressbars[src]))
|
||||
var/datum/progressbar/progbar = new(user, C.maxcharge, src)
|
||||
progbar.update(C.charge)
|
||||
LAZYADD(chargebars, progbar)
|
||||
chargebars[progbar] = addtimer(CALLBACK(src, .proc/remove_bar, progbar, null), 3 SECONDS, TIMER_UNIQUE | TIMER_STOPPABLE)
|
||||
|
||||
/obj/machinery/recharger/proc/remove_bar(datum/progressbar/bar, timerid)
|
||||
if (!timerid || deltimer(timerid))
|
||||
LAZYREMOVE(chargebars, bar)
|
||||
qdel(bar)
|
||||
|
||||
/obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob)
|
||||
if(portable && iswrench(G))
|
||||
@@ -41,32 +64,21 @@
|
||||
if(!dropsafety(G))
|
||||
return
|
||||
|
||||
var/allowed = 0
|
||||
for (var/allowed_type in allowed_devices)
|
||||
if (istype(G, allowed_type)) allowed = 1
|
||||
|
||||
if(allowed)
|
||||
if(is_type_in_list(G, allowed_devices))
|
||||
if (G.get_cell() == DEVICE_NO_CELL)
|
||||
if (G.charge_failure_message)
|
||||
user << "<span class='warning'>\The [G][G.charge_failure_message]</span>"
|
||||
return
|
||||
if(charging)
|
||||
user << "<span class='warning'>\A [charging] is already charging here.</span>"
|
||||
return
|
||||
// Checks to make sure he's not in space doing it, and that the area got proper power.
|
||||
if(!powered())
|
||||
user << "<span class='warning'>The [name] blinks red as you try to insert the item!</span>"
|
||||
user << "<span class='warning'>\The [name] blinks red as you try to insert the item!</span>"
|
||||
return
|
||||
if (istype(G, /obj/item/weapon/gun/energy/gun/nuclear) || istype(G, /obj/item/weapon/gun/energy/crossbow))
|
||||
user << "<span class='notice'>Your gun's recharge port was removed to make room for a miniaturized reactor.</span>"
|
||||
return
|
||||
if (istype(G, /obj/item/weapon/gun/energy/staff))
|
||||
return
|
||||
if (istype(G, /obj/item/weapon/gun/energy/wand))
|
||||
return
|
||||
if(istype(G, /obj/item/modular_computer))
|
||||
var/obj/item/modular_computer/C = G
|
||||
if(!C.battery_module)
|
||||
user << "This device does not have a battery installed."
|
||||
return
|
||||
|
||||
user.drop_item()
|
||||
G.loc = src
|
||||
G.forceMove(src)
|
||||
charging = G
|
||||
update_icon()
|
||||
|
||||
@@ -80,6 +92,9 @@
|
||||
charging.update_icon()
|
||||
user.put_in_hands(charging)
|
||||
charging = null
|
||||
if (chargebars)
|
||||
for (var/thing in chargebars)
|
||||
remove_bar(thing, chargebars[thing])
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/recharger/machinery_process()
|
||||
@@ -92,20 +107,8 @@
|
||||
update_use_power(1)
|
||||
icon_state = icon_state_idle
|
||||
else
|
||||
var/cell = charging
|
||||
if(istype(charging, /obj/item/weapon/melee/baton))
|
||||
var/obj/item/weapon/melee/baton/B = charging
|
||||
cell = B.bcell
|
||||
else if(istype(charging, /obj/item/modular_computer))
|
||||
var/obj/item/modular_computer/C = charging
|
||||
cell = C.battery_module.battery
|
||||
else if(istype(charging, /obj/item/weapon/gun/energy))
|
||||
var/obj/item/weapon/gun/energy/E = charging
|
||||
cell = E.power_supply
|
||||
else if(istype(charging, /obj/item/weapon/computer_hardware/battery_module))
|
||||
var/obj/item/weapon/computer_hardware/battery_module/BM = charging
|
||||
cell = BM.battery
|
||||
if(istype(cell, /obj/item/weapon/cell))
|
||||
var/obj/item/weapon/cell/cell = charging.get_cell()
|
||||
if(istype(cell))
|
||||
var/obj/item/weapon/cell/C = cell
|
||||
if(!C.fully_charged())
|
||||
icon_state = icon_state_charging
|
||||
@@ -114,7 +117,20 @@
|
||||
else
|
||||
icon_state = icon_state_charged
|
||||
update_use_power(1)
|
||||
return
|
||||
|
||||
if (chargebars)
|
||||
for (var/thing in chargebars)
|
||||
var/datum/progressbar/bar = thing
|
||||
if (QDELETED(bar))
|
||||
LAZYREMOVE(chargebars, bar)
|
||||
else
|
||||
bar.update(C.charge)
|
||||
|
||||
else if (cell == DEVICE_NO_CELL)
|
||||
log_debug("recharger: Item [DEBUG_REF(charging)] was in charger, but claims to have no internal cell slot; booting item.")
|
||||
charging.forceMove(loc)
|
||||
charging.visible_message("\The [charging] falls out of [src].")
|
||||
charging = null
|
||||
|
||||
/obj/machinery/recharger/emp_act(severity)
|
||||
if(stat & (NOPOWER|BROKEN) || !anchored)
|
||||
@@ -138,13 +154,16 @@
|
||||
else
|
||||
icon_state = icon_state_idle
|
||||
|
||||
obj/machinery/recharger/wallcharger
|
||||
/obj/machinery/recharger/wallcharger
|
||||
name = "wall recharger"
|
||||
desc = "A heavy duty wall recharger specialized for energy weaponry."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "wrecharger0"
|
||||
active_power_usage = 50 KILOWATTS //50 kW , It's more specialized than the standalone recharger (guns and batons only) so make it more powerful
|
||||
allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton)
|
||||
allowed_devices = list(
|
||||
/obj/item/weapon/gun/energy,
|
||||
/obj/item/weapon/melee/baton
|
||||
)
|
||||
icon_state_charged = "wrecharger2"
|
||||
icon_state_charging = "wrecharger1"
|
||||
icon_state_idle = "wrecharger0"
|
||||
|
||||
@@ -75,6 +75,8 @@
|
||||
|
||||
var/icon_override //Used to override hardcoded clothing dmis in human clothing pr
|
||||
|
||||
var/charge_failure_message = " cannot be recharged."
|
||||
|
||||
/obj/item/Destroy()
|
||||
if(ismob(loc))
|
||||
var/mob/m = loc
|
||||
@@ -84,9 +86,13 @@
|
||||
src.loc = null
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/device
|
||||
icon = 'icons/obj/device.dmi'
|
||||
|
||||
/obj/item/proc/get_cell()
|
||||
return DEVICE_NO_CELL
|
||||
|
||||
//Checks if the item is being held by a mob, and if so, updates the held icons
|
||||
/obj/item/proc/update_held_icon()
|
||||
if(ismob(src.loc))
|
||||
|
||||
@@ -15,20 +15,20 @@
|
||||
var/stunforce = 0
|
||||
var/agonyforce = 120
|
||||
var/status = 0 //whether the thing is on or not
|
||||
var/obj/item/weapon/cell/bcell = null
|
||||
var/obj/item/weapon/cell/bcell
|
||||
var/hitcost = 1000 //oh god why do power cells carry so much charge? We probably need to make a distinction between "industrial" sized power cells for APCs and power cells for everything else.
|
||||
var/baton_color = "#FF6A00"
|
||||
|
||||
/obj/item/weapon/melee/baton/New()
|
||||
..()
|
||||
/obj/item/weapon/melee/baton/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/melee/baton/loaded/New() //this one starts with a cell pre-installed.
|
||||
..()
|
||||
/obj/item/weapon/melee/baton/loaded/Initialize() //this one starts with a cell pre-installed.
|
||||
bcell = new/obj/item/weapon/cell/high(src)
|
||||
update_icon()
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/weapon/melee/baton/get_cell()
|
||||
return bcell
|
||||
|
||||
/obj/item/weapon/melee/baton/proc/deductcharge(var/chrgdeductamt)
|
||||
if(bcell)
|
||||
@@ -59,14 +59,14 @@
|
||||
|
||||
if(bcell)
|
||||
user <<"<span class='notice'>The baton is [round(bcell.percent())]% charged.</span>"
|
||||
if(!bcell)
|
||||
else
|
||||
user <<"<span class='warning'>The baton does not have a power source installed.</span>"
|
||||
|
||||
/obj/item/weapon/melee/baton/attackby(obj/item/weapon/W, mob/user)
|
||||
if(istype(W, /obj/item/weapon/cell))
|
||||
if(!bcell)
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
W.forceMove(src)
|
||||
bcell = W
|
||||
user << "<span class='notice'>You install a cell in [src].</span>"
|
||||
update_icon()
|
||||
@@ -76,7 +76,7 @@
|
||||
else if(isscrewdriver(W))
|
||||
if(bcell)
|
||||
bcell.update_icon()
|
||||
bcell.loc = get_turf(src.loc)
|
||||
bcell.forceMove(get_turf(src))
|
||||
bcell = null
|
||||
user << "<span class='notice'>You remove the cell from the [src].</span>"
|
||||
status = 0
|
||||
@@ -225,11 +225,9 @@
|
||||
origin_tech = list(TECH_COMBAT = 4, TECH_ILLEGAL = 2)
|
||||
contained_sprite = 1
|
||||
|
||||
/obj/item/weapon/melee/baton/stunrod/New()
|
||||
..()
|
||||
/obj/item/weapon/melee/baton/stunrod/Initialize()
|
||||
bcell = new/obj/item/weapon/cell/high(src)
|
||||
update_icon()
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/weapon/melee/baton/stunrod/update_icon() //this is needed due to how contained sprites work
|
||||
if(status)
|
||||
@@ -258,9 +256,8 @@
|
||||
contained_sprite = 1
|
||||
|
||||
/obj/item/weapon/melee/baton/slime/Initialize()
|
||||
. = ..()
|
||||
bcell = new/obj/item/weapon/cell/high(src)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/weapon/melee/baton/slime/attack(mob/M, mob/user, var/hit_zone)
|
||||
if(isrobot(M) || ishuman(M))
|
||||
|
||||
@@ -216,3 +216,9 @@
|
||||
//This is useful for setting special behaviour for built items that shouldn't apply to those spawned at roundstart
|
||||
/obj/proc/Created()
|
||||
return
|
||||
|
||||
/obj/proc/animate_shake()
|
||||
var/init_px = pixel_x
|
||||
var/shake_dir = pick(-1, 1)
|
||||
animate(src, transform = turn(matrix(), 8*shake_dir), pixel_x = init_px + 2*shake_dir, time = 1)
|
||||
animate(transform = null, pixel_x = init_px, time = 6, easing = ELASTIC_EASING)
|
||||
|
||||
@@ -276,3 +276,6 @@
|
||||
return active_program.check_eye(user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/modular_computer/get_cell()
|
||||
return battery_module ? battery_module.get_cell() : DEVICE_NO_CELL
|
||||
|
||||
@@ -59,3 +59,5 @@
|
||||
var/obj/item/weapon/computer_hardware/tesla_link/tesla_link // Tesla Link, Allows remote charging from nearest APC.
|
||||
|
||||
var/listener/listener //Listener needed for things
|
||||
|
||||
charge_failure_message = " does not have a battery installed."
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
malfunction_probability = 1
|
||||
origin_tech = list(TECH_POWER = 1, TECH_ENGINEERING = 1)
|
||||
var/battery_rating = 750
|
||||
var/obj/item/weapon/cell/battery = null
|
||||
var/obj/item/weapon/cell/battery
|
||||
|
||||
/obj/item/weapon/computer_hardware/battery_module/advanced
|
||||
name = "advanced battery"
|
||||
@@ -51,24 +51,27 @@
|
||||
// This is not intended to be obtainable in-game. Intended for adminbus and debugging purposes.
|
||||
/obj/item/weapon/computer_hardware/battery_module/lambda
|
||||
name = "lambda coil"
|
||||
desc = "A very complex device that creates it's own bluespace dimension. This dimension may be used to store massive amounts of energy."
|
||||
desc = "A very complex device that creates its own bluespace dimension. This dimension may be used to store massive amounts of energy."
|
||||
icon_state = "battery_lambda"
|
||||
hardware_size = 1
|
||||
battery_rating = 1000000
|
||||
/obj/item/weapon/computer_hardware/battery_module/lambda/New()
|
||||
..()
|
||||
|
||||
/obj/item/weapon/computer_hardware/battery_module/lambda/Initialize()
|
||||
. = ..()
|
||||
battery = new/obj/item/weapon/cell/infinite(src)
|
||||
|
||||
/obj/item/weapon/computer_hardware/battery_module/diagnostics(var/mob/user)
|
||||
..()
|
||||
user << "Internal battery charge: [battery.charge]/[battery.maxcharge] CU"
|
||||
user << "Internal battery charge: [battery.charge]/[battery.maxcharge] mAh"
|
||||
|
||||
/obj/item/weapon/computer_hardware/battery_module/New()
|
||||
battery = new/obj/item/weapon/cell(src)
|
||||
battery.maxcharge = battery_rating
|
||||
/obj/item/weapon/computer_hardware/battery_module/Initialize()
|
||||
. = ..()
|
||||
battery = new/obj/item/weapon/cell/device/variable(src, battery_rating)
|
||||
battery.charge = 0
|
||||
..()
|
||||
|
||||
/obj/item/weapon/computer_hardware/battery_module/proc/charge_to_full()
|
||||
if(battery)
|
||||
battery.charge = battery.maxcharge
|
||||
|
||||
/obj/item/weapon/computer_hardware/battery_module/get_cell()
|
||||
return battery
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
icon_state = "energy"
|
||||
fire_sound = 'sound/weapons/Taser.ogg'
|
||||
fire_sound_text = "laser blast"
|
||||
update_icon_on_init = TRUE
|
||||
|
||||
var/obj/item/weapon/cell/power_supply //What type of power cell this uses
|
||||
var/charge_cost = 200 //How much energy is needed to fire.
|
||||
@@ -34,7 +35,10 @@
|
||||
|
||||
/obj/item/weapon/gun/energy/emp_act(severity)
|
||||
..()
|
||||
update_icon()
|
||||
queue_icon_update()
|
||||
|
||||
/obj/item/weapon/gun/energy/get_cell()
|
||||
return power_supply
|
||||
|
||||
/obj/item/weapon/gun/energy/Initialize()
|
||||
. = ..()
|
||||
@@ -42,7 +46,6 @@
|
||||
power_supply = new cell_type(src)
|
||||
else
|
||||
power_supply = new /obj/item/weapon/cell/device/variable(src, max_shots*charge_cost)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/Destroy()
|
||||
QDEL_NULL(power_supply)
|
||||
|
||||
@@ -187,6 +187,10 @@ obj/item/weapon/gun/energy/staff/focus/attack_self(mob/living/user as mob)
|
||||
projectile_type = /obj/item/projectile/magic
|
||||
origin_tech = list(TECH_COMBAT = 6, TECH_MAGNET = 5, TECH_BLUESPACE = 6)
|
||||
charge_meter = 0
|
||||
charge_failure_message = null
|
||||
|
||||
/obj/item/weapon/gun/energy/wand/get_cell()
|
||||
return DEVICE_NO_CELL
|
||||
|
||||
/obj/item/weapon/gun/energy/wand/handle_click_empty(mob/user = null)
|
||||
if (user)
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
modifystate = null
|
||||
var/reliability = 95
|
||||
turret_sprite_set = "nuclear"
|
||||
charge_failure_message = "'s charging socket was removed to make room for a minaturized reactor."
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_sound='sound/weapons/Taser.ogg'),
|
||||
@@ -48,6 +49,8 @@
|
||||
|
||||
var/lightfail = 0
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/nuclear/get_cell()
|
||||
return DEVICE_NO_CELL
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/nuclear/proc/failcheck()
|
||||
lightfail = 0
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
charge_meter = 0
|
||||
can_turret = 1
|
||||
turret_sprite_set = "crossbow"
|
||||
charge_failure_message = "'s charging socket was removed to make room for a minaturized reactor."
|
||||
|
||||
/obj/item/weapon/gun/energy/crossbow/get_cell()
|
||||
return DEVICE_NO_CELL
|
||||
|
||||
/obj/item/weapon/gun/energy/crossbow/ninja
|
||||
name = "energy dart thrower"
|
||||
|
||||
Reference in New Issue
Block a user