diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 74202a2f82a..f447c378f65 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -672,7 +672,8 @@ Turf and target are seperate in case you want to teleport some distance from a t
else return get_step(ref, base_dir)
-/proc/do_mob(mob/user , mob/target, time = 30, numticks = 5, uninterruptible = 0) //This is quite an ugly solution but i refuse to use the old request system.
+/proc/do_mob(mob/user , mob/target, time = 30, numticks = 5, uninterruptible = 0, progress = 1)
+ //This is quite an ugly solution but i refuse to use the old request system.
if(!user || !target)
return 0
if(numticks == 0)
@@ -683,7 +684,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
var/timefraction = round(time/numticks)
var/image/progbar
for(var/i = 1 to numticks)
- if(user.client)
+ if(user.client && progress)
progbar = make_progress_bar(i, numticks, target)
user.client.images |= progbar
sleep(timefraction)
@@ -709,7 +710,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
progbar.pixel_y = 32
return progbar
-/proc/do_after(mob/user, delay, numticks = 5, needhand = 1, atom/target = null)
+/proc/do_after(mob/user, delay, numticks = 5, needhand = 1, atom/target = null, progress = 1)
if(!user)
return 0
@@ -728,7 +729,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
holdingnull = 0 //User is holding a tool of some kind
var/image/progbar
for (var/i = 1 to numticks)
- if(user.client)
+ if(user.client && progress)
progbar = make_progress_bar(i, numticks, target)
if(progbar)
user.client.images |= progbar
diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm
index f07cfcee824..acbd6511c01 100644
--- a/code/game/gamemodes/sandbox/h_sandbox.dm
+++ b/code/game/gamemodes/sandbox/h_sandbox.dm
@@ -30,7 +30,7 @@ var/hsboxspawn = 1
/obj/item/weapon/grab, /obj/item/tk_grab, /obj/item/weapon/implant, // not implanter, the actual thing that is inside you
/obj/item/assembly,/obj/item/device/onetankbomb, /obj/item/radio, /obj/item/device/pda/ai,
/obj/item/device/uplink/hidden, /obj/item/smallDelivery, /obj/item/missile,/obj/item/projectile,
- /obj/item/borg/sight,/obj/item/borg/overdrive,/obj/item/borg/stun,/obj/item/weapon/robot_module)
+ /obj/item/borg/sight,/obj/item/borg/stun,/obj/item/weapon/robot_module)
/datum/hSB/proc/update()
var/global/list/hrefs = list(
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 48962ff51a7..a300a65cf7b 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -139,51 +139,6 @@
/obj/machinery/recharge_station/proc/restock_modules()
if(occupant)
var/mob/living/silicon/robot/R = occupant
- if(R.module && R.module.modules)
- var/list/um = R.contents|R.module.modules // Makes single list of active (R.contents) and inactive (R.module.modules) modules
+ if(R && R.module)
var/coeff = recharge_speed / 200
- for (var/datum/robot_energy_storage/st in R.module.storages)
- st.energy = min(st.max_energy, st.energy + coeff * st.recharge_rate)
- for(var/obj/O in um)
- //General
- if(istype(O,/obj/item/device/assembly/flash))
- var/obj/item/device/assembly/flash/F = O
- if(F.crit_fail)
- F.crit_fail = 0
- F.times_used = 0
- F.update_icon()
- // Security
- if(istype(O,/obj/item/weapon/gun/energy/gun/advtaser/cyborg))
- var/obj/item/weapon/gun/energy/gun/advtaser/cyborg/T = O
- if(T.power_supply.charge < T.power_supply.maxcharge)
- var/obj/item/ammo_casing/energy/S = T.ammo_type[T.select]
- T.power_supply.give(S.e_cost * coeff)
- T.update_icon()
- else
- T.charge_tick = 0
- if(istype(O,/obj/item/weapon/melee/baton))
- var/obj/item/weapon/melee/baton/B = O
- if(B.bcell)
- B.bcell.charge = B.bcell.maxcharge
- //Service
- if(istype(O,/obj/item/weapon/reagent_containers/food/condiment/enzyme))
- if(O.reagents.get_reagent_amount("enzyme") < 50)
- O.reagents.add_reagent("enzyme", 2 * coeff)
- //Janitor
- if(istype(O, /obj/item/device/lightreplacer))
- var/obj/item/device/lightreplacer/LR = O
- var/i = 1
- for(1, i <= coeff, i++)
- LR.Charge(R)
-
- if(R && R.module)
- R.module.respawn_consumable(R)
-
- //Emagged items for janitor and medical borg
- if(R.module.emag)
- if(istype(R.module.emag, /obj/item/weapon/reagent_containers/spray))
- var/obj/item/weapon/reagent_containers/spray/S = R.module.emag
- if(S.name == "Fluacid spray")
- S.reagents.add_reagent("facid", 2 * coeff)
- else if(S.name == "lube spray")
- S.reagents.add_reagent("lube", 2 * coeff)
+ R.module.respawn_consumable(R, coeff)
diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm
index c0fad8ee6fb..832792bb552 100644
--- a/code/game/objects/items/apc_frame.dm
+++ b/code/game/objects/items/apc_frame.dm
@@ -46,10 +46,17 @@
/obj/item/wallframe/attackby(obj/item/weapon/W, mob/user, params)
..()
+ if(istype(W, /obj/item/weapon/screwdriver))
+ // For camera-building borgs
+ var/turf/T = get_step(get_turf(user), user.dir)
+ if(istype(T, /turf/simulated/wall))
+ T.attackby(src, user, params)
+
+
var/metal_amt = round(materials[MAT_METAL]/MINERAL_MATERIAL_AMOUNT)
var/glass_amt = round(materials[MAT_GLASS]/MINERAL_MATERIAL_AMOUNT)
- if (istype(W, /obj/item/weapon/wrench) && (metal_amt || glass_amt))
+ if(istype(W, /obj/item/weapon/wrench) && (metal_amt || glass_amt))
user << "You dismantle [src]."
if(metal_amt)
new /obj/item/stack/sheet/metal(get_turf(src), metal_amt)
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index 607060233b7..9c50d02b0f7 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -1,59 +1,177 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
/**********************************************************************
Cyborg Spec Items
***********************************************************************/
-//Might want to move this into several files later but for now it works here
-/obj/item/borg/stun
- name = "electrified arm"
+/obj/item/borg
icon = 'icons/mob/robot_items.dmi'
+
+
+/obj/item/borg/stun
+ name = "electrically-charged arm"
icon_state = "elecarm"
-/obj/item/borg/stun/attack(mob/M, mob/living/silicon/robot/user)
-
- user.cell.charge -= 30
+/obj/item/borg/stun/attack(mob/living/M, mob/living/silicon/robot/user)
+ if(!user.cell.use(30)) return
M.Weaken(5)
- if (M.stuttering < 5)
- M.stuttering = 5
+ M.apply_effect(STUTTER, 5)
M.Stun(5)
- for(var/mob/O in viewers(M, null))
- if (O.client)
- O.show_message("[user] has prodded [M] with an electrically-charged arm!", 1,
- "You hear someone fall.", 2)
+ M.visible_message("[user] has prodded [M] with [src]!", \
+ "[user] has prodded you with [src]!")
add_logs(user, M, "stunned", src, "(INTENT: [uppertext(user.a_intent)])")
-/obj/item/borg/overdrive
- name = "overdrive"
- icon = 'icons/obj/decals.dmi'
- icon_state = "shock"
+
+
+/obj/item/borg/charger
+ name = "power connector"
+ icon_state = "charger_draw"
+ flags = NOBLUDGEON
+ var/mode = "draw"
+ var/list/charge_machines = list(/obj/machinery/cell_charger, /obj/machinery/recharger,
+ /obj/machinery/recharge_station, /obj/machinery/mech_bay_recharge_port)
+ var/list/charge_items = list(/obj/item/weapon/stock_parts/cell, /obj/item/weapon/gun/energy,
+ )
+
+/obj/item/borg/charger/update_icon()
+ ..()
+ icon_state = "charger_[mode]"
+
+/obj/item/borg/charger/attack_self(mob/user)
+ if(mode == "draw")
+ mode = "charge"
+ else
+ mode = "draw"
+ user << "You toggle [src] to \"[mode]\" mode."
+ update_icon()
+
+/obj/item/borg/charger/afterattack(obj/item/target, mob/living/silicon/robot/user, proximity_flag)
+ if(!proximity_flag || !isrobot(user))
+ return
+ if(mode == "draw")
+ if(is_type_in_list(target, charge_machines))
+ var/obj/machinery/M = target
+ if((M.stat & (NOPOWER|BROKEN)) || !M.anchored)
+ user << "[M] is unpowered!"
+ return
+
+ user << "You connect to [M]'s power line..."
+ while(do_after(user, 15, target = M, progress = 0))
+ if(!user || !user.cell || mode != "draw")
+ return
+
+ if((M.stat & (NOPOWER|BROKEN)) || !M.anchored)
+ break
+
+ if(!user.cell.give(150))
+ break
+
+ M.use_power(200)
+
+ user << "You stop charging youself."
+
+ else if(is_type_in_list(target, charge_items))
+ var/obj/item/weapon/stock_parts/cell/cell = target
+ if(!istype(cell))
+ cell = locate(/obj/item/weapon/stock_parts/cell) in target
+ if(!cell)
+ user << "[target] has no power cell!"
+ return
+
+ if(istype(target, /obj/item/weapon/gun/energy))
+ var/obj/item/weapon/gun/energy/E = target
+ if(!E.can_charge)
+ user << "[target] has no power port!"
+ return
+
+ if(!cell.charge)
+ user << "[target] has no power!"
+
+
+ user << "You connect to [target]'s power port..."
+
+ while(do_after(user, 15, target = target, progress = 0))
+ if(!user || !user.cell || mode != "draw")
+ return
+
+ if(!cell || !target)
+ return
+
+ if(cell != target && cell.loc != target)
+ return
+
+ var/draw = min(cell.charge, cell.chargerate*0.5, user.cell.maxcharge-user.cell.charge)
+ if(!cell.use(draw))
+ break
+ if(!user.cell.give(draw))
+ break
+ target.update_icon()
+
+ user << "You stop charging youself."
+
+ else if(is_type_in_list(target, charge_items))
+ var/obj/item/weapon/stock_parts/cell/cell = target
+ if(!istype(cell))
+ cell = locate(/obj/item/weapon/stock_parts/cell) in target
+ if(!cell)
+ user << "[target] has no power cell!"
+ return
+
+ if(istype(target, /obj/item/weapon/gun/energy))
+ var/obj/item/weapon/gun/energy/E = target
+ if(!E.can_charge)
+ user << "[target] has no power port!"
+ return
+
+ if(cell.charge >= cell.maxcharge)
+ user << "[target] is already charged!"
+
+ user << "You connect to [target]'s power port..."
+
+ while(do_after(user, 15, target = target, progress = 0))
+ if(!user || !user.cell || mode != "charge")
+ return
+
+ if(!cell || !target)
+ return
+
+ if(cell != target && cell.loc != target)
+ return
+
+ var/draw = min(user.cell.charge, cell.chargerate*0.5, cell.maxcharge-cell.charge)
+ if(!user.cell.use(draw))
+ break
+ if(!cell.give(draw))
+ break
+ target.update_icon()
+
+ user << "You stop charging [target]."
+
+
+
/**********************************************************************
HUD/SIGHT things
***********************************************************************/
/obj/item/borg/sight
- icon = 'icons/obj/decals.dmi'
- icon_state = "securearea"
var/sight_mode = null
/obj/item/borg/sight/xray
name = "\proper x-ray Vision"
+ icon = 'icons/obj/decals.dmi'
+ icon_state = "securearea"
sight_mode = BORGXRAY
/obj/item/borg/sight/thermal
name = "\proper thermal vision"
sight_mode = BORGTHERM
- icon = 'icons/mob/robot_items.dmi'
icon_state = "thermal"
/obj/item/borg/sight/meson
name = "\proper meson vision"
sight_mode = BORGMESON
- icon = 'icons/mob/robot_items.dmi'
icon_state = "meson"
@@ -64,10 +182,8 @@
/obj/item/borg/sight/hud/med
name = "medical hud"
- icon = 'icons/mob/robot_items.dmi'
icon_state = "healthhud"
-
/obj/item/borg/sight/hud/med/New()
..()
hud = new /obj/item/clothing/glasses/hud/health(src)
@@ -76,7 +192,6 @@
/obj/item/borg/sight/hud/sec
name = "security hud"
- icon = 'icons/mob/robot_items.dmi'
icon_state = "securityhud"
/obj/item/borg/sight/hud/sec/New()
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index 66cbfef59cb..fa73dded3a7 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -6,14 +6,20 @@
desc = "Protected by FRM."
icon = 'icons/obj/module.dmi'
icon_state = "cyborg_upgrade"
+ origin_tech = "programming=4"
var/locked = 0
var/require_module = 0
var/installed = 0
+ var/module_type = null
/obj/item/borg/upgrade/proc/action(mob/living/silicon/robot/R)
if(R.stat == DEAD)
usr << "[src] will not function on a deceased cyborg."
return 1
+ if(module_type && !istype(R.module, module_type))
+ R << "Upgrade mounting error! No suitable hardpoint detected!"
+ usr << "There's no mounting point for the module!"
+ return 1
return 0
/obj/item/borg/upgrade/reset
@@ -40,6 +46,7 @@
return 1
+
/obj/item/borg/upgrade/rename
name = "cyborg reclassification board"
desc = "Used to rename a cyborg."
@@ -59,12 +66,12 @@
return 1
+
/obj/item/borg/upgrade/restart
name = "cyborg emergency reboot module"
desc = "Used to force a reboot of a disabled-but-repaired cyborg, bringing it back online."
icon_state = "cyborg_upgrade1"
-
/obj/item/borg/upgrade/restart/action(mob/living/silicon/robot/R)
if(R.health < 0)
usr << "You have to repair the cyborg before using this module!"
@@ -88,6 +95,7 @@
desc = "Used to kick in a cyborg's VTEC systems, increasing their speed."
icon_state = "cyborg_upgrade2"
require_module = 1
+ origin_tech = "engineering=4;materials=5"
/obj/item/borg/upgrade/vtec/action(mob/living/silicon/robot/R)
if(..()) return 0
@@ -104,16 +112,12 @@
desc = "Used to cool a mounted disabler, increasing the potential current in it and thus its recharge rate."
icon_state = "cyborg_upgrade3"
require_module = 1
-
+ module_type = /obj/item/weapon/robot_module/security
+ origin_tech = "engineering=4;powerstorage=4"
/obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/R)
if(..()) return 0
- if(!istype(R.module, /obj/item/weapon/robot_module/security))
- R << "Upgrade mounting error! No suitable hardpoint detected!"
- usr << "There's no mounting point for the module!"
- return 0
-
var/obj/item/weapon/gun/energy/disabler/cyborg/T = locate() in R.module
if(!T)
T = locate() in R.module.contents
@@ -133,74 +137,70 @@
return 1
+
/obj/item/borg/upgrade/jetpack
name = "mining cyborg jetpack"
desc = "A carbon dioxide jetpack suitable for low-gravity mining operations."
icon_state = "cyborg_upgrade3"
require_module = 1
+ module_type = /obj/item/weapon/robot_module/miner
+ origin_tech = "engineering=4;powerstorage=4"
/obj/item/borg/upgrade/jetpack/action(mob/living/silicon/robot/R)
if(..()) return 0
- if(!istype(R.module, /obj/item/weapon/robot_module/miner))
- R << "Upgrade mounting error! No suitable hardpoint detected!"
- usr << "There's no mounting point for the module!"
- return 0
- else
- R.module.modules += new/obj/item/weapon/tank/jetpack/carbondioxide(R.module)
- for(var/obj/item/weapon/tank/jetpack/carbondioxide in R.module.modules)
- R.internals = src
- R.jetpackoverlay = 1
- R.module.rebuild()
- return 1
+ R.module.modules += new/obj/item/weapon/tank/jetpack/carbondioxide(R.module)
+ for(var/obj/item/weapon/tank/jetpack/carbondioxide in R.module.modules)
+ R.internals = src
+ R.jetpackoverlay = 1
+ R.module.rebuild()
+ return 1
+
/obj/item/borg/upgrade/ddrill
name = "mining cyborg diamond drill"
desc = "A diamond drill replacement for the mining module's standard drill."
icon_state = "cyborg_upgrade3"
require_module = 1
+ module_type = /obj/item/weapon/robot_module/miner
+ origin_tech = "engineering=5;materials=5"
/obj/item/borg/upgrade/ddrill/action(mob/living/silicon/robot/R)
if(..()) return 0
- if(!istype(R.module, /obj/item/weapon/robot_module/miner))
- R << "Upgrade mounting error! No suitable hardpoint detected!"
- usr << "There's no mounting point for the module!"
- return 0
- else
- for(var/obj/item/weapon/pickaxe/drill/cyborg/D in R.module.modules)
- qdel(D)
- for(var/obj/item/weapon/shovel/S in R.module.modules)
- qdel(S)
- R.module.modules += new /obj/item/weapon/pickaxe/drill/cyborg/diamond(R.module)
- R.module.rebuild()
- return 1
+ for(var/obj/item/weapon/pickaxe/drill/cyborg/D in R.module.modules)
+ qdel(D)
+ for(var/obj/item/weapon/shovel/S in R.module.modules)
+ qdel(S)
+ R.module.modules += new /obj/item/weapon/pickaxe/drill/cyborg/diamond(R.module)
+ R.module.rebuild()
+ return 1
+
/obj/item/borg/upgrade/soh
name = "mining cyborg satchel of holding"
desc = "A satchel of holding replacement for mining cyborg's ore satchel module."
icon_state = "cyborg_upgrade3"
require_module = 1
+ module_type = /obj/item/weapon/robot_module/miner
+ origin_tech = "engineering=5;materials=5;bluespace=3"
/obj/item/borg/upgrade/soh/action(mob/living/silicon/robot/R)
if(..()) return 0
- if(!istype(R.module, /obj/item/weapon/robot_module/miner))
- R << "Upgrade mounting error! No suitable hardpoint detected!"
- usr << "There's no mounting point for the module!"
- return 0
- else
- for(var/obj/item/weapon/storage/bag/ore/cyborg/S in R.module.modules)
- qdel(S)
- R.module.modules += new /obj/item/weapon/storage/bag/ore/holding(R.module)
- R.module.rebuild()
- return 1
+ for(var/obj/item/weapon/storage/bag/ore/cyborg/S in R.module.modules)
+ qdel(S)
+ R.module.modules += new /obj/item/weapon/storage/bag/ore/holding(R.module)
+ R.module.rebuild()
+ return 1
+
/obj/item/borg/upgrade/syndicate
name = "illegal equipment module"
desc = "Unlocks the hidden, deadlier functions of a cyborg"
icon_state = "cyborg_upgrade3"
require_module = 1
+ origin_tech = "combat=4;syndicate=2"
/obj/item/borg/upgrade/syndicate/action(mob/living/silicon/robot/R)
if(..()) return 0
diff --git a/code/game/objects/items/weapons/chrono_eraser.dm b/code/game/objects/items/weapons/chrono_eraser.dm
index 7266fcf1bc0..96c48aab975 100644
--- a/code/game/objects/items/weapons/chrono_eraser.dm
+++ b/code/game/objects/items/weapons/chrono_eraser.dm
@@ -44,6 +44,7 @@
w_class = 3
flags = NODROP
ammo_type = list(/obj/item/ammo_casing/energy/chrono_beam)
+ can_charge = 0
fire_delay = 50
var/obj/item/weapon/chrono_eraser/TED = null
var/obj/effect/chrono_field/field = null
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index 1fb6648a806..be562abd8ef 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -47,20 +47,27 @@
else
user << "You fail to handcuff [C]!"
-/obj/item/weapon/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user)
- if(!target.handcuffed)
- if(!user.drop_item())
- return
- //target.throw_alert("handcuffed", src) // Can't do this because escaping cuffs isn't standardized. Also zipties.
- if(trashtype)
- target.handcuffed = new trashtype(target)
- qdel(src)
- else
- loc = target
- target.handcuffed = src
- target.update_inv_handcuffed(0)
+/obj/item/weapon/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user, var/dispense = 0)
+ if(target.handcuffed)
return
+ if(!user.drop_item() && !dispense)
+ return
+
+ var/obj/item/weapon/restraints/handcuffs/cuffs = src
+ if(trashtype)
+ cuffs = new trashtype()
+ else if(dispense)
+ cuffs = new type()
+
+ cuffs.loc = target
+ target.handcuffed = cuffs
+
+ target.update_inv_handcuffed(0)
+ if(trashtype && !dispense)
+ qdel(src)
+ return
+
/obj/item/weapon/restraints/handcuffs/cable
name = "cable restraints"
desc = "Looks like some cables tied together. Could be used to tie something up."
@@ -68,6 +75,24 @@
item_state = "coil_red"
breakouttime = 300 //Deciseconds = 30s
cuffsound = 'sound/weapons/cablecuff.ogg'
+ var/datum/robot_energy_storage/wirestorage = null
+
+/obj/item/weapon/restraints/handcuffs/cable/attack(mob/living/carbon/C, mob/living/carbon/human/user)
+ if(!istype(C))
+ return
+ if(wirestorage && wirestorage.energy < 15)
+ user << "You need at least 15 wire to restrain [C]!"
+ return
+ return ..()
+
+/obj/item/weapon/restraints/handcuffs/cable/apply_cuffs(mob/living/carbon/target, mob/user, var/dispense = 0)
+ if(wirestorage)
+ if(!wirestorage.use_charge(15))
+ user << "You need at least 15 wire to restrain [target]!"
+ return
+ return ..(target, user, 1)
+
+ return ..()
/obj/item/weapon/restraints/handcuffs/cable/red
icon_state = "cuff_red"
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 495923b86d5..9b89c0c01e7 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1863,9 +1863,7 @@
if(isrobot(L))
var/mob/living/silicon/robot/R = L
if(R.module)
- R.module.modules += I
- I.loc = R.module
- R.module.rebuild()
+ R.module.add_module(I)
R.activate_module(I)
diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm
index ca469d59ec4..4a6392266c7 100644
--- a/code/modules/mob/living/silicon/robot/examine.dm
+++ b/code/modules/mob/living/silicon/robot/examine.dm
@@ -1,24 +1,27 @@
/mob/living/silicon/robot/examine(mob/user)
var/msg = "*---------*\nThis is \icon[src] \a [src]!\n"
+ if(desc)
+ msg += "[desc]\n"
+
var/obj/act_module = get_active_hand()
if(act_module)
msg += "It is holding \icon[act_module] \a [act_module].\n"
msg += ""
if (src.getBruteLoss())
- if (src.getBruteLoss() < 60)
+ if (src.getBruteLoss() < maxHealth*0.5)
msg += "It looks slightly dented.\n"
else
msg += "It looks severely dented!\n"
if (src.getFireLoss())
- if (src.getFireLoss() < 60)
+ if (src.getFireLoss() < maxHealth*0.5)
msg += "It looks slightly charred.\n"
else
msg += "It looks severely burnt and heat-warped!\n"
- if (src.health < -50)
+ if (src.health < -maxHealth*0.5)
msg += "It looks barely operational.\n"
if (src.fire_stacks < 0)
msg += "It's covered in water.\n"
- if (src.fire_stacks > 0)
+ else if (src.fire_stacks > 0)
msg += "It's coated in something flammable.\n"
msg += ""
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index fed748e1a3d..fd76b500aa9 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -42,21 +42,21 @@
if (..()) //Alive.
- if(health <= config.health_threshold_dead) //die only once
+ if(health <= -maxHealth) //die only once
death()
return
- if(health < 50) //Gradual break down of modules as more damage is sustained
+ if(health < maxHealth*0.5) //Gradual break down of modules as more damage is sustained
if(uneq_module(module_state_3))
src << "SYSTEM ERROR: Module 3 OFFLINE."
if(health < 0)
if(uneq_module(module_state_2))
src << "SYSTEM ERROR: Module 2 OFFLINE."
- if(health < -50)
+ if(health < -maxHealth*0.5)
if(uneq_module(module_state_1))
src << "CRITICAL ERROR: All modules OFFLINE."
- if(getOxyLoss() > 50)
+ if(getOxyLoss() > maxHealth*0.5)
Paralyse(3)
if (paralysis || stunned || weakened) //Stunned etc.
@@ -131,25 +131,24 @@
/mob/living/silicon/robot/handle_hud_icons_health()
if (healths)
if (stat != DEAD)
- switch(health)
- if(100 to INFINITY)
- healths.icon_state = "health0"
- if(50 to 100)
- healths.icon_state = "health2"
- if(0 to 50)
- healths.icon_state = "health3"
- if(-50 to 0)
- healths.icon_state = "health4"
- if(config.health_threshold_dead to -50)
- healths.icon_state = "health5"
- else
- healths.icon_state = "health6"
+ if(health >= maxHealth)
+ healths.icon_state = "health0"
+ else if(health > maxHealth*0.5)
+ healths.icon_state = "health2"
+ else if(health > 0)
+ healths.icon_state = "health3"
+ else if(health > -maxHealth*0.5)
+ healths.icon_state = "health4"
+ else if(health > -maxHealth)
+ healths.icon_state = "health5"
+ else
+ healths.icon_state = "health6"
else
healths.icon_state = "health7"
/mob/living/silicon/robot/proc/update_cell()
if (cell)
- var/cellcharge = src.cell.charge/src.cell.maxcharge
+ var/cellcharge = cell.charge/cell.maxcharge
switch(cellcharge)
if(0.75 to INFINITY)
clear_alert("charge")
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 924ae2cb4db..8a6998e22ab 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -328,20 +328,20 @@
stat(null, "Time left: [max(malf.AI_win_timeleft/malf.apcs, 0)]")
if(cell)
- stat(null, text("Charge Left: [cell.charge]/[cell.maxcharge]"))
+ stat("Charge Left:", "[cell.charge]/[cell.maxcharge]")
else
stat(null, text("No Cell Inserted!"))
- stat(null, "Station Time: [worldtime2text()]")
+ stat("Station Time:", worldtime2text())
if(module)
internal = locate(/obj/item/weapon/tank/jetpack) in module.modules
if(internal)
- stat("Internal Atmosphere Info", internal.name)
- stat("Tank Pressure", internal.air_contents.return_pressure())
- for (var/datum/robot_energy_storage/st in module.storages)
- stat("[st.name]: [st.energy]/[st.max_energy]")
+ stat("Internal Atmosphere Info:", internal.name)
+ stat("Tank Pressure:", internal.air_contents.return_pressure())
+ for(var/datum/robot_energy_storage/st in module.storages)
+ stat("[st.name]:", "[st.energy]/[st.max_energy]")
if(connected_ai)
- stat(null, text("Master AI: [connected_ai.name]"))
+ stat("Master AI:", connected_ai.name)
/mob/living/silicon/robot/restrained()
return 0
@@ -418,20 +418,22 @@
if (istype(W, /obj/item/weapon/restraints/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do
return
- if (istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm")
+ if (istype(W, /obj/item/weapon/weldingtool) && (user.a_intent != "harm" || user == src))
user.changeNext_move(CLICK_CD_MELEE)
var/obj/item/weapon/weldingtool/WT = W
- if (src == user)
- user << "You lack the reach to be able to repair yourself!"
- return
- if (src.health >= src.maxHealth)
+ if (!getBruteLoss())
user << "[src] is already in good condition!"
return
if (WT.remove_fuel(0, user)) //The welder has 1u of fuel consumed by it's afterattack, so we don't need to worry about taking any away.
+ if(src == user)
+ user << "You start fixing youself..."
+ if(!do_after(user, 50, target = src))
+ return
+
adjustBruteLoss(-30)
updatehealth()
add_fingerprint(user)
- visible_message("[user] has fixed some of the dents on [src].")
+ visible_message("[user] has fixed some of the dents on [src].")
return
else
user << "The welder must be on for this task!"
@@ -439,7 +441,11 @@
else if(istype(W, /obj/item/stack/cable_coil) && wiresexposed)
var/obj/item/stack/cable_coil/coil = W
- if (fireloss > 0)
+ if (getFireLoss() > 0)
+ if(src == user)
+ user << "You start fixing youself..."
+ if(!do_after(user, 50, target = src))
+ return
if (coil.use(1))
adjustFireLoss(-30)
updatehealth()
@@ -753,7 +759,6 @@
return update_icons()
/mob/living/silicon/robot/update_icons()
-
overlays.Cut()
if(stat != DEAD && !(paralysis || stunned || weakened)) //Not dead, not stunned.
var/state_name = icon_state //For easy conversion and/or different names
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 4073292af07..13b6c061b55 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -38,6 +38,45 @@
if((m != R.module_state_1) && (m != R.module_state_2) && (m != R.module_state_3))
. += m
+/obj/item/weapon/robot_module/proc/get_or_create_estorage(var/storage_type)
+ for(var/datum/robot_energy_storage/S in storages)
+ if(istype(S, storage_type))
+ return S
+
+ return new storage_type(src)
+
+/obj/item/weapon/robot_module/proc/add_module(var/obj/item/I)
+ if(istype(I, /obj/item/stack))
+ var/obj/item/stack/S = I
+
+ if(is_type_in_list(S, list(/obj/item/stack/sheet/metal, /obj/item/stack/rods, /obj/item/stack/tile/plasteel)))
+ if(S.materials[MAT_METAL])
+ S.cost = S.materials[MAT_METAL] * 0.25
+ S.source = get_or_create_estorage(/datum/robot_energy_storage/metal)
+
+ else if(istype(S, /obj/item/stack/sheet/glass))
+ S.cost = 500
+ S.source = get_or_create_estorage(/datum/robot_energy_storage/glass)
+
+ else if(istype(S, /obj/item/stack/medical))
+ S.cost = 250
+ S.source = get_or_create_estorage(/datum/robot_energy_storage/medical)
+
+ else if(istype(S, /obj/item/stack/cable_coil))
+ S.cost = 1
+ S.source = get_or_create_estorage(/datum/robot_energy_storage/wire)
+
+ if(S && S.source)
+ S.materials = list()
+ S.is_cyborg = 1
+
+ if(istype(I, /obj/item/weapon/restraints/handcuffs/cable))
+ var/obj/item/weapon/restraints/handcuffs/cable/C = I
+ C.wirestorage = get_or_create_estorage(/datum/robot_energy_storage/wire)
+
+ I.loc = src
+ modules += I
+ rebuild()
/obj/item/weapon/robot_module/New()
modules += new /obj/item/device/assembly/flash/cyborg(src)
@@ -46,7 +85,20 @@
return
-/obj/item/weapon/robot_module/proc/respawn_consumable(mob/living/silicon/robot/R)
+/obj/item/weapon/robot_module/proc/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
+ for(var/datum/robot_energy_storage/st in storages)
+ st.energy = min(st.max_energy, st.energy + coeff * st.recharge_rate)
+
+ for(var/obj/item/I in get_usable_modules())
+ if(istype(I, /obj/item/device/assembly/flash))
+ var/obj/item/device/assembly/flash/F = I
+ F.times_used = 0
+ F.crit_fail = 0
+ F.update_icon()
+ 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
return
/obj/item/weapon/robot_module/proc/rebuild()//Rebuilds the list so it's possible to add/remove items from the module
@@ -83,6 +135,7 @@
fix_modules()
+
/obj/item/weapon/robot_module/medical
name = "medical robot module"
@@ -102,22 +155,20 @@
modules += new /obj/item/weapon/circular_saw(src)
modules += new /obj/item/weapon/extinguisher/mini(src)
modules += new /obj/item/roller/robo(src)
- emag = new /obj/item/weapon/reagent_containers/spray(src)
+ add_module(new /obj/item/stack/medical/gauze/cyborg())
+
+ emag = new /obj/item/weapon/reagent_containers/spray(src)
emag.reagents.add_reagent("facid", 250)
emag.name = "Fluacid spray"
-
- var/datum/robot_energy_storage/gauze/gauzestore = new /datum/robot_energy_storage/gauze(src)
-
- var/obj/item/stack/medical/gauze/cyborg/G = new /obj/item/stack/medical/gauze/cyborg(src)
- G.source = gauzestore
- modules += G
-
- storages += gauzestore
-
fix_modules()
+/obj/item/weapon/robot_module/medical/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
+ ..()
+ if(R.emagged && istype(emag, /obj/item/weapon/reagent_containers/spray))
+ emag.reagents.add_reagent("facid", 2 * coeff)
+
/obj/item/weapon/robot_module/engineering
@@ -139,40 +190,22 @@
modules += new /obj/item/device/t_scanner(src)
modules += new /obj/item/device/analyzer(src)
- var/datum/robot_energy_storage/metal/metstore = new /datum/robot_energy_storage/metal(src)
- var/datum/robot_energy_storage/glass/glastore = new /datum/robot_energy_storage/glass(src)
- var/datum/robot_energy_storage/wire/wirestore = new /datum/robot_energy_storage/wire(src)
-
- var/obj/item/stack/sheet/metal/cyborg/M = new /obj/item/stack/sheet/metal/cyborg(src)
- M.source = metstore
- modules += M
-
- var/obj/item/stack/sheet/glass/cyborg/Q = new /obj/item/stack/sheet/glass/cyborg(src)
- Q.source = glastore
- modules += Q
+ add_module(new /obj/item/stack/sheet/metal/cyborg())
+ add_module(new /obj/item/stack/sheet/glass/cyborg())
var/obj/item/stack/sheet/rglass/cyborg/G = new /obj/item/stack/sheet/rglass/cyborg(src)
- G.metsource = metstore
- G.glasource = glastore
- modules += G
+ G.metsource = get_or_create_estorage(/datum/robot_energy_storage/metal)
+ G.glasource = get_or_create_estorage(/datum/robot_energy_storage/glass)
+ add_module(G)
- var/obj/item/stack/rods/cyborg/R = new /obj/item/stack/rods/cyborg(src)
- R.source = metstore
- modules += R
+ add_module(new /obj/item/stack/rods/cyborg())
+ add_module(new /obj/item/stack/tile/plasteel/cyborg())
+ add_module(new /obj/item/stack/cable_coil/cyborg(src,MAXCOIL,"red"))
- var/obj/item/stack/cable_coil/cyborg/W = new /obj/item/stack/cable_coil/cyborg(src,MAXCOIL,pick("red","yellow","green","blue","pink","orange","cyan","white"))
- W.source = wirestore
- modules += W
-
- var/obj/item/stack/tile/plasteel/cyborg/F = new /obj/item/stack/tile/plasteel/cyborg(src) //"Plasteel" is the normal metal floor tile, Don't be confused - RR
- F.source = metstore
- modules += F //'F' for floor tile - RR(src)
-
- storages += metstore
- storages += glastore
- storages += wirestore
fix_modules()
+
+
/obj/item/weapon/robot_module/security
name = "security robot module"
@@ -185,6 +218,18 @@
emag = new /obj/item/weapon/gun/energy/laser/cyborg(src)
fix_modules()
+/obj/item/weapon/robot_module/security/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
+ ..()
+ var/obj/item/weapon/gun/energy/gun/advtaser/cyborg/T = locate(/obj/item/weapon/gun/energy/gun/advtaser/cyborg) in get_usable_modules()
+ if(T)
+ if(T.power_supply.charge < T.power_supply.maxcharge)
+ var/obj/item/ammo_casing/energy/S = T.ammo_type[T.select]
+ T.power_supply.give(S.e_cost * coeff)
+ T.update_icon()
+ else
+ T.charge_tick = 0
+
+
/obj/item/weapon/robot_module/janitor
name = "janitorial robot module"
@@ -202,6 +247,16 @@
emag.name = "lube spray"
fix_modules()
+/obj/item/weapon/robot_module/janitor/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
+ ..()
+ var/obj/item/device/lightreplacer/LR = locate(/obj/item/device/lightreplacer) in get_usable_modules()
+ if(LR)
+ for(var/i = 1, i <= coeff, i++)
+ LR.Charge(R)
+
+ if(R.emagged && istype(emag, /obj/item/weapon/reagent_containers/spray))
+ emag.reagents.add_reagent("lube", 2 * coeff)
+
/obj/item/weapon/robot_module/butler
name = "service robot module"
@@ -214,22 +269,20 @@
modules += new /obj/item/weapon/razor(src)
modules += new /obj/item/device/instrument/violin(src)
modules += new /obj/item/device/instrument/guitar(src)
-
- var/obj/item/weapon/rsf/M = new /obj/item/weapon/rsf(src)
- M.matter = 30
- modules += M
-
+ modules += new /obj/item/weapon/rsf{matter = 30}(src)
modules += new /obj/item/weapon/reagent_containers/dropper(src)
-
- var/obj/item/weapon/lighter/L = new /obj/item/weapon/lighter(src)
- L.lit = 1
- modules += L
-
+ modules += new /obj/item/weapon/lighter{lit = 1}(src)
modules += new /obj/item/weapon/storage/bag/tray(src)
modules += new /obj/item/weapon/reagent_containers/borghypo/borgshaker(src)
emag = new /obj/item/weapon/reagent_containers/borghypo/borgshaker/hacked(src)
fix_modules()
+/obj/item/weapon/robot_module/butler/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
+ ..()
+
+ var/obj/item/weapon/reagent_containers/O = locate(/obj/item/weapon/reagent_containers/food/condiment/enzyme) in get_usable_modules()
+ if(O)
+ O.reagents.add_reagent("enzyme", 2 * coeff)
/obj/item/weapon/robot_module/miner
name = "miner robot module"
@@ -247,6 +300,7 @@
fix_modules()
+
/obj/item/weapon/robot_module/syndicate
name = "syndicate assault robot module"
@@ -257,7 +311,7 @@
modules += new /obj/item/weapon/gun/projectile/revolver/grenadelauncher/cyborg(src)
modules += new /obj/item/weapon/card/emag(src)
modules += new /obj/item/weapon/tank/jetpack/carbondioxide(src)
- modules += new /obj/item/weapon/crowbar(src)
+ modules += new /obj/item/weapon/crowbar/red(src)
modules += new /obj/item/weapon/pinpointer/operative(src)
emag = null
fix_modules()
@@ -283,13 +337,8 @@
modules += new /obj/item/weapon/pinpointer/operative(src)
emag = null
- var/datum/robot_energy_storage/gauze/gauzestore = new /datum/robot_energy_storage/gauze(src)
- var/obj/item/stack/medical/gauze/cyborg/G = new /obj/item/stack/medical/gauze/cyborg(src)
- G.source = gauzestore
- modules += G
-
- storages += gauzestore
+ add_module(new /obj/item/stack/medical/gauze/cyborg())
fix_modules()
@@ -299,8 +348,10 @@
var/recharge_rate = 1000
var/energy
-/datum/robot_energy_storage/New()
+/datum/robot_energy_storage/New(var/obj/item/weapon/robot_module/R = null)
energy = max_energy
+ if(R)
+ R.storages |= src
return
/datum/robot_energy_storage/proc/use_charge(amount)
@@ -326,7 +377,7 @@
recharge_rate = 2
name = "Wire Synthesizer"
-/datum/robot_energy_storage/gauze
+/datum/robot_energy_storage/medical
max_energy = 2500
recharge_rate = 250
- name = "Gauze Synthesizer"
\ No newline at end of file
+ name = "Medical Synthesizer"
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index 2e86e52f5fd..fdb6681d978 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -54,6 +54,7 @@
return 1
/obj/item/weapon/gun/energy/laser/cyborg
+ can_charge = 0
desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?"
/obj/item/weapon/gun/energy/laser/cyborg/newshot()
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 9ad6ea678c0..901badc27c6 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -290,6 +290,7 @@
icon = 'icons/obj/guns/projectile.dmi'
cell_type = "/obj/item/weapon/stock_parts/cell/secborg"
ammo_type = list(/obj/item/ammo_casing/energy/c3dbullet)
+ can_charge = 0
var/charge_tick = 0
var/recharge_time = 5
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index acd06b2eda3..e2b500bb4b7 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -30,6 +30,7 @@
var/charge_tick = 0
var/recharge_time = 10
can_flashlight = 0
+ can_charge = 0
/obj/item/weapon/gun/energy/gun/advtaser/cyborg/New()
..()
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index 5c7b6096d40..ecab7f5cf22 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -18,7 +18,7 @@
if(!reagents.total_volume)
user << "[src] is empty!"
return
- if(!istype(M))
+ if(!iscarbon(M))
return
if(reagents.total_volume && (ignore_flags || M.can_inject(user, 1))) // Ignore flag should be checked first or there will be an error message.
@@ -69,19 +69,23 @@
flags = null
list_reagents = list("epinephrine" = 10)
-/obj/item/weapon/reagent_containers/hypospray/medipen/New()
- ..()
- update_icon()
- return
-
/obj/item/weapon/reagent_containers/hypospray/medipen/attack(mob/M, mob/user)
+ if(!reagents.total_volume)
+ user << "[src] is empty!"
+ return
..()
update_icon()
+ spawn(80)
+ if(isrobot(user) && !reagents.total_volume)
+ var/mob/living/silicon/robot/R = user
+ if(R.cell.use(100))
+ reagents.add_reagent_list(list_reagents)
+ update_icon()
return
/obj/item/weapon/reagent_containers/hypospray/medipen/update_icon()
if(reagents.total_volume > 0)
- icon_state = "[initial(icon_state)]1"
+ icon_state = initial(icon_state)
else
icon_state = "[initial(icon_state)]0"
@@ -100,6 +104,10 @@
amount_per_transfer_from_this = 20
list_reagents = list("ephedrine" = 10, "coffee" = 10)
+/obj/item/weapon/reagent_containers/hypospray/medipen/stimpack/traitor
+ desc = "A modified stimulants autoinjector for use in combat situations. Has a mild healing effect."
+ list_reagents = list("stimulants" = 10, "omnizine" = 10)
+
/obj/item/weapon/reagent_containers/hypospray/medipen/morphine
name = "morphine medipen"
desc = "A rapid way to get you out of a tight situation and fast! You'll feel rather drowsy, though."
diff --git a/icons/mob/robot_items.dmi b/icons/mob/robot_items.dmi
index 35a2148f538..0ac3137707f 100644
Binary files a/icons/mob/robot_items.dmi and b/icons/mob/robot_items.dmi differ
diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi
index 35ba3462fb8..647f1d492c8 100644
Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ