Merge pull request #6428 from atlantiscze/cyborg-power

Cyborg power overhaul
This commit is contained in:
Chinsky
2014-09-25 00:19:13 +04:00
14 changed files with 316 additions and 114 deletions
+1
View File
@@ -1036,6 +1036,7 @@
#include "code\modules\mob\living\silicon\pai\recruit.dm"
#include "code\modules\mob\living\silicon\pai\say.dm"
#include "code\modules\mob\living\silicon\pai\software.dm"
#include "code\modules\mob\living\silicon\robot\analyzer.dm"
#include "code\modules\mob\living\silicon\robot\component.dm"
#include "code\modules\mob\living\silicon\robot\death.dm"
#include "code\modules\mob\living\silicon\robot\emote.dm"
+11 -2
View File
@@ -194,9 +194,18 @@
. = list()
// Returns a list of mobs who can hear any of the radios given in @radios
var/list/speaker_coverage = list()
for(var/i = 1; i <= radios.len; i++)
var/obj/item/device/radio/R = radios[i]
for(var/obj/item/device/radio/R in radios)
if(R)
//Cyborg checks. Receiving message uses a bit of cyborg's charge.
var/obj/item/device/radio/borg/BR = R
if(istype(BR) && BR.myborg)
var/mob/living/silicon/robot/borg = BR.myborg
var/datum/robot_component/CO = borg.get_component("radio")
if(!CO)
continue //No radio component (Shouldn't happen)
if(!borg.is_component_functioning("radio") || !borg.cell_use_power(CO.active_usage))
continue //No power.
var/turf/speaker = get_turf(R)
if(speaker)
for(var/turf/T in hear(R.canhear_range,speaker))
+2 -2
View File
@@ -159,8 +159,8 @@ Class Procs:
del(src)
//sets the use_power var and then forces an area power update
/obj/machinery/proc/update_use_power(var/new_use_power)
if (new_use_power == use_power)
/obj/machinery/proc/update_use_power(var/new_use_power, var/force_update = 0)
if ((new_use_power == use_power) && !force_update)
return //don't need to do anything
use_power = new_use_power
+73 -5
View File
@@ -5,28 +5,76 @@
density = 1
anchored = 1.0
use_power = 1
idle_power_usage = 5 //internal circuitry
active_power_usage = 75000 //75 kW charging station
idle_power_usage = 50
active_power_usage = 50
var/mob/occupant = null
var/max_internal_charge = 15000 // Two charged borgs in a row with default cell
var/current_internal_charge = 15000 // Starts charged, to prevent power surges on round start
var/charging_cap_active = 25000 // Active Cap - When cyborg is inside
var/charging_cap_passive = 2500 // Passive Cap - Recharging internal capacitor when no cyborg is inside
var/icon_update_tick = 0 // Used to update icon only once every 10 ticks
New()
..()
build_icon()
update_icon()
process()
if(!(NOPOWER|BROKEN))
if(stat & (BROKEN))
return
if((stat & (NOPOWER)) && !current_internal_charge) // No Power.
return
var/chargemode = 0
if(src.occupant)
process_occupant()
chargemode = 1
// Power Stuff
if(stat & NOPOWER)
current_internal_charge = max(0, (current_internal_charge - (50 * CELLRATE))) // Internal Circuitry, 50W load. No power - Runs from internal cell
return // No external power = No charging
if(max_internal_charge < current_internal_charge)
current_internal_charge = max_internal_charge// Safety check if varedit adminbus or something screws up
// Calculating amount of power to draw
var/charge_diff = max_internal_charge - current_internal_charge // OK we have charge differences
charge_diff = charge_diff / CELLRATE // Deconvert from Charge to Joules
if(chargemode) // Decide if use passive or active power
charge_diff = between(0, charge_diff, charging_cap_active) // Trim the values to limits
else // We should have load for this tick in Watts
charge_diff = between(0, charge_diff, charging_cap_passive)
charge_diff += 50 // 50W for circuitry
if(idle_power_usage != charge_diff) // Force update, but only when our power usage changed this tick.
idle_power_usage = charge_diff
update_use_power(1,1)
current_internal_charge = min((current_internal_charge + ((charge_diff - 50) * CELLRATE)), max_internal_charge)
if(icon_update_tick >= 10)
update_icon()
icon_update_tick = 0
else
icon_update_tick++
return 1
allow_drop()
return 0
examine()
usr << "The charge meter reads: [round(chargepercentage())]%"
proc/chargepercentage()
return ((current_internal_charge / max_internal_charge) * 100)
relaymove(mob/user as mob)
if(user.stat)
@@ -43,6 +91,23 @@
go_out()
..(severity)
update_icon()
..()
overlays.Cut()
switch(round(chargepercentage()))
if(1 to 20)
overlays += image('icons/obj/objects.dmi', "statn_c0")
if(21 to 40)
overlays += image('icons/obj/objects.dmi', "statn_c20")
if(41 to 60)
overlays += image('icons/obj/objects.dmi', "statn_c40")
if(61 to 80)
overlays += image('icons/obj/objects.dmi', "statn_c60")
if(81 to 98)
overlays += image('icons/obj/objects.dmi', "statn_c80")
if(99 to 110)
overlays += image('icons/obj/objects.dmi', "statn_c100")
proc
build_icon()
if(NOPOWER|BROKEN)
@@ -62,7 +127,10 @@
if(!R.cell)
return
if(!R.cell.fully_charged())
R.cell.give(active_power_usage*CELLRATE)
var/diff = min(R.cell.maxcharge - R.cell.charge, 250) // Capped at 250 charge / tick
diff = min(diff, current_internal_charge) // No over-discharging
R.cell.give(diff)
current_internal_charge -= diff
else
update_use_power(1)
go_out()
@@ -116,5 +184,5 @@
O.loc = src.loc*/
src.add_fingerprint(usr)
build_icon()
update_use_power(2)
update_use_power(1)
return
@@ -682,9 +682,12 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
//Giving borgs their own radio to have some more room to work with -Sieve
/obj/item/device/radio/borg
var/mob/living/silicon/robot/myborg = null // Cyborg which owns this radio. Used for power checks
var/obj/item/device/encryptionkey/keyslot = null//Borg radios can handle a single encryption key
var/shut_up = 0
icon = 'icons/obj/robot_component.dmi' // Cyborgs radio icons should look like the component.
icon_state = "radio"
canhear_range = 3
/obj/item/device/radio/borg/attackby(obj/item/weapon/W as obj, mob/user as mob)
// ..()
@@ -774,6 +777,13 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
channels = list()
else
recalculateChannels()
if (href_list["shutup"]) // Toggle loudspeaker mode, AKA everyone around you hearing your radio.
shut_up = !shut_up
if(shut_up)
canhear_range = 0
else
canhear_range = 3
..()
/obj/item/device/radio/borg/interact(mob/user as mob)
@@ -790,6 +800,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
<A href='byond://?src=\ref[src];freq=2'>+</A>
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
<A href='byond://?src=\ref[src];mode=1'>Toggle Broadcast Mode</A><BR>
<A href='byond://?src=\ref[src];shutup=1'>Toggle Loudspeaker</A><BR>
"}
if(!subspace_transmission)//Don't even bother if subspace isn't turned on
@@ -0,0 +1,79 @@
//
//Robotic Component Analyser, basically a health analyser for robots
//
/obj/item/device/robotanalyzer
name = "cyborg analyzer"
icon_state = "robotanalyzer"
item_state = "analyzer"
desc = "A hand-held scanner able to diagnose robotic injuries."
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BELT
throwforce = 3
w_class = 2.0
throw_speed = 5
throw_range = 10
matter = list("metal" = 200)
origin_tech = "magnets=1;biotech=1"
var/mode = 1;
/obj/item/device/robotanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
if(( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))
user << text("\red You try to analyze the floor's vitals!")
for(var/mob/O in viewers(M, null))
O.show_message(text("\red [user] has analyzed the floor's vitals!"), 1)
user.show_message(text("\blue Analyzing Results for The floor:\n\t Overall Status: Healthy"), 1)
user.show_message(text("\blue \t Damage Specifics: [0]-[0]-[0]-[0]"), 1)
user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1)
user.show_message("\blue Body Temperature: ???", 1)
return
if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
user << "\red You don't have the dexterity to do this!"
return
if(!istype(M, /mob/living/silicon/robot) && !(ishuman(M) && (M:species.flags & IS_SYNTHETIC)))
user << "\red You can't analyze non-robotic things!"
return
user.visible_message("<span class='notice'> [user] has analyzed [M]'s components.","<span class='notice'> You have analyzed [M]'s components.")
var/BU = M.getFireLoss() > 50 ? "<b>[M.getFireLoss()]</b>" : M.getFireLoss()
var/BR = M.getBruteLoss() > 50 ? "<b>[M.getBruteLoss()]</b>" : M.getBruteLoss()
user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health - M.halloss]% functional"]")
user.show_message("\t Key: <font color='#FFA500'>Electronics</font>/<font color='red'>Brute</font>", 1)
user.show_message("\t Damage Specifics: <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>")
if(M.tod && M.stat == DEAD)
user.show_message("\blue Time of Disable: [M.tod]")
if (istype(M, /mob/living/silicon/robot))
var/mob/living/silicon/robot/H = M
var/list/damaged = H.get_damaged_components(1,1,1)
user.show_message("\blue Localized Damage:",1)
if(length(damaged)>0)
for(var/datum/robot_component/org in damaged)
user.show_message(text("\blue \t []: [][] - [] - [] - []", \
capitalize(org.name), \
(org.installed == -1) ? "<font color='red'><b>DESTROYED</b></font> " :"",\
(org.electronics_damage > 0) ? "<font color='#FFA500'>[org.electronics_damage]</font>" :0, \
(org.brute_damage > 0) ? "<font color='red'>[org.brute_damage]</font>" :0, \
(org.toggled) ? "Toggled ON" : "<font color='red'>Toggled OFF</font>",\
(org.powered) ? "Power ON" : "<font color='red'>Power OFF</font>"),1)
else
user.show_message("\blue \t Components are OK.",1)
if(H.emagged && prob(5))
user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1)
if (ishuman(M) && (M:species.flags & IS_SYNTHETIC))
var/mob/living/carbon/human/H = M
var/list/damaged = H.get_damaged_organs(1,1)
user.show_message("\blue Localized Damage, Brute/Electronics:",1)
if(length(damaged)>0)
for(var/datum/organ/external/org in damaged)
user.show_message(text("\blue \t []: [] - []", \
capitalize(org.display_name), \
(org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \
(org.burn_dam > 0) ? "<font color='#FFA500'>[org.burn_dam]</font>" :0),1)
else
user.show_message("\blue \t Components are OK.",1)
user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]&deg;C ([M.bodytemperature*1.8-459.67]&deg;F)", 1)
src.add_fingerprint(user)
return
@@ -6,8 +6,9 @@
/datum/robot_component/var/toggled = 1
/datum/robot_component/var/brute_damage = 0
/datum/robot_component/var/electronics_damage = 0
/datum/robot_component/var/energy_consumption = 0
/datum/robot_component/var/max_damage = 30
/datum/robot_component/var/idle_usage = 0 // Amount of power used every MC tick. In joules.
/datum/robot_component/var/active_usage = 0 // Amount of power used for every action. Actions are module-specific. Actuator for each tile moved, etc.
/datum/robot_component/var/max_damage = 30 // HP of this component.
/datum/robot_component/var/mob/living/silicon/robot/owner
// The actual device object that has to be installed for this.
@@ -55,34 +56,47 @@
electronics_damage = max(0, electronics_damage - electronics)
/datum/robot_component/proc/is_powered()
return (installed == 1) && (brute_damage + electronics_damage < max_damage) && (!energy_consumption || powered)
return (installed == 1) && (brute_damage + electronics_damage < max_damage) && (!idle_usage || powered)
/datum/robot_component/proc/update_power_state()
if(toggled == 0)
powered = 0
return
if(owner.cell && owner.cell.charge >= energy_consumption)
owner.cell.use(energy_consumption)
if(owner.cell && owner.cell.charge >= idle_usage)
owner.cell_use_power(idle_usage)
powered = 1
else
powered = 0
// ARMOUR
// Protects the cyborg from damage. Usually first module to be hit
// No power usage
/datum/robot_component/armour
name = "armour plating"
energy_consumption = 0
external_type = /obj/item/robot_parts/robot_component/armour
max_damage = 60
// ACTUATOR
// Enables movement.
// Uses no power when idle. Uses 200J for each tile the cyborg moves.
/datum/robot_component/actuator
name = "actuator"
energy_consumption = 2
idle_usage = 0
active_usage = 200
external_type = /obj/item/robot_parts/robot_component/actuator
max_damage = 50
//A fixed and much cleaner implementation of /tg/'s special snowflake code.
/datum/robot_component/actuator/is_powered()
return (installed == 1) && (brute_damage + electronics_damage < max_damage)
// POWER CELL
// Stores power (how unexpected..)
// No power usage
/datum/robot_component/cell
name = "power cell"
max_damage = 50
@@ -91,33 +105,55 @@
..()
owner.cell = null
// RADIO
// Enables radio communications
// Uses no power when idle. Uses 10J for each received radio message, 50 for each transmitted message.
/datum/robot_component/radio
name = "radio"
external_type = /obj/item/robot_parts/robot_component/radio
energy_consumption = 1
active_usage = 10
max_damage = 40
// BINARY RADIO
// Enables binary communications with other cyborgs/AIs
// Uses no power when idle. Uses 10J for each received radio message, 50 for each transmitted message
/datum/robot_component/binary_communication
name = "binary communication device"
external_type = /obj/item/robot_parts/robot_component/binary_communication_device
energy_consumption = 0
active_usage = 10
max_damage = 30
// CAMERA
// Enables cyborg vision. Can also be remotely accessed via consoles.
// Uses 10J constantly
/datum/robot_component/camera
name = "camera"
external_type = /obj/item/robot_parts/robot_component/camera
energy_consumption = 1
idle_usage = 10
max_damage = 40
// SELF DIAGNOSIS MODULE
// Analyses cyborg's modules, providing damage readouts and basic information
// Uses 1kJ burst when analysis is done
/datum/robot_component/diagnosis_unit
name = "self-diagnosis unit"
energy_consumption = 1
active_usage = 1000
external_type = /obj/item/robot_parts/robot_component/diagnosis_unit
max_damage = 30
/mob/living/silicon/robot/proc/initialize_components()
// This only initializes the components, it doesn't set them to installed.
// HELPER STUFF
// Initializes cyborg's components. Technically, adds default set of components to new borgs
/mob/living/silicon/robot/proc/initialize_components()
components["actuator"] = new/datum/robot_component/actuator(src)
components["radio"] = new/datum/robot_component/radio(src)
components["power cell"] = new/datum/robot_component/cell(src)
@@ -126,10 +162,25 @@
components["comms"] = new/datum/robot_component/binary_communication(src)
components["armour"] = new/datum/robot_component/armour(src)
// Checks if component is functioning
/mob/living/silicon/robot/proc/is_component_functioning(module_name)
var/datum/robot_component/C = components[module_name]
return C && C.installed == 1 && C.toggled && C.is_powered()
// Returns component by it's string name
/mob/living/silicon/robot/proc/get_component(var/component_name)
var/datum/robot_component/C = components[component_name]
return C
// COMPONENT OBJECTS
// Component Objects
// These objects are visual representation of modules
/obj/item/broken_device
name = "broken component"
icon = 'icons/obj/robot_component.dmi'
@@ -144,7 +195,6 @@
var/burn = 0
var/icon_state_broken = "broken"
// TODO: actual icons ;)
/obj/item/robot_parts/robot_component/binary_communication_device
name = "binary communication device"
icon_state = "binradio"
@@ -173,84 +223,4 @@
/obj/item/robot_parts/robot_component/radio
name = "radio"
icon_state = "radio"
icon_state_broken = "radio_broken"
//
//Robotic Component Analyser, basically a health analyser for robots
//
/obj/item/device/robotanalyzer
name = "cyborg analyzer"
icon_state = "robotanalyzer"
item_state = "analyzer"
desc = "A hand-held scanner able to diagnose robotic injuries."
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BELT
throwforce = 3
w_class = 2.0
throw_speed = 5
throw_range = 10
matter = list("metal" = 200)
origin_tech = "magnets=1;biotech=1"
var/mode = 1;
/obj/item/device/robotanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
if(( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))
user << text("\red You try to analyze the floor's vitals!")
for(var/mob/O in viewers(M, null))
O.show_message(text("\red [user] has analyzed the floor's vitals!"), 1)
user.show_message(text("\blue Analyzing Results for The floor:\n\t Overall Status: Healthy"), 1)
user.show_message(text("\blue \t Damage Specifics: [0]-[0]-[0]-[0]"), 1)
user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1)
user.show_message("\blue Body Temperature: ???", 1)
return
if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
user << "\red You don't have the dexterity to do this!"
return
if(!istype(M, /mob/living/silicon/robot) && !(ishuman(M) && (M:species.flags & IS_SYNTHETIC)))
user << "\red You can't analyze non-robotic things!"
return
user.visible_message("<span class='notice'> [user] has analyzed [M]'s components.","<span class='notice'> You have analyzed [M]'s components.")
var/BU = M.getFireLoss() > 50 ? "<b>[M.getFireLoss()]</b>" : M.getFireLoss()
var/BR = M.getBruteLoss() > 50 ? "<b>[M.getBruteLoss()]</b>" : M.getBruteLoss()
user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "fully disabled" : "[M.health - M.halloss]% functional"]")
user.show_message("\t Key: <font color='#FFA500'>Electronics</font>/<font color='red'>Brute</font>", 1)
user.show_message("\t Damage Specifics: <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>")
if(M.tod && M.stat == DEAD)
user.show_message("\blue Time of Disable: [M.tod]")
if (istype(M, /mob/living/silicon/robot))
var/mob/living/silicon/robot/H = M
var/list/damaged = H.get_damaged_components(1,1,1)
user.show_message("\blue Localized Damage:",1)
if(length(damaged)>0)
for(var/datum/robot_component/org in damaged)
user.show_message(text("\blue \t []: [][] - [] - [] - []", \
capitalize(org.name), \
(org.installed == -1) ? "<font color='red'><b>DESTROYED</b></font> " :"",\
(org.electronics_damage > 0) ? "<font color='#FFA500'>[org.electronics_damage]</font>" :0, \
(org.brute_damage > 0) ? "<font color='red'>[org.brute_damage]</font>" :0, \
(org.toggled) ? "Toggled ON" : "<font color='red'>Toggled OFF</font>",\
(org.powered) ? "Power ON" : "<font color='red'>Power OFF</font>"),1)
else
user.show_message("\blue \t Components are OK.",1)
if(H.emagged && prob(5))
user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1)
if (ishuman(M) && (M:species.flags & IS_SYNTHETIC))
var/mob/living/carbon/human/H = M
var/list/damaged = H.get_damaged_organs(1,1)
user.show_message("\blue Localized Damage, Brute/Electronics:",1)
if(length(damaged)>0)
for(var/datum/organ/external/org in damaged)
user.show_message(text("\blue \t []: [] - []", \
capitalize(org.display_name), \
(org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \
(org.burn_dam > 0) ? "<font color='#FFA500'>[org.burn_dam]</font>" :0),1)
else
user.show_message("\blue \t Components are OK.",1)
user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]&deg;C ([M.bodytemperature*1.8-459.67]&deg;F)", 1)
src.add_fingerprint(user)
return
icon_state_broken = "radio_broken"
+12 -5
View File
@@ -32,25 +32,32 @@
adjustFireLoss(0)
/mob/living/silicon/robot/proc/use_power()
// Debug only
// world << "DEBUG: life.dm line 35: cyborg use_power() called at tick [controller_iteration]"
used_power_this_tick = 0
for(var/V in components)
var/datum/robot_component/C = components[V]
C.update_power_state()
if ( cell && is_component_functioning("power cell") && src.cell.charge > 0 )
if(src.module_state_1)
src.cell.use(3)
cell_use_power(50) // 50W load for every enabled tool TODO: tool-specific loads
if(src.module_state_2)
src.cell.use(3)
cell_use_power(50)
if(src.module_state_3)
src.cell.use(3)
cell_use_power(50)
if(lights_on)
cell_use_power(30) // 30W light. Normal lights would use ~15W, but increased for balance reasons.
src.has_power = 1
else
if (src.has_power)
src << "\red You are now running on emergency backup power."
src.has_power = 0
if(lights_on) // Light is on but there is no power!
lights_on = 0
SetLuminosity(0)
/mob/living/silicon/robot/proc/handle_regular_status_updates()
+39 -2
View File
@@ -2,6 +2,8 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/proc/sensor_mode
)
#define CYBORG_POWER_USAGE_MULTIPLIER 2.5 // Multiplier for amount of power cyborgs use.
/mob/living/silicon/robot
name = "Cyborg"
real_name = "Cyborg"
@@ -10,6 +12,8 @@ var/list/robot_verbs_default = list(
maxHealth = 200
health = 200
var/lights_on = 0 // Is our integrated light on?
var/used_power_this_tick = 0
var/sight_mode = 0
var/custom_name = ""
var/custom_sprite = 0 //Due to all the sprites involved, a var for our custom borgs may be best
@@ -384,10 +388,20 @@ var/list/robot_verbs_default = list(
var/dat = "<HEAD><TITLE>[src.name] Self-Diagnosis Report</TITLE></HEAD><BODY>\n"
for (var/V in components)
var/datum/robot_component/C = components[V]
dat += "<b>[C.name]</b><br><table><tr><td>Power consumption</td><td>[C.energy_consumption]</td></tr><tr><td>Brute Damage:</td><td>[C.brute_damage]</td></tr><tr><td>Electronics Damage:</td><td>[C.electronics_damage]</td></tr><tr><td>Powered:</td><td>[(!C.energy_consumption || C.is_powered()) ? "Yes" : "No"]</td></tr><tr><td>Toggled:</td><td>[ C.toggled ? "Yes" : "No"]</td></table><br>"
dat += "<b>[C.name]</b><br><table><tr><td>Brute Damage:</td><td>[C.brute_damage]</td></tr><tr><td>Electronics Damage:</td><td>[C.electronics_damage]</td></tr><tr><td>Powered:</td><td>[(!C.idle_usage || C.is_powered()) ? "Yes" : "No"]</td></tr><tr><td>Toggled:</td><td>[ C.toggled ? "Yes" : "No"]</td></table><br>"
return dat
/mob/living/silicon/robot/verb/toggle_lights()
set category = "Robot Commands"
set name = "Toggle Lights"
lights_on = !lights_on
usr << "You [lights_on ? "enable" : "disable"] your integrated light."
if(lights_on)
SetLuminosity(6) // 1.5x luminosity of flashlight
else
SetLuminosity(0)
/mob/living/silicon/robot/verb/self_diagnosis_verb()
set category = "Robot Commands"
@@ -396,6 +410,9 @@ var/list/robot_verbs_default = list(
if(!is_component_functioning("diagnosis unit"))
src << "\red Your self-diagnosis component isn't functioning."
var/datum/robot_component/CO = get_component("diagnosis unit")
if (!cell_use_power(CO.active_usage))
src << "\red Low Power."
var/dat = self_diagnosis()
src << browse(dat, "window=robotdiagnosis")
@@ -465,7 +482,9 @@ var/list/robot_verbs_default = list(
// this function displays the cyborgs current cell charge in the stat panel
/mob/living/silicon/robot/proc/show_cell_power()
if(cell)
stat(null, text("Charge Left: [cell.charge]/[cell.maxcharge]"))
stat(null, text("Charge Left: [round(cell.percent())]%"))
stat(null, text("Cell Rating: [round(cell.maxcharge)]")) // Round just in case we somehow get crazy values
stat(null, text("Power Cell Load: [round(used_power_this_tick)]W"))
else
stat(null, text("No Cell Inserted!"))
@@ -477,6 +496,7 @@ var/list/robot_verbs_default = list(
if (client.statpanel == "Status")
show_cell_power()
show_jetpack_pressure()
stat(null, text("Lights: [lights_on ? "ON" : "OFF"]"))
/mob/living/silicon/robot/restrained()
return 0
@@ -1331,3 +1351,20 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/proc/remove_robot_verbs()
src.verbs -= robot_verbs_default
// Uses power from cyborg's cell. Returns 1 on success or 0 on failure.
// Properly converts using CELLRATE now! Amount is in Joules.
/mob/living/silicon/robot/proc/cell_use_power(var/amount = 0)
// No cell inserted
if(!cell)
return 0
// Power cell is empty.
if(cell.charge == 0)
return 0
if(cell.use(amount * CELLRATE * CYBORG_POWER_USAGE_MULTIPLIER))
used_power_this_tick += amount * CYBORG_POWER_USAGE_MULTIPLIER
return 1
return 0
@@ -22,7 +22,7 @@
New()
src.modules += new /obj/item/device/flashlight(src)
// src.modules += new /obj/item/device/flashlight(src) // Replaced by verb and integrated light which uses power.
src.modules += new /obj/item/device/flash(src)
src.emag = new /obj/item/toy/sword(src)
src.emag.name = "Placeholder Emag Item"
@@ -22,5 +22,11 @@
return tally+config.robot_delay
// NEW: Use power while moving.
/mob/living/silicon/robot/Move()
..()
if (!is_component_functioning("actuator"))
return
var/datum/robot_component/actuator/A = get_component("actuator")
if (cell_use_power(A.active_usage))
..()
+14 -1
View File
@@ -72,7 +72,11 @@
if(message_mode && bot_type == IS_ROBOT && message_mode != "binary" && !R.is_component_functioning("radio"))
src << "\red Your radio isn't functional at this time."
return
if(bot_type == IS_ROBOT && message_mode != "binary")
var/datum/robot_component/radio/RA = R.get_component("radio")
if (!R.cell_use_power(RA.active_usage))
usr << "\red Not enough power to transmit message."
return
//parse language key and consume it
var/datum/language/speaking = parse_language(message)
@@ -100,6 +104,10 @@
if(!R.is_component_functioning("comms"))
src << "\red Your binary communications component isn't functional."
return
var/datum/robot_component/binary_communication/B = R.get_component("comms")
if(!R.cell_use_power(B.active_usage))
src << "\red Not enough power to transmit message."
return
if(IS_PAI)
src << "You do not appear to have that function"
return
@@ -197,6 +205,11 @@
var/renderedAI = "<i><span class='game say'>Robotic Talk, <a href='byond://?src=\ref[S];track2=\ref[S];track=\ref[src];trackname=[html_encode(src.name)]'><span class='name'>[name]</span></a> <span class='message'>[verb], \"[message]\"</span></span></i>"
S.show_message(renderedAI, 2)
else
var/mob/living/silicon/robot/borg = S
if(istype(borg) && borg.is_component_functioning("comms"))
var/datum/robot_component/RC = borg.get_component("comms")
if(!borg.use_power(RC.active_usage))
continue // No power.
S.show_message(rendered, 2)
+1
View File
@@ -67,6 +67,7 @@
if(!autocalled)
log_power_update_request(A.master, src)
A.master.powerupdate = 2 // Decremented by 2 each GC tick, since it's not auto power change we're going to update power twice.
return 1
//The master_area optional argument can be used to save on a lot of processing if the master area is already known. This is mainly intended for when this proc is called by the master controller.
/obj/machinery/proc/power_change(var/area/master_area = null) // called whenever the power settings of the containing area change
Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 120 KiB