diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index 89379611881..aed8a826874 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -36271,7 +36271,7 @@
},
/obj/effect/landmark/blobstart,
/obj/item/weapon/melee/baton/cattleprod{
- bcell = new /obj/item/weapon/stock_parts/cell/high()
+ cell = new /obj/item/weapon/stock_parts/cell/high()
},
/turf/open/floor/plasteel/black,
/area/medical/exam_room)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index af9672c3df2..4c5f408f52a 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -680,3 +680,7 @@
set waitfor = FALSE
if(!anchored && has_gravity())
step(src, movedir)
+
+//Returns an atom's power cell, if it has one. Overload for individual items.
+/atom/movable/proc/get_cell()
+ return
diff --git a/code/game/gamemodes/clock_cult/clock_helpers/clock_powerdrain.dm b/code/game/gamemodes/clock_cult/clock_helpers/clock_powerdrain.dm
index 705273876c2..cdde45bb4cc 100644
--- a/code/game/gamemodes/clock_cult/clock_helpers/clock_powerdrain.dm
+++ b/code/game/gamemodes/clock_cult/clock_helpers/clock_powerdrain.dm
@@ -29,7 +29,7 @@
if(charge)
. = min(charge, 250)
charge = use(.)
- updateicon()
+ update_icon()
/obj/machinery/light/power_drain(clockcult_user)
if(on)
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index 112c4fcfb17..f51c842e546 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -71,7 +71,7 @@
/obj/machinery/cell_charger/proc/removecell()
- charging.updateicon()
+ charging.update_icon()
charging = null
chargelevel = -1
updateicon()
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 6cc42b73b5c..03e95ee2de3 100755
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -108,41 +108,25 @@
var/using_power = 0
if(charging)
- if(istype(charging, /obj/item/weapon/gun/energy))
- var/obj/item/weapon/gun/energy/E = charging
- if(E.power_supply.charge < E.power_supply.maxcharge)
- E.power_supply.give(E.power_supply.chargerate * recharge_coeff)
- E.recharge_newshot()
+ var/obj/item/weapon/stock_parts/cell/C = charging.get_cell()
+ if(C)
+ if(C.charge < C.maxcharge)
+ C.give(C.chargerate * recharge_coeff)
use_power(250 * recharge_coeff)
using_power = 1
-
-
- if(istype(charging, /obj/item/weapon/melee/baton))
- var/obj/item/weapon/melee/baton/B = charging
- if(B.bcell)
- if(B.bcell.give(B.bcell.chargerate * recharge_coeff))
- use_power(200 * recharge_coeff)
- using_power = 1
-
+ update_icon(using_power)
+ if(istype(charging, /obj/item/weapon/gun/energy))
+ var/obj/item/weapon/gun/energy/E = charging
+ E.recharge_newshot()
+ return
if(istype(charging, /obj/item/ammo_box/magazine/recharge))
var/obj/item/ammo_box/magazine/recharge/R = charging
if(R.stored_ammo.len < R.max_ammo)
R.stored_ammo += new R.ammo_type(R)
use_power(200 * recharge_coeff)
using_power = 1
-
- if(istype(charging, /obj/item/device/modular_computer))
- var/obj/item/device/modular_computer/C = charging
- var/obj/item/weapon/computer_hardware/battery/battery_module = C.all_components[MC_CELL]
- if(battery_module)
- var/obj/item/weapon/computer_hardware/battery/B = battery_module
- if(B.battery)
- if(B.battery.charge < B.battery.maxcharge)
- B.battery.give(B.battery.chargerate * recharge_coeff)
- use_power(200 * recharge_coeff)
- using_power = 1
-
- update_icon(using_power)
+ update_icon(using_power)
+ return
/obj/machinery/recharger/power_change()
..()
@@ -152,13 +136,13 @@
if(!(stat & (NOPOWER|BROKEN)) && anchored)
if(istype(charging, /obj/item/weapon/gun/energy))
var/obj/item/weapon/gun/energy/E = charging
- if(E.power_supply)
- E.power_supply.emp_act(severity)
+ if(E.cell)
+ E.cell.emp_act(severity)
else if(istype(charging, /obj/item/weapon/melee/baton))
var/obj/item/weapon/melee/baton/B = charging
- if(B.bcell)
- B.bcell.charge = 0
+ if(B.cell)
+ B.cell.charge = 0
..()
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index df76fef5a9f..671dfbbdf29 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -24,6 +24,9 @@
var/settableTemperatureMedian = 30 + T0C
var/settableTemperatureRange = 30
+/obj/machinery/space_heater/get_cell()
+ return cell
+
/obj/machinery/space_heater/New()
..()
cell = new(src)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 669dcb51157..09052e1b35f 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -142,6 +142,8 @@
diag_hud_set_mechstat()
diag_hud_set_mechtracking()
+/obj/mecha/get_cell()
+ return cell
/obj/mecha/Destroy()
go_out()
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index 4bdf6ddf3c2..df23172b4fd 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -19,10 +19,13 @@
var/safety = 1 //if you can zap people with the defibs on harm mode
var/powered = 0 //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise
var/obj/item/weapon/twohanded/shockpaddles/paddles
- var/obj/item/weapon/stock_parts/cell/high/bcell = null
+ var/obj/item/weapon/stock_parts/cell/high/cell
var/combat = 0 //can we revive through space suits?
var/grab_ghost = FALSE // Do we pull the ghost back into their body?
+/obj/item/weapon/defibrillator/get_cell()
+ return cell
+
/obj/item/weapon/defibrillator/Initialize() //starts without a cell for rnd
. = ..()
paddles = make_paddles()
@@ -32,7 +35,7 @@
/obj/item/weapon/defibrillator/loaded/Initialize() //starts with hicap
. = ..()
paddles = make_paddles()
- bcell = new(src)
+ cell = new(src)
update_icon()
return
@@ -42,8 +45,8 @@
update_charge()
/obj/item/weapon/defibrillator/proc/update_power()
- if(bcell)
- if(bcell.charge < paddles.revivecost)
+ if(cell)
+ if(cell.charge < paddles.revivecost)
powered = 0
else
powered = 1
@@ -56,21 +59,21 @@
add_overlay("[initial(icon_state)]-paddles")
if(powered)
add_overlay("[initial(icon_state)]-powered")
- if(!bcell)
+ if(!cell)
add_overlay("[initial(icon_state)]-nocell")
if(!safety)
add_overlay("[initial(icon_state)]-emagged")
/obj/item/weapon/defibrillator/proc/update_charge()
if(powered) //so it doesn't show charge if it's unpowered
- if(bcell)
- var/ratio = bcell.charge / bcell.maxcharge
+ if(cell)
+ var/ratio = cell.charge / cell.maxcharge
ratio = Ceiling(ratio*4) * 25
add_overlay("[initial(icon_state)]-charge[ratio]")
/obj/item/weapon/defibrillator/CheckParts(list/parts_list)
..()
- bcell = locate(/obj/item/weapon/stock_parts/cell) in contents
+ cell = locate(/obj/item/weapon/stock_parts/cell) in contents
update_icon()
/obj/item/weapon/defibrillator/ui_action_click()
@@ -105,7 +108,7 @@
toggle_paddles()
else if(istype(W, /obj/item/weapon/stock_parts/cell))
var/obj/item/weapon/stock_parts/cell/C = W
- if(bcell)
+ if(cell)
to_chat(user, "[src] already has a cell.")
else
if(C.maxcharge < paddles.revivecost)
@@ -113,15 +116,15 @@
return
if(!user.transferItemToLoc(W, src))
return
- bcell = W
+ cell = W
to_chat(user, "You install a cell in [src].")
update_icon()
else if(istype(W, /obj/item/weapon/screwdriver))
- if(bcell)
- bcell.updateicon()
- bcell.loc = get_turf(src.loc)
- bcell = null
+ if(cell)
+ cell.update_icon()
+ cell.forceMove(get_turf(src))
+ cell = null
to_chat(user, "You remove the cell from [src].")
update_icon()
else
@@ -136,7 +139,7 @@
to_chat(user, "You silently enable [src]'s safety protocols with the cryptographic sequencer.")
/obj/item/weapon/defibrillator/emp_act(severity)
- if(bcell)
+ if(cell)
deductcharge(1000 / severity)
if(safety)
safety = 0
@@ -200,11 +203,11 @@
update_icon()
/obj/item/weapon/defibrillator/proc/deductcharge(chrgdeductamt)
- if(bcell)
- if(bcell.charge < (paddles.revivecost+chrgdeductamt))
+ if(cell)
+ if(cell.charge < (paddles.revivecost+chrgdeductamt))
powered = 0
update_icon()
- if(bcell.use(chrgdeductamt))
+ if(cell.use(chrgdeductamt))
update_icon()
return 1
else
@@ -213,8 +216,8 @@
/obj/item/weapon/defibrillator/proc/cooldowncheck(mob/user)
spawn(50)
- if(bcell)
- if(bcell.charge >= paddles.revivecost)
+ if(cell)
+ if(cell.charge >= paddles.revivecost)
user.visible_message("[src] beeps: Unit ready.")
playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50, 0)
else
@@ -240,7 +243,7 @@
/obj/item/weapon/defibrillator/compact/loaded/Initialize()
. = ..()
paddles = make_paddles()
- bcell = new(src)
+ cell = new(src)
update_icon()
/obj/item/weapon/defibrillator/compact/combat
@@ -252,7 +255,7 @@
/obj/item/weapon/defibrillator/compact/combat/loaded/Initialize()
. = ..()
paddles = make_paddles()
- bcell = new /obj/item/weapon/stock_parts/cell/infinite(src)
+ cell = new /obj/item/weapon/stock_parts/cell/infinite(src)
update_icon()
/obj/item/weapon/defibrillator/compact/combat/loaded/attackby(obj/item/weapon/W, mob/user, params)
diff --git a/code/game/objects/items/weapons/inducer.dm b/code/game/objects/items/weapons/inducer.dm
new file mode 100644
index 00000000000..fdd44795ad7
--- /dev/null
+++ b/code/game/objects/items/weapons/inducer.dm
@@ -0,0 +1,183 @@
+/obj/item/weapon/inducer
+ name = "inducer"
+ desc = "A tool for inductively charging internal power cells."
+ icon = 'icons/obj/tools.dmi'
+ icon_state = "inducer-engi"
+ item_state = "inducer-engi"
+ origin_tech = "engineering=4;magnets=4;powerstorage=4"
+ force = 7
+ var/powertransfer = 1000
+ var/opened = FALSE
+ var/cell_type = /obj/item/weapon/stock_parts/cell/high
+ var/obj/item/weapon/stock_parts/cell/cell
+ var/recharging = FALSE
+
+/obj/item/weapon/inducer/Initialize()
+ . = ..()
+ if(!cell && cell_type)
+ cell = new cell_type
+
+/obj/item/weapon/inducer/proc/induce(obj/item/weapon/stock_parts/cell/target, coefficient)
+ var/totransfer = min(cell.charge,(powertransfer * coefficient))
+ var/transferred = target.give(totransfer)
+ cell.use(transferred)
+ cell.update_icon()
+ target.update_icon()
+
+/obj/item/weapon/inducer/get_cell()
+ return cell
+
+/obj/item/weapon/inducer/emp_act(severity)
+ ..()
+ if(cell)
+ cell.emp_act()
+
+/obj/item/weapon/inducer/attack_obj(obj/O, mob/living/carbon/user)
+ if(user.a_intent == INTENT_HARM)
+ return ..()
+
+ if(cantbeused(user))
+ return
+
+ if(recharge(O, user))
+ return
+
+ return ..()
+
+/obj/item/weapon/inducer/proc/cantbeused(mob/user)
+ if(!user.IsAdvancedToolUser())
+ to_chat(user, "You don't have the dexterity to use \the [src]!")
+ return TRUE
+
+ if(!cell)
+ to_chat(user, "\The [src] doesn't have a power cell installed!")
+ return TRUE
+
+ if(!cell.charge)
+ to_chat(user, "\The [src]'s battery is dead!")
+ return TRUE
+ return FALSE
+
+
+/obj/item/weapon/inducer/attackby(obj/item/weapon/W, mob/user)
+ if(istype(W,/obj/item/weapon/screwdriver))
+ playsound(src, W.usesound, 50, 1)
+ if(!opened)
+ to_chat(user, "You unscrew the battery compartment.")
+ opened = TRUE
+ update_icon()
+ return
+ else
+ to_chat(user, "You close the battery compartment.")
+ opened = FALSE
+ update_icon()
+ return
+ if(istype(W,/obj/item/weapon/stock_parts/cell))
+ if(opened)
+ if(!cell)
+ if(!user.transferItemToLoc(W, src))
+ return
+ to_chat(user, "You insert \the [W] into \the [src].")
+ cell = W
+ update_icon()
+ return
+ else
+ to_chat(user, "\The [src] already has \a [cell] installed!")
+ return
+
+ if(cantbeused(user))
+ return
+
+ if(recharge(W, user))
+ return
+
+ return ..()
+
+/obj/item/weapon/inducer/proc/recharge(atom/movable/A, mob/user)
+ if(recharging)
+ return TRUE
+ else
+ recharging = TRUE
+ var/obj/item/weapon/stock_parts/cell/C = A.get_cell()
+ var/obj/item/weapon/gun/energy/E
+ var/obj/O
+ var/coefficient = 1
+ if(istype(A, /obj/item/weapon/gun/energy))
+ coefficient = 0.075 // 14 loops to recharge an egun from 0-1000
+ E = A
+ if(istype(A, /obj))
+ O = A
+ if(C)
+ if(C.charge >= C.maxcharge)
+ to_chat(user, "\The [A] is fully charged!")
+ recharging = FALSE
+ return TRUE
+ user.visible_message("[user] starts recharging \the [A] with \the [src]","You start recharging [A] with \the [src]")
+ while(C.charge < C.maxcharge)
+ if(E)
+ E.chambered = null // Prevents someone from firing continuously while recharging the gun.
+ if(do_after(user, 10, target = user) && cell.charge)
+ induce(C, coefficient)
+ do_sparks(1, FALSE, A)
+ if(O)
+ O.update_icon()
+ else
+ break
+ if(E)
+ E.recharge_newshot() //We're done charging, so we'll let someone fire it now.
+ user.visible_message("[user] recharged \the [A]!","You recharged \the [A]!")
+ recharging = FALSE
+ return TRUE
+
+
+/obj/item/weapon/inducer/attack(mob/M, mob/user)
+ if(user.a_intent == INTENT_HARM)
+ return ..()
+
+ if(cantbeused(user))
+ return
+
+ if(recharge(M, user))
+ return
+ return ..()
+
+
+/obj/item/weapon/inducer/attack_self(mob/user)
+ if(opened && cell)
+ user.visible_message("[user] removes \the [cell] from \the [src]!","You remove \the [cell].")
+ cell.update_icon()
+ user.put_in_hands(cell)
+ cell = null
+ update_icon()
+
+
+/obj/item/weapon/inducer/examine(mob/living/M)
+ ..()
+ if(cell)
+ to_chat(M, "It's display shows: [cell.charge]W")
+ else
+ to_chat(M,"It's display is dark.")
+ if(opened)
+ to_chat(M,"It's battery compartment is open.")
+
+/obj/item/weapon/inducer/update_icon()
+ cut_overlays()
+ if(opened)
+ if(!cell)
+ add_overlay("inducer-nobat")
+ else
+ add_overlay("inducer-bat")
+
+/obj/item/weapon/inducer/sci
+ icon_state = "inducer-sci"
+ item_state = "inducer-sci"
+ desc = "A tool for inductively charging internal power cells. This one has a science color scheme, and is less potent than it's engineering counterpart."
+ cell_type = null
+ powertransfer = 500
+ opened = TRUE
+
+/obj/item/weapon/inducer/sci/Initialize()
+ . = ..()
+ update_icon()
+
+
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index 05a83203cec..33ac3565977 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -13,10 +13,13 @@
var/stunforce = 7
var/status = 0
- var/obj/item/weapon/stock_parts/cell/high/bcell = null
+ var/obj/item/weapon/stock_parts/cell/high/cell
var/hitcost = 1000
var/throw_hit_chance = 35
+/obj/item/weapon/melee/baton/get_cell()
+ return cell
+
/obj/item/weapon/melee/baton/suicide_act(mob/user)
user.visible_message("[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide!")
return (FIRELOSS)
@@ -32,15 +35,16 @@
baton_stun(hit_atom)
/obj/item/weapon/melee/baton/loaded/Initialize() //this one starts with a cell pre-installed.
- bcell = new(src)
+ cell = new(src)
+ update_icon()
. = ..()
/obj/item/weapon/melee/baton/proc/deductcharge(chrgdeductamt)
- if(bcell)
+ if(cell)
//Note this value returned is significant, as it will determine
//if a stun is applied or not
- . = bcell.use(chrgdeductamt)
- if(status && bcell.charge < hitcost)
+ . = cell.use(chrgdeductamt)
+ if(status && cell.charge < hitcost)
//we're below minimum, turn off
status = 0
update_icon()
@@ -50,22 +54,22 @@
/obj/item/weapon/melee/baton/update_icon()
if(status)
icon_state = "[initial(name)]_active"
- else if(!bcell)
+ else if(!cell)
icon_state = "[initial(name)]_nocell"
else
icon_state = "[initial(name)]"
/obj/item/weapon/melee/baton/examine(mob/user)
..()
- if(bcell)
- to_chat(user, "The baton is [round(bcell.percent())]% charged.")
+ if(cell)
+ to_chat(user, "The baton is [round(cell.percent())]% charged.")
else
to_chat(user, "The baton does not have a power source installed.")
/obj/item/weapon/melee/baton/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/stock_parts/cell))
var/obj/item/weapon/stock_parts/cell/C = W
- if(bcell)
+ if(cell)
to_chat(user, "[src] already has a cell.")
else
if(C.maxcharge < hitcost)
@@ -73,15 +77,15 @@
return
if(!user.transferItemToLoc(W, src))
return
- bcell = W
+ cell = W
to_chat(user, "You install a cell in [src].")
update_icon()
else if(istype(W, /obj/item/weapon/screwdriver))
- if(bcell)
- bcell.updateicon()
- bcell.loc = get_turf(src.loc)
- bcell = null
+ if(cell)
+ cell.update_icon()
+ cell.forceMove(get_turf(src))
+ cell = null
to_chat(user, "You remove the cell from [src].")
status = 0
update_icon()
@@ -89,13 +93,13 @@
return ..()
/obj/item/weapon/melee/baton/attack_self(mob/user)
- if(bcell && bcell.charge > hitcost)
+ if(cell && cell.charge > hitcost)
status = !status
to_chat(user, "[src] is now [status ? "on" : "off"].")
playsound(loc, "sparks", 75, 1, -1)
else
status = 0
- if(!bcell)
+ if(!cell)
to_chat(user, "[src] does not have a power source!")
else
to_chat(user, "[src] is out of charge.")
diff --git a/code/game/objects/items/weapons/teleprod.dm b/code/game/objects/items/weapons/teleprod.dm
index 07af7a30c47..d14788e0b18 100644
--- a/code/game/objects/items/weapons/teleprod.dm
+++ b/code/game/objects/items/weapons/teleprod.dm
@@ -28,7 +28,7 @@
/obj/item/weapon/melee/baton/cattleprod/attackby(obj/item/I, mob/user, params)//handles sticking a crystal onto a stunprod to make a teleprod
if(istype(I, /obj/item/weapon/ore/bluespace_crystal))
- if(!bcell)
+ if(!cell)
var/obj/item/weapon/melee/baton/cattleprod/teleprod/S = new /obj/item/weapon/melee/baton/cattleprod/teleprod
remove_item_from_storage(user)
qdel(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
index 38ffdad47bf..e30f40d173d 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
@@ -26,6 +26,7 @@
new /obj/item/clothing/glasses/meson/engine(src)
new /obj/item/weapon/door_remote/chief_engineer(src)
new /obj/item/weapon/pipe_dispenser(src)
+ new /obj/item/weapon/inducer(src)
/obj/structure/closet/secure_closet/engineering_electrical
name = "electrical supplies locker"
@@ -37,6 +38,8 @@
..()
new /obj/item/clothing/gloves/color/yellow(src)
new /obj/item/clothing/gloves/color/yellow(src)
+ new /obj/item/weapon/inducer(src)
+ new /obj/item/weapon/inducer(src)
for(var/i in 1 to 3)
new /obj/item/weapon/storage/toolbox/electrical(src)
for(var/i in 1 to 3)
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 1e5c16f6656..90c26657f59 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -480,8 +480,8 @@
if(istype(O, /obj/item/weapon/melee/baton))
var/obj/item/weapon/melee/baton/B = O
- if(B.bcell)
- if(B.bcell.charge > 0 && B.status == 1)
+ if(B.cell)
+ if(B.cell.charge > 0 && B.status == 1)
flick("baton_active", src)
var/stunforce = B.stunforce
user.Stun(stunforce)
diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm
index 421b8a057e8..fbce7a705dd 100644
--- a/code/modules/cargo/packs.dm
+++ b/code/modules/cargo/packs.dm
@@ -543,6 +543,13 @@
crate_name = "electrical maintenance crate"
crate_type = /obj/structure/closet/crate/engineering/electrical
+/datum/supply_pack/engineering/inducers
+ name = "NT-75 Electromagnetic Power Inducers Crate"
+ cost = 2000
+ contains = list(/obj/item/weapon/inducer/sci {cell_type = /obj/item/weapon/stock_parts/cell/{maxcharge = 5000; charge = 5000};opened = 0},/obj/item/weapon/inducer/sci {cell_type = /obj/item/weapon/stock_parts/cell/{maxcharge = 5000; charge = 5000};opened = 0}) //FALSE doesn't work in modified type paths apparently.
+ crate_name = "inducer crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
/datum/supply_pack/engineering/engiequipment
name = "Engineering Gear Crate"
cost = 1300
diff --git a/code/modules/mob/living/carbon/human/interactive.dm b/code/modules/mob/living/carbon/human/interactive.dm
index 9b4f963d075..c93a79f4fc6 100644
--- a/code/modules/mob/living/carbon/human/interactive.dm
+++ b/code/modules/mob/living/carbon/human/interactive.dm
@@ -1540,7 +1540,7 @@
if(stunning && stunCheck.stunned)
shouldFire = 0
if(shouldFire)
- if(P.power_supply.charge <= 10) // can shoot seems to bug out for tasers, using this hacky method instead
+ if(P.cell.charge <= 10) // can shoot seems to bug out for tasers, using this hacky method instead
P.update_icon()
npcDrop(P,1)
else
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index a35e15dc7b7..d29064ce3a8 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -97,6 +97,9 @@
buckle_lying = FALSE
can_ride_typecache = list(/mob/living/carbon/human)
+/mob/living/silicon/robot/get_cell()
+ return cell
+
/mob/living/silicon/robot/Initialize(mapload)
spark_system = new /datum/effect_system/spark_spread()
spark_system.set_up(5, 0, src)
diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm
index 01c700768f1..96247fa1b1d 100644
--- a/code/modules/mob/living/silicon/robot/robot_defense.dm
+++ b/code/modules/mob/living/silicon/robot/robot_defense.dm
@@ -56,7 +56,7 @@
add_fingerprint(user)
if(opened && !wiresexposed && !issilicon(user))
if(cell)
- cell.updateicon()
+ cell.update_icon()
cell.add_fingerprint(user)
user.put_in_active_hand(cell)
to_chat(user, "You remove \the [cell].")
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 92e6448cb37..aa14cd1c789 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -149,8 +149,8 @@
F.update_icon()
else if(istype(I, /obj/item/weapon/melee/baton))
var/obj/item/weapon/melee/baton/B = I
- if(B.bcell)
- B.bcell.charge = B.bcell.maxcharge
+ if(B.cell)
+ B.cell.charge = B.cell.maxcharge
else if(istype(I, /obj/item/weapon/gun/energy))
var/obj/item/weapon/gun/energy/EG = I
if(!EG.chambered)
@@ -347,9 +347,9 @@
..()
var/obj/item/weapon/gun/energy/e_gun/advtaser/cyborg/T = locate(/obj/item/weapon/gun/energy/e_gun/advtaser/cyborg) in basic_modules
if(T)
- if(T.power_supply.charge < T.power_supply.maxcharge)
+ if(T.cell.charge < T.cell.maxcharge)
var/obj/item/ammo_casing/energy/S = T.ammo_type[T.select]
- T.power_supply.give(S.e_cost * coeff)
+ T.cell.give(S.e_cost * coeff)
T.update_icon()
else
T.charge_tick = 0
diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
index 81bf1145f85..893c34ea656 100644
--- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
@@ -364,15 +364,15 @@ Auto Patrol[]"},
if(!lasercolor)
var/obj/item/weapon/gun/energy/e_gun/advtaser/G = new /obj/item/weapon/gun/energy/e_gun/advtaser(Tsec)
- G.power_supply.charge = 0
+ G.cell.charge = 0
G.update_icon()
else if(lasercolor == "b")
var/obj/item/weapon/gun/energy/laser/bluetag/G = new /obj/item/weapon/gun/energy/laser/bluetag(Tsec)
- G.power_supply.charge = 0
+ G.cell.charge = 0
G.update_icon()
else if(lasercolor == "r")
var/obj/item/weapon/gun/energy/laser/redtag/G = new /obj/item/weapon/gun/energy/laser/redtag(Tsec)
- G.power_supply.charge = 0
+ G.cell.charge = 0
G.update_icon()
if(prob(50))
diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm
index d0c0a35b53a..8b588afdbd8 100644
--- a/code/modules/mob/living/simple_animal/hostile/mimic.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm
@@ -229,10 +229,10 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
/mob/living/simple_animal/hostile/mimic/copy/ranged/OpenFire(the_target)
if(Zapgun)
- if(Zapgun.power_supply)
+ if(Zapgun.cell)
var/obj/item/ammo_casing/energy/shot = Zapgun.ammo_type[Zapgun.select]
- if(Zapgun.power_supply.charge >= shot.e_cost)
- Zapgun.power_supply.use(shot.e_cost)
+ if(Zapgun.cell.charge >= shot.e_cost)
+ Zapgun.cell.use(shot.e_cost)
Zapgun.update_icon()
..()
else if(Zapstick)
diff --git a/code/modules/modular_computers/computers/item/computer_power.dm b/code/modules/modular_computers/computers/item/computer_power.dm
index c03570c3353..963aaf33099 100644
--- a/code/modules/modular_computers/computers/item/computer_power.dm
+++ b/code/modules/modular_computers/computers/item/computer_power.dm
@@ -26,6 +26,10 @@
return battery_module.battery.give(amount)
return 0
+/obj/item/device/modular_computer/get_cell()
+ var/obj/item/weapon/computer_hardware/battery/battery_module = all_components[MC_CELL]
+ if(battery_module && battery_module.battery)
+ return battery_module.battery
// Used in following function to reduce copypaste
/obj/item/device/modular_computer/proc/power_failure()
diff --git a/code/modules/ninja/suit/ninjaDrainAct.dm b/code/modules/ninja/suit/ninjaDrainAct.dm
index 7a3e119a56d..c75dd1032d5 100644
--- a/code/modules/ninja/suit/ninjaDrainAct.dm
+++ b/code/modules/ninja/suit/ninjaDrainAct.dm
@@ -111,7 +111,7 @@ They *could* go in their appropriate files, but this is supposed to be modular
S.cell.charge += charge
charge = 0
corrupt()
- updateicon()
+ update_icon()
//RDCONSOLE//
diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm
index d5811e32c93..2f3c64ca8f8 100644
--- a/code/modules/ninja/suit/suit.dm
+++ b/code/modules/ninja/suit/suit.dm
@@ -57,6 +57,9 @@ Contents:
var/a_boost = 3//Number of adrenaline boosters.
+/obj/item/clothing/suit/space/space_ninja/get_cell()
+ return cell
+
/obj/item/clothing/suit/space/space_ninja/New()
..()
diff --git a/code/modules/ninja/suit/suit_attackby.dm b/code/modules/ninja/suit/suit_attackby.dm
index e54a5e0e85f..7903d4c3e7c 100644
--- a/code/modules/ninja/suit/suit_attackby.dm
+++ b/code/modules/ninja/suit/suit_attackby.dm
@@ -32,7 +32,7 @@
U.put_in_hands(old_cell)
old_cell.add_fingerprint(U)
old_cell.corrupt()
- old_cell.updateicon()
+ old_cell.update_icon()
cell = CELL
to_chat(U, "Upgrade complete. Maximum capacity: [round(cell.maxcharge/100)]%")
else
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index e526d6ba6d5..0dcbf89ab51 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -93,6 +93,9 @@
var/update_overlay = -1
var/icon_update_needed = FALSE
+/obj/machinery/power/apc/get_cell()
+ return cell
+
/obj/machinery/power/apc/connect_to_network()
//Override because the APC does not directly connect to the network; it goes through a terminal.
//The terminal is what the power computer looks for anyway.
@@ -620,14 +623,10 @@
return
if(usr == user && opened && (!issilicon(user)))
if(cell)
+ user.visible_message("[user] removes \the [cell] from [src]!","You remove \the [cell].")
user.put_in_hands(cell)
- cell.add_fingerprint(user)
- cell.updateicon()
-
+ cell.update_icon()
src.cell = null
- user.visible_message("[user.name] removes the power cell from [src.name]!",\
- "You remove the power cell.")
- //to_chat(user, "You remove the power cell.")
charging = 0
src.update_icon()
return
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 5cee0f3bfe5..0b74b1ec31d 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -19,13 +19,16 @@
var/ratingdesc = TRUE
var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it.
+/obj/item/weapon/stock_parts/cell/get_cell()
+ return src
+
/obj/item/weapon/stock_parts/cell/New()
..()
START_PROCESSING(SSobj, src)
charge = maxcharge
if(ratingdesc)
desc += " This one has a power rating of [maxcharge], and you should not swallow it."
- updateicon()
+ update_icon()
/obj/item/weapon/stock_parts/cell/Destroy()
STOP_PROCESSING(SSobj, src)
@@ -46,7 +49,7 @@
else
return PROCESS_KILL
-/obj/item/weapon/stock_parts/cell/proc/updateicon()
+/obj/item/weapon/stock_parts/cell/update_icon()
cut_overlays()
if(grown_battery)
add_overlay("grown_wires")
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index aba3b9bc8a9..e20cb770899 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -4,7 +4,7 @@
desc = "A basic energy-based gun."
icon = 'icons/obj/guns/energy.dmi'
- var/obj/item/weapon/stock_parts/cell/power_supply //What type of power cell this uses
+ var/obj/item/weapon/stock_parts/cell/cell //What type of power cell this uses
var/cell_type = /obj/item/weapon/stock_parts/cell
var/modifystate = 0
var/list/ammo_type = list(/obj/item/ammo_casing/energy)
@@ -20,19 +20,21 @@
var/use_cyborg_cell = 0 //whether the gun's cell drains the cyborg user's cell to recharge
/obj/item/weapon/gun/energy/emp_act(severity)
- power_supply.use(round(power_supply.charge / severity))
+ cell.use(round(cell.charge / severity))
chambered = null //we empty the chamber
recharge_newshot() //and try to charge a new shot
update_icon()
+/obj/item/weapon/gun/energy/get_cell()
+ return cell
/obj/item/weapon/gun/energy/Initialize()
. = ..()
if(cell_type)
- power_supply = new cell_type(src)
+ cell = new cell_type(src)
else
- power_supply = new(src)
- power_supply.give(power_supply.maxcharge)
+ cell = new(src)
+ cell.give(cell.maxcharge)
update_ammo_types()
recharge_newshot(1)
if(selfcharge)
@@ -50,9 +52,7 @@
fire_delay = shot.delay
/obj/item/weapon/gun/energy/Destroy()
- if(power_supply)
- qdel(power_supply)
- power_supply = null
+ QDEL_NULL(cell)
STOP_PROCESSING(SSobj, src)
return ..()
@@ -62,9 +62,9 @@
if(charge_tick < charge_delay)
return
charge_tick = 0
- if(!power_supply)
+ if(!cell)
return
- power_supply.give(100)
+ cell.give(100)
if(!chambered) //if empty chamber we try to charge a new shot
recharge_newshot(1)
update_icon()
@@ -76,10 +76,10 @@
/obj/item/weapon/gun/energy/can_shoot()
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
- return power_supply.charge >= shot.e_cost
+ return cell.charge >= shot.e_cost
/obj/item/weapon/gun/energy/recharge_newshot(no_cyborg_drain)
- if (!ammo_type || !power_supply)
+ if (!ammo_type || !cell)
return
if(use_cyborg_cell && !no_cyborg_drain)
if(iscyborg(loc))
@@ -87,10 +87,10 @@
if(R.cell)
var/obj/item/ammo_casing/energy/shot = ammo_type[select] //Necessary to find cost of shot
if(R.cell.use(shot.e_cost)) //Take power from the borg...
- power_supply.give(shot.e_cost) //... to recharge the shot
+ cell.give(shot.e_cost) //... to recharge the shot
if(!chambered)
var/obj/item/ammo_casing/energy/AC = ammo_type[select]
- if(power_supply.charge >= AC.e_cost) //if there's enough power in the power_supply cell...
+ 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)
chambered.newshot()
@@ -98,7 +98,7 @@
/obj/item/weapon/gun/energy/process_chamber()
if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired...
var/obj/item/ammo_casing/energy/shot = chambered
- power_supply.use(shot.e_cost)//... drain the power_supply cell
+ cell.use(shot.e_cost)//... drain the cell cell
chambered = null //either way, released the prepared shot
recharge_newshot() //try to charge a new shot
@@ -120,7 +120,7 @@
..()
if(!automatic_charge_overlays)
return
- var/ratio = Ceiling((power_supply.charge / power_supply.maxcharge) * charge_sections)
+ var/ratio = Ceiling((cell.charge / cell.maxcharge) * charge_sections)
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
var/iconState = "[icon_state]_charge"
var/itemState = null
@@ -131,7 +131,7 @@
iconState += "_[shot.select_name]"
if(itemState)
itemState += "[shot.select_name]"
- if(power_supply.charge < shot.e_cost)
+ if(cell.charge < shot.e_cost)
add_overlay("[icon_state]_empty")
else
if(!shaded_charge)
@@ -157,7 +157,7 @@
user.visible_message("[user] melts [user.p_their()] face off with [src]!")
playsound(loc, fire_sound, 50, 1, -1)
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
- power_supply.use(shot.e_cost)
+ cell.use(shot.e_cost)
update_icon()
return(FIRELOSS)
else
@@ -192,17 +192,17 @@
user.visible_message("[user] tries to light their [A.name] with [src], but it doesn't do anything. Dumbass.")
playsound(user, E.fire_sound, 50, 1)
playsound(user, BB.hitsound, 50, 1)
- power_supply.use(E.e_cost)
+ cell.use(E.e_cost)
. = ""
else if(BB.damage_type != BURN)
user.visible_message("[user] tries to light their [A.name] with [src], but only succeeds in utterly destroying it. Dumbass.")
playsound(user, E.fire_sound, 50, 1)
playsound(user, BB.hitsound, 50, 1)
- power_supply.use(E.e_cost)
+ cell.use(E.e_cost)
qdel(A)
. = ""
else
playsound(user, E.fire_sound, 50, 1)
playsound(user, BB.hitsound, 50, 1)
- power_supply.use(E.e_cost)
+ cell.use(E.e_cost)
. = "[user] casually lights their [A.name] with [src]. Damn."
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index 770a8952048..410e2bbe68a 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -97,7 +97,7 @@
empty()
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/empty()
- power_supply.use(500)
+ cell.use(500)
update_icon()
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/attempt_reload()
@@ -122,7 +122,7 @@
return
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/reload()
- power_supply.give(500)
+ cell.give(500)
recharge_newshot(1)
if(!suppressed)
playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 90c3b4a72ab..196d44ad083 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -39,7 +39,7 @@
/obj/item/weapon/gun/energy/decloner/update_icon()
..()
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
- if(power_supply.charge > shot.e_cost)
+ if(cell.charge > shot.e_cost)
add_overlay("decloner_spin")
/obj/item/weapon/gun/energy/floragun
@@ -137,19 +137,19 @@
/obj/item/weapon/gun/energy/plasmacutter/examine(mob/user)
..()
- if(power_supply)
- to_chat(user, "[src] is [round(power_supply.percent())]% charged.")
+ if(cell)
+ to_chat(user, "[src] is [round(cell.percent())]% charged.")
/obj/item/weapon/gun/energy/plasmacutter/attackby(obj/item/A, mob/user)
if(istype(A, /obj/item/stack/sheet/mineral/plasma))
var/obj/item/stack/sheet/S = A
S.use(1)
- power_supply.give(1000)
+ cell.give(1000)
recharge_newshot(1)
to_chat(user, "You insert [A] in [src], recharging it.")
else if(istype(A, /obj/item/weapon/ore/plasma))
qdel(A)
- power_supply.give(500)
+ cell.give(500)
recharge_newshot(1)
to_chat(user, "You insert [A] in [src], recharging it.")
else
diff --git a/code/modules/research/designs/power_designs.dm b/code/modules/research/designs/power_designs.dm
index f03bb8f3e9d..aa52acc2fb9 100644
--- a/code/modules/research/designs/power_designs.dm
+++ b/code/modules/research/designs/power_designs.dm
@@ -68,6 +68,16 @@
build_path = /obj/item/device/lightreplacer
category = list("Power Designs")
+/datum/design/inducer
+ name = "Inducer"
+ desc = "The NT-75 Electromagnetic Power Inducer can wirelessly induce electric charge in an object, allowing you to recharge power cells without having to remove them."
+ id = "inducer"
+ req_tech = list("powerstorage" = 4, "engineering" = 4, "magnets" = 4)
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 3000, MAT_GLASS = 1000)
+ build_path = /obj/item/weapon/inducer/sci
+ category = list("Power Designs")
+
/datum/design/board/pacman
name = "Machine Design (PACMAN-type Generator Board)"
desc = "The circuit board that for a PACMAN-type portable generator."
diff --git a/config/admins.txt b/config/admins.txt
index b4485c08411..296377199e7 100644
--- a/config/admins.txt
+++ b/config/admins.txt
@@ -8,6 +8,7 @@
# NOTE: syntax was changed to allow hyphenation of ranknames, since spaces are stripped. #
###############################################################################################
Optimumtact = Host
+Expletives = Game Master
kingofkosmos = Game Master
MrStonedOne = Game Master
microscopics = Game Master
diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi
index 42b390ff3b4..68f8caac6bd 100644
Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ
diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi
index 64a58e66987..262c802ca1c 100644
Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ
diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi
index 042a8c12cd3..cdbaa9e2489 100644
Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 06ee87f2961..2321b804069 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -798,6 +798,7 @@
#include "code\game\objects\items\weapons\his_grace.dm"
#include "code\game\objects\items\weapons\holosign_creator.dm"
#include "code\game\objects\items\weapons\holy_weapons.dm"
+#include "code\game\objects\items\weapons\inducer.dm"
#include "code\game\objects\items\weapons\kitchen.dm"
#include "code\game\objects\items\weapons\manuals.dm"
#include "code\game\objects\items\weapons\miscellaneous.dm"