Files
Paradise/code/modules/power/apc/apc_overlay.dm
Ryan 7c3cd86f14 APC & Machinery Refactor + Local Powernets (#19991)
* local powernet and machine power refactor

* some fixes

* more tweaks + powerchange() refactor

* fixes var edited apcs on meatpackers.dmm

* fixes issue with power channels

* Reviews

* delta fix

* Update code/game/machinery/portable_turret.dm

Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com>

* removed area power change proc

* damn morgues

* requested changes

* request changes

* deconfliction

* mapping fixes

* some fixes from TM

---------

Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com>
2023-01-30 22:28:10 +00:00

235 lines
7.4 KiB
Plaintext

//update_state
#define UPSTATE_CELL_IN 1
#define UPSTATE_OPENED1 2
#define UPSTATE_OPENED2 4
#define UPSTATE_MAINT 8
#define UPSTATE_BROKE 16
#define UPSTATE_BLUESCREEN 32
#define UPSTATE_WIREEXP 64
#define UPSTATE_ALLGOOD 128
//update_overlay
#define APC_UPOVERLAY_CHARGEING0 1
#define APC_UPOVERLAY_CHARGEING1 2
#define APC_UPOVERLAY_CHARGEING2 4
#define APC_UPOVERLAY_EQUIPMENT0 8
#define APC_UPOVERLAY_EQUIPMENT1 16
#define APC_UPOVERLAY_EQUIPMENT2 32
#define APC_UPOVERLAY_LIGHTING0 64
#define APC_UPOVERLAY_LIGHTING1 128
#define APC_UPOVERLAY_LIGHTING2 256
#define APC_UPOVERLAY_ENVIRON0 512
#define APC_UPOVERLAY_ENVIRON1 1024
#define APC_UPOVERLAY_ENVIRON2 2048
#define APC_UPOVERLAY_LOCKED 4096
#define APC_UPDATE_ICON_COOLDOWN 20 SECONDS // 20 seconds
// update the APC icon to show the three base states
// also add overlays for indicator lights
/obj/machinery/power/apc/update_icon(force_update = FALSE)
if(!status_overlays || force_update)
status_overlays = TRUE
status_overlays_lock = new
status_overlays_charging = new
status_overlays_equipment = new
status_overlays_lighting = new
status_overlays_environ = new
status_overlays_lock.len = 2
status_overlays_charging.len = 3
status_overlays_equipment.len = 4
status_overlays_lighting.len = 4
status_overlays_environ.len = 4
status_overlays_lock[1] = image(icon, "apcox-0") // 0=blue 1=red
status_overlays_lock[2] = image(icon, "apcox-1")
status_overlays_charging[1] = image(icon, "apco3-0")
status_overlays_charging[2] = image(icon, "apco3-1")
status_overlays_charging[3] = image(icon, "apco3-2")
status_overlays_equipment[1] = image(icon, "apco0-0") // 0=red, 1=green, 2=blue
status_overlays_equipment[2] = image(icon, "apco0-1")
status_overlays_equipment[3] = image(icon, "apco0-2")
status_overlays_equipment[4] = image(icon, "apco0-3")
status_overlays_lighting[1] = image(icon, "apco1-0")
status_overlays_lighting[2] = image(icon, "apco1-1")
status_overlays_lighting[3] = image(icon, "apco1-2")
status_overlays_lighting[4] = image(icon, "apco1-3")
status_overlays_environ[1] = image(icon, "apco2-0")
status_overlays_environ[2] = image(icon, "apco2-1")
status_overlays_environ[3] = image(icon, "apco2-2")
status_overlays_environ[4] = image(icon, "apco2-3")
var/update = check_updates() //returns 0 if no need to update icons.
// 1 if we need to update the icon_state
// 2 if we need to update the overlays
if(!update && !force_update)
return
if(force_update || update & 1) // Updating the icon state
..(UPDATE_ICON_STATE)
if(!(update_state & UPSTATE_ALLGOOD))
if(managed_overlays)
..(UPDATE_OVERLAYS)
return
if(force_update || update & 2)
..(UPDATE_OVERLAYS)
/obj/machinery/power/apc/update_icon_state()
if(update_state & UPSTATE_ALLGOOD)
icon_state = "apc0"
else if(update_state & (UPSTATE_OPENED1|UPSTATE_OPENED2))
var/basestate = "apc[ cell ? "2" : "1" ]"
if(update_state & UPSTATE_OPENED1)
if(update_state & (UPSTATE_MAINT|UPSTATE_BROKE))
icon_state = "apcmaint" //disabled APC cannot hold cell
else
icon_state = basestate
else if(update_state & UPSTATE_OPENED2)
icon_state = "[basestate]-nocover"
else if(update_state & UPSTATE_BROKE)
icon_state = "apc-b"
else if(update_state & UPSTATE_BLUESCREEN)
icon_state = "apcemag"
else if(update_state & UPSTATE_WIREEXP)
icon_state = "apcewires"
/obj/machinery/power/apc/update_overlays()
. = ..()
underlays.Cut()
if(update_state & UPSTATE_BLUESCREEN)
underlays += emissive_appearance(icon, "emit_apcemag")
return
if(!(update_state & UPSTATE_ALLGOOD))
return
if(!(stat & (BROKEN|MAINT)) && update_state & UPSTATE_ALLGOOD)
var/image/statover_lock = status_overlays_lock[locked + 1]
var/image/statover_charg = status_overlays_charging[charging + 1]
. += statover_lock
. += statover_charg
underlays += emissive_appearance(icon, statover_lock.icon_state)
underlays += emissive_appearance(icon, statover_charg.icon_state)
if(operating)
var/image/statover_equip = status_overlays_equipment[equipment_channel + 1]
var/image/statover_light = status_overlays_lighting[lighting_channel + 1]
var/image/statover_envir = status_overlays_environ[environment_channel + 1]
. += statover_equip
. += statover_light
. += statover_envir
underlays += emissive_appearance(icon, statover_equip.icon_state)
underlays += emissive_appearance(icon, statover_light.icon_state)
underlays += emissive_appearance(icon, statover_envir.icon_state)
/obj/machinery/power/apc/proc/check_updates()
var/last_update_state = update_state
var/last_update_overlay = update_overlay
update_state = NONE
update_overlay = NONE
if(cell)
update_state |= UPSTATE_CELL_IN
if(stat & BROKEN)
update_state |= UPSTATE_BROKE
if(stat & MAINT)
update_state |= UPSTATE_MAINT
if(opened)
if(opened == APC_OPENED)
update_state |= UPSTATE_OPENED1
if(opened == APC_COVER_OFF)
update_state |= UPSTATE_OPENED2
else if(emagged || malfai)
update_state |= UPSTATE_BLUESCREEN
else if(panel_open)
update_state |= UPSTATE_WIREEXP
if(update_state <= 1)
update_state |= UPSTATE_ALLGOOD
if(update_state & UPSTATE_ALLGOOD)
if(locked)
update_overlay |= APC_UPOVERLAY_LOCKED
if(charging == APC_NOT_CHARGING)
update_overlay |= APC_UPOVERLAY_CHARGEING0
else if(charging == APC_IS_CHARGING)
update_overlay |= APC_UPOVERLAY_CHARGEING1
else if(charging == APC_FULLY_CHARGED)
update_overlay |= APC_UPOVERLAY_CHARGEING2
if(!equipment_channel)
update_overlay |= APC_UPOVERLAY_EQUIPMENT0
else if(equipment_channel == CHANNEL_SETTING_AUTO_OFF)
update_overlay |= APC_UPOVERLAY_EQUIPMENT1
else if(equipment_channel == CHANNEL_SETTING_ON)
update_overlay |= APC_UPOVERLAY_EQUIPMENT2
if(!lighting_channel)
update_overlay |= APC_UPOVERLAY_LIGHTING0
else if(lighting_channel == CHANNEL_SETTING_AUTO_OFF)
update_overlay |= APC_UPOVERLAY_LIGHTING1
else if(lighting_channel == CHANNEL_SETTING_ON)
update_overlay |= APC_UPOVERLAY_LIGHTING2
if(!environment_channel)
update_overlay |= APC_UPOVERLAY_ENVIRON0
else if(environment_channel == CHANNEL_SETTING_AUTO_OFF)
update_overlay |= APC_UPOVERLAY_ENVIRON1
else if(environment_channel == CHANNEL_SETTING_ON)
update_overlay |= APC_UPOVERLAY_ENVIRON2
var/results = 0
if(last_update_state == update_state && last_update_overlay == update_overlay)
return 0
if(last_update_state != update_state)
results += 1
if(last_update_overlay != update_overlay)
results += 2
return results
// Used in process so it doesn't update the icon too much
/obj/machinery/power/apc/proc/queue_icon_update()
if(!updating_icon)
updating_icon = TRUE
// Start the update
spawn(APC_UPDATE_ICON_COOLDOWN)
update_icon()
updating_icon = FALSE
/obj/machinery/power/apc/flicker(second_pass = FALSE)
if(opened || panel_open)
return FALSE
if(stat & (NOPOWER | BROKEN))
return FALSE
if(!second_pass) //The first time, we just cut overlays
addtimer(CALLBACK(src, PROC_REF(flicker), TRUE), 1)
cut_overlays()
managed_overlays = null
// APC power distruptions have a chance to propogate to other machines on its network
for(var/obj/machinery/M in apc_area)
// Please don't cascade, thanks
if(M == src)
continue
if(prob(10))
M.flicker()
else
flick("apcemag", src) //Second time we cause the APC to update its icon, then add a timer to update icon later
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), TRUE), 10)
return TRUE
#undef APC_UPDATE_ICON_COOLDOWN