This commit is contained in:
SandPoot
2024-05-20 18:55:33 -03:00
10 changed files with 109 additions and 96 deletions

View File

@@ -145,6 +145,7 @@
#define ui_borg_language_menu "CENTER+4:21,SOUTH+1:5" #define ui_borg_language_menu "CENTER+4:21,SOUTH+1:5"
#define ui_borg_pda_send "CENTER+5:21,SOUTH:5" // To the right of the alert panel #define ui_borg_pda_send "CENTER+5:21,SOUTH:5" // To the right of the alert panel
#define ui_borg_pda_log "CENTER+6:21,SOUTH:5" #define ui_borg_pda_log "CENTER+6:21,SOUTH:5"
#define ui_borg_movi "CENTER+7:21,SOUTH:5"
#define ui_borg_sensor "CENTER-6:16, SOUTH:5" //LEGACY #define ui_borg_sensor "CENTER-6:16, SOUTH:5" //LEGACY
#define ui_borg_thrusters "CENTER-5:16, SOUTH:5" //LEGACY #define ui_borg_thrusters "CENTER-5:16, SOUTH:5" //LEGACY

View File

@@ -155,12 +155,26 @@
static_inventory += using static_inventory += using
robit.thruster_button = using robit.thruster_button = using
//PDA message
using = new /atom/movable/screen/robot/pda_msg_send
using.screen_loc = ui_borg_pda_send
using.hud = src
static_inventory += using
//PDA log
using = new /atom/movable/screen/robot/pda_msg_show
using.screen_loc = ui_borg_pda_log
using.hud = src
static_inventory += using
//Intent //Intent
action_intent = new /atom/movable/screen/act_intent/robot() action_intent = new /atom/movable/screen/act_intent/robot()
action_intent.icon_state = mymob.a_intent action_intent.icon_state = mymob.a_intent
action_intent.hud = src action_intent.hud = src
static_inventory += action_intent static_inventory += action_intent
assert_move_intent_ui(owner, TRUE)
//Health //Health
healths = new /atom/movable/screen/healths/robot() healths = new /atom/movable/screen/healths/robot()
healths.hud = src healths.hud = src
@@ -190,6 +204,41 @@
zone_select.update_icon() zone_select.update_icon()
static_inventory += zone_select static_inventory += zone_select
/datum/hud/robot/proc/assert_move_intent_ui(mob/living/silicon/robot/owner = mymob, on_new = FALSE)
var/atom/movable/screen/using
// delete old ones
var/list/atom/movable/screen/victims = list()
victims += locate(/atom/movable/screen/mov_intent) in static_inventory
victims += locate(/atom/movable/screen/sprintbutton) in static_inventory
if(victims)
static_inventory -= victims
if(mymob?.client)
mymob.client.screen -= victims
QDEL_LIST(victims)
// make new ones
// walk/run
using = new /atom/movable/screen/mov_intent
using.icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
using.screen_loc = ui_borg_movi
using.hud = src
using.update_icon()
static_inventory += using
if(!on_new)
owner?.client?.screen += using
if(!CONFIG_GET(flag/sprint_enabled))
return
// sprint button
using = new /atom/movable/screen/sprintbutton
using.icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
using.icon_state = owner.cansprint ? ((owner.combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) ? "act_sprint_on" : "act_sprint") : "act_sprint_locked"
using.screen_loc = ui_borg_movi
using.hud = src
static_inventory += using
if(!on_new)
owner?.client?.screen += using
/datum/hud/proc/toggle_show_robot_modules() /datum/hud/proc/toggle_show_robot_modules()
if(!iscyborg(mymob)) if(!iscyborg(mymob))
@@ -344,24 +393,6 @@
return return
robot.modularInterface?.interact(robot) robot.modularInterface?.interact(robot)
//borg pda
/datum/hud/robot/New(mob/owner)
. = ..()
var/atom/movable/screen/using
//PDA message
using = new /atom/movable/screen/robot/pda_msg_send
using.screen_loc = ui_borg_pda_send
using.hud = src
static_inventory += using
//PDA log
using = new /atom/movable/screen/robot/pda_msg_show
using.screen_loc = ui_borg_pda_log
using.hud = src
static_inventory += using
/atom/movable/screen/robot/pda_msg_send /atom/movable/screen/robot/pda_msg_send
name = "PDA - Send Message" name = "PDA - Send Message"
icon = 'icons/mob/screen_ai.dmi' icon = 'icons/mob/screen_ai.dmi'

View File

@@ -9,9 +9,9 @@
var/mutable_appearance/flashy var/mutable_appearance/flashy
/atom/movable/screen/sprintbutton/Click() /atom/movable/screen/sprintbutton/Click()
if(ishuman(usr)) if(isliving(usr))
var/mob/living/carbon/human/H = usr var/mob/living/owner = usr
H.default_toggle_sprint() owner.default_toggle_sprint()
/atom/movable/screen/sprintbutton/update_icon_state() /atom/movable/screen/sprintbutton/update_icon_state()
var/mob/living/user = hud?.mymob var/mob/living/user = hud?.mymob

View File

@@ -68,6 +68,8 @@
. = ..() . = ..()
for(var/datum/hud/human/H) for(var/datum/hud/human/H)
H.assert_move_intent_ui() H.assert_move_intent_ui()
for(var/datum/hud/robot/robot)
robot.assert_move_intent_ui()
if(!config_entry_value) // disabled if(!config_entry_value) // disabled
for(var/mob/living/L in world) for(var/mob/living/L in world)
L.disable_intentional_sprint_mode() L.disable_intentional_sprint_mode()

View File

@@ -92,6 +92,9 @@
VC = new /obj/effect/proc_holder/silicon/cyborg/vtecControl VC = new /obj/effect/proc_holder/silicon/cyborg/vtecControl
R.AddAbility(VC) R.AddAbility(VC)
R.cansprint = 0 R.cansprint = 0
var/datum/hud/robot/robohud = R.hud_used
if(istype(robohud))
robohud.assert_move_intent_ui()
/obj/item/borg/upgrade/vtec/deactivate(mob/living/silicon/robot/R, user = usr) /obj/item/borg/upgrade/vtec/deactivate(mob/living/silicon/robot/R, user = usr)
. = ..() . = ..()
@@ -99,6 +102,9 @@
R.RemoveAbility(VC) R.RemoveAbility(VC)
R.vtec = initial(R.vtec) R.vtec = initial(R.vtec)
R.cansprint = 1 R.cansprint = 1
var/datum/hud/robot/robohud = R.hud_used
if(istype(robohud))
robohud.assert_move_intent_ui()
/obj/item/borg/upgrade/disablercooler /obj/item/borg/upgrade/disablercooler
name = "cyborg rapid energy blaster cooling module" name = "cyborg rapid energy blaster cooling module"

View File

@@ -45,7 +45,7 @@
radiomod = ";" //AIs will, by default, state their laws on the internal radio. radiomod = ";" //AIs will, by default, state their laws on the internal radio.
var/obj/item/pda/ai/aiPDA var/obj/item/pda/ai/aiPDA
var/obj/item/multitool/aiMulti 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/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/datum/effect_system/spark_spread/spark_system //So they can initialize sparks whenever/N
var/obj/machinery/status_display/controlled_display var/obj/machinery/status_display/controlled_display
@@ -100,7 +100,6 @@
var/display_icon_override 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. 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 var/datum/robot_control/robot_control
// TODO: Currently unused, needs port from TG. // TODO: Currently unused, needs port from TG.
/// Station alert datum for showing alerts UI /// Station alert datum for showing alerts UI
@@ -203,14 +202,13 @@
QDEL_NULL(spark_system) QDEL_NULL(spark_system)
QDEL_NULL(malf_picker) QDEL_NULL(malf_picker)
QDEL_NULL(doomsday_device) 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(alert_control)
QDEL_NULL(aiMulti) QDEL_NULL(aiMulti)
QDEL_NULL(aiPDA) QDEL_NULL(aiPDA)
malfhack = null malfhack = null
current = null current = null
Bot = null bot_ref = null
controlled_equipment = null controlled_equipment = null
linked_core = null linked_core = null
apc_override = null apc_override = null
@@ -480,24 +478,6 @@
else else
to_chat(src, "Target is not on or near any active cameras on the station.") to_chat(src, "Target is not on or near any active cameras on the station.")
return 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 if (href_list["ai_take_control"]) //Mech domination
var/obj/vehicle/sealed/mecha/M = locate(href_list["ai_take_control"]) in GLOB.mechas_list 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 category = "AI Commands"
set name = "Access Robot Control" set name = "Access Robot Control"
set desc = "Wirelessly control various automatic robots." set desc = "Wirelessly control various automatic robots."
if(incapacitated())
return
if(control_disabled) if(!robot_control)
to_chat(src, "<span class='warning'>Wireless control is disabled.</span>") robot_control = new(src)
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>"
for (Bot in GLOB.alive_mob_list) robot_control.ui_interact(src)
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()
/mob/living/silicon/ai/proc/set_waypoint(atom/A) /mob/living/silicon/ai/proc/set_waypoint(atom/A)
var/turf/turf_check = get_turf(A) var/turf/turf_check = get_turf(A)
@@ -580,22 +538,21 @@
else if(GLOB.cameranet && GLOB.cameranet.checkTurfVis(turf_check)) else if(GLOB.cameranet && GLOB.cameranet.checkTurfVis(turf_check))
call_bot(turf_check) call_bot(turf_check)
else 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) /mob/living/silicon/ai/proc/call_bot(turf/waypoint)
var/mob/living/simple_animal/bot/bot = bot_ref.resolve()
if(!Bot) if(!bot)
return return
if(Bot.calling_ai && Bot.calling_ai != src) //Prevents an override if another AI is controlling this bot. 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>") to_chat(src, span_danger("Interface error. Unit is already in use."))
return 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 call_bot_cooldown = world.time + CALL_BOT_COOLDOWN
Bot.call_bot(src, waypoint) bot.call_bot(src, waypoint)
call_bot_cooldown = 0 call_bot_cooldown = 0
/mob/living/silicon/ai/triggerAlarm(class, area/home, cameras, obj/source) /mob/living/silicon/ai/triggerAlarm(class, area/home, cameras, obj/source)
if(source.z != z) if(source.z != z)
return return

View File

@@ -10,7 +10,7 @@
if(user != owner || owner.incapacitated()) if(user != owner || owner.incapacitated())
return FALSE return FALSE
if(owner.control_disabled) 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 FALSE
return TRUE return TRUE
@@ -35,17 +35,23 @@
var/turf/ai_current_turf = get_turf(owner) var/turf/ai_current_turf = get_turf(owner)
var/ai_zlevel = ai_current_turf.z 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() data["robots"] = list()
for(var/mob/living/simple_animal/bot/B in GLOB.bots_list) for(var/mob/living/simple_animal/bot/our_bot as anything in GLOB.bots_list)
if(B.z != ai_zlevel || B.remote_disabled) //Only non-emagged bots on the same Z-level are detected! if(our_bot.z != ai_zlevel || our_bot.remote_disabled) //Only non-emagged bots on the same Z-level are detected!
continue continue
var/list/robot_data = list( var/list/robot_data = list(
name = B.name, name = our_bot.name,
model = B.model, model = our_bot.model,
mode = B.get_mode(), mode = our_bot.get_mode(),
hacked = B.hacked, hacked = our_bot.hacked,
location = get_area_name(B, TRUE), location = get_area_name(our_bot, TRUE),
ref = REF(B) ref = REF(our_bot)
) )
data["robots"] += list(robot_data) data["robots"] += list(robot_data)
@@ -54,23 +60,30 @@
/datum/robot_control/ui_act(action, params) /datum/robot_control/ui_act(action, params)
if(..()) if(..())
return 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 return
switch(action) switch(action)
if("callbot") //Command a bot to move to a selected location. if("callbot") //Command a bot to move to a selected location.
if(owner.call_bot_cooldown > world.time) 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 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 return
owner.bot_ref = WEAKREF(bot)
owner.waypoint_mode = TRUE owner.waypoint_mode = TRUE
to_chat(usr, "<span class='notice'>Set your waypoint by clicking on a valid location free of obstructions.</span>") to_chat(our_user, span_notice("Set your waypoint by clicking on a valid location free of obstructions."))
. = TRUE
if("interface") //Remotely connect to a bot! if("interface") //Remotely connect to a bot!
owner.Bot = locate(params["ref"]) in GLOB.bots_list owner.bot_ref = WEAKREF(bot)
if(!owner.Bot || owner.Bot.remote_disabled || owner.control_disabled) if(bot.remote_disabled)
return return
owner.Bot.attack_ai(usr) bot.attack_ai(our_user)
. = TRUE
return TRUE

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -2865,6 +2865,7 @@
#include "code\modules\mob\living\silicon\ai\login.dm" #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\logout.dm"
#include "code\modules\mob\living\silicon\ai\multicam.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\say.dm"
#include "code\modules\mob\living\silicon\ai\vox_sounds.dm" #include "code\modules\mob\living\silicon\ai\vox_sounds.dm"
#include "code\modules\mob\living\silicon\ai\freelook\cameranet.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 { act, data } = useBackend(context);
const { const {
robots = [], robots = [],
commandeering,
} = data; } = data;
if (!robots.length) { if (!robots.length) {
return ( return (
@@ -46,6 +47,7 @@ export const RemoteRobotControlContent = (props, context) => {
<Button <Button
icon="phone-alt" icon="phone-alt"
content="Call" content="Call"
selected={robot.ref === commandeering}
onClick={() => act('callbot', { onClick={() => act('callbot', {
ref: robot.ref, ref: robot.ref,
})} /> })} />