mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-16 16:47:32 +01:00
* upgraded machines and pre-loading * agghhhh! * stovetop of failure * Update cerestation.dmm --------- Signed-off-by: CRUNCH <143041327+CRUNCH-Borg@users.noreply.github.com>
398 lines
13 KiB
Plaintext
398 lines
13 KiB
Plaintext
/// Stores a list of all AI resource nodes
|
|
GLOBAL_LIST_EMPTY(ai_nodes)
|
|
|
|
#define ALLOCATED_RESOURCES 0
|
|
#define ONLINE_NODES 1
|
|
|
|
/obj/machinery/ai_node
|
|
name = "AI Node"
|
|
desc = "If you see me, make an issue report!"
|
|
icon = 'icons/obj/machines/ai_machinery.dmi'
|
|
icon_state = "processor-off"
|
|
density = TRUE
|
|
anchored = TRUE
|
|
max_integrity = 100
|
|
idle_power_consumption = 5
|
|
active_power_consumption = 750
|
|
var/icon_base
|
|
/// Is the machine active
|
|
var/active = FALSE
|
|
/// What AI is this machine associated with
|
|
var/mob/living/silicon/ai/assigned_ai = null
|
|
/// Identifier for what resource to remove
|
|
var/resource_key
|
|
/// How much resources does this machine provide
|
|
var/resource_amount = 1
|
|
/// How much heat does this put out?
|
|
var/heat_amount = 25000
|
|
/// Are we overheating?
|
|
var/overheating = FALSE
|
|
// What's the overheat temperature?
|
|
var/overheat_temp = 324
|
|
/// Used to ensure it takes a few seconds of being hot before overheating
|
|
var/overheat_counter = 0
|
|
/// How efficient is this machine?
|
|
var/efficiency = 1
|
|
/// Milla controller
|
|
var/datum/milla_safe/ai_node_process/milla = new()
|
|
|
|
|
|
/obj/machinery/ai_node/Initialize(mapload)
|
|
. = ..()
|
|
GLOB.ai_nodes += src
|
|
|
|
/obj/machinery/ai_node/examine(mob/user)
|
|
. = ..()
|
|
. += SPAN_NOTICE("This machine is temperature sensitive. Any temperature colder than 273K will freeze it, whle any temperature higher than [overheat_temp]K will cause it to overheat.")
|
|
|
|
/obj/machinery/ai_node/process()
|
|
..()
|
|
if(active)
|
|
if(stat & NOPOWER)
|
|
atom_say("ERROR: Insufficient power! Shutting down...")
|
|
turn_off()
|
|
return
|
|
milla.invoke_async(src)
|
|
|
|
/obj/machinery/ai_node/Destroy()
|
|
. = ..()
|
|
turn_off()
|
|
GLOB.ai_nodes -= src
|
|
|
|
/obj/machinery/ai_node/on_deconstruction()
|
|
. = ..()
|
|
if(assigned_ai)
|
|
assigned_ai.program_picker.modify_resource(resource_key, -resource_amount)
|
|
assigned_ai = null
|
|
GLOB.ai_nodes -= src
|
|
|
|
/obj/machinery/ai_node/screwdriver_act(mob/user, obj/item/I)
|
|
if(!I.use_tool(src, user, 0, volume = 0))
|
|
return
|
|
. = TRUE
|
|
default_deconstruction_screwdriver(user, icon_state, icon_state, I)
|
|
|
|
/obj/machinery/ai_node/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I)
|
|
. = ..()
|
|
update_icon(UPDATE_ICON_STATE)
|
|
|
|
/obj/machinery/ai_node/crowbar_act(mob/user, obj/item/I)
|
|
if(default_deconstruction_crowbar(user, I))
|
|
return TRUE
|
|
|
|
/obj/machinery/ai_node/update_icon_state()
|
|
. = ..()
|
|
if(overheating)
|
|
icon_state = "[icon_base]-hot"
|
|
return
|
|
if(panel_open)
|
|
icon_state = "[icon_base]-open"
|
|
return
|
|
icon_state = "[icon_base]-[active ? "on" : "off"]"
|
|
|
|
/obj/machinery/ai_node/attack_ai(mob/user)
|
|
return
|
|
|
|
/obj/machinery/ai_node/RefreshParts()
|
|
. = ..()
|
|
var/E
|
|
for(var/obj/item/stock_parts/capacitor/M in component_parts)
|
|
E += M.rating
|
|
efficiency = E / 2
|
|
// Adjust values according to the new stock parts.
|
|
heat_amount = initial(heat_amount) * efficiency
|
|
overheat_temp = initial(overheat_temp) + (50 * efficiency)
|
|
update_idle_power_consumption(power_channel, initial(idle_power_consumption) * efficiency)
|
|
update_active_power_consumption(power_channel, initial(active_power_consumption) * efficiency)
|
|
var/old_resource_amount = resource_amount
|
|
resource_amount = round_down(initial(resource_amount) * efficiency)
|
|
// Adjust the resources of the connected AI if the machine is on
|
|
if(assigned_ai)
|
|
assigned_ai.program_picker.modify_resource(resource_key, (resource_amount - old_resource_amount))
|
|
|
|
/obj/machinery/ai_node/attack_hand(user as mob)
|
|
toggle(user)
|
|
|
|
/obj/machinery/ai_node/proc/toggle(mob/user = null)
|
|
if(overheating)
|
|
if(user)
|
|
to_chat(user, SPAN_NOTICE("You turn the overheating [src] off."))
|
|
overheating = FALSE
|
|
update_icon(UPDATE_ICON_STATE)
|
|
return
|
|
active = !active
|
|
if(user)
|
|
to_chat(user, SPAN_NOTICE("You turn [src] [active ? "on" : "off"]."))
|
|
if(active) // We're booting up
|
|
refresh_ai()
|
|
else // We're shutting down
|
|
turn_off()
|
|
update_icon(UPDATE_ICON_STATE)
|
|
|
|
/obj/machinery/ai_node/proc/refresh_ai()
|
|
assigned_ai = null
|
|
find_ai()
|
|
if(!assigned_ai) // No eligible AI found, abort
|
|
active = FALSE
|
|
atom_say("ERROR: No AI detected. Shutting down...")
|
|
turn_off()
|
|
else // We have an AI
|
|
assigned_ai.program_picker.modify_resource(resource_key, resource_amount)
|
|
var/area/our_area = get_area(src)
|
|
to_chat(assigned_ai, SPAN_NOTICE("New server node connected at: [our_area.name]."))
|
|
change_power_mode(ACTIVE_POWER_USE)
|
|
update_icon(UPDATE_ICON_STATE)
|
|
|
|
/obj/machinery/ai_node/proc/turn_off()
|
|
active = FALSE
|
|
if(assigned_ai)
|
|
assigned_ai.program_picker.modify_resource(resource_key, -resource_amount)
|
|
var/area/our_area = get_area(src)
|
|
to_chat(assigned_ai, SPAN_WARNING("Server node disconnected at: [our_area.name]!"))
|
|
assigned_ai = null
|
|
change_power_mode(IDLE_POWER_USE)
|
|
update_icon(UPDATE_ICON_STATE)
|
|
|
|
/obj/machinery/ai_node/proc/find_ai()
|
|
if(!resource_key)
|
|
return
|
|
for(var/mob/living/silicon/ai/new_ai as anything in GLOB.ai_list)
|
|
if(new_ai.stat || new_ai.in_storage || new_ai.shunted)
|
|
continue
|
|
if(istype(new_ai.loc, /obj/machinery/power/apc))
|
|
continue
|
|
if(!assigned_ai) // Not found
|
|
assigned_ai = new_ai // Assign to the first AI in the list to start
|
|
continue
|
|
if(resource_key == "memory" && assigned_ai.program_picker.memory > new_ai.program_picker.memory)
|
|
assigned_ai = new_ai
|
|
continue
|
|
if(resource_key == "bandwidth" && assigned_ai.program_picker.bandwidth > new_ai.program_picker.bandwidth)
|
|
assigned_ai = new_ai
|
|
|
|
/obj/machinery/ai_node/proc/overheat()
|
|
turn_off()
|
|
atom_say("ERROR: Heat critical!")
|
|
obj_integrity -= (max_integrity / 3) // Overheat it three times and it breaks
|
|
change_power_mode(IDLE_POWER_USE)
|
|
update_icon(UPDATE_ICON_STATE)
|
|
|
|
/obj/machinery/ai_node/proc/change_ai(mob/living/silicon/ai/new_ai)
|
|
if(!new_ai)
|
|
return
|
|
if(!istype(new_ai))
|
|
return
|
|
var/area/our_area = get_area(src)
|
|
assigned_ai.program_picker.modify_resource(resource_key, -resource_amount)
|
|
to_chat(assigned_ai, SPAN_WARNING("Server node disconnected at: [our_area.name]!"))
|
|
assigned_ai = new_ai
|
|
assigned_ai.program_picker.modify_resource(resource_key, resource_amount)
|
|
to_chat(assigned_ai, SPAN_NOTICE("New server node connected at: [our_area.name]."))
|
|
|
|
/datum/milla_safe/ai_node_process
|
|
|
|
/datum/milla_safe/ai_node_process/on_run(obj/machinery/ai_node/node)
|
|
var/turf/simulated/L = get_turf(node)
|
|
if(!istype(L))
|
|
return
|
|
var/datum/gas_mixture/env = get_turf_air(L)
|
|
var/transfer_moles = 0.25 * env.total_moles()
|
|
var/datum/gas_mixture/removed = env.remove(transfer_moles)
|
|
if(!removed)
|
|
node.overheat_counter++
|
|
if(node.overheat_counter >= 5)
|
|
node.overheat()
|
|
return
|
|
var/heat_capacity = removed.heat_capacity()
|
|
if(heat_capacity)
|
|
removed.set_temperature(removed.temperature() + node.heat_amount / heat_capacity)
|
|
env.merge(removed)
|
|
// Heat check
|
|
if(env.temperature() > node.overheat_temp || env.temperature() < 273) // If the temperature is outside 0-100C...
|
|
// Turn the node off due to temperature problems
|
|
node.overheat_counter++
|
|
if(node.overheat_counter >= 5)
|
|
node.overheat()
|
|
return
|
|
if(node.overheat_counter)
|
|
node.overheat_counter--
|
|
|
|
/obj/machinery/ai_node/processing_node
|
|
name = "processing node"
|
|
desc = "A rack of processors with a manual on/off switch. While running, it grants an AI memory."
|
|
resource_key = "memory"
|
|
icon_base = "processor"
|
|
|
|
/obj/machinery/ai_node/processing_node/Initialize(mapload)
|
|
. = ..()
|
|
component_parts = list()
|
|
component_parts += new /obj/item/circuitboard/processing_node(null)
|
|
component_parts += new /obj/item/stock_parts/capacitor(null)
|
|
component_parts += new /obj/item/stock_parts/capacitor(null)
|
|
component_parts += new /obj/item/stack/sheet/mineral/gold(null)
|
|
component_parts += new /obj/item/stack/sheet/mineral/silver(null)
|
|
component_parts += new /obj/item/stack/cable_coil(null, 5)
|
|
component_parts += new /obj/item/stack/sheet/mineral/diamond(null)
|
|
RefreshParts()
|
|
|
|
/obj/machinery/ai_node/processing_node/upgraded/Initialize(mapload)
|
|
..()
|
|
component_parts = list()
|
|
component_parts += new /obj/item/circuitboard/processing_node(null)
|
|
component_parts += new /obj/item/stock_parts/capacitor/quadratic(null)
|
|
component_parts += new /obj/item/stock_parts/capacitor/quadratic(null)
|
|
component_parts += new /obj/item/stack/sheet/mineral/gold(null)
|
|
component_parts += new /obj/item/stack/sheet/mineral/silver(null)
|
|
component_parts += new /obj/item/stack/cable_coil(null, 5)
|
|
component_parts += new /obj/item/stack/sheet/mineral/diamond(null)
|
|
RefreshParts()
|
|
|
|
/obj/machinery/ai_node/network_node
|
|
name = "network node"
|
|
desc = "A rack of servers with a manual on/off switch. While running, it grants an AI bandwidth."
|
|
icon_state = "network-off"
|
|
resource_key = "bandwidth"
|
|
icon_base = "network"
|
|
|
|
/obj/machinery/ai_node/network_node/examine_more(mob/user)
|
|
. = ..()
|
|
. += "I don't know but I've been told, \
|
|
Captain's got a network node, \
|
|
Likes to press the on/off switch, \
|
|
Dig that crazy corporate snitch!"
|
|
|
|
/obj/machinery/ai_node/network_node/Initialize(mapload)
|
|
. = ..()
|
|
component_parts = list()
|
|
component_parts += new /obj/item/circuitboard/network_node(null)
|
|
component_parts += new /obj/item/stock_parts/capacitor(null)
|
|
component_parts += new /obj/item/stock_parts/capacitor(null)
|
|
component_parts += new /obj/item/stack/sheet/mineral/gold(null)
|
|
component_parts += new /obj/item/stack/sheet/mineral/silver(null)
|
|
component_parts += new /obj/item/stack/cable_coil(null, 5)
|
|
RefreshParts()
|
|
|
|
/obj/machinery/ai_node/network_node/upgraded/Initialize(mapload)
|
|
..()
|
|
component_parts = list()
|
|
component_parts += new /obj/item/circuitboard/network_node(null)
|
|
component_parts += new /obj/item/stock_parts/capacitor/quadratic(null)
|
|
component_parts += new /obj/item/stock_parts/capacitor/quadratic(null)
|
|
component_parts += new /obj/item/stack/sheet/mineral/gold(null)
|
|
component_parts += new /obj/item/stack/sheet/mineral/silver(null)
|
|
component_parts += new /obj/item/stack/cable_coil(null, 5)
|
|
RefreshParts()
|
|
|
|
/obj/machinery/computer/ai_resource
|
|
name = "AI Resource Control Console"
|
|
desc = "Used to reassign memory and bandwidth between multiple AI units."
|
|
icon_keyboard = "rd_key"
|
|
icon_screen = "ai_resource"
|
|
req_access = list(ACCESS_RD)
|
|
circuit = /obj/item/circuitboard/ai_resource_console
|
|
light_color = LIGHT_COLOR_PURPLE
|
|
/// UI Screen Index
|
|
var/screen = ALLOCATED_RESOURCES
|
|
|
|
/obj/machinery/computer/ai_resource/attack_ai(mob/user) // Bad AI, no access to stealing resources
|
|
to_chat(user, SPAN_WARNING("ERROR: Firewall blocked! Station AI's are not permitted to interface with this console!"))
|
|
return
|
|
|
|
/obj/machinery/computer/ai_resource/attack_hand(mob/user)
|
|
if(..())
|
|
return
|
|
if(stat & (NOPOWER|BROKEN))
|
|
return
|
|
ui_interact(user)
|
|
|
|
/obj/machinery/computer/ai_resource/proc/is_authenticated(mob/user)
|
|
if(!istype(user))
|
|
return FALSE
|
|
if(user.can_admin_interact())
|
|
return TRUE
|
|
if(allowed(user))
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/obj/machinery/computer/ai_resource/ui_state(mob/user)
|
|
return GLOB.default_state
|
|
|
|
/obj/machinery/computer/ai_resource/ui_interact(mob/user, datum/tgui/ui = null)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "AIResourceManagementConsole", name)
|
|
ui.open()
|
|
|
|
/obj/machinery/computer/ai_resource/ui_data(mob/user)
|
|
var/list/data = list()
|
|
data["auth"] = is_authenticated(user)
|
|
data["screen"] = screen
|
|
data["ai_list"] = list()
|
|
data["nodes_list"] = list()
|
|
for(var/mob/living/silicon/ai/A in GLOB.ai_list)
|
|
if(istype(A.loc, /obj/machinery/power/apc)) // AIs in APCs as malf should be hidden
|
|
continue
|
|
if(A.shunted)
|
|
continue
|
|
var/list/ai_data = list(
|
|
"name" = A.name,
|
|
"uid" = A.UID(),
|
|
"memory" = A.program_picker.memory,
|
|
"memory_max" = A.program_picker.total_memory,
|
|
"bandwidth" = A.program_picker.bandwidth,
|
|
"bandwidth_max" = A.program_picker.total_bandwidth
|
|
)
|
|
data["ai_list"] += list(ai_data)
|
|
for(var/obj/machinery/ai_node/node as anything in GLOB.ai_nodes)
|
|
var/list/node_data = list(
|
|
"name" = node.name,
|
|
"uid" = node.UID(),
|
|
"resource" = node.resource_key,
|
|
"amount" = node.resource_amount,
|
|
"assigned_ai" = node.assigned_ai
|
|
)
|
|
data["nodes_list"] += list(node_data)
|
|
return data
|
|
|
|
/obj/machinery/computer/ai_resource/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
|
|
if(..())
|
|
return
|
|
. = FALSE
|
|
if(!is_authenticated(ui.user))
|
|
to_chat(ui.user, SPAN_WARNING("Access denied."))
|
|
return
|
|
if(SSticker.current_state == GAME_STATE_FINISHED)
|
|
to_chat(ui.user, SPAN_WARNING("Access denied, AIs are no longer your station's property."))
|
|
return
|
|
|
|
switch(action)
|
|
if("menu")
|
|
switch(text2num(params["screen"]))
|
|
if(ALLOCATED_RESOURCES)
|
|
screen = ALLOCATED_RESOURCES
|
|
return TRUE
|
|
if(ONLINE_NODES)
|
|
screen = ONLINE_NODES
|
|
return TRUE
|
|
if("reassign")
|
|
if(!length(GLOB.ai_list))
|
|
return FALSE
|
|
var/list/ais = list()
|
|
for(var/mob/living/silicon/ai/new_ai as anything in GLOB.ai_list)
|
|
if(new_ai.stat || new_ai.in_storage || new_ai.shunted)
|
|
continue
|
|
if(istype(new_ai.loc, /obj/machinery/power/apc))
|
|
continue
|
|
ais += new_ai
|
|
var/new_ai = tgui_input_list(usr, "Pick a new AI", "AI Selector", ais)
|
|
if(!new_ai)
|
|
return FALSE
|
|
var/obj/machinery/ai_node/selected_node = locateUID(params["uid"])
|
|
if(!selected_node)
|
|
return FALSE
|
|
selected_node.change_ai(new_ai)
|
|
return TRUE
|
|
|
|
#undef ALLOCATED_RESOURCES
|
|
#undef ONLINE_NODES
|