mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-16 01:23:41 +01:00
[READY] Bot Refactor (#18930)
* [WIP] Bot Refactor * No more spawns, sleeps, and working EDs * Mules * GC fixing * h
This commit is contained in:
@@ -23,8 +23,6 @@
|
||||
bubble_icon = "machine"
|
||||
faction = list("neutral", "silicon")
|
||||
|
||||
var/obj/machinery/bot_core/bot_core = null
|
||||
var/bot_core_type = /obj/machinery/bot_core
|
||||
var/list/users = list() //for dialog updates
|
||||
var/window_id = "bot_control"
|
||||
var/window_name = "Protobot 1.0" //Popup title
|
||||
@@ -93,6 +91,9 @@
|
||||
var/path_image_color = "#FFFFFF"
|
||||
var/reset_access_timer_id
|
||||
|
||||
/// List of access values you can have to access the bot. Consider this as req_one_access
|
||||
var/list/req_access = list()
|
||||
|
||||
hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD, DIAG_PATH_HUD = HUD_LIST_LIST)//Diagnostic HUD views
|
||||
|
||||
/obj/item/radio/headset/bot
|
||||
@@ -159,11 +160,6 @@
|
||||
add_language("Trinary", 1)
|
||||
default_language = GLOB.all_languages["Galactic Common"]
|
||||
|
||||
bot_core = new bot_core_type(src)
|
||||
|
||||
if(SSradio && bot_filter)
|
||||
SSradio.add_object(bot_core, control_freq, bot_filter)
|
||||
|
||||
prepare_huds()
|
||||
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
|
||||
diag_hud.add_to_hud(src)
|
||||
@@ -194,12 +190,11 @@
|
||||
GLOB.bots_list -= src
|
||||
QDEL_NULL(Radio)
|
||||
QDEL_NULL(access_card)
|
||||
|
||||
if(reset_access_timer_id)
|
||||
deltimer(reset_access_timer_id)
|
||||
reset_access_timer_id = null
|
||||
if(SSradio && bot_filter)
|
||||
SSradio.remove_object(bot_core, control_freq)
|
||||
QDEL_NULL(bot_core)
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/death(gibbed)
|
||||
@@ -319,7 +314,7 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The maintenance panel is locked.</span>")
|
||||
else if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda))
|
||||
if(bot_core.allowed(user) && !open && !emagged)
|
||||
if(allowed(user) && !open && !emagged)
|
||||
locked = !locked
|
||||
to_chat(user, "Controls are now [locked ? "locked." : "unlocked."]")
|
||||
else
|
||||
@@ -405,14 +400,18 @@
|
||||
|
||||
if(paicard)
|
||||
paicard.emp_act(severity)
|
||||
src.visible_message("[paicard] is flies out of [bot_name]!","<span class='warning'>You are forcefully ejected from [bot_name]!</span>")
|
||||
ejectpai(0)
|
||||
visible_message("[paicard] is flies out of [bot_name]!")
|
||||
ejectpai()
|
||||
|
||||
if(on)
|
||||
turn_off()
|
||||
spawn(severity*300)
|
||||
stat &= ~EMPED
|
||||
if(was_on)
|
||||
turn_on()
|
||||
addtimer(CALLBACK(src, .proc/un_emp, was_on), severity * 300)
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/proc/un_emp(was_on)
|
||||
stat &= ~EMPED
|
||||
if(was_on)
|
||||
turn_on()
|
||||
|
||||
/mob/living/simple_animal/bot/rename_character(oldname, newname)
|
||||
if(!..(oldname, newname))
|
||||
@@ -478,43 +477,50 @@ Movement proc for stepping a bot through a path generated through A-star.
|
||||
Pass a positive integer as an argument to override a bot's default speed.
|
||||
*/
|
||||
/mob/living/simple_animal/bot/proc/bot_move(dest, move_speed)
|
||||
|
||||
if(!dest || !path || path.len == 0) //A-star failed or a path/destination was not set.
|
||||
set_path(null)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
dest = get_turf(dest) //We must always compare turfs, so get the turf of the dest var if dest was originally something else.
|
||||
var/turf/last_node = get_turf(path[path.len]) //This is the turf at the end of the path, it should be equal to dest.
|
||||
if(get_turf(src) == dest) //We have arrived, no need to move again.
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
else if(dest != last_node) //The path should lead us to our given destination. If this is not true, we must stop.
|
||||
set_path(null)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/step_count = move_speed ? move_speed : base_speed //If a value is passed into move_speed, use that instead of the default speed var.
|
||||
|
||||
if(step_count >= 1 && tries < BOT_STEP_MAX_RETRIES)
|
||||
for(var/step_number = 0, step_number < step_count,step_number++)
|
||||
spawn(BOT_STEP_DELAY*step_number)
|
||||
bot_step(dest)
|
||||
for(var/step_number in 1 to step_count)
|
||||
// Hopefully this wont fill the buckets too much
|
||||
addtimer(CALLBACK(src, .proc/bot_step), BOT_STEP_DELAY * (step_number - 1))
|
||||
else
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/proc/bot_step(dest) //Step,increase tries if failed
|
||||
if(!path)
|
||||
return 0
|
||||
if(path.len > 1)
|
||||
/mob/living/simple_animal/bot/proc/bot_step() //Step,increase tries if failed
|
||||
if(!length(path))
|
||||
return FALSE
|
||||
|
||||
// Only one destination
|
||||
if(length(path) == 1)
|
||||
step_to(src, path[1])
|
||||
set_path(null)
|
||||
|
||||
else
|
||||
// Move us slowly
|
||||
Move(path[1], get_dir(src, path[1]), BOT_STEP_DELAY)
|
||||
if(get_turf(src) == path[1]) //Successful move
|
||||
increment_path()
|
||||
tries = 0
|
||||
else
|
||||
tries++
|
||||
return 0
|
||||
else if(path.len == 1)
|
||||
step_to(src, dest)
|
||||
set_path(null)
|
||||
return 1
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/proc/check_bot_access()
|
||||
@@ -584,10 +590,11 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
|
||||
/mob/living/simple_animal/bot/proc/bot_patrol()
|
||||
patrol_step()
|
||||
spawn(5)
|
||||
if(mode == BOT_PATROL)
|
||||
patrol_step()
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/do_patrol), 5)
|
||||
|
||||
/mob/living/simple_animal/bot/proc/do_patrol()
|
||||
if(mode == BOT_PATROL)
|
||||
patrol_step()
|
||||
|
||||
/mob/living/simple_animal/bot/proc/start_patrol()
|
||||
|
||||
@@ -602,18 +609,20 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
|
||||
if(patrol_target) // has patrol target
|
||||
spawn(0)
|
||||
calc_path() // Find a route to it
|
||||
if(path.len == 0)
|
||||
patrol_target = null
|
||||
return
|
||||
mode = BOT_PATROL
|
||||
else // no patrol target, so need a new one
|
||||
|
||||
if(patrol_target) // has patrol target
|
||||
INVOKE_ASYNC(src, .proc/target_patrol)
|
||||
else // no patrol target, so need a new one
|
||||
speak("Engaging patrol mode.")
|
||||
find_patrol_target()
|
||||
tries++
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/proc/target_patrol()
|
||||
calc_path() // Find a route to it
|
||||
if(!length(path))
|
||||
patrol_target = null
|
||||
return
|
||||
mode = BOT_PATROL
|
||||
|
||||
// perform a single patrol step
|
||||
|
||||
@@ -637,18 +646,19 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
|
||||
var/moved = bot_move(patrol_target)//step_towards(src, next) // attempt to move
|
||||
if(!moved) //Couldn't proceed the next step of the path BOT_STEP_MAX_RETRIES times
|
||||
spawn(2)
|
||||
calc_path()
|
||||
if(path.len == 0)
|
||||
find_patrol_target()
|
||||
tries = 0
|
||||
addtimer(CALLBACK(src, .proc/patrol_step_not_moved), 2)
|
||||
|
||||
else // no path, so calculate new one
|
||||
mode = BOT_START_PATROL
|
||||
|
||||
/mob/living/simple_animal/bot/proc/patrol_step_not_moved()
|
||||
calc_path()
|
||||
if(!length(path))
|
||||
find_patrol_target()
|
||||
tries = 0
|
||||
|
||||
// finds the nearest beacon to self
|
||||
/mob/living/simple_animal/bot/proc/find_patrol_target()
|
||||
send_status()
|
||||
nearest_beacon = null
|
||||
new_destination = null
|
||||
find_nearest_beacon()
|
||||
@@ -659,7 +669,6 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
auto_patrol = FALSE
|
||||
mode = BOT_IDLE
|
||||
speak("Disengaging patrol mode.")
|
||||
send_status()
|
||||
|
||||
/mob/living/simple_animal/bot/proc/get_next_patrol_target()
|
||||
// search the beacon list for the next target in the list.
|
||||
@@ -702,83 +711,41 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
else
|
||||
to_chat(src, "<span class='warning'>Unidentified control sequence recieved: [command]</span>")
|
||||
|
||||
/obj/machinery/bot_core/receive_signal(datum/signal/signal)
|
||||
owner.receive_signal(signal)
|
||||
|
||||
/mob/living/simple_animal/bot/proc/receive_signal(datum/signal/signal)
|
||||
/mob/living/simple_animal/bot/proc/handle_command(mob/user, command, list/params)
|
||||
// We aint even on, why bother
|
||||
if(!on)
|
||||
return 1 //ACCESS DENIED
|
||||
|
||||
var/recv = signal.data["command"]
|
||||
var/user = signal.data["user"]
|
||||
|
||||
// process all-bot input
|
||||
if(recv == "bot_status" && (!signal.data["active"] || signal.data["active"] == src))
|
||||
send_status()
|
||||
return 1
|
||||
return FALSE
|
||||
|
||||
// check to see if we are the commanded bot
|
||||
if(signal.data["active"] == src)
|
||||
if(emagged == 2 || remote_disabled) //Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands.
|
||||
return 1
|
||||
if(client)
|
||||
bot_control_message(recv, user, signal.data["target"] ? signal.data["target"] : "Unknown")
|
||||
// process control input
|
||||
switch(recv)
|
||||
if("stop")
|
||||
bot_reset() //HOLD IT!!
|
||||
auto_patrol = FALSE
|
||||
if(emagged == 2 || remote_disabled) //Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands.
|
||||
return FALSE
|
||||
|
||||
if("go")
|
||||
auto_patrol = TRUE
|
||||
if(client)
|
||||
bot_control_message(command, user, params["target"] ? params["target"] : "Unknown")
|
||||
|
||||
if("summon")
|
||||
bot_reset()
|
||||
var/list/user_access = signal.data["useraccess"]
|
||||
summon_target = signal.data["target"] //Location of the user
|
||||
if(user_access.len != 0)
|
||||
access_card.access = user_access + prev_access //Adds the user's access, if any.
|
||||
mode = BOT_SUMMON
|
||||
calc_summon_path()
|
||||
speak("Responding.", radio_channel)
|
||||
// process control input
|
||||
switch(command)
|
||||
if("stop")
|
||||
bot_reset() //HOLD IT!!
|
||||
auto_patrol = FALSE
|
||||
|
||||
else
|
||||
return 0
|
||||
return 1
|
||||
if("go")
|
||||
auto_patrol = TRUE
|
||||
|
||||
// send a radio signal with a single data key/value pair
|
||||
/mob/living/simple_animal/bot/proc/post_signal(freq, key, value)
|
||||
post_signal_multiple(freq, list("[key]" = value) )
|
||||
if("summon")
|
||||
bot_reset()
|
||||
var/list/user_access = params["useraccess"]
|
||||
summon_target = params["target"] // Location of the user
|
||||
|
||||
// send a radio signal with multiple data key/values
|
||||
/mob/living/simple_animal/bot/proc/post_signal_multiple(freq, list/keyval)
|
||||
if(!is_station_level(z)) //Bot control will only work on station.
|
||||
return
|
||||
var/datum/radio_frequency/frequency = SSradio.return_frequency(freq)
|
||||
if(!frequency)
|
||||
return
|
||||
if(length(user_access))
|
||||
access_card.access = user_access + prev_access //Adds the user's access, if any.
|
||||
|
||||
var/datum/signal/signal = new()
|
||||
signal.source = bot_core
|
||||
signal.transmission_method = 1
|
||||
signal.data = keyval
|
||||
spawn()
|
||||
if(signal.data["type"] == bot_type)
|
||||
frequency.post_signal(bot_core, signal, filter = bot_filter)
|
||||
else
|
||||
frequency.post_signal(bot_core, signal)
|
||||
mode = BOT_SUMMON
|
||||
calc_summon_path()
|
||||
speak("Responding.", radio_channel)
|
||||
|
||||
return TRUE
|
||||
|
||||
// signals bot status etc. to controller
|
||||
/mob/living/simple_animal/bot/proc/send_status()
|
||||
if(remote_disabled || emagged == 2)
|
||||
return
|
||||
var/list/kv = list(
|
||||
"type" = bot_type,
|
||||
"name" = name,
|
||||
"loca" = get_area(src), // area
|
||||
"mode" = mode
|
||||
)
|
||||
post_signal_multiple(control_freq, kv)
|
||||
|
||||
/mob/living/simple_animal/bot/proc/bot_summon() // summoned to PDA
|
||||
summon_step()
|
||||
@@ -790,12 +757,12 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
set_path(get_path_to(src, patrol_target, /turf/proc/Distance_cardinal, 0, 120, id=access_card, exclude=avoid))
|
||||
|
||||
/mob/living/simple_animal/bot/proc/calc_summon_path(turf/avoid)
|
||||
set waitfor = FALSE
|
||||
check_bot_access()
|
||||
spawn()
|
||||
set_path(get_path_to(src, summon_target, /turf/proc/Distance_cardinal, 0, 150, id=access_card, exclude=avoid))
|
||||
if(!path.len) //Cannot reach target. Give up and announce the issue.
|
||||
speak("Summon command failed, destination unreachable.",radio_channel)
|
||||
bot_reset()
|
||||
set_path(get_path_to(src, summon_target, /turf/proc/Distance_cardinal, 0, 150, id=access_card, exclude=avoid))
|
||||
if(!path.len) //Cannot reach target. Give up and announce the issue.
|
||||
speak("Summon command failed, destination unreachable.",radio_channel)
|
||||
bot_reset()
|
||||
|
||||
/mob/living/simple_animal/bot/proc/summon_step()
|
||||
|
||||
@@ -814,13 +781,17 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
|
||||
var/moved = bot_move(summon_target, 3) // Move attempt
|
||||
if(!moved)
|
||||
spawn(2)
|
||||
calc_summon_path()
|
||||
tries = 0
|
||||
addtimer(CALLBACK(src, .proc/try_calc_path), 2)
|
||||
|
||||
|
||||
else // no path, so calculate new one
|
||||
calc_summon_path()
|
||||
|
||||
/mob/living/simple_animal/bot/proc/try_calc_path()
|
||||
calc_summon_path()
|
||||
tries = 0
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/proc/openedDoor(obj/machinery/door/D)
|
||||
frustration = 0
|
||||
|
||||
@@ -844,6 +815,14 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
/mob/living/simple_animal/bot/proc/get_controls(mob/M)
|
||||
return "PROTOBOT - NOT FOR USE"
|
||||
|
||||
/mob/living/simple_animal/bot/proc/allowed(mob/M)
|
||||
var/acc = M.get_access() //see mob.dm
|
||||
|
||||
if(acc == IGNORE_ACCESS || M.can_admin_interact())
|
||||
return TRUE //Mob ignores access
|
||||
|
||||
return has_access(list(), req_access, acc)
|
||||
|
||||
/mob/living/simple_animal/bot/Topic(href, href_list)
|
||||
if(href_list["close"])// HUE HUE
|
||||
if(usr in users)
|
||||
@@ -855,7 +834,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
return 1
|
||||
add_fingerprint(usr)
|
||||
|
||||
if((href_list["power"]) && (bot_core.allowed(usr) || !locked || usr.can_admin_interact()))
|
||||
if((href_list["power"]) && (allowed(usr) || !locked || usr.can_admin_interact()))
|
||||
if(on)
|
||||
turn_off()
|
||||
else
|
||||
@@ -902,17 +881,6 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
/mob/living/simple_animal/bot/update_icon_state()
|
||||
icon_state = "[initial(icon_state)][on]"
|
||||
|
||||
// Machinery to simplify topic and access calls
|
||||
/obj/machinery/bot_core
|
||||
use_power = NO_POWER_USE
|
||||
var/mob/living/simple_animal/bot/owner = null
|
||||
|
||||
/obj/machinery/bot_core/New(loc)
|
||||
..()
|
||||
owner = loc
|
||||
if(!istype(owner))
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_animal/bot/proc/topic_denied(mob/user) //Access check proc for bot topics! Remember to place in a bot's individual Topic if desired.
|
||||
if(user.can_admin_interact())
|
||||
return FALSE
|
||||
@@ -975,7 +943,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
faction = initial(faction)
|
||||
|
||||
/mob/living/simple_animal/bot/proc/ejectpairemote(mob/user)
|
||||
if(bot_core.allowed(user) && paicard)
|
||||
if(allowed(user) && paicard)
|
||||
speak("Ejecting personality chip.", radio_channel)
|
||||
ejectpai(user)
|
||||
|
||||
@@ -1035,8 +1003,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
switch(message_mode)
|
||||
if("intercom")
|
||||
for(var/obj/item/radio/intercom/I in view(1, src))
|
||||
spawn(0)
|
||||
I.talk_into(src, message, null, verb, speaking)
|
||||
I.talk_into(src, message, null, verb, speaking)
|
||||
used_radios += I
|
||||
if("headset")
|
||||
Radio.talk_into(src, message, null, verb, speaking)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
bot_type = CLEAN_BOT
|
||||
model = "Cleanbot"
|
||||
bot_purpose = "seek out messes and clean them"
|
||||
bot_core_type = /obj/machinery/bot_core/cleanbot
|
||||
req_access = list(ACCESS_JANITOR, ACCESS_ROBOTICS)
|
||||
window_id = "autoclean"
|
||||
window_name = "Automatic Station Cleaner v1.1"
|
||||
pass_flags = PASSMOB
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/card/id)||istype(W, /obj/item/pda))
|
||||
if(bot_core.allowed(user) && !open && !emagged)
|
||||
if(allowed(user) && !open && !emagged)
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>You [ locked ? "lock" : "unlock"] \the [src] behaviour controls.</span>")
|
||||
else
|
||||
@@ -131,7 +131,7 @@
|
||||
return
|
||||
|
||||
if(target && loc == target.loc)
|
||||
clean(target)
|
||||
start_clean(target)
|
||||
path = list()
|
||||
target = null
|
||||
|
||||
@@ -163,17 +163,19 @@
|
||||
target_types += /obj/effect/decal/cleanable/dirt
|
||||
target_types += /obj/effect/decal/cleanable/trail_holder
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/proc/clean(obj/effect/decal/cleanable/target)
|
||||
/mob/living/simple_animal/bot/cleanbot/proc/start_clean(obj/effect/decal/cleanable/target)
|
||||
anchored = TRUE
|
||||
icon_state = "cleanbot-c"
|
||||
visible_message("<span class='notice'>[src] begins to clean up [target]</span>")
|
||||
mode = BOT_CLEANING
|
||||
spawn(50)
|
||||
if(mode == BOT_CLEANING)
|
||||
QDEL_NULL(target)
|
||||
anchored = FALSE
|
||||
mode = BOT_IDLE
|
||||
icon_state = "cleanbot[on]"
|
||||
addtimer(CALLBACK(src, .proc/do_clean, target), 5 SECONDS)
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/proc/do_clean(obj/effect/decal/cleanable/target)
|
||||
if(mode == BOT_CLEANING)
|
||||
QDEL_NULL(target)
|
||||
anchored = FALSE
|
||||
mode = BOT_IDLE
|
||||
icon_state = "cleanbot[on]"
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/explode()
|
||||
on = FALSE
|
||||
@@ -186,10 +188,6 @@
|
||||
do_sparks(3, 1, src)
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/cleanbot
|
||||
req_one_access = list(ACCESS_JANITOR, ACCESS_ROBOTICS)
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/show_controls(mob/M)
|
||||
ui_interact(M)
|
||||
|
||||
@@ -245,6 +243,6 @@
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/UnarmedAttack(atom/A)
|
||||
if(istype(A,/obj/effect/decal/cleanable))
|
||||
clean(A)
|
||||
start_clean(A)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -405,7 +405,7 @@
|
||||
if(!syndicate_aligned)
|
||||
var/mob/living/simple_animal/bot/medbot/S = new /mob/living/simple_animal/bot/medbot(T, skin)
|
||||
S.name = created_name
|
||||
S.bot_core.req_one_access = req_one_access
|
||||
S.req_access = req_one_access
|
||||
S.treatment_oxy = treatment_oxy
|
||||
S.treatment_brute = treatment_brute
|
||||
S.treatment_fire = treatment_fire
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
bot_filter = RADIO_SECBOT
|
||||
model = "ED-209"
|
||||
bot_purpose = "seek out criminals, handcuff them, and report their location to security"
|
||||
bot_core_type = /obj/machinery/bot_core/secbot
|
||||
req_access = list(ACCESS_SECURITY)
|
||||
window_id = "autoed209"
|
||||
window_name = "Automatic Security Unit v2.6"
|
||||
path_image_color = "#FF0000"
|
||||
@@ -62,7 +62,7 @@
|
||||
check_records = FALSE //Don't actively target people set to arrest
|
||||
arrest_type = TRUE //Don't even try to cuff
|
||||
declare_arrests = FALSE // Don't spam sec
|
||||
bot_core.req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE, ACCESS_ROBOTICS)
|
||||
req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE, ACCESS_ROBOTICS)
|
||||
|
||||
if(created_name == initial(name) || !created_name)
|
||||
if(lasercolor == "b")
|
||||
@@ -296,7 +296,7 @@
|
||||
if(iscarbon(target) && target.canBeHandcuffed())
|
||||
if(!arrest_type)
|
||||
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
|
||||
cuff(target)
|
||||
start_cuffing(target)
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
@@ -340,15 +340,13 @@
|
||||
target = null
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
spawn(0)
|
||||
handle_automated_action() //ensure bot quickly responds
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/back_to_hunt()
|
||||
anchored = FALSE
|
||||
frustration = 0
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action() //ensure bot quickly responds
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action)
|
||||
|
||||
// look for a criminal in view of the bot
|
||||
|
||||
@@ -376,8 +374,7 @@
|
||||
playsound(loc, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, 0)
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action() // ensure bot quickly responds to a perp
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action)
|
||||
break
|
||||
else
|
||||
continue
|
||||
@@ -488,8 +485,7 @@
|
||||
pulse2.name = "emp sparks"
|
||||
pulse2.anchored = TRUE
|
||||
pulse2.dir = pick(GLOB.cardinal)
|
||||
spawn(10)
|
||||
qdel(pulse2)
|
||||
QDEL_IN(pulse2, 1 SECONDS)
|
||||
var/list/mob/living/carbon/targets = new
|
||||
for(var/mob/living/carbon/C in view(12,src))
|
||||
if(C.stat==2)
|
||||
@@ -522,23 +518,29 @@
|
||||
if((lasercolor == "b"))
|
||||
if(istype(Proj, /obj/item/projectile/beam/lasertag/redtag))
|
||||
lasertag_check++
|
||||
|
||||
else if((lasercolor == "r"))
|
||||
if(istype(Proj, /obj/item/projectile/beam/lasertag/bluetag))
|
||||
lasertag_check++
|
||||
|
||||
if(lasertag_check)
|
||||
icon_state = "[lasercolor]ed2090"
|
||||
disabled = TRUE
|
||||
walk_to(src, 0)
|
||||
target = null
|
||||
spawn(100)
|
||||
disabled = FALSE
|
||||
icon_state = "[lasercolor]ed2091"
|
||||
return 1
|
||||
addtimer(CALLBACK(src, .proc/unset_disabled), 10 SECONDS)
|
||||
return TRUE
|
||||
|
||||
else
|
||||
..(Proj)
|
||||
|
||||
else
|
||||
..(Proj)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/unset_disabled()
|
||||
disabled = FALSE
|
||||
icon_state = "[lasercolor]ed2091"
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/bluetag
|
||||
lasercolor = "b"
|
||||
|
||||
@@ -553,7 +555,7 @@
|
||||
if(!C.IsStunned() || arrest_type && !baton_delayed)
|
||||
stun_attack(A)
|
||||
else if(C.canBeHandcuffed() && !C.handcuffed)
|
||||
cuff(A)
|
||||
start_cuffing(A)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -573,8 +575,7 @@
|
||||
/mob/living/simple_animal/bot/ed209/proc/stun_attack(mob/living/carbon/C)
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
icon_state = "[lasercolor]ed209-c"
|
||||
spawn(2)
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
addtimer(VARSET_CALLBACK(src, icon_state, "[lasercolor]ed209[on]"), 2)
|
||||
var/threat = C.assess_threat(src)
|
||||
C.SetStuttering(10 SECONDS)
|
||||
C.adjustStaminaLoss(60)
|
||||
@@ -588,18 +589,21 @@
|
||||
C.visible_message("<span class='danger'>[src] has stunned [C]!</span>",\
|
||||
"<span class='userdanger'>[src] has stunned you!</span>")
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/cuff(mob/living/carbon/C)
|
||||
/mob/living/simple_animal/bot/ed209/proc/start_cuffing(mob/living/carbon/C)
|
||||
mode = BOT_ARREST
|
||||
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
|
||||
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
|
||||
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
|
||||
|
||||
spawn(60)
|
||||
if( !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
|
||||
return
|
||||
if(!C.handcuffed)
|
||||
C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.update_handcuffed()
|
||||
back_to_idle()
|
||||
addtimer(CALLBACK(src, .proc/cuff_target, C), 6 SECONDS)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/cuff_target(mob/living/carbon/C)
|
||||
if(!Adjacent(C)|| !isturf(C.loc)) //if he's in a closet or not adjacent, we cancel cuffing.
|
||||
return
|
||||
|
||||
if(!C.handcuffed)
|
||||
C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.update_handcuffed()
|
||||
back_to_idle()
|
||||
|
||||
#undef BATON_COOLDOWN
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
bot_filter = RADIO_FLOORBOT
|
||||
model = "Floorbot"
|
||||
bot_purpose = "seek out damaged or missing floor tiles, and repair or replace them as necessary"
|
||||
bot_core_type = /obj/machinery/bot_core/floorbot
|
||||
req_access = list(ACCESS_CONSTRUCTION, ACCESS_ROBOTICS)
|
||||
window_id = "autofloor"
|
||||
window_name = "Automatic Station Floor Repairer v1.1"
|
||||
path_image_color = "#FFA500"
|
||||
@@ -233,9 +233,9 @@
|
||||
|
||||
if(loc == target || loc == target.loc)
|
||||
if(istype(target, /obj/item/stack/tile/plasteel))
|
||||
eattile(target)
|
||||
start_eattile(target)
|
||||
else if(istype(target, /obj/item/stack/sheet/metal))
|
||||
maketile(target)
|
||||
start_maketile(target)
|
||||
else if(istype(target, /turf/) && emagged < 2)
|
||||
repair(target)
|
||||
else if(emagged == 2 && istype(target,/turf/simulated/floor))
|
||||
@@ -247,20 +247,23 @@
|
||||
else
|
||||
F.ReplaceWithLattice()
|
||||
audible_message("<span class='danger'>[src] makes an excited booping sound.</span>")
|
||||
spawn(50)
|
||||
amount ++
|
||||
anchored = FALSE
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
addtimer(CALLBACK(src, .proc/inc_amount_callback), 5 SECONDS)
|
||||
|
||||
path = list()
|
||||
return
|
||||
|
||||
oldloc = loc
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/inc_amount_callback()
|
||||
amount ++
|
||||
anchored = FALSE
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/nag() //Annoy everyone on the channel to refill us!
|
||||
if(!nagged)
|
||||
speak("Requesting refill at <b>[get_area(src)]</b>!", radio_channel)
|
||||
nagged = 1
|
||||
nagged = TRUE
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/is_hull_breach(turf/t) //Ignore space tiles not considered part of a structure, also ignores shuttle docking areas.
|
||||
var/area/t_area = get_area(t)
|
||||
@@ -299,90 +302,106 @@
|
||||
return result
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/repair(turf/target_turf)
|
||||
|
||||
if(istype(target_turf, /turf/space/))
|
||||
//Must be a hull breach or in bridge mode to continue.
|
||||
if(!is_hull_breach(target_turf) && !targetdirection)
|
||||
target = null
|
||||
return
|
||||
|
||||
else if(!istype(target_turf, /turf/simulated/floor))
|
||||
return
|
||||
|
||||
if(amount <= 0)
|
||||
mode = BOT_IDLE
|
||||
target = null
|
||||
return
|
||||
|
||||
anchored = TRUE
|
||||
|
||||
if(istype(target_turf, /turf/space/)) //If we are fixing an area not part of pure space, it is
|
||||
visible_message("<span class='notice'>[targetdirection ? "[src] begins installing a bridge plating." : "[src] begins to repair the hole."] </span>")
|
||||
mode = BOT_REPAIRING
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
spawn(50)
|
||||
if(mode == BOT_REPAIRING)
|
||||
if(autotile) //Build the floor and include a tile.
|
||||
target_turf.ChangeTurf(/turf/simulated/floor/plasteel)
|
||||
else //Build a hull plating without a floor tile.
|
||||
target_turf.ChangeTurf(/turf/simulated/floor/plating)
|
||||
mode = BOT_IDLE
|
||||
amount -= 1
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
anchored = FALSE
|
||||
target = null
|
||||
addtimer(CALLBACK(src, .proc/make_bridge_plating, target_turf), 5 SECONDS)
|
||||
|
||||
else
|
||||
var/turf/simulated/floor/F = target_turf
|
||||
mode = BOT_REPAIRING
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
visible_message("<span class='notice'>[src] begins repairing the floor.</span>")
|
||||
spawn(50)
|
||||
if(mode == BOT_REPAIRING)
|
||||
F.broken = FALSE
|
||||
F.burnt = FALSE
|
||||
F.ChangeTurf(/turf/simulated/floor/plasteel)
|
||||
mode = BOT_IDLE
|
||||
amount -= 1
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
anchored = FALSE
|
||||
target = null
|
||||
addtimer(CALLBACK(src, .proc/make_bridge_plating, F), 5 SECONDS)
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/eattile(obj/item/stack/tile/plasteel/T)
|
||||
/mob/living/simple_animal/bot/floorbot/proc/make_floor(turf/simulated/floor/F)
|
||||
if(mode != BOT_REPAIRING)
|
||||
return
|
||||
|
||||
F.broken = FALSE
|
||||
F.burnt = FALSE
|
||||
F.ChangeTurf(/turf/simulated/floor/plasteel)
|
||||
mode = BOT_IDLE
|
||||
amount--
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
anchored = FALSE
|
||||
target = null
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/make_bridge_plating(turf/target_turf)
|
||||
if(mode != BOT_REPAIRING)
|
||||
return
|
||||
|
||||
if(autotile) //Build the floor and include a tile.
|
||||
target_turf.ChangeTurf(/turf/simulated/floor/plasteel)
|
||||
else //Build a hull plating without a floor tile.
|
||||
target_turf.ChangeTurf(/turf/simulated/floor/plating)
|
||||
mode = BOT_IDLE
|
||||
amount--
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
anchored = FALSE
|
||||
target = null
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/start_eattile(obj/item/stack/tile/plasteel/T)
|
||||
if(!istype(T, /obj/item/stack/tile/plasteel))
|
||||
return
|
||||
visible_message("<span class='notice'>[src] begins to collect tiles.</span>")
|
||||
mode = BOT_REPAIRING
|
||||
spawn(20)
|
||||
if(isnull(T))
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
if(amount + T.amount > 50)
|
||||
var/i = 50 - amount
|
||||
amount += i
|
||||
T.amount -= i
|
||||
else
|
||||
amount += T.amount
|
||||
qdel(T)
|
||||
addtimer(CALLBACK(src, .proc/do_eattile, T), 2 SECONDS)
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/do_eattile(obj/item/stack/tile/plasteel/T)
|
||||
if(isnull(T))
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
return
|
||||
if(amount + T.amount > 50)
|
||||
var/i = 50 - amount
|
||||
amount += i
|
||||
T.amount -= i
|
||||
else
|
||||
amount += T.amount
|
||||
qdel(T)
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/maketile(obj/item/stack/sheet/metal/M)
|
||||
/mob/living/simple_animal/bot/floorbot/proc/start_maketile(obj/item/stack/sheet/metal/M)
|
||||
if(!istype(M, /obj/item/stack/sheet/metal))
|
||||
return
|
||||
visible_message("<span class='notice'>[src] begins to create tiles.</span>")
|
||||
mode = BOT_REPAIRING
|
||||
spawn(20)
|
||||
if(isnull(M))
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
var/obj/item/stack/tile/plasteel/T = new /obj/item/stack/tile/plasteel
|
||||
T.amount = 4
|
||||
T.forceMove(M.loc)
|
||||
if(M.amount > 1)
|
||||
M.amount--
|
||||
else
|
||||
qdel(M)
|
||||
addtimer(CALLBACK(src, .proc/do_maketile, M), 2 SECONDS)
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/do_maketile(obj/item/stack/sheet/metal/M)
|
||||
if(isnull(M))
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
return
|
||||
var/obj/item/stack/tile/plasteel/T = new /obj/item/stack/tile/plasteel
|
||||
T.amount = 4
|
||||
T.forceMove(M.loc)
|
||||
if(M.amount > 1)
|
||||
M.amount--
|
||||
else
|
||||
qdel(M)
|
||||
target = null
|
||||
mode = BOT_IDLE
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/update_icon_state()
|
||||
if(mode == BOT_REPAIRING)
|
||||
@@ -416,15 +435,12 @@
|
||||
do_sparks(3, 1, src)
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/floorbot
|
||||
req_one_access = list(ACCESS_CONSTRUCTION, ACCESS_ROBOTICS)
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/UnarmedAttack(atom/A)
|
||||
if(isturf(A))
|
||||
repair(A)
|
||||
else if(istype(A,/obj/item/stack/tile/plasteel))
|
||||
eattile(A)
|
||||
start_eattile(A)
|
||||
else if(istype(A,/obj/item/stack/sheet/metal))
|
||||
maketile(A)
|
||||
start_maketile(A)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -29,14 +29,11 @@
|
||||
block_chance_melee = 1
|
||||
block_chance_ranged = 1
|
||||
stun_chance = 0
|
||||
bot_core_type = /obj/machinery/bot_core/toy
|
||||
req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE, ACCESS_ROBOTICS)
|
||||
weapon = /obj/item/toy/sword
|
||||
frustration_number = 5
|
||||
locked = FALSE
|
||||
|
||||
/obj/machinery/bot_core/toy
|
||||
req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE, ACCESS_ROBOTICS)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/griefsky/proc/spam_flag_false() //used for addtimer to not spam comms
|
||||
spam_flag = 0
|
||||
|
||||
@@ -82,9 +79,11 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/griefsky/proc/sword_attack(mob/living/carbon/C) // esword attack
|
||||
src.do_attack_animation(C)
|
||||
do_attack_animation(C)
|
||||
playsound(loc, 'sound/weapons/blade1.ogg', 50, 1, -1)
|
||||
spawn(2)
|
||||
addtimer(CALLBACK(src, .proc/do_sword_attack, C), 2)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/griefsky/proc/do_sword_attack(mob/living/carbon/C)
|
||||
icon_state = spin_icon
|
||||
var/threat = C.assess_threat(src)
|
||||
if(ishuman(C))
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
bot_type = HONK_BOT
|
||||
bot_filter = RADIO_HONKBOT
|
||||
model = "Honkbot"
|
||||
bot_core_type = /obj/machinery/bot_core/honkbot
|
||||
req_access = list(ACCESS_CLOWN, ACCESS_ROBOTICS, ACCESS_MIME)
|
||||
window_id = "autohonk"
|
||||
window_name = "Honkomatic Bike Horn Unit v1.0.7"
|
||||
data_hud_type = DATA_HUD_SECURITY_BASIC // show jobs
|
||||
@@ -30,9 +30,6 @@
|
||||
var/threatlevel = FALSE
|
||||
var/arrest_type = FALSE
|
||||
|
||||
/obj/machinery/bot_core/honkbot
|
||||
req_one_access = list(ACCESS_CLOWN, ACCESS_ROBOTICS, ACCESS_MIME)
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/Initialize(mapload)
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
bot_filter = RADIO_MEDBOT
|
||||
model = "Medibot"
|
||||
bot_purpose = "seek out hurt crewmembers and ensure that they are healed"
|
||||
bot_core_type = /obj/machinery/bot_core/medbot
|
||||
req_access = list(ACCESS_MEDICAL, ACCESS_ROBOTICS)
|
||||
window_id = "automed"
|
||||
window_name = "Automatic Medical Unit v1.1"
|
||||
path_image_color = "#DDDDFF"
|
||||
@@ -87,7 +87,7 @@
|
||||
treatment_fire = "kelotane"
|
||||
treatment_tox = "charcoal"
|
||||
syndicate_aligned = TRUE
|
||||
bot_core_type = /obj/machinery/bot_core/medbot/syndicate
|
||||
req_access = list(ACCESS_SYNDICATE)
|
||||
control_freq = BOT_FREQ + 1000 // make it not show up on lists
|
||||
radio_channel = "Syndicate"
|
||||
radio_config = list("Common" = 1, "Medical" = 1, "Syndicate" = 1)
|
||||
@@ -508,31 +508,31 @@
|
||||
bot_reset()
|
||||
return
|
||||
else
|
||||
if(!emagged && check_overdose(patient,reagent_id,injection_amount))
|
||||
if(!emagged && check_overdose(patient, reagent_id, injection_amount))
|
||||
soft_reset()
|
||||
return
|
||||
C.visible_message("<span class='danger'>[src] is trying to inject [patient]!</span>", \
|
||||
"<span class='userdanger'>[src] is trying to inject you!</span>")
|
||||
|
||||
spawn(30)//replace with do mob
|
||||
if((get_dist(src, patient) <= 1) && on && assess_patient(patient))
|
||||
if(inject_beaker)
|
||||
if(use_beaker && reagent_glass && reagent_glass.reagents.total_volume)
|
||||
var/fraction = min(injection_amount/reagent_glass.reagents.total_volume, 1)
|
||||
reagent_glass.reagents.reaction(patient, REAGENT_INGEST, fraction)
|
||||
reagent_glass.reagents.trans_to(patient, injection_amount) //Inject from beaker instead.
|
||||
else
|
||||
patient.reagents.add_reagent(reagent_id,injection_amount)
|
||||
C.visible_message("<span class='danger'>[src] injects [patient] with its syringe!</span>", \
|
||||
"<span class='userdanger'>[src] injects you with its syringe!</span>")
|
||||
else
|
||||
visible_message("[src] retracts its syringe.")
|
||||
update_icon()
|
||||
soft_reset()
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/do_inject, C, inject_beaker, reagent_id), 3 SECONDS)
|
||||
return
|
||||
|
||||
reagent_id = null
|
||||
return
|
||||
/mob/living/simple_animal/bot/medbot/proc/do_inject(mob/living/carbon/C, inject_beaker, reagent_id)
|
||||
if((get_dist(src, patient) <= 1) && on && assess_patient(patient))
|
||||
if(inject_beaker)
|
||||
if(use_beaker && reagent_glass && reagent_glass.reagents.total_volume)
|
||||
var/fraction = min(injection_amount/reagent_glass.reagents.total_volume, 1)
|
||||
reagent_glass.reagents.reaction(patient, REAGENT_INGEST, fraction)
|
||||
reagent_glass.reagents.trans_to(patient, injection_amount) //Inject from beaker instead.
|
||||
else
|
||||
patient.reagents.add_reagent(reagent_id, injection_amount)
|
||||
|
||||
C.visible_message("<span class='danger'>[src] injects [patient] with its syringe!</span>", "<span class='userdanger'>[src] injects you with its syringe!</span>")
|
||||
else
|
||||
visible_message("[src] retracts its syringe.")
|
||||
|
||||
update_icon()
|
||||
soft_reset()
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/proc/check_overdose(mob/living/carbon/patient,reagent_id,injection_amount)
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[reagent_id]
|
||||
@@ -598,8 +598,3 @@
|
||||
spawn(200) //Twenty seconds
|
||||
declare_cooldown = 0
|
||||
|
||||
/obj/machinery/bot_core/medbot
|
||||
req_one_access = list(ACCESS_MEDICAL, ACCESS_ROBOTICS)
|
||||
|
||||
/obj/machinery/bot_core/medbot/syndicate
|
||||
req_one_access = list(ACCESS_SYNDICATE)
|
||||
|
||||
@@ -25,12 +25,17 @@
|
||||
bot_filter = RADIO_MULEBOT
|
||||
model = "MULE"
|
||||
bot_purpose = "deliver crates and other packages between departments, as requested"
|
||||
bot_core_type = /obj/machinery/bot_core/mulebot
|
||||
req_access = list(ACCESS_CARGO)
|
||||
path_image_color = "#7F5200"
|
||||
|
||||
|
||||
suffix = ""
|
||||
|
||||
/// Delay in deciseconds between each step
|
||||
var/step_delay = 0
|
||||
/// world.time of next move
|
||||
var/next_move_time = 0
|
||||
|
||||
var/global/mulebot_count = 0
|
||||
var/atom/movable/load = null
|
||||
var/mob/living/passenger = null
|
||||
@@ -50,6 +55,8 @@
|
||||
var/currentBloodColor = "#A10808"
|
||||
var/currentDNA = null
|
||||
|
||||
var/num_steps
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/get_cell()
|
||||
return cell
|
||||
|
||||
@@ -250,7 +257,7 @@
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/toggle_lock(mob/user)
|
||||
if(bot_core.allowed(user))
|
||||
if(allowed(user))
|
||||
locked = !locked
|
||||
update_controls()
|
||||
return 1
|
||||
@@ -442,7 +449,7 @@
|
||||
// with items dropping as mobs are loaded
|
||||
|
||||
for(var/atom/movable/AM in src)
|
||||
if(AM == cell || AM == access_card || AM == Radio || AM == bot_core || AM == paicard)
|
||||
if(AM == cell || AM == access_card || AM == Radio || AM == paicard)
|
||||
continue
|
||||
|
||||
AM.forceMove(loc)
|
||||
@@ -466,109 +473,100 @@
|
||||
if(!has_power())
|
||||
on = FALSE
|
||||
return
|
||||
if(on)
|
||||
var/speed = (!wires.is_cut(WIRE_MOTOR1) ? 1 : 0) + (!wires.is_cut(WIRE_MOTOR2) ? 2 : 0)
|
||||
var/num_steps = 0
|
||||
switch(speed)
|
||||
if(0)
|
||||
// do nothing
|
||||
if(1)
|
||||
num_steps = 10
|
||||
if(2)
|
||||
num_steps = 5
|
||||
if(3)
|
||||
num_steps = 3
|
||||
|
||||
if(num_steps)
|
||||
process_bot()
|
||||
num_steps--
|
||||
if(mode != BOT_IDLE)
|
||||
spawn(0)
|
||||
for(var/i=num_steps,i>0,i--)
|
||||
sleep(2)
|
||||
process_bot()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/process_bot()
|
||||
if(!on)
|
||||
return
|
||||
update_icon()
|
||||
|
||||
var/new_speed = (!wires.is_cut(WIRE_MOTOR1) ? 1 : 0) + (!wires.is_cut(WIRE_MOTOR2) ? 2 : 0)
|
||||
if(!new_speed)//Devide by zero man bad
|
||||
return
|
||||
|
||||
|
||||
num_steps = round(10 / new_speed) //10, 5, or 3 steps, depending on how many wires we have cut
|
||||
step_delay = num_steps // step_delay shouldnt change, num_steps should
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/process()
|
||||
if(!on)
|
||||
return PROCESS_KILL
|
||||
|
||||
num_steps--
|
||||
|
||||
switch(mode)
|
||||
if(BOT_IDLE) // idle
|
||||
return
|
||||
|
||||
if(BOT_DELIVER, BOT_GO_HOME, BOT_BLOCKED) // navigating to deliver,home, or blocked
|
||||
if(world.time < next_move_time)
|
||||
return
|
||||
|
||||
next_move_time = world.time + step_delay
|
||||
|
||||
if(loc == target) // reached target
|
||||
at_target()
|
||||
return
|
||||
|
||||
else if(path.len > 0 && target) // valid path
|
||||
else if(length(path) && target) // valid path
|
||||
var/turf/next = path[1]
|
||||
reached_target = 0
|
||||
reached_target = FALSE
|
||||
if(next == loc)
|
||||
increment_path()
|
||||
path -= next
|
||||
return
|
||||
if(istype(next, /turf/simulated))
|
||||
// to_chat(world, "at ([x],[y]) moving to ([next.x],[next.y])")
|
||||
|
||||
if(isturf(next))
|
||||
var/oldloc = loc
|
||||
var/moved = step_towards(src, next) // attempt to move
|
||||
if(cell) cell.use(1)
|
||||
if(moved && oldloc!=loc) // successful move
|
||||
// to_chat(world, "Successful move.")
|
||||
var/moved = step_towards(src, next) // attempt to move
|
||||
if(moved && oldloc!=loc) // successful move
|
||||
blockcount = 0
|
||||
increment_path()
|
||||
|
||||
path -= loc
|
||||
if(destination == home_destination)
|
||||
mode = BOT_GO_HOME
|
||||
else
|
||||
mode = BOT_DELIVER
|
||||
|
||||
else // failed to move
|
||||
else // failed to move
|
||||
|
||||
// to_chat(world, "Unable to move.")
|
||||
blockcount++
|
||||
mode = BOT_BLOCKED
|
||||
if(blockcount == 3)
|
||||
buzz(ANNOYED)
|
||||
|
||||
if(blockcount > 10) // attempt 10 times before recomputing
|
||||
if(blockcount > 10) // attempt 10 times before recomputing
|
||||
// find new path excluding blocked turf
|
||||
buzz(SIGH)
|
||||
mode = BOT_WAIT_FOR_NAV
|
||||
blockcount = 0
|
||||
spawn(20)
|
||||
calc_path(avoid=next)
|
||||
if(path.len > 0)
|
||||
buzz(DELIGHT)
|
||||
mode = BOT_BLOCKED
|
||||
addtimer(CALLBACK(src, .proc/process_blocked, next), 2 SECONDS)
|
||||
return
|
||||
return
|
||||
else
|
||||
buzz(ANNOYED)
|
||||
// to_chat(world, "Bad turf.")
|
||||
mode = BOT_NAV
|
||||
return
|
||||
else
|
||||
// to_chat(world, "No path.")
|
||||
mode = BOT_NAV
|
||||
return
|
||||
|
||||
if(BOT_NAV) // calculate new path
|
||||
// to_chat(world, "Calc new path.")
|
||||
if(BOT_NAV) // calculate new path
|
||||
mode = BOT_WAIT_FOR_NAV
|
||||
spawn(0)
|
||||
calc_path()
|
||||
INVOKE_ASYNC(src, .proc/process_nav)
|
||||
|
||||
if(path.len > 0)
|
||||
blockcount = 0
|
||||
mode = BOT_BLOCKED
|
||||
buzz(DELIGHT)
|
||||
/mob/living/simple_animal/bot/mulebot/proc/process_blocked(turf/next)
|
||||
calc_path(avoid=next)
|
||||
if(length(path))
|
||||
buzz(DELIGHT)
|
||||
mode = BOT_BLOCKED
|
||||
|
||||
else
|
||||
buzz(SIGH)
|
||||
/mob/living/simple_animal/bot/mulebot/proc/process_nav()
|
||||
calc_path()
|
||||
|
||||
mode = BOT_NO_ROUTE
|
||||
if(length(path))
|
||||
blockcount = 0
|
||||
mode = BOT_BLOCKED
|
||||
buzz(DELIGHT)
|
||||
|
||||
else
|
||||
buzz(SIGH)
|
||||
|
||||
mode = BOT_NO_ROUTE
|
||||
|
||||
// calculates a path to the current destination
|
||||
// given an optional turf to avoid
|
||||
@@ -599,9 +597,11 @@
|
||||
/mob/living/simple_animal/bot/mulebot/proc/start_home()
|
||||
if(!on)
|
||||
return
|
||||
spawn(0)
|
||||
set_destination(home_destination)
|
||||
mode = BOT_BLOCKED
|
||||
INVOKE_ASYNC(src, .proc/do_start_home)
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/proc/do_start_home()
|
||||
set_destination(home_destination)
|
||||
mode = BOT_BLOCKED
|
||||
update_icon()
|
||||
|
||||
// called when bot reaches current target
|
||||
@@ -732,72 +732,52 @@
|
||||
to_chat(src, "<span class='warning big'>DELIVER [load] TO [destination]</span>")
|
||||
else
|
||||
to_chat(src, "<span class='warning big'>PICK UP DELIVERY AT [destination]</span>")
|
||||
if("unload")
|
||||
|
||||
if("unload", "load")
|
||||
if(load)
|
||||
to_chat(src, "<span class='warning big'>UNLOAD</span>")
|
||||
else
|
||||
to_chat(src, "<span class='warning big'>LOAD</span>")
|
||||
if("autoret", "autopick", "target")
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/receive_signal(datum/signal/signal)
|
||||
if(wires.is_cut(WIRE_REMOTE_RX) || ..())
|
||||
return TRUE
|
||||
|
||||
var/recv = signal.data["command"]
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/handle_command(mob/user, command, list/params)
|
||||
if(wires.is_cut(WIRE_REMOTE_RX) || !..())
|
||||
return FALSE
|
||||
|
||||
if(client)
|
||||
bot_control_message(command, user, null)
|
||||
return
|
||||
|
||||
. = TRUE
|
||||
|
||||
// process control input
|
||||
switch(recv)
|
||||
switch(command)
|
||||
if("start")
|
||||
start()
|
||||
|
||||
if("target")
|
||||
set_destination(signal.data["destination"])
|
||||
if("stop")
|
||||
bot_reset()
|
||||
|
||||
if("home")
|
||||
start_home()
|
||||
|
||||
if("unload")
|
||||
if(client)
|
||||
return 1
|
||||
if(loc == target)
|
||||
unload(loaddir)
|
||||
else
|
||||
unload(0)
|
||||
|
||||
if("home")
|
||||
start_home()
|
||||
if("target")
|
||||
var/dest = input("Select Bot Destination", "Mulebot [suffix] Interlink", destination) as null|anything in GLOB.deliverybeacontags
|
||||
if(dest)
|
||||
set_destination(dest)
|
||||
|
||||
if("autoret")
|
||||
auto_return = text2num(signal.data["value"])
|
||||
if("set_auto_return")
|
||||
auto_return = text2num(params["autoret"])
|
||||
|
||||
if("autopick")
|
||||
auto_pickup = text2num(signal.data["value"])
|
||||
|
||||
else
|
||||
return 0
|
||||
return 1
|
||||
|
||||
// send a radio signal with multiple data key/values
|
||||
/mob/living/simple_animal/bot/mulebot/post_signal_multiple(freq, list/keyval)
|
||||
if(wires.is_cut(WIRE_REMOTE_TX))
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
// signals bot status etc. to controller
|
||||
/mob/living/simple_animal/bot/mulebot/send_status()
|
||||
var/list/kv = list(
|
||||
"type" = MULE_BOT,
|
||||
"name" = suffix,
|
||||
"loca" = get_area(src),
|
||||
"mode" = mode,
|
||||
"powr" = (cell ? cell.percent() : 0),
|
||||
"dest" = destination,
|
||||
"home" = home_destination,
|
||||
"load" = load,
|
||||
"retn" = auto_return,
|
||||
"pick" = auto_pickup,
|
||||
)
|
||||
post_signal_multiple(control_freq, kv)
|
||||
if("set_pickup_type")
|
||||
auto_pickup = text2num(params["autopick"])
|
||||
|
||||
// player on mulebot attempted to move
|
||||
/mob/living/simple_animal/bot/mulebot/relaymove(mob/user)
|
||||
@@ -874,5 +854,3 @@
|
||||
#undef ANNOYED
|
||||
#undef DELIGHT
|
||||
|
||||
/obj/machinery/bot_core/mulebot
|
||||
req_access = list(ACCESS_CARGO)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
bot_filter = RADIO_SECBOT
|
||||
model = "Securitron"
|
||||
bot_purpose = "seek out criminals, handcuff them, and report their location to security"
|
||||
bot_core_type = /obj/machinery/bot_core/secbot
|
||||
req_access = list(ACCESS_SECURITY)
|
||||
window_id = "autosec"
|
||||
window_name = "Automatic Security Unit v1.6"
|
||||
path_image_color = "#FF0000"
|
||||
@@ -264,8 +264,7 @@
|
||||
playsound(loc, 'sound/weapons/genhit1.ogg', 50, 1, -1)
|
||||
do_attack_animation(C)
|
||||
icon_state = "[base_icon]-c"
|
||||
spawn(2)
|
||||
icon_state = "[base_icon][on]"
|
||||
addtimer(VARSET_CALLBACK(src, icon_state, "[base_icon][on]"), 2)
|
||||
var/threat = C.assess_threat(src)
|
||||
if(ishuman(C) && harmbaton) // Bots with harmbaton enabled become shitcurity. - Dave
|
||||
C.apply_damage(10, BRUTE)
|
||||
@@ -395,15 +394,13 @@
|
||||
target = null
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
spawn(0)
|
||||
handle_automated_action() //ensure bot quickly responds
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/back_to_hunt()
|
||||
anchored = FALSE
|
||||
frustration = 0
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action() //ensure bot quickly responds
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action)
|
||||
// look for a criminal in view of the bot
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/look_for_perp()
|
||||
@@ -427,8 +424,7 @@
|
||||
playsound(loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0)
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action() // ensure bot quickly responds to a perp
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action)
|
||||
break
|
||||
else
|
||||
continue
|
||||
@@ -476,7 +472,4 @@
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/secbot
|
||||
req_access = list(ACCESS_SECURITY)
|
||||
|
||||
#undef BATON_COOLDOWN
|
||||
|
||||
@@ -173,7 +173,7 @@
|
||||
return
|
||||
shootAt(A)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/syndicate/cuff(mob/living/carbon/C)
|
||||
/mob/living/simple_animal/bot/ed209/syndicate/start_cuffing(mob/living/carbon/C)
|
||||
shootAt(C)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/syndicate/stun_attack(mob/living/carbon/C)
|
||||
|
||||
@@ -250,7 +250,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
playsound(src, 'sound/machines/pda_button1.ogg', 50, TRUE)
|
||||
return
|
||||
|
||||
/obj/item/pda/attackby(obj/item/C as obj, mob/user as mob, params)
|
||||
/obj/item/pda/attackby(obj/item/C, mob/user, params)
|
||||
..()
|
||||
if(istype(C, /obj/item/cartridge) && !cartridge)
|
||||
cartridge = C
|
||||
@@ -260,8 +260,6 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
update_shortcuts()
|
||||
to_chat(user, "<span class='notice'>You insert [cartridge] into [src].</span>")
|
||||
SStgui.update_uis(src)
|
||||
if(cartridge.radio)
|
||||
cartridge.radio.hostpda = src
|
||||
playsound(src, 'sound/machines/pda_button1.ogg', 50, TRUE)
|
||||
|
||||
else if(istype(C, /obj/item/card/id))
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
/// Integrated signaler for captain, science & generic signaler cartridge
|
||||
var/obj/item/assembly/signaler/integ_signaler
|
||||
|
||||
var/obj/item/integrated_radio/radio = null
|
||||
|
||||
var/charges = 0
|
||||
|
||||
var/list/stored_data = list()
|
||||
@@ -18,7 +16,6 @@
|
||||
var/list/messenger_plugins = list()
|
||||
|
||||
/obj/item/cartridge/Destroy()
|
||||
QDEL_NULL(radio)
|
||||
QDEL_LIST(programs)
|
||||
QDEL_LIST(messenger_plugins)
|
||||
return ..()
|
||||
@@ -70,10 +67,6 @@
|
||||
new /datum/data/pda/app/secbot_control
|
||||
)
|
||||
|
||||
/obj/item/cartridge/security/Initialize(mapload)
|
||||
. = ..()
|
||||
radio = new /obj/item/integrated_radio/beepsky(src)
|
||||
|
||||
/obj/item/cartridge/detective
|
||||
name = "D.E.T.E.C.T. Cartridge"
|
||||
icon_state = "cart-s"
|
||||
@@ -148,10 +141,6 @@
|
||||
new /datum/data/pda/app/mule_control
|
||||
)
|
||||
|
||||
/obj/item/cartridge/quartermaster/Initialize(mapload)
|
||||
. = ..()
|
||||
radio = new /obj/item/integrated_radio/mule(src)
|
||||
|
||||
/obj/item/cartridge/head
|
||||
name = "Easy-Record DELUXE"
|
||||
icon_state = "cart-h"
|
||||
@@ -170,10 +159,6 @@
|
||||
new /datum/data/pda/app/status_display
|
||||
)
|
||||
|
||||
/obj/item/cartridge/hop/Initialize(mapload)
|
||||
. = ..()
|
||||
radio = new /obj/item/integrated_radio/mule(src)
|
||||
|
||||
/obj/item/cartridge/hos
|
||||
name = "R.O.B.U.S.T. DELUXE"
|
||||
icon_state = "cart-hos"
|
||||
@@ -183,10 +168,6 @@
|
||||
new /datum/data/pda/app/status_display
|
||||
)
|
||||
|
||||
/obj/item/cartridge/hos/Initialize(mapload)
|
||||
. = ..()
|
||||
radio = new /obj/item/integrated_radio/beepsky(src)
|
||||
|
||||
/obj/item/cartridge/ce
|
||||
name = "Power-On DELUXE"
|
||||
icon_state = "cart-ce"
|
||||
@@ -242,7 +223,6 @@
|
||||
|
||||
/obj/item/cartridge/captain/Initialize(mapload)
|
||||
. = ..()
|
||||
radio = new /obj/item/integrated_radio/beepsky(src)
|
||||
integ_signaler = new /obj/item/assembly/signaler(src)
|
||||
|
||||
/obj/item/cartridge/supervisor
|
||||
@@ -271,10 +251,6 @@
|
||||
new /datum/data/pda/app/status_display
|
||||
)
|
||||
|
||||
/obj/item/cartridge/centcom/Initialize(mapload)
|
||||
. = ..()
|
||||
radio = new /obj/item/integrated_radio/beepsky(src)
|
||||
|
||||
/obj/item/cartridge/syndicate
|
||||
name = "Detomatix Cartridge"
|
||||
icon_state = "cart"
|
||||
|
||||
+88
-109
@@ -201,40 +201,41 @@
|
||||
template = "pda_secbot"
|
||||
category = "Security"
|
||||
|
||||
var/active_uid = null
|
||||
|
||||
/datum/data/pda/app/secbot_control/update_ui(mob/user as mob, list/data)
|
||||
var/list/botsData = list()
|
||||
var/list/beepskyData = list()
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/beepsky))
|
||||
var/obj/item/integrated_radio/beepsky/SC = pda.cartridge.radio
|
||||
beepskyData["active"] = SC.active ? sanitize(SC.active.name) : null
|
||||
has_back = SC.active ? 1 : 0
|
||||
if(SC.active && !isnull(SC.botstatus))
|
||||
var/area/loca = SC.botstatus["loca"]
|
||||
var/loca_name = sanitize(loca.name)
|
||||
beepskyData["botstatus"] = list("loca" = loca_name, "mode" = SC.botstatus["mode"])
|
||||
else
|
||||
beepskyData["botstatus"] = list("loca" = null, "mode" = -1)
|
||||
var/botsCount=0
|
||||
if(SC.botlist && SC.botlist.len)
|
||||
for(var/mob/living/simple_animal/bot/B in SC.botlist)
|
||||
botsCount++
|
||||
if(B.loc)
|
||||
botsData[++botsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "uid" = "[B.UID()]")
|
||||
|
||||
if(!botsData.len)
|
||||
var/mob/living/simple_animal/bot/secbot/active_bot = locateUID(active_uid)
|
||||
|
||||
if(active_bot && !QDELETED(active_bot))
|
||||
beepskyData["active"] = active_bot ? sanitize(active_bot.name) : null
|
||||
has_back = !!active_bot
|
||||
if(active_bot && !isnull(active_bot.mode))
|
||||
var/area/loca = get_area(active_bot)
|
||||
var/loca_name = sanitize(loca.name)
|
||||
beepskyData["botstatus"] = list("loca" = loca_name, "mode" = active_bot.mode)
|
||||
|
||||
else
|
||||
var/botsCount = 0
|
||||
var/list/mob/living/simple_animal/bot/bots = list()
|
||||
for(var/mob/living/simple_animal/bot/secbot/SB in GLOB.bots_list)
|
||||
bots += SB
|
||||
for(var/mob/living/simple_animal/bot/ed209/ED in GLOB.bots_list)
|
||||
bots += ED
|
||||
|
||||
for(var/mob/living/simple_animal/bot/B in bots)
|
||||
botsCount++
|
||||
if(B.loc)
|
||||
botsData[++botsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(get_area(B).name), "uid" = "[B.UID()]")
|
||||
|
||||
if(!length(botsData))
|
||||
botsData[++botsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "uid"= null)
|
||||
|
||||
beepskyData["bots"] = botsData
|
||||
beepskyData["count"] = botsCount
|
||||
|
||||
else
|
||||
beepskyData["active"] = 0
|
||||
botsData[++botsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "uid"= null)
|
||||
beepskyData["botstatus"] = list("loca" = null, "mode" = null)
|
||||
beepskyData["bots"] = botsData
|
||||
beepskyData["count"] = 0
|
||||
has_back = 0
|
||||
|
||||
data["beepsky"] = beepskyData
|
||||
|
||||
/datum/data/pda/app/secbot_control/ui_act(action, list/params)
|
||||
@@ -246,36 +247,26 @@
|
||||
|
||||
. = TRUE
|
||||
|
||||
// Aight listen up. Its time for a comment rant again.
|
||||
// The old way of doing this was to proxy things directly from the NanoUI into the PDA's cartridge's radio Topic() function directly
|
||||
// It was AWFUL and took me 30 minutes to even understand
|
||||
// This is in no way a good solution, but it works atleast
|
||||
// Why do we rely on this whole "magical radio system" anyways
|
||||
// Hell, I would rather take GLOBs with direct interactions over this
|
||||
// WHYYYYYYYYYYYYYYY -aa07
|
||||
|
||||
switch(action)
|
||||
if("Back")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/beepsky))
|
||||
pda.cartridge.radio.Topic(null, list(op = "botlist"))
|
||||
if("Rescan")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/beepsky))
|
||||
pda.cartridge.radio.Topic(null, list(op = "scanbots"))
|
||||
if("AccessBot")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/beepsky))
|
||||
pda.cartridge.radio.Topic(null, list(op = "control", bot = params["uid"]))
|
||||
if("Stop")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/beepsky))
|
||||
pda.cartridge.radio.Topic(null, list(op = "stop"))
|
||||
if("Go")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/beepsky))
|
||||
pda.cartridge.radio.Topic(null, list(op = "go"))
|
||||
if("Home")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/beepsky))
|
||||
pda.cartridge.radio.Topic(null, list(op = "home"))
|
||||
if("Summon")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/beepsky))
|
||||
pda.cartridge.radio.Topic(null, list(op = "summon"))
|
||||
if("control")
|
||||
active_uid = params["bot"]
|
||||
|
||||
if("botlist", "Back") // "Back" is part of the PDA TGUI itself.
|
||||
active_uid = null
|
||||
|
||||
if("stop", "go", "home")
|
||||
var/mob/living/simple_animal/bot/active_bot = locateUID(active_uid)
|
||||
if(active_bot && !QDELETED(active_bot))
|
||||
active_bot.handle_command(usr, action)
|
||||
else
|
||||
active_uid = null
|
||||
|
||||
if("summon")
|
||||
var/mob/living/simple_animal/bot/active_bot = locateUID(active_uid)
|
||||
if(active_bot && !QDELETED(active_bot))
|
||||
active_bot.handle_command(usr, "summon", list("target" = get_turf(usr), "useraccess" = usr.get_access()))
|
||||
else
|
||||
active_uid = null
|
||||
|
||||
/datum/data/pda/app/mule_control
|
||||
name = "Delivery Bot Control"
|
||||
@@ -283,27 +274,37 @@
|
||||
template = "pda_mule"
|
||||
category = "Quartermaster"
|
||||
|
||||
var/active_uid = null
|
||||
|
||||
/datum/data/pda/app/mule_control/update_ui(mob/user as mob, list/data)
|
||||
var/list/muleData = list()
|
||||
var/list/mulebotsData = list()
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/mule))
|
||||
var/obj/item/integrated_radio/mule/QC = pda.cartridge.radio
|
||||
muleData["active"] = QC.active ? sanitize(QC.active.name) : null
|
||||
has_back = QC.active ? 1 : 0
|
||||
if(QC.active && !isnull(QC.botstatus))
|
||||
var/area/loca = QC.botstatus["loca"]
|
||||
|
||||
var/mob/living/simple_animal/bot/mulebot/active_bot = locateUID(active_uid)
|
||||
|
||||
if(active_bot && !QDELETED(active_bot))
|
||||
muleData["active"] = active_bot ? sanitize(active_bot.name) : null
|
||||
has_back = !!active_bot
|
||||
if(active_bot && !isnull(active_bot.mode))
|
||||
var/area/loca = get_area(active_bot)
|
||||
var/loca_name = sanitize(loca.name)
|
||||
muleData["botstatus"] = list("loca" = loca_name, "mode" = QC.botstatus["mode"],"home"=QC.botstatus["home"],"powr" = QC.botstatus["powr"],"retn" =QC.botstatus["retn"], "pick"=QC.botstatus["pick"], "load" = QC.botstatus["load"], "dest" = sanitize(QC.botstatus["dest"]))
|
||||
muleData["botstatus"] = list(
|
||||
"loca" = loca_name,
|
||||
"mode" = active_bot.mode,
|
||||
"home" = active_bot.home_destination,
|
||||
"powr" = (active_bot.cell ? active_bot.cell.percent() : 0),
|
||||
"retn" = active_bot.auto_return,
|
||||
"pick" = active_bot.auto_pickup,
|
||||
"load" = active_bot.load,
|
||||
"dest" = sanitize(active_bot.destination)
|
||||
)
|
||||
|
||||
else
|
||||
muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null)
|
||||
|
||||
|
||||
var/mulebotsCount=0
|
||||
for(var/mob/living/simple_animal/bot/B in QC.botlist)
|
||||
else
|
||||
var/mulebotsCount = 0
|
||||
for(var/mob/living/simple_animal/bot/mulebot/B in GLOB.bots_list)
|
||||
mulebotsCount++
|
||||
if(B.loc)
|
||||
mulebotsData[++mulebotsData.len] = list("Name" = sanitize(B.name), "Location" = sanitize(B.loc.loc.name), "uid" = "[B.UID()]")
|
||||
mulebotsData[++mulebotsData.len] = list("Name" = sanitize(B.name), "Location" = get_area(B).name, "uid" = "[B.UID()]")
|
||||
|
||||
if(!mulebotsData.len)
|
||||
mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "uid"= null)
|
||||
@@ -311,14 +312,6 @@
|
||||
muleData["bots"] = mulebotsData
|
||||
muleData["count"] = mulebotsCount
|
||||
|
||||
else
|
||||
muleData["botstatus"] = list("loca" = null, "mode" = -1,"home"=null,"powr" = null,"retn" =null, "pick"=null, "load" = null, "dest" = null)
|
||||
muleData["active"] = 0
|
||||
mulebotsData[++mulebotsData.len] = list("Name" = "No bots found", "Location" = "Invalid", "uid"= null)
|
||||
muleData["bots"] = mulebotsData
|
||||
muleData["count"] = 0
|
||||
has_back = 0
|
||||
|
||||
data["mulebot"] = muleData
|
||||
|
||||
/datum/data/pda/app/mule_control/ui_act(action, list/params)
|
||||
@@ -330,40 +323,26 @@
|
||||
|
||||
. = TRUE
|
||||
|
||||
// Heres the exact same shit as before, but worse
|
||||
// See L257 to L263 for explanation
|
||||
|
||||
switch(action)
|
||||
if("Back")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/mule))
|
||||
pda.cartridge.radio.Topic(null, list(op = "botlist"))
|
||||
if("Rescan")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/mule))
|
||||
pda.cartridge.radio.Topic(null, list(op = "scanbots"))
|
||||
if("AccessBot")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/mule))
|
||||
pda.cartridge.radio.Topic(null, list(op = "control", bot = params["uid"]))
|
||||
if("Unload")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/mule))
|
||||
pda.cartridge.radio.Topic(null, list(op = "unload"))
|
||||
if("SetDest")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/mule))
|
||||
pda.cartridge.radio.Topic(null, list(op = "setdest"))
|
||||
if("SetAutoReturn")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/mule))
|
||||
pda.cartridge.radio.Topic(null, list(op = params["autoReturnType"])) // "retoff" or "reton"
|
||||
if("SetAutoPickup")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/mule))
|
||||
pda.cartridge.radio.Topic(null, list(op = params["autoPickupType"])) // "pickoff" or "pickon"
|
||||
if("Stop")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/mule))
|
||||
pda.cartridge.radio.Topic(null, list(op = "stop"))
|
||||
if("Start")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/mule))
|
||||
pda.cartridge.radio.Topic(null, list(op = "start"))
|
||||
if("ReturnHome")
|
||||
if(pda.cartridge && istype(pda.cartridge.radio, /obj/item/integrated_radio/mule))
|
||||
pda.cartridge.radio.Topic(null, list(op = "home"))
|
||||
if("control")
|
||||
active_uid = params["bot"]
|
||||
|
||||
if("botlist", "Back") // "Back" is part of the PDA TGUI itself.
|
||||
active_uid = null
|
||||
|
||||
if("stop", "start", "home", "unload", "target")
|
||||
var/mob/living/simple_animal/bot/active_bot = locateUID(active_uid)
|
||||
if(active_bot && !QDELETED(active_bot))
|
||||
active_bot.handle_command(usr, action)
|
||||
else
|
||||
active_uid = null
|
||||
|
||||
if("set_auto_return", "set_pickup_type")
|
||||
var/mob/living/simple_animal/bot/active_bot = locateUID(active_uid)
|
||||
if(active_bot && !QDELETED(active_bot))
|
||||
active_bot.handle_command(usr, action, params)
|
||||
else
|
||||
active_uid = null
|
||||
|
||||
/datum/data/pda/app/supply
|
||||
name = "Supply Records"
|
||||
|
||||
@@ -86,8 +86,6 @@
|
||||
scanmode = null
|
||||
if(current_app in C.programs)
|
||||
start_program(find_program(/datum/data/pda/app/main_menu))
|
||||
if(C.radio)
|
||||
C.radio.hostpda = null
|
||||
for(var/datum/data/pda/P in notifying_programs)
|
||||
if(P in C.programs)
|
||||
P.unnotify()
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
//TODO convert this crap over to proper radios or find a way to utilize regualr radios for this object, this thing needs to go.
|
||||
|
||||
/obj/item/integrated_radio
|
||||
name = "\improper PDA radio module"
|
||||
desc = "An electronic radio system of Nanotrasen origin."
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "power_mod"
|
||||
var/obj/item/pda/hostpda = null
|
||||
var/list/botlist = null // list of bots
|
||||
var/mob/living/simple_animal/bot/active // the active bot; if null, show bot list
|
||||
var/list/botstatus // the status signal sent by the bot
|
||||
var/bot_type //The type of bot it is.
|
||||
var/bot_filter //Determines which radio filter to use.
|
||||
|
||||
var/control_freq = 1447
|
||||
|
||||
var/on = FALSE //Are we currently active??
|
||||
var/menu_message = ""
|
||||
|
||||
/obj/item/integrated_radio/Initialize(mapload)
|
||||
. = ..()
|
||||
if(istype(loc.loc, /obj/item/pda))
|
||||
hostpda = loc.loc
|
||||
if(bot_filter)
|
||||
add_to_radio(bot_filter)
|
||||
|
||||
/obj/item/integrated_radio/Destroy()
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src, control_freq)
|
||||
hostpda = null
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_radio/proc/post_signal(freq, key, value, key2, value2, key3, value3, key4, value4, s_filter)
|
||||
|
||||
// to_chat(world, "Post: [freq]: [key]=[value], [key2]=[value2]")
|
||||
var/datum/radio_frequency/frequency = SSradio.return_frequency(freq)
|
||||
|
||||
if(!frequency)
|
||||
return
|
||||
|
||||
var/datum/signal/signal = new()
|
||||
signal.source = src
|
||||
signal.transmission_method = 1
|
||||
signal.data[key] = value
|
||||
if(key2)
|
||||
signal.data[key2] = value2
|
||||
if(key3)
|
||||
signal.data[key3] = value3
|
||||
if(key4)
|
||||
signal.data[key4] = value4
|
||||
|
||||
frequency.post_signal(src, signal, filter = s_filter)
|
||||
|
||||
/obj/item/integrated_radio/receive_signal(datum/signal/signal)
|
||||
if(bot_type && istype(signal.source, /obj/machinery/bot_core) && signal.data["type"] == bot_type)
|
||||
if(!botlist)
|
||||
botlist = new()
|
||||
|
||||
var/obj/machinery/bot_core/core = signal.source
|
||||
|
||||
if(istype(core) && !(core.owner in botlist))
|
||||
botlist += core.owner
|
||||
|
||||
if(active == core.owner)
|
||||
var/list/b = signal.data
|
||||
botstatus = b.Copy()
|
||||
|
||||
/obj/item/integrated_radio/Topic(href, href_list)
|
||||
..()
|
||||
switch(href_list["op"])
|
||||
if("control")
|
||||
active = locateUID(href_list["bot"])
|
||||
post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter)
|
||||
|
||||
if("scanbots") // find all bots
|
||||
botlist = null
|
||||
post_signal(control_freq, "command", "bot_status", s_filter = bot_filter)
|
||||
|
||||
if("botlist")
|
||||
active = null
|
||||
|
||||
if("stop", "go", "home")
|
||||
post_signal(control_freq, "command", href_list["op"], "active", active, s_filter = bot_filter)
|
||||
post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter)
|
||||
|
||||
if("summon")
|
||||
post_signal(control_freq, "command", "summon", "active", active, "target", get_turf(hostpda), "useraccess", hostpda.GetAccess(), "user", usr, s_filter = bot_filter)
|
||||
post_signal(control_freq, "command", "bot_status", "active", active, s_filter = bot_filter)
|
||||
|
||||
/obj/item/integrated_radio/proc/add_to_radio(bot_filter) //Master filter control for bots. Must be placed in the bot's local New() to support map spawned bots.
|
||||
if(SSradio)
|
||||
SSradio.add_object(src, control_freq, filter = bot_filter)
|
||||
|
||||
/obj/item/integrated_radio/honkbot
|
||||
bot_filter = RADIO_HONKBOT
|
||||
bot_type = HONK_BOT
|
||||
|
||||
/obj/item/integrated_radio/beepsky
|
||||
bot_filter = RADIO_SECBOT
|
||||
bot_type = SEC_BOT
|
||||
|
||||
/obj/item/integrated_radio/medbot
|
||||
bot_filter = RADIO_MEDBOT
|
||||
bot_type = MED_BOT
|
||||
|
||||
/obj/item/integrated_radio/floorbot
|
||||
bot_filter = RADIO_FLOORBOT
|
||||
bot_type = FLOOR_BOT
|
||||
|
||||
/obj/item/integrated_radio/cleanbot
|
||||
bot_filter = RADIO_CLEANBOT
|
||||
bot_type = CLEAN_BOT
|
||||
|
||||
/obj/item/integrated_radio/mule
|
||||
bot_filter = RADIO_MULEBOT
|
||||
bot_type = MULE_BOT
|
||||
|
||||
/obj/item/integrated_radio/mule/Topic(href, href_list)
|
||||
..()
|
||||
switch(href_list["op"])
|
||||
if("start")
|
||||
post_signal(control_freq, "command", "start", "active", active, s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("unload")
|
||||
post_signal(control_freq, "command", "unload", "active", active, s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("setdest")
|
||||
if(GLOB.deliverybeacons)
|
||||
var/dest = input("Select Bot Destination", "Mulebot [active.suffix] Interlink", active.destination) as null|anything in GLOB.deliverybeacontags
|
||||
if(dest)
|
||||
post_signal(control_freq, "command", "target", "active", active, "destination", dest, s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("retoff")
|
||||
post_signal(control_freq, "command", "autoret", "active", active, "value", 0, s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("reton")
|
||||
post_signal(control_freq, "command", "autoret", "active", active, "value", 1, s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("pickoff")
|
||||
post_signal(control_freq, "command", "autopick", "active", active, "value", 0, s_filter = RADIO_MULEBOT)
|
||||
|
||||
if("pickon")
|
||||
post_signal(control_freq, "command", "autopick", "active", active, "value", 1, s_filter = RADIO_MULEBOT)
|
||||
|
||||
post_signal(control_freq, "command", "bot_status", "active", active, s_filter = RADIO_MULEBOT)
|
||||
Reference in New Issue
Block a user