Merge pull request #16088 from SandPoot/robot-control-tgui

Robot control tgui
This commit is contained in:
deathride58
2024-05-20 17:39:44 -04:00
committed by GitHub
4 changed files with 48 additions and 75 deletions

View File

@@ -45,7 +45,7 @@
radiomod = ";" //AIs will, by default, state their laws on the internal radio.
var/obj/item/pda/ai/aiPDA
var/obj/item/multitool/aiMulti
var/mob/living/simple_animal/bot/Bot
var/datum/weakref/bot_ref
var/tracking = FALSE //this is 1 if the AI is currently tracking somebody, but the track has not yet been completed.
var/datum/effect_system/spark_spread/spark_system //So they can initialize sparks whenever/N
var/obj/machinery/status_display/controlled_display
@@ -100,7 +100,6 @@
var/display_icon_override
var/emote_display = "Neutral" //text string of the current emote we set for the status displays, to prevent logins resetting it.
// TODO: Currently unused, needs port from TG.
var/datum/robot_control/robot_control
// TODO: Currently unused, needs port from TG.
/// Station alert datum for showing alerts UI
@@ -203,14 +202,13 @@
QDEL_NULL(spark_system)
QDEL_NULL(malf_picker)
QDEL_NULL(doomsday_device)
// TODO: Port implementation of these from TG or remove the unused code.
// QDEL_NULL(robot_control)
QDEL_NULL(robot_control)
// QDEL_NULL(alert_control)
QDEL_NULL(aiMulti)
QDEL_NULL(aiPDA)
malfhack = null
current = null
Bot = null
bot_ref = null
controlled_equipment = null
linked_core = null
apc_override = null
@@ -480,24 +478,6 @@
else
to_chat(src, "Target is not on or near any active cameras on the station.")
return
if(href_list["callbot"]) //Command a bot to move to a selected location.
if(call_bot_cooldown > world.time)
to_chat(src, "<span class='danger'>Error: Your last call bot command is still processing, please wait for the bot to finish calculating a route.</span>")
return
Bot = locate(href_list["callbot"]) in GLOB.alive_mob_list
if(!Bot || Bot.remote_disabled || src.control_disabled)
return //True if there is no bot found, the bot is manually emagged, or the AI is carded with wireless off.
waypoint_mode = 1
to_chat(src, "<span class='notice'>Set your waypoint by clicking on a valid location free of obstructions.</span>")
return
if(href_list["interface"]) //Remotely connect to a bot!
Bot = locate(href_list["interface"]) in GLOB.alive_mob_list
if(!Bot || Bot.remote_disabled || src.control_disabled)
return
Bot.attack_ai(src)
if(href_list["botrefresh"]) //Refreshes the bot control panel.
botcall()
return
if (href_list["ai_take_control"]) //Mech domination
var/obj/vehicle/sealed/mecha/M = locate(href_list["ai_take_control"]) in GLOB.mechas_list
@@ -544,33 +524,11 @@
set category = "AI Commands"
set name = "Access Robot Control"
set desc = "Wirelessly control various automatic robots."
if(incapacitated())
return
if(control_disabled)
to_chat(src, "<span class='warning'>Wireless control is disabled.</span>")
return
var/turf/ai_current_turf = get_turf(src)
var/ai_Zlevel = ai_current_turf.z
var/d
d += "<A HREF=?src=[REF(src)];botrefresh=1>Query network status</A><br>"
d += "<table width='100%'><tr><td width='40%'><h3>Name</h3></td><td width='30%'><h3>Status</h3></td><td width='30%'><h3>Location</h3></td><td width='10%'><h3>Control</h3></td></tr>"
if(!robot_control)
robot_control = new(src)
for (Bot in GLOB.alive_mob_list)
if(Bot.z == ai_Zlevel && !Bot.remote_disabled) //Only non-emagged bots on the same Z-level are detected!
var/bot_mode = Bot.get_mode()
d += "<tr><td width='30%'>[Bot.hacked ? "<span class='bad'>(!)</span>" : ""] [Bot.name]</A> ([Bot.model])</td>"
//If the bot is on, it will display the bot's current mode status. If the bot is not mode, it will just report "Idle". "Inactive if it is not on at all.
d += "<td width='30%'>[bot_mode]</td>"
d += "<td width='30%'>[get_area_name(Bot, TRUE)]</td>"
d += "<td width='10%'><A HREF=?src=[REF(src)];interface=[REF(Bot)]>Interface</A></td>"
d += "<td width='10%'><A HREF=?src=[REF(src)];callbot=[REF(Bot)]>Call</A></td>"
d += "</tr>"
d = format_text(d)
var/datum/browser/popup = new(src, "botcall", "Remote Robot Control", 700, 400)
popup.set_content(d)
popup.open()
robot_control.ui_interact(src)
/mob/living/silicon/ai/proc/set_waypoint(atom/A)
var/turf/turf_check = get_turf(A)
@@ -580,22 +538,21 @@
else if(GLOB.cameranet && GLOB.cameranet.checkTurfVis(turf_check))
call_bot(turf_check)
else
to_chat(src, "<span class='danger'>Selected location is not visible.</span>")
to_chat(src, span_danger("Selected location is not visible."))
/mob/living/silicon/ai/proc/call_bot(turf/waypoint)
if(!Bot)
var/mob/living/simple_animal/bot/bot = bot_ref.resolve()
if(!bot)
return
if(Bot.calling_ai && Bot.calling_ai != src) //Prevents an override if another AI is controlling this bot.
to_chat(src, "<span class='danger'>Interface error. Unit is already in use.</span>")
if(bot.calling_ai && bot.calling_ai != src) //Prevents an override if another AI is controlling this bot.
to_chat(src, span_danger("Interface error. Unit is already in use."))
return
to_chat(src, "<span class='notice'>Sending command to bot...</span>")
to_chat(src, span_notice("Sending command to bot..."))
call_bot_cooldown = world.time + CALL_BOT_COOLDOWN
Bot.call_bot(src, waypoint)
bot.call_bot(src, waypoint)
call_bot_cooldown = 0
/mob/living/silicon/ai/triggerAlarm(class, area/home, cameras, obj/source)
if(source.z != z)
return

View File

@@ -10,7 +10,7 @@
if(user != owner || owner.incapacitated())
return FALSE
if(owner.control_disabled)
to_chat(user, "<span class='warning'>Wireless control is disabled.</span>")
to_chat(user, span_warning("Wireless control is disabled."))
return FALSE
return TRUE
@@ -35,17 +35,23 @@
var/turf/ai_current_turf = get_turf(owner)
var/ai_zlevel = ai_current_turf.z
var/mob/living/simple_animal/bot/bot = owner.bot_ref?.resolve()
if((owner.waypoint_mode && bot) && !(bot.remote_disabled || owner.control_disabled))
data["commandeering"] = REF(bot)
else
data["commandeering"] = null
data["robots"] = list()
for(var/mob/living/simple_animal/bot/B in GLOB.bots_list)
if(B.z != ai_zlevel || B.remote_disabled) //Only non-emagged bots on the same Z-level are detected!
for(var/mob/living/simple_animal/bot/our_bot as anything in GLOB.bots_list)
if(our_bot.z != ai_zlevel || our_bot.remote_disabled) //Only non-emagged bots on the same Z-level are detected!
continue
var/list/robot_data = list(
name = B.name,
model = B.model,
mode = B.get_mode(),
hacked = B.hacked,
location = get_area_name(B, TRUE),
ref = REF(B)
name = our_bot.name,
model = our_bot.model,
mode = our_bot.get_mode(),
hacked = our_bot.hacked,
location = get_area_name(our_bot, TRUE),
ref = REF(our_bot)
)
data["robots"] += list(robot_data)
@@ -54,23 +60,30 @@
/datum/robot_control/ui_act(action, params)
if(..())
return
if(!is_interactable(usr))
var/mob/living/our_user = usr
if(!is_interactable(our_user))
return
var/mob/living/simple_animal/bot/bot = locate(params["ref"]) in GLOB.bots_list
if(isnull(bot))
return
switch(action)
if("callbot") //Command a bot to move to a selected location.
if(owner.call_bot_cooldown > world.time)
to_chat(usr, "<span class='danger'>Error: Your last call bot command is still processing, please wait for the bot to finish calculating a route.</span>")
to_chat(our_user, span_danger("Error: Your last call bot command is still processing, please wait for the bot to finish calculating a route."))
return
owner.Bot = locate(params["ref"]) in GLOB.bots_list
if(!owner.Bot || owner.Bot.remote_disabled || owner.control_disabled)
if(bot.remote_disabled)
return
owner.bot_ref = WEAKREF(bot)
owner.waypoint_mode = TRUE
to_chat(usr, "<span class='notice'>Set your waypoint by clicking on a valid location free of obstructions.</span>")
. = TRUE
to_chat(our_user, span_notice("Set your waypoint by clicking on a valid location free of obstructions."))
if("interface") //Remotely connect to a bot!
owner.Bot = locate(params["ref"]) in GLOB.bots_list
if(!owner.Bot || owner.Bot.remote_disabled || owner.control_disabled)
owner.bot_ref = WEAKREF(bot)
if(bot.remote_disabled)
return
owner.Bot.attack_ai(usr)
. = TRUE
bot.attack_ai(our_user)
return TRUE

View File

@@ -2840,6 +2840,7 @@
#include "code\modules\mob\living\silicon\ai\login.dm"
#include "code\modules\mob\living\silicon\ai\logout.dm"
#include "code\modules\mob\living\silicon\ai\multicam.dm"
#include "code\modules\mob\living\silicon\ai\robot_control.dm"
#include "code\modules\mob\living\silicon\ai\say.dm"
#include "code\modules\mob\living\silicon\ai\vox_sounds.dm"
#include "code\modules\mob\living\silicon\ai\freelook\cameranet.dm"

View File

@@ -20,6 +20,7 @@ export const RemoteRobotControlContent = (props, context) => {
const { act, data } = useBackend(context);
const {
robots = [],
commandeering,
} = data;
if (!robots.length) {
return (
@@ -46,6 +47,7 @@ export const RemoteRobotControlContent = (props, context) => {
<Button
icon="phone-alt"
content="Call"
selected={robot.ref === commandeering}
onClick={() => act('callbot', {
ref: robot.ref,
})} />