diff --git a/_maps/RandomZLevels/research.dmm b/_maps/RandomZLevels/research.dmm
index 64f54fe8898..2910cedafff 100644
--- a/_maps/RandomZLevels/research.dmm
+++ b/_maps/RandomZLevels/research.dmm
@@ -3652,14 +3652,7 @@
/obj/effect/turf_decal/tile/red{
dir = 4
},
-/mob/living/simple_animal/bot/secbot/beepsky{
- desc = "A beefy variant of the standard securitron model.";
- emagged = 1;
- faction = list("nanotrasenprivate");
- health = 50;
- maxHealth = 50;
- name = "Officer Genesky"
- },
+/mob/living/simple_animal/bot/secbot/genesky,
/turf/open/floor/iron/white,
/area/awaymission/research/interior/security)
"ik" = (
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 2f2a553ebf9..fbe14e8899d 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -83299,10 +83299,7 @@
/obj/effect/turf_decal/tile/neutral{
dir = 8
},
-/mob/living/simple_animal/bot/secbot/beepsky{
- desc = "It's Officer Beepsky! Powered by a potato and a shot of whiskey.";
- name = "Officer Beepsky"
- },
+/mob/living/simple_animal/bot/secbot/beepsky/officer,
/turf/open/floor/iron,
/area/hallway/primary/starboard)
"sHr" = (
diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
index 3bcaab21ec4..c4da403ef0b 100644
--- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm
+++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
@@ -12650,9 +12650,7 @@
/area/construction)
"cCh" = (
/obj/item/bedsheet/red,
-/mob/living/simple_animal/bot/secbot/beepsky{
- name = "Officer Beepsky"
- },
+/mob/living/simple_animal/bot/secbot/beepsky,
/turf/open/floor/plating,
/area/security/processing)
"cCj" = (
diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm
index a6826024df3..47bd597c8bd 100644
--- a/_maps/map_files/KiloStation/KiloStation.dmm
+++ b/_maps/map_files/KiloStation/KiloStation.dmm
@@ -19874,11 +19874,7 @@
dir = 1
},
/obj/effect/landmark/event_spawn,
-/mob/living/simple_animal/bot/medbot{
- auto_patrol = 1;
- desc = "A little medical robot, officially part of the Nanotrasen medical inspectorate. He looks somewhat underwhelmed.";
- name = "Inspector Johnson"
- },
+/mob/living/simple_animal/bot/medbot/autopatrol,
/turf/open/floor/iron/showroomfloor,
/area/medical/medbay/lobby)
"cgO" = (
@@ -27303,11 +27299,7 @@
/obj/structure/disposalpipe/segment{
dir = 5
},
-/mob/living/simple_animal/bot/cleanbot{
- auto_patrol = 1;
- icon_state = "cleanbot1";
- name = "Mopficcer Sweepsky"
- },
+/mob/living/simple_animal/bot/cleanbot/autopatrol,
/turf/open/floor/iron,
/area/hallway/primary/starboard)
"dAD" = (
@@ -50506,12 +50498,7 @@
/obj/effect/turf_decal/tile/neutral{
dir = 1
},
-/mob/living/simple_animal/bot/secbot/beepsky{
- desc = "It's Officer Beepsky! Powered by a potato and a shot of whiskey, and with a sturdier reinforced chassis, too.";
- health = 45;
- maxHealth = 45;
- name = "Officer Beepsky"
- },
+/mob/living/simple_animal/bot/secbot/beepsky/officer,
/turf/open/floor/iron/dark,
/area/security/office)
"lXd" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 7c8b6057992..fc0f7f94c53 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -2630,12 +2630,7 @@
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 8
},
-/mob/living/simple_animal/bot/secbot/beepsky{
- desc = "It's Officer Beepsky! Powered by a potato and a shot of whiskey, and with a sturdier reinforced chassis, too.";
- health = 45;
- maxHealth = 45;
- name = "Officer Beepsky"
- },
+/mob/living/simple_animal/bot/secbot/beepsky/officer,
/turf/open/floor/iron,
/area/security/brig)
"awj" = (
@@ -22059,11 +22054,7 @@
/obj/effect/turf_decal/tile/blue{
dir = 1
},
-/mob/living/simple_animal/bot/medbot{
- auto_patrol = 1;
- desc = "A little medical robot, officially part of the Nanotrasen medical inspectorate. He looks somewhat underwhelmed.";
- name = "Inspector Johnson"
- },
+/mob/living/simple_animal/bot/medbot/autopatrol,
/turf/open/floor/iron/white/corner{
dir = 8
},
@@ -27795,11 +27786,7 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
-/mob/living/simple_animal/bot/cleanbot{
- auto_patrol = 1;
- icon_state = "cleanbot1";
- name = "Mopficcer Sweepsky"
- },
+/mob/living/simple_animal/bot/cleanbot/autopatrol,
/turf/open/floor/iron,
/area/hallway/primary/central)
"hPP" = (
diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm
index 8a49b7bcc37..9e32c5fa1b8 100644
--- a/_maps/map_files/tramstation/tramstation.dmm
+++ b/_maps/map_files/tramstation/tramstation.dmm
@@ -37778,10 +37778,7 @@
/obj/machinery/camera/directional/south{
c_tag = "Maintenance - East Tram Tunnel 4"
},
-/mob/living/simple_animal/bot/secbot{
- auto_patrol = 1;
- name = "Officer Tunnel Rat"
- },
+/mob/living/simple_animal/bot/secbot/beepsky/officer,
/turf/open/floor/iron,
/area/maintenance/tram/right)
"mna" = (
@@ -62519,11 +62516,7 @@
/obj/effect/turf_decal/trimline/neutral/filled/corner{
dir = 1
},
-/mob/living/simple_animal/bot/medbot{
- auto_patrol = 1;
- desc = "A little medical robot. He looks somewhat overwhelmed.";
- name = "Emergency T.R.A.M Unit"
- },
+/mob/living/simple_animal/bot/medbot/autopatrol,
/turf/open/floor/iron,
/area/maintenance/tram/left)
"vMm" = (
diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm
index 983aa2d91ae..af82e038a16 100644
--- a/code/__DEFINES/robots.dm
+++ b/code/__DEFINES/robots.dm
@@ -50,38 +50,72 @@
/** Simple Animal BOT defines */
+//Assembly defines
+#define ASSEMBLY_FIRST_STEP 1
+#define ASSEMBLY_SECOND_STEP 2
+#define ASSEMBLY_THIRD_STEP 3
+#define ASSEMBLY_FOURTH_STEP 4
+#define ASSEMBLY_FIFTH_STEP 5
+#define ASSEMBLY_SIXTH_STEP 6
+#define ASSEMBLY_SEVENTH_STEP 7
+#define ASSEMBLY_EIGHTH_STEP 8
+#define ASSEMBLY_NINTH_STEP 9
+
//Bot defines, placed here so they can be read by other things!
/// Delay between movemements
#define BOT_STEP_DELAY 4
/// Maximum times a bot will retry to step from its position
#define BOT_STEP_MAX_RETRIES 5
-
/// Default view range for finding targets.
#define DEFAULT_SCAN_RANGE 7
+//Amount of time that must pass after a Commissioned bot gets saluted to get another.
+#define BOT_COMMISSIONED_SALUTE_DELAY (60 SECONDS)
+
+//Bot mode defines displaying how Bots act
+///The Bot is currently active, and will do whatever it is programmed to do.
+#define BOT_MODE_ON (1<<0)
+///The Bot is currently set to automatically patrol the station.
+#define BOT_MODE_AUTOPATROL (1<<1)
+///The Bot is currently allowed to be remote controlled by Silicon.
+#define BOT_MODE_REMOTE_ENABLED (1<<2)
+///The Bot is allowed to have a pAI placed in control of it.
+#define BOT_MODE_PAI_CONTROLLABLE (1<<3)
+
+//Bot cover defines indicating the Bot's status
+///The Bot's cover is open and can be modified/emagged by anyone.
+#define BOT_COVER_OPEN (1<<0)
+///The Bot's cover is locked, and cannot be opened without unlocking it.
+#define BOT_COVER_LOCKED (1<<1)
+///The Bot is emagged.
+#define BOT_COVER_EMAGGED (1<<2)
+///The Bot has been hacked by a Silicon, emagging them, but revertable.
+#define BOT_COVER_HACKED (1<<3)
//Bot types
/// Secutritrons (Beepsky)
-#define SEC_BOT (1<<0)
+#define SEC_BOT "Securitron"
/// ED-209s
-#define ADVANCED_SEC_BOT (1<<1)
+#define ADVANCED_SEC_BOT "ED-209"
/// MULEbots
-#define MULE_BOT (1<<2)
+#define MULE_BOT "MULEbot"
/// Floorbots
-#define FLOOR_BOT (1<<3)
+#define FLOOR_BOT "Floorbot"
/// Cleanbots
-#define CLEAN_BOT (1<<4)
+#define CLEAN_BOT "Cleanbot"
/// Medibots
-#define MED_BOT (1<<5)
+#define MED_BOT "Medibot"
/// Honkbots & ED-Honks
-#define HONK_BOT (1<<6)
+#define HONK_BOT "Honkbot"
/// Firebots
-#define FIRE_BOT (1<<7)
+#define FIRE_BOT "Firebot"
/// Hygienebots
-#define HYGIENE_BOT (1<<8)
+#define HYGIENE_BOT "Hygienebot"
/// Vibe bots
-#define VIBE_BOT (1<<9)
+#define VIBE_BOT "Vibebot"
//Mode defines. If you add a new one make sure you update mode_name in /mob/living/simple_animal/bot
+
+// General Bot modes //
/// Idle
#define BOT_IDLE 0
/// Found target, hunting
@@ -96,6 +130,8 @@
#define BOT_SUMMON 5
/// Currently moving
#define BOT_MOVING 6
+
+// Unique modes //
/// Secbot - At target, preparing to arrest
#define BOT_PREP_ARREST 7
/// Secbot - Arresting target
@@ -134,12 +170,3 @@
#define SECBOT_CHECK_RECORDS (1<<3)
///Whether we will stun & cuff or endlessly stun
#define SECBOT_HANDCUFF_TARGET (1<<4)
-
-/** Misc Robot defines */
-
-//Assembly defines
-#define ASSEMBLY_FIRST_STEP 0
-#define ASSEMBLY_SECOND_STEP 1
-#define ASSEMBLY_THIRD_STEP 2
-#define ASSEMBLY_FOURTH_STEP 3
-#define ASSEMBLY_FIFTH_STEP 4
diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm
index 267bad5c265..857a6870190 100644
--- a/code/datums/brain_damage/special.dm
+++ b/code/datums/brain_damage/special.dm
@@ -395,7 +395,7 @@
/obj/effect/hallucination/simple/securitron/Initialize(mapload)
. = ..()
- name = pick("officer Beepsky", "officer Johnson", "officer Pingsky")
+ name = pick("Officer Beepsky", "Officer Johnson", "Officer Pingsky")
START_PROCESSING(SSfastprocess, src)
/obj/effect/hallucination/simple/securitron/process()
diff --git a/code/datums/wires/mulebot.dm b/code/datums/wires/mulebot.dm
index f2296641388..8351da231b0 100644
--- a/code/datums/wires/mulebot.dm
+++ b/code/datums/wires/mulebot.dm
@@ -20,7 +20,7 @@
if(!..())
return FALSE
var/mob/living/simple_animal/bot/mulebot/mule = holder
- if(mule.open)
+ if(mule.bot_cover_flags & BOT_COVER_OPEN)
return TRUE
/datum/wires/mulebot/on_cut(wire, mend)
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index 1294b27e817..b2a2d51af76 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -428,7 +428,7 @@ Diagnostic HUDs!
var/image/holder = hud_list[DIAG_STAT_HUD]
var/icon/I = icon(icon, icon_state, dir)
holder.pixel_y = I.Height() - world.icon_size
- if(on)
+ if(bot_mode_flags & BOT_MODE_ON)
holder.icon_state = "hudstat"
else if(stat) //Generally EMP causes this
holder.icon_state = "hudoffline"
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index 7236eb5406e..3f2f9e3c2f9 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -161,7 +161,7 @@
continue //only find medibots on the same z-level as the computer
var/turf/bl = get_turf(M)
if(bl) //if it can't find a turf for the medibot, then it probably shouldn't be showing up
- bdat += "[M.name] - \[[bl.x],[bl.y]\] - [M.on ? "Online" : "Offline"]
"
+ bdat += "[M.name] - \[[bl.x],[bl.y]\] - [M.bot_mode_flags & BOT_MODE_ON ? "Online" : "Offline"]
"
if(!bdat)
dat += "
None detected"
else
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index 9dedd04fc66..880849c2242 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -319,7 +319,7 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "Utilities
"
dat += ""
if (cartridge)
- if(cartridge.bot_access_flags)
+ if(!isnull(cartridge.bot_access))
dat += "- [PDAIMG(medbot)]Bots Access
"
if (cartridge.access & CART_JANITOR)
dat += "- [PDAIMG(bucket)]Custodial Locator
"
diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm
index c8f845b9e3b..64af4990ee1 100644
--- a/code/game/objects/items/devices/PDA/cart.dm
+++ b/code/game/objects/items/devices/PDA/cart.dm
@@ -14,7 +14,9 @@
var/remote_door_id = ""
- var/bot_access_flags = 0 //Bit flags. Selection: SEC_BOT | ADVANCED_SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT | VIBE_BOT
+ var/list/bot_access = list()
+// Selection: SEC_BOT | ADVANCED_SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT | VIBE_BOT
+
var/spam_enabled = 0 //Enables "Send to All" Option
var/obj/item/pda/host_pda = null
@@ -42,44 +44,61 @@
name = "\improper Power-ON cartridge"
icon_state = "cart-e"
access = CART_ENGINE | CART_DRONEPHONE
- bot_access_flags = FLOOR_BOT
+ bot_access = list(
+ FLOOR_BOT,
+ )
/obj/item/cartridge/atmos
name = "\improper BreatheDeep cartridge"
icon_state = "cart-a"
access = CART_ATMOS | CART_DRONEPHONE
- bot_access_flags = FLOOR_BOT | FIRE_BOT
+ bot_access = list(
+ FLOOR_BOT,
+ FIRE_BOT,
+ )
/obj/item/cartridge/medical
name = "\improper Med-U cartridge"
icon_state = "cart-m"
access = CART_MEDICAL
- bot_access_flags = MED_BOT
+ bot_access = list(
+ MED_BOT,
+ )
/obj/item/cartridge/chemistry
name = "\improper ChemWhiz cartridge"
icon_state = "cart-chem"
access = CART_REAGENT_SCANNER
- bot_access_flags = MED_BOT
+ bot_access = list(
+ MED_BOT,
+ )
/obj/item/cartridge/security
name = "\improper R.O.B.U.S.T. cartridge"
icon_state = "cart-s"
access = CART_SECURITY | CART_MANIFEST
- bot_access_flags = SEC_BOT | ADVANCED_SEC_BOT
+ bot_access = list(
+ SEC_BOT,
+ ADVANCED_SEC_BOT,
+ )
/obj/item/cartridge/detective
name = "\improper D.E.T.E.C.T. cartridge"
icon_state = "cart-s"
access = CART_SECURITY | CART_MEDICAL | CART_MANIFEST
- bot_access_flags = SEC_BOT | ADVANCED_SEC_BOT
+ bot_access = list(
+ SEC_BOT,
+ ADVANCED_SEC_BOT,
+ )
/obj/item/cartridge/janitor
name = "\improper CustodiPRO cartridge"
desc = "The ultimate in clean-room design."
icon_state = "cart-j"
access = CART_JANITOR | CART_DRONEPHONE
- bot_access_flags = CLEAN_BOT
+ bot_access = list(
+ CLEAN_BOT,
+ )
/obj/item/cartridge/lawyer
name = "\improper P.R.O.V.E. cartridge"
@@ -95,8 +114,14 @@
/obj/item/cartridge/roboticist
name = "\improper B.O.O.P. Remote Control cartridge"
desc = "Packed with heavy duty quad-bot interlink!"
- bot_access_flags = FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT | VIBE_BOT
access = CART_DRONEPHONE
+ bot_access = list(
+ FLOOR_BOT,
+ CLEAN_BOT,
+ MED_BOT,
+ FIRE_BOT,
+ VIBE_BOT,
+ )
/obj/item/cartridge/signal
name = "generic signaler cartridge"
@@ -119,7 +144,9 @@
desc = "Perfect for the Quartermaster on the go!"
icon_state = "cart-q"
access = CART_QUARTERMASTER
- bot_access_flags = MULE_BOT
+ bot_access = list(
+ MULE_BOT,
+ )
/obj/item/cartridge/head
name = "\improper Easy-Record DELUXE cartridge"
@@ -130,32 +157,50 @@
name = "\improper HumanResources9001 cartridge"
icon_state = "cart-h"
access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_JANITOR | CART_SECURITY | CART_NEWSCASTER | CART_QUARTERMASTER | CART_DRONEPHONE
- bot_access_flags = MULE_BOT | CLEAN_BOT | VIBE_BOT
+ bot_access = list(
+ MULE_BOT,
+ CLEAN_BOT,
+ VIBE_BOT,
+ )
/obj/item/cartridge/hos
name = "\improper R.O.B.U.S.T. DELUXE cartridge"
icon_state = "cart-hos"
access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_SECURITY
- bot_access_flags = SEC_BOT | ADVANCED_SEC_BOT
+ bot_access = list(
+ SEC_BOT,
+ ADVANCED_SEC_BOT,
+ )
/obj/item/cartridge/ce
name = "\improper Power-On DELUXE cartridge"
icon_state = "cart-ce"
access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_ENGINE | CART_ATMOS | CART_DRONEPHONE | CART_DRONEACCESS
- bot_access_flags = FLOOR_BOT | FIRE_BOT
+ bot_access = list(
+ FLOOR_BOT,
+ FIRE_BOT,
+ )
/obj/item/cartridge/cmo
name = "\improper Med-U DELUXE cartridge"
icon_state = "cart-cmo"
access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_REAGENT_SCANNER | CART_MEDICAL
- bot_access_flags = MED_BOT
+ bot_access = list(
+ MED_BOT,
+ )
/obj/item/cartridge/rd
name = "\improper Signal Ace DELUXE cartridge"
icon_state = "cart-rd"
access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_REAGENT_SCANNER | CART_ATMOS | CART_DRONEPHONE
- bot_access_flags = FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT | VIBE_BOT
+ bot_access = list(
+ FLOOR_BOT,
+ CLEAN_BOT,
+ MED_BOT,
+ FIRE_BOT,
+ VIBE_BOT,
+ )
/obj/item/cartridge/rd/Initialize(mapload)
. = ..()
@@ -166,8 +211,17 @@
desc = "Now with 350% more value!" //Give the Captain...EVERYTHING! (Except Mime, Clown, and Syndie)
icon_state = "cart-c"
access = ~(CART_CLOWN | CART_MIME | CART_REMOTE_DOOR)
- bot_access_flags = SEC_BOT | ADVANCED_SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT | VIBE_BOT
spam_enabled = 1
+ bot_access = list(
+ SEC_BOT,
+ ADVANCED_SEC_BOT,
+ MULE_BOT,
+ FLOOR_BOT,
+ CLEAN_BOT,
+ MED_BOT,
+ FIRE_BOT,
+ VIBE_BOT,
+ )
/obj/item/cartridge/captain/Initialize(mapload)
. = ..()
@@ -489,7 +543,7 @@
if (bl.z != cl.z)
continue
var/direction = get_dir(src, B)
- ldat += "Cleanbot - \[[bl.x],[bl.y] ([uppertext(dir2text(direction))])\] - [B.on ? "Online" : "Offline"]
"
+ ldat += "Cleanbot - \[[bl.x],[bl.y] ([uppertext(dir2text(direction))])\] - [B.bot_mode_flags & BOT_MODE_ON ? "Online" : "Offline"]
"
if (!ldat)
menu += "None"
@@ -661,10 +715,10 @@
/obj/item/cartridge/proc/bot_control()
if(active_bot)
menu += "[active_bot]
Status: ([PDAIMG(refresh)]refresh)
"
- menu += "Model: [active_bot.model]
"
+ menu += "Model: [active_bot.bot_type]
"
menu += "Location: [get_area(active_bot)]
"
menu += "Mode: [active_bot.get_mode()]"
- if(active_bot.allow_pai)
+ if(active_bot.bot_mode_flags & BOT_MODE_PAI_CONTROLLABLE)
menu += "
pAI: "
if(active_bot.paicard && active_bot.paicard.pai)
menu += "[active_bot.paicard.pai.name]"
@@ -704,7 +758,7 @@
var/botcount = 0
for(var/B in GLOB.bots_list) //Git da botz
var/mob/living/simple_animal/bot/Bot = B
- if(!Bot.on || Bot.z != zlevel || Bot.remote_disabled || !(bot_access_flags & Bot.bot_type)) //Only non-emagged bots on the same Z-level are detected!
+ if(!(Bot.bot_mode_flags & BOT_MODE_ON) || Bot.z != zlevel || !(Bot.bot_mode_flags & BOT_MODE_REMOTE_ENABLED) || !(Bot.bot_type in bot_access)) //Only non-emagged bots on the same Z-level are detected!
continue //Also, the PDA must have access to the bot type.
menu += "[Bot.name] ([Bot.get_mode()])
"
botcount++
diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm
index 34dac31a074..c1c9caadae4 100644
--- a/code/modules/antagonists/revenant/revenant_abilities.dm
+++ b/code/modules/antagonists/revenant/revenant_abilities.dm
@@ -303,10 +303,10 @@
/obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction/proc/malfunction(turf/T, mob/user)
for(var/mob/living/simple_animal/bot/bot in T)
- if(!bot.emagged)
+ if(!(bot.bot_cover_flags & BOT_COVER_EMAGGED))
new /obj/effect/temp_visual/revenant(bot.loc)
- bot.locked = FALSE
- bot.open = TRUE
+ bot.bot_cover_flags &= ~BOT_COVER_LOCKED
+ bot.bot_cover_flags |= BOT_COVER_OPEN
bot.emag_act(user)
for(var/mob/living/carbon/human/human in T)
if(human == user)
diff --git a/code/modules/mob/living/silicon/ai/robot_control.dm b/code/modules/mob/living/silicon/ai/robot_control.dm
index c739f52f393..f8bcab9cfdd 100644
--- a/code/modules/mob/living/silicon/ai/robot_control.dm
+++ b/code/modules/mob/living/silicon/ai/robot_control.dm
@@ -37,13 +37,13 @@
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!
+ if(B.z != ai_zlevel || !(B.bot_mode_flags & BOT_MODE_REMOTE_ENABLED)) //Only non-emagged bots on the same Z-level are detected!
continue
var/list/robot_data = list(
name = B.name,
- model = B.model,
+ model = B.bot_type,
mode = B.get_mode(),
- hacked = B.hacked,
+ hacked = B.bot_cover_flags & BOT_COVER_HACKED,
location = get_area_name(B, TRUE),
ref = REF(B)
)
@@ -64,14 +64,14 @@
to_chat(usr, 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(!owner.Bot || !(owner.Bot.bot_mode_flags & BOT_MODE_REMOTE_ENABLED) || owner.control_disabled)
return
owner.waypoint_mode = TRUE
to_chat(usr, span_notice("Set your waypoint by clicking on a valid location free of obstructions."))
. = TRUE
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)
+ if(!owner.Bot || !(owner.Bot.bot_mode_flags & BOT_MODE_REMOTE_ENABLED) || owner.control_disabled)
return
owner.Bot.attack_ai(usr)
. = TRUE
diff --git a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm
index 8b5da43b58d..bdd7f6adf5e 100644
--- a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm
+++ b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm
@@ -5,18 +5,20 @@
icon_state = "grievous"
health = 150
maxHealth = 150
- weapon = /obj/item/melee/energy/sword/saber
+
+ baton_type = /obj/item/melee/energy/sword/saber
base_speed = 4 //he's a fast fucker
- var/block_chance = 50
weapon_force = 30
+ var/block_chance = 50
+
/mob/living/simple_animal/bot/secbot/grievous/toy //A toy version of general beepsky!
name = "Genewul Bweepskee"
desc = "An adorable looking secbot with four toy swords taped to its arms"
health = 50
maxHealth = 50
- weapon = /obj/item/toy/sword
+ baton_type = /obj/item/toy/sword
weapon_force = 0
/mob/living/simple_animal/bot/secbot/grievous/bullet_act(obj/projectile/P)
@@ -56,14 +58,14 @@
/mob/living/simple_animal/bot/secbot/grievous/handle_automated_action()
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
return
switch(mode)
if(BOT_IDLE) // idle
update_appearance()
walk_to(src,0)
look_for_perp() // see if any criminals are in range
- if(!mode && auto_patrol) // still idle, and set to patrol
+ if(!mode && bot_mode_flags & BOT_MODE_AUTOPATROL) // still idle, and set to patrol
mode = BOT_START_PATROL // switch to patrol mode
if(BOT_HUNT) // hunting for perp
update_appearance()
@@ -127,24 +129,9 @@
else
continue
-
/mob/living/simple_animal/bot/secbot/grievous/explode()
-
- walk_to(src,0)
- visible_message(span_boldannounce("[src] lets out a huge cough as it blows apart!"))
+ ..()
var/atom/Tsec = drop_location()
-
- var/obj/item/bot_assembly/secbot/Sa = new (Tsec)
- Sa.build_step = 1
- Sa.add_overlay("hs_hole")
- Sa.created_name = name
- new /obj/item/assembly/prox_sensor(Tsec)
-
- if(prob(50))
- drop_part(robot_arm, Tsec)
-
- do_sparks(3, TRUE, src)
- for(var/IS = 0 to 4)
+ //Parent is dropping the weapon, so let's drop 3 more to make up for it.
+ for(var/IS = 0 to 3)
drop_part(weapon, Tsec)
- new /obj/effect/decal/cleanable/oil(Tsec)
- qdel(src)
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index e257d29dd12..cb6541e4209 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -4,11 +4,12 @@
layer = MOB_LAYER
gender = NEUTER
mob_biotypes = MOB_ROBOTIC
- stop_automated_movement = 1
- wander = 0
- healable = 0
+ stop_automated_movement = TRUE
+ wander = FALSE
+ healable = FALSE
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_PATH_HUD = HUD_LIST_LIST)
maxbodytemp = INFINITY
minbodytemp = 0
has_unlimited_silicon_privilege = TRUE
@@ -22,85 +23,115 @@
initial_language_holder = /datum/language_holder/synthetic
bubble_icon = "machine"
speech_span = SPAN_ROBOT
- faction = list("neutral", "silicon" , "turret")
+ faction = list("neutral", "silicon", "turret")
light_system = MOVABLE_LIGHT
light_range = 3
light_power = 0.9
- 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
- var/window_width = 0 //0 for default size
- var/window_height = 0
- var/obj/item/paicard/paicard // Inserted pai card.
- ///If a pAI is allowed to be inserted into this bot.
- var/allow_pai = TRUE
- var/bot_name
+ ///Will other (noncommissioned) bots salute this bot?
+ var/commissioned = FALSE
+ ///Cooldown between salutations for commissioned bots
+ COOLDOWN_DECLARE(next_salute_check)
- var/list/player_access = list() //Additonal access the bots gets when player controlled
- var/emagged = FALSE
+ ///The core this bot uses, usually only used to set access? This is a hack and should be removed eventually.
+ var/obj/machinery/bot_core/bot_core = /obj/machinery/bot_core
+ ///The Robot arm attached to this robot - has a 50% chance to drop on death.
+ var/robot_arm = /obj/item/bodypart/r_arm/robot
+ ///People currently looking into a bot's UI panel.
+ var/list/users = list()
+ ///The inserted (if any) pAI in this bot.
+ var/obj/item/paicard/paicard
+ ///The type of bot it is, for radio control.
+ var/bot_type = NONE
+
+ ///Additonal access given to player-controlled bots.
+ var/list/player_access = list()
+ ///All initial access this bot started with.
var/list/prev_access = list()
- var/on = TRUE
- var/open = FALSE//Maint panel
- var/locked = TRUE
- ///If the bot is hacked by silicons or emagged by humans.
- var/hacked = FALSE
- var/text_hack = "" //Custom text returned to a silicon upon hacking a bot.
- var/text_dehack = "" //Text shown when resetting a bots hacked status to normal.
- var/text_dehack_fail = "" //Shown when a silicon tries to reset a bot emagged with the emag item, which cannot be reset.
- var/declare_message = "" //What the bot will display to the HUD user.
- var/frustration = 0 //Used by some bots for tracking failures to reach their target.
- var/base_speed = 2 //The speed at which the bot moves, or the number of times it moves per process() tick.
- var/turf/ai_waypoint //The end point of a bot's path, or the target location.
- var/list/path = list() //List of turfs through which a bot 'steps' to reach the waypoint, associated with the path image, if there is one.
- var/pathset = 0
- var/list/ignore_list = list() //List of unreachable targets for an ignore-list enabled bot to ignore.
- var/mode = BOT_IDLE //Standardizes the vars that indicate the bot is busy with its function.
- var/tries = 0 //Number of times the bot tried and failed to move.
- var/remote_disabled = FALSE //If enabled, the AI cannot *Remotely* control a bot. It can still control it through cameras.
- var/mob/living/silicon/ai/calling_ai //Links a bot to the AI calling it.
- var/obj/item/radio/Radio //The bot's radio, for speaking to people.
- var/radio_key = null //which channels can the bot listen to
- var/radio_channel = RADIO_CHANNEL_COMMON //The bot's default radio channel
- var/auto_patrol = 0// set to make bot automatically patrol
- var/turf/patrol_target // this is turf to navigate to (location of beacon)
- var/turf/summon_target // The turf of a user summoning a bot.
- var/new_destination // pending new destination (waiting for beacon response)
- var/destination // destination description tag
- var/next_destination // the next destination in the patrol route
- var/shuffle = FALSE // If we should shuffle our adjacency checking
- var/blockcount = 0 //number of times retried a blocked path
- var/awaiting_beacon = 0 // count of pticks awaiting a beacon response
+ ///Bot-related mode flags on the Bot indicating how they will act.
+ var/bot_mode_flags = BOT_MODE_ON | BOT_MODE_REMOTE_ENABLED | BOT_MODE_PAI_CONTROLLABLE
+// Selections: BOT_MODE_ON | BOT_MODE_AUTOPATROL | BOT_MODE_REMOTE_ENABLED | BOT_MODE_PAI_CONTROLLABLE
- var/nearest_beacon // the nearest beacon's tag
- var/turf/nearest_beacon_loc // the nearest beacon's location
+ ///Bot-related cover flags on the Bot to deal with what has been done to their cover, including emagging.
+ var/bot_cover_flags = BOT_COVER_LOCKED
+// Selections: BOT_COVER_OPEN | BOT_COVER_LOCKED | BOT_COVER_EMAGGED | BOT_COVER_HACKED
+
+ ///Small name of what the bot gets messed with when getting hacked/emagged.
+ var/hackables = "system circuits"
+ ///Used by some bots for tracking failures to reach their target.
+ var/frustration = 0
+ ///The speed at which the bot moves, or the number of times it moves per process() tick.
+ var/base_speed = 2
+ ///The end point of a bot's path, or the target location.
+ var/turf/ai_waypoint
+ ///The bot is on a custom set path.
+ var/pathset = FALSE
+ ///List of turfs through which a bot 'steps' to reach the waypoint, associated with the path image, if there is one.
+ var/list/path = list()
+ ///List of unreachable targets for an ignore-list enabled bot to ignore.
+ var/list/ignore_list = list()
+ ///Standardizes the vars that indicate the bot is busy with its function.
+ var/mode = BOT_IDLE
+ ///Number of times the bot tried and failed to move.
+ var/tries = 0
+ ///Links a bot to the AI calling it.
+ var/mob/living/silicon/ai/calling_ai
+ ///The bot's radio, for speaking to people.
+ var/obj/item/radio/internal_radio
+ ///which channels can the bot listen to
+ var/radio_key = null
+ ///The bot's default radio channel
+ var/radio_channel = RADIO_CHANNEL_COMMON
+ ///Turf a bot is summoned to navitage towards.
+ var/turf/patrol_target
+ ///Turf of a user summoning a bot towards their location.
+ var/turf/summon_target
+ ///Pending new destination (waiting for beacon response)
+ var/new_destination
+ ///Destination description tag
+ var/destination
+ ///The next destination in the patrol route
+ var/next_destination
+ ///If we should shuffle our adjacency checking
+ var/shuffle = FALSE
+
+ /// the nearest beacon's tag
+ var/nearest_beacon
+ ///The nearest beacon's location
+ var/turf/nearest_beacon_loc
var/beacon_freq = FREQ_NAV_BEACON
- var/model = "" //The type of bot it is.
- var/bot_type = NONE //The type of bot it is, for radio control.
- var/data_hud_type = DATA_HUD_DIAGNOSTIC_BASIC //The type of data HUD the bot uses. Diagnostic by default.
- //This holds text for what the bot is mode doing, reported on the remote bot control interface. This is in order of the defines for the mode defines in robots.dm, in order
- var/list/mode_name = list("In Pursuit","Preparing to Arrest", "Arresting", \
- "Beginning Patrol", "Patrolling", "Summoned by PDA", \
- "Cleaning", "Repairing", "Proceeding to work site", "Healing", \
- "Proceeding to AI waypoint", "Navigating to Delivery Location", "Navigating to Home", \
- "Waiting for clear path", "Calculating navigation path", "Pinging beacon network", "Unable to reach destination", "Chasing filth", "No route")
+ ///The type of data HUD the bot uses. Diagnostic by default.
+ var/data_hud_type = DATA_HUD_DIAGNOSTIC_BASIC
+ //This holds text for what the bot is mode doing, reported on the remote bot control interface.
+ var/list/mode_name = list(
+ "In Pursuit",
+ "Preparing to Arrest",
+ "Arresting",
+ "Beginning Patrol",
+ "Patrolling",
+ "Summoned by PDA",
+ "Cleaning",
+ "Repairing",
+ "Proceeding to work site",
+ "Healing",
+ "Proceeding to AI waypoint",
+ "Navigating to Delivery Location",
+ "Navigating to Home",
+ "Waiting for clear path",
+ "Calculating navigation path",
+ "Pinging beacon network",
+ "Unable to reach destination",
+ "Chasing filth",
+ "No Route",
+ )
var/datum/atom_hud/data/bot_path/path_hud = new /datum/atom_hud/data/bot_path()
var/path_image_icon = 'icons/mob/aibots.dmi'
var/path_image_icon_state = "path_indicator"
var/path_image_color = "#FFFFFF"
var/reset_access_timer_id
var/ignorelistcleanuptimer = 1 // This ticks up every automated action, at 300 we clean the ignore list
- var/robot_arm = /obj/item/bodypart/r_arm/robot
-
- var/commissioned = FALSE // Will other (noncommissioned) bots salute this bot?
- COOLDOWN_DECLARE(next_salute_check)
- var/salute_delay = 60 SECONDS
-
- hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD, DIAG_PATH_HUD = HUD_LIST_LIST) //Diagnostic HUD views
/mob/living/simple_animal/bot/proc/get_mode()
if(client) //Player bots do not have modes, thus the override. Also an easy way for PDA users/AI to know when a bot is a player.
@@ -108,7 +139,7 @@
return "pAI Controlled"
else
return "Autonomous"
- else if(!on)
+ else if(!(bot_mode_flags & BOT_MODE_ON))
return "Inactive"
else if(!mode)
return "Idle"
@@ -121,7 +152,7 @@
/mob/living/simple_animal/bot/proc/get_mode_ui()
if(client) //Player bots do not have modes, thus the override. Also an easy way for PDA users/AI to know when a bot is a player.
return paicard ? "pAI Controlled" : "Autonomous"
- else if(!on)
+ else if(!(bot_mode_flags & BOT_MODE_ON))
return "Inactive"
else if(!mode)
return "Idle"
@@ -131,26 +162,31 @@
/mob/living/simple_animal/bot/proc/turn_on()
if(stat)
return FALSE
- on = TRUE
+ bot_mode_flags |= BOT_MODE_ON
REMOVE_TRAIT(src, TRAIT_INCAPACITATED, POWER_LACK_TRAIT)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, POWER_LACK_TRAIT)
REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, POWER_LACK_TRAIT)
- set_light_on(on)
+ set_light_on(bot_mode_flags & BOT_MODE_ON ? TRUE : FALSE)
update_appearance()
- to_chat(src, span_boldnotice("You turned on!"))
+ balloon_alert(src, "turned on")
diag_hud_set_botstat()
return TRUE
/mob/living/simple_animal/bot/proc/turn_off()
- on = FALSE
+ bot_mode_flags &= ~BOT_MODE_ON
ADD_TRAIT(src, TRAIT_INCAPACITATED, POWER_LACK_TRAIT)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, POWER_LACK_TRAIT)
ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, POWER_LACK_TRAIT)
- set_light_on(on)
+ set_light_on(bot_mode_flags & BOT_MODE_ON ? TRUE : FALSE)
bot_reset() //Resets an AI's call, should it exist.
- to_chat(src, span_userdanger("You turned off!"))
+ balloon_alert(src, "turned off")
update_appearance()
+/mob/living/simple_animal/bot/proc/get_bot_flag(checked_flag)
+ if(bot_mode_flags & checked_flag)
+ return TRUE
+ return FALSE
+
/mob/living/simple_animal/bot/Initialize(mapload)
. = ..()
GLOB.bots_list += src
@@ -158,15 +194,14 @@
access_card = new /obj/item/card/id/advanced/simple_bot(src)
// This access is so bots can be immediately set to patrol and leave Robotics, instead of having to be let out first.
access_card.set_access(list(ACCESS_ROBOTICS))
- set_custom_texts()
- Radio = new/obj/item/radio(src)
+ internal_radio = new/obj/item/radio(src)
if(radio_key)
- Radio.keyslot = new radio_key
- Radio.subspace_transmission = TRUE
- Radio.canhear_range = 0 // anything greater will have the bot broadcast the channel as if it were saying it out loud.
- Radio.recalculateChannels()
+ internal_radio.keyslot = new radio_key
+ internal_radio.subspace_transmission = TRUE
+ internal_radio.canhear_range = 0 // anything greater will have the bot broadcast the channel as if it were saying it out loud.
+ internal_radio.recalculateChannels()
- bot_core = new bot_core_type(src)
+ bot_core = new(src)
//Adds bot to the diagnostic HUD system
prepare_huds()
@@ -192,7 +227,7 @@
GLOB.bots_list -= src
if(paicard)
ejectpai()
- QDEL_NULL(Radio)
+ QDEL_NULL(internal_radio)
QDEL_NULL(access_card)
QDEL_NULL(bot_core)
return ..()
@@ -206,16 +241,20 @@
/mob/living/simple_animal/bot/proc/explode()
qdel(src)
+ var/atom/location_destroyed = drop_location()
+ if(prob(50))
+ drop_part(robot_arm, location_destroyed)
-/mob/living/simple_animal/bot/emag_act(mob/user)
- if(locked) //First emag application unlocks the bot's interface. Apply a screwdriver to use the emag again.
- locked = FALSE
- to_chat(user, span_notice("You bypass [src]'s controls."))
+/mob/living/simple_animal/bot/emag_act(mob/user, obj/item/card/emag/emag_card)
+ . = ..()
+ if(bot_cover_flags & BOT_COVER_LOCKED) //First emag application unlocks the bot's interface. Apply a screwdriver to use the emag again.
+ bot_cover_flags &= ~BOT_COVER_LOCKED
+ to_chat(user, span_notice("You bypass [src]'s [hackables]."))
return
- if(!locked && open) //Bot panel is unlocked by ID or emag, and the panel is screwed open. Ready for emagging.
- emagged = TRUE
- remote_disabled = TRUE //Manually emagging the bot locks out the AI built in panel.
- locked = TRUE //Access denied forever!
+ if(!(bot_cover_flags & BOT_COVER_LOCKED) && bot_cover_flags & BOT_COVER_OPEN) //Bot panel is unlocked by ID or emag, and the panel is screwed open. Ready for emagging.
+ bot_cover_flags |= BOT_COVER_EMAGGED
+ bot_cover_flags &= ~BOT_COVER_LOCKED //Manually emagging the bot locks out the panel.
+ bot_mode_flags &= ~BOT_MODE_REMOTE_ENABLED //Manually emagging the bot also locks the AI from controlling it.
bot_reset()
turn_on() //The bot automatically turns on when emagged, unless recently hit with EMP.
to_chat(src, span_userdanger("(#$*#$^^( OVERRIDE DETECTED"))
@@ -234,20 +273,20 @@
. += "[src]'s parts look very loose!"
else
. += "[src] is in pristine condition."
- . += span_notice("Its maintenance panel is [open ? "open" : "closed"].")
- . += span_info("You can use a screwdriver to [open ? "close" : "open"] it.")
- if(open)
- . += span_notice("Its control panel is [locked ? "locked" : "unlocked"].")
+ . += span_notice("Its maintenance panel is [bot_cover_flags & BOT_COVER_OPEN ? "open" : "closed"].")
+ . += span_info("You can use a screwdriver to [bot_cover_flags & BOT_COVER_OPEN ? "close" : "open"] it.")
+ if(bot_cover_flags & BOT_COVER_OPEN)
+ . += span_notice("Its control panel is [bot_cover_flags & BOT_COVER_LOCKED ? "locked" : "unlocked"].")
var/is_sillycone = issilicon(user)
- if(!emagged && (is_sillycone || user.Adjacent(src)))
- . += span_info("Alt-click [is_sillycone ? "" : "or use your ID on "]it to [locked ? "un" : ""]lock its control panel.")
+ if(!(bot_cover_flags & BOT_COVER_EMAGGED) && (is_sillycone || user.Adjacent(src)))
+ . += span_info("Alt-click [is_sillycone ? "" : "or use your ID on "]it to [bot_cover_flags & BOT_COVER_LOCKED ? "un" : ""]lock its control panel.")
if(paicard)
. += span_notice("It has a pAI device installed.")
- if(!open)
+ if(!(bot_cover_flags & BOT_COVER_OPEN))
. += span_info("You can use a hemostat to remove it.")
/mob/living/simple_animal/bot/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
- if(amount>0 && prob(10))
+ if(amount > 0 && prob(10))
new /obj/effect/decal/cleanable/oil(loc)
. = ..()
@@ -273,13 +312,13 @@
else
ignorelistcleanuptimer++
- if(!on || client)
+ if(!(bot_mode_flags & BOT_MODE_ON) || client)
return FALSE
if(commissioned && COOLDOWN_FINISHED(src, next_salute_check))
- COOLDOWN_START(src, next_salute_check, salute_delay)
+ COOLDOWN_START(src, next_salute_check, BOT_COMMISSIONED_SALUTE_DELAY)
for(var/mob/living/simple_animal/bot/B in view(5, src))
- if(!B.commissioned && B.on)
+ if(!B.commissioned && B.bot_mode_flags & BOT_MODE_ON)
visible_message("[B] performs an elaborate salute for [src]!")
break
@@ -320,24 +359,24 @@
unlock_with_id(user)
/mob/living/simple_animal/bot/proc/unlock_with_id(mob/user)
- if(emagged)
+ if(bot_cover_flags & BOT_COVER_EMAGGED)
to_chat(user, span_danger("ERROR"))
return
- if(open)
- to_chat(user, span_warning("Please close the access panel before [locked ? "un" : ""]locking it."))
+ if(bot_cover_flags & BOT_COVER_OPEN)
+ to_chat(user, span_warning("Please close the access panel before [bot_cover_flags & BOT_COVER_LOCKED ? "un" : ""]locking it."))
return
if(!bot_core.allowed(user))
to_chat(user, span_warning("Access denied."))
return
- locked = !locked
- to_chat(user, span_notice("Controls are now [locked ? "locked" : "unlocked"]."))
+ bot_cover_flags ^= BOT_COVER_LOCKED
+ to_chat(user, span_notice("Controls are now [bot_cover_flags & BOT_COVER_LOCKED ? "locked" : "unlocked"]."))
return TRUE
/mob/living/simple_animal/bot/attackby(obj/item/attacking_item, mob/living/user, params)
if(attacking_item.tool_behaviour == TOOL_SCREWDRIVER)
- if(!locked)
- open = !open
- to_chat(user, span_notice("The maintenance panel is now [open ? "opened" : "closed"]."))
+ if(!(bot_cover_flags & BOT_COVER_LOCKED))
+ bot_cover_flags ^= BOT_COVER_OPEN
+ to_chat(user, span_notice("The maintenance panel is now [bot_cover_flags & BOT_COVER_OPEN ? "opened" : "closed"]."))
else
to_chat(user, span_warning("The maintenance panel is locked!"))
else if(attacking_item.GetID())
@@ -345,13 +384,13 @@
else if(istype(attacking_item, /obj/item/paicard))
insertpai(user, attacking_item)
else if(attacking_item.tool_behaviour == TOOL_HEMOSTAT && paicard)
- if(open)
+ if(bot_cover_flags & BOT_COVER_OPEN)
to_chat(user, span_warning("Close the access panel before manipulating the personality slot!"))
else
to_chat(user, span_notice("You attempt to pull [paicard] free..."))
if(do_after(user, 30, target = src))
if (paicard)
- user.visible_message(span_notice("[user] uses [attacking_item] to pull [paicard] out of [bot_name]!"),span_notice("You pull [paicard] out of [bot_name] with [attacking_item]."))
+ user.visible_message(span_notice("[user] uses [attacking_item] to pull [paicard] out of [initial(src.name)]!"),span_notice("You pull [paicard] out of [initial(src.name)] with [attacking_item]."))
ejectpai(user)
else
user.changeNext_move(CLICK_CD_MELEE)
@@ -359,7 +398,7 @@
if(health >= maxHealth)
to_chat(user, span_warning("[src] does not need a repair!"))
return
- if(!open)
+ if(!(bot_cover_flags & BOT_COVER_OPEN))
to_chat(user, span_warning("Unable to repair with the maintenance panel closed!"))
return
@@ -381,32 +420,27 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- var/was_on = on
+ var/was_on = bot_mode_flags & BOT_MODE_ON ? TRUE : FALSE
stat |= EMPED
new /obj/effect/temp_visual/emp(loc)
if(paicard)
paicard.emp_act(severity)
- src.visible_message(span_notice("[paicard] is flies out of [bot_name]!"),span_warning("You are forcefully ejected from [bot_name]!"))
+ src.visible_message(span_notice("[paicard] is flies out of [initial(src.name)]!"), span_warning("You are forcefully ejected from [initial(src.name)]!"))
ejectpai(0)
- if(on)
+ if(bot_mode_flags & BOT_MODE_ON)
turn_off()
- addtimer(CALLBACK(src, .proc/emp_reset, was_on), severity*30 SECONDS)
+ addtimer(CALLBACK(src, .proc/emp_reset, was_on), severity * 30 SECONDS)
/mob/living/simple_animal/bot/proc/emp_reset(was_on)
stat &= ~EMPED
if(was_on)
turn_on()
-/mob/living/simple_animal/bot/proc/set_custom_texts() //Superclass for setting hack texts. Appears only if a set is not given to a bot locally.
- text_hack = "You hack [name]."
- text_dehack = "You reset [name]."
- text_dehack_fail = "You fail to reset [name]."
-
/mob/living/simple_animal/bot/proc/speak(message,channel) //Pass a message to have the bot say() it. Pass a frequency to say it on the radio.
- if((!on) || (!message))
+ if((!(bot_mode_flags & BOT_MODE_ON)) || (!message))
return
- if(channel && Radio.channels[channel])// Use radio if we have channel key
- Radio.talk_into(src, message, channel)
+ if(channel && internal_radio.channels[channel])// Use radio if we have channel key
+ internal_radio.talk_into(src, message, channel)
else
say(message)
@@ -416,34 +450,32 @@
return
if(message_mods[MODE_HEADSET])
- Radio.talk_into(src, message, , spans, language, message_mods)
+ internal_radio.talk_into(src, message, , spans, language, message_mods)
return REDUCE_RANGE
else if(message_mods[RADIO_EXTENSION] == MODE_DEPARTMENT)
- Radio.talk_into(src, message, message_mods[RADIO_EXTENSION], spans, language, message_mods)
+ internal_radio.talk_into(src, message, message_mods[RADIO_EXTENSION], spans, language, message_mods)
return REDUCE_RANGE
else if(message_mods[RADIO_EXTENSION] in GLOB.radiochannels)
- Radio.talk_into(src, message, message_mods[RADIO_EXTENSION], spans, language, message_mods)
+ internal_radio.talk_into(src, message, message_mods[RADIO_EXTENSION], spans, language, message_mods)
return REDUCE_RANGE
/mob/living/simple_animal/bot/proc/drop_part(obj/item/drop_item, dropzone)
- var/obj/item/dropped_item
if(ispath(drop_item))
- dropped_item = new drop_item(dropzone)
+ new drop_item(dropzone)
else
- dropped_item = drop_item
- dropped_item.forceMove(dropzone)
+ drop_item.forceMove(dropzone)
- if(istype(dropped_item, /obj/item/stock_parts/cell))
- var/obj/item/stock_parts/cell/dropped_cell = dropped_item
+ if(istype(drop_item, /obj/item/stock_parts/cell))
+ var/obj/item/stock_parts/cell/dropped_cell = drop_item
dropped_cell.charge = 0
dropped_cell.update_appearance()
- else if(istype(dropped_item, /obj/item/storage))
- var/obj/item/storage/S = dropped_item
+ else if(istype(drop_item, /obj/item/storage))
+ var/obj/item/storage/S = drop_item
S.contents = list()
- else if(istype(dropped_item, /obj/item/gun/energy))
- var/obj/item/gun/energy/dropped_gun = dropped_item
+ else if(istype(drop_item, /obj/item/gun/energy))
+ var/obj/item/gun/energy/dropped_gun = drop_item
dropped_gun.cell.charge = 0
dropped_gun.update_appearance()
@@ -488,7 +520,7 @@ Pass the desired type path itself, declaring a temporary var beforehand is not r
/mob/living/simple_animal/bot/proc/checkscan(scan, scan_type, old_target)
if(!istype(scan, scan_type)) //Check that the thing we found is the type we want!
return FALSE //If not, keep searching!
- if( (REF(scan) in ignore_list) || (scan == old_target) ) //Filter for blacklisted elements, usually unreachable or previously processed oness
+ if((REF(scan) in ignore_list) || (scan == old_target)) //Filter for blacklisted elements, usually unreachable or previously processed oness
return FALSE
var/scan_result = process_scan(scan) //Some bots may require additional processing when a result is selected.
@@ -562,19 +594,19 @@ Pass a positive integer as an argument to override a bot's default speed.
if(mode != BOT_SUMMON && mode != BOT_RESPONDING)
access_card.set_access(prev_access)
-/mob/living/simple_animal/bot/proc/call_bot(caller, turf/waypoint, message=TRUE)
+/mob/living/simple_animal/bot/proc/call_bot(caller, turf/waypoint, message = TRUE)
bot_reset() //Reset a bot before setting it to call mode.
//For giving the bot temporary all-access. This method is bad and makes me feel bad. Refactoring access to a component is for another PR.
var/obj/item/card/id/all_access = new /obj/item/card/id/advanced/gold/captains_spare()
- set_path(get_path_to(src, waypoint, 200, id=all_access))
+ set_path(get_path_to(src, waypoint, 200, id = all_access))
qdel(all_access)
calling_ai = caller //Link the AI to the bot!
ai_waypoint = waypoint
if(path?.len) //Ensures that a valid path is calculated!
var/end_area = get_area_name(waypoint)
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
turn_on() //Saves the AI the hassle of having to activate a bot manually.
access_card.set_access(REGION_ACCESS_ALL_STATION) //Give the bot all-access while under the AI's command.
if(client)
@@ -582,7 +614,7 @@ Pass a positive integer as an argument to override a bot's default speed.
to_chat(src, span_notice("[span_big("Priority waypoint set by [icon2html(calling_ai, src)] [caller]. Proceed to [end_area].")]
[path.len-1] meters to destination. You have been granted additional door access for 60 seconds."))
if(message)
to_chat(calling_ai, span_notice("[icon2html(src, calling_ai)] [name] called to [end_area]. [path.len-1] meters to destination."))
- pathset = 1
+ pathset = TRUE
mode = BOT_RESPONDING
tries = 0
else
@@ -609,7 +641,7 @@ Pass a positive integer as an argument to override a bot's default speed.
reset_access_timer_id = null
set_path(null)
summon_target = null
- pathset = 0
+ pathset = FALSE
access_card.set_access(prev_access)
tries = 0
mode = BOT_IDLE
@@ -634,13 +666,13 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/start_patrol()
if(tries >= BOT_STEP_MAX_RETRIES) //Bot is trapped, so stop trying to patrol.
- auto_patrol = 0
+ bot_mode_flags &= ~BOT_MODE_AUTOPATROL
tries = 0
speak("Unable to start patrol.")
return
- if(!auto_patrol) //A bot not set to patrol should not be patrolling.
+ if(!(bot_mode_flags & BOT_MODE_AUTOPATROL)) //A bot not set to patrol should not be patrolling.
mode = BOT_IDLE
return
@@ -699,7 +731,7 @@ Pass a positive integer as an argument to override a bot's default speed.
patrol_target = nearest_beacon_loc
destination = next_destination
else
- auto_patrol = FALSE
+ bot_mode_flags &= ~BOT_MODE_AUTOPATROL
mode = BOT_IDLE
speak("Disengaging patrol mode.")
@@ -731,7 +763,7 @@ Pass a positive integer as an argument to override a bot's default speed.
//PDA control. Some bots, especially MULEs, may have more parameters.
/mob/living/simple_animal/bot/proc/bot_control(command, mob/user, list/user_access = list())
- if(!on || emagged || remote_disabled) //Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands.
+ if(!(bot_mode_flags & BOT_MODE_ON) || bot_cover_flags & BOT_COVER_EMAGGED || !(bot_mode_flags & BOT_MODE_REMOTE_ENABLED)) //Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands.
return TRUE //ACCESS DENIED
if(client)
bot_control_message(command, user)
@@ -739,10 +771,10 @@ Pass a positive integer as an argument to override a bot's default speed.
switch(command)
if("patroloff")
bot_reset() //HOLD IT!! //OBJECTION!!
- auto_patrol = FALSE
+ bot_mode_flags &= ~BOT_MODE_AUTOPATROL
if("patrolon")
- auto_patrol = TRUE
+ bot_mode_flags |= BOT_MODE_AUTOPATROL
if("summon")
bot_reset()
@@ -832,22 +864,21 @@ Pass a positive integer as an argument to override a bot's default speed.
D.open()
frustration = 0
-// Variables sent to TGUI
/mob/living/simple_animal/bot/ui_data(mob/user)
var/list/data = list()
data["can_hack"] = (issilicon(user) || isAdminGhostAI(user))
data["custom_controls"] = list()
- data["emagged"] = emagged
- data["locked"] = locked
+ data["emagged"] = bot_cover_flags & BOT_COVER_EMAGGED
+ data["locked"] = bot_cover_flags & BOT_COVER_LOCKED
data["pai"] = list()
data["settings"] = list()
- if(!locked || issilicon(user) || isAdminGhostAI(user))
- data["pai"]["allow_pai"] = allow_pai
+ if(!(bot_cover_flags & BOT_COVER_LOCKED) || issilicon(user) || isAdminGhostAI(user))
+ data["pai"]["allow_pai"] = bot_mode_flags & BOT_MODE_PAI_CONTROLLABLE
data["pai"]["card_inserted"] = paicard
- data["settings"]["airplane_mode"] = remote_disabled
- data["settings"]["maintenance_lock"] = !open
- data["settings"]["power"] = on
- data["settings"]["patrol_station"] = auto_patrol
+ data["settings"]["airplane_mode"] = !(bot_mode_flags & BOT_MODE_REMOTE_ENABLED)
+ data["settings"]["maintenance_lock"] = !(bot_cover_flags & BOT_COVER_OPEN)
+ data["settings"]["power"] = bot_mode_flags & BOT_MODE_ON
+ data["settings"]["patrol_station"] = bot_mode_flags & BOT_MODE_AUTOPATROL
return data
// Actions received from TGUI
@@ -859,49 +890,46 @@ Pass a positive integer as an argument to override a bot's default speed.
to_chat(usr, span_warning("Access denied."))
return
if(action == "lock")
- locked = !locked
- if(locked && !(issilicon(usr) || isAdminGhostAI(usr)))
+ bot_cover_flags ^= BOT_COVER_LOCKED
+ if(bot_cover_flags & BOT_COVER_LOCKED && !(issilicon(usr) || isAdminGhostAI(usr)))
return
switch(action)
if("power")
- on = !on
- update_appearance()
+ if(bot_mode_flags & BOT_MODE_ON)
+ turn_off()
+ else
+ turn_on()
if("maintenance")
- open = !open
+ bot_cover_flags ^= BOT_COVER_OPEN
if("patrol")
- auto_patrol = !auto_patrol
+ bot_mode_flags ^= BOT_MODE_AUTOPATROL
bot_reset()
if("airplane")
- remote_disabled = !remote_disabled
+ bot_mode_flags ^= BOT_MODE_REMOTE_ENABLED
if("hack")
if(!(issilicon(usr) || isAdminGhostAI(usr)))
return
- if(!emagged)
- emagged = TRUE
- hacked = TRUE
- locked = TRUE
- to_chat(usr, span_warning("[text_hack]"))
+ if(!(bot_cover_flags & BOT_COVER_EMAGGED))
+ bot_cover_flags |= (BOT_COVER_EMAGGED|BOT_COVER_HACKED|BOT_COVER_LOCKED)
+ to_chat(usr, span_warning("You overload [src]'s [hackables]."))
message_admins("Safety lock of [ADMIN_LOOKUPFLW(src)] was disabled by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_VERBOSEJMP(src)]")
log_game("Safety lock of [src] was disabled by [key_name(usr)] in [AREACOORD(src)]")
bot_reset()
- else if(!hacked)
- to_chat(usr, span_boldannounce("[text_dehack_fail]"))
+ else if(!(bot_cover_flags & BOT_COVER_HACKED))
+ to_chat(usr, span_boldannounce("You fail to repair [src]'s [hackables]."))
else
- emagged = FALSE
- hacked = FALSE
- to_chat(usr, span_notice("[text_dehack]"))
+ bot_cover_flags &= ~(BOT_COVER_EMAGGED|BOT_COVER_HACKED)
+ to_chat(usr, span_notice("You reset the [src]'s [hackables]."))
log_game("Safety lock of [src] was re-enabled by [key_name(usr)] in [AREACOORD(src)]")
bot_reset()
if("eject_pai")
- if(locked && !(issilicon(usr) || isAdminGhostAI(usr)))
- return
if(paicard)
- to_chat(usr, span_notice("You eject [paicard] from [bot_name]."))
+ to_chat(usr, span_notice("You eject [paicard] from [initial(src.name)]."))
ejectpai(usr)
return
/mob/living/simple_animal/bot/update_icon_state()
- icon_state = "[initial(icon_state)][on]"
+ icon_state = "[initial(icon_state)][get_bot_flag(BOT_MODE_ON)]"
return ..()
// Machinery to simplify topic and access calls
@@ -918,8 +946,8 @@ Pass a positive integer as an argument to override a bot's default speed.
if(!user.canUseTopic(src, !issilicon(user)))
return TRUE
// 0 for access, 1 for denied.
- if(emagged) //An emagged bot cannot be controlled by humans, silicons can if one hacked it.
- if(!hacked) //Manually emagged by a human - access denied to all.
+ if(bot_cover_flags & BOT_COVER_EMAGGED) //An emagged bot cannot be controlled by humans, silicons can if one hacked it.
+ if(!(bot_cover_flags & BOT_COVER_HACKED)) //Manually emagged by a human - access denied to all.
return TRUE
else if(!issilicon(user) && !isAdminGhostAI(user)) //Bot is hacked, so only silicons and admins are allowed access.
return TRUE
@@ -928,28 +956,28 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/insertpai(mob/user, obj/item/paicard/card)
if(paicard)
to_chat(user, span_warning("A [paicard] is already inserted!"))
- else if(allow_pai && !key)
- if(!locked && !open)
- if(card.pai && card.pai.mind)
- if(!user.transferItemToLoc(card, src))
- return
- paicard = card
- user.visible_message(span_notice("[user] inserts [card] into [src]!"), span_notice("You insert [card] into [src]."))
- paicard.pai.mind.transfer_to(src)
- to_chat(src, span_notice("You sense your form change as you are uploaded into [src]."))
- bot_name = name
- name = paicard.pai.name
- faction = user.faction.Copy()
- log_combat(user, paicard.pai, "uploaded to [bot_name],")
- return TRUE
- else
- to_chat(user, span_warning("[card] is inactive."))
- else
- to_chat(user, span_warning("The personality slot is locked."))
- else
+ return
+ if(!(bot_mode_flags & BOT_MODE_PAI_CONTROLLABLE) || !key)
to_chat(user, span_warning("[src] is not compatible with [card]!"))
+ return
+ if(bot_cover_flags & BOT_COVER_LOCKED || !(bot_cover_flags & BOT_COVER_OPEN))
+ to_chat(user, span_warning("The personality slot is locked."))
+ return
+ if(!card.pai || !card.pai.mind)
+ to_chat(user, span_warning("[card] is inactive."))
+ return
+ if(!user.transferItemToLoc(card, src))
+ return
+ paicard = card
+ user.visible_message(span_notice("[user] inserts [card] into [src]!"), span_notice("You insert [card] into [src]."))
+ paicard.pai.mind.transfer_to(src)
+ to_chat(src, span_notice("You sense your form change as you are uploaded into [src]."))
+ name = paicard.pai.name
+ faction = user.faction.Copy()
+ log_combat(user, paicard.pai, "uploaded to [initial(src.name)],")
+ return TRUE
-/mob/living/simple_animal/bot/proc/ejectpai(mob/user = null, announce = 1)
+/mob/living/simple_animal/bot/proc/ejectpai(mob/user = null, announce = TRUE)
if(paicard)
if(mind && paicard.pai)
mind.transfer_to(paicard.pai)
@@ -960,13 +988,13 @@ Pass a positive integer as an argument to override a bot's default speed.
key = null
paicard.forceMove(loc)
if(user)
- log_combat(user, paicard.pai, "ejected from [src.bot_name],")
+ log_combat(user, paicard.pai, "ejected from [initial(src.name)],")
else
log_combat(src, paicard.pai, "ejected")
if(announce)
- to_chat(paicard.pai, span_notice("You feel your control fade as [paicard] ejects from [bot_name]."))
+ to_chat(paicard.pai, span_notice("You feel your control fade as [paicard] ejects from [initial(src.name)]."))
paicard = null
- name = bot_name
+ name = initial(src.name)
faction = initial(faction)
/mob/living/simple_animal/bot/proc/ejectpairemote(mob/user)
@@ -994,7 +1022,7 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/ghost()
if(stat != DEAD) // Only ghost if we're doing this while alive, the pAI probably isn't dead yet.
- ..()
+ return ..()
if(paicard && (!client || stat == DEAD))
ejectpai(0)
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index 0ff3f293da2..c53277b8299 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -4,18 +4,17 @@
desc = "A little cleaning robot, he looks so excited!"
icon = 'icons/mob/aibots.dmi'
icon_state = "cleanbot0"
+ pass_flags = PASSMOB | PASSFLAPS
density = FALSE
anchored = FALSE
health = 25
maxHealth = 25
+
+ bot_core = /obj/machinery/bot_core/cleanbot
radio_key = /obj/item/encryptionkey/headset_service
radio_channel = RADIO_CHANNEL_SERVICE //Service
bot_type = CLEAN_BOT
- model = "Cleanbot"
- bot_core_type = /obj/machinery/bot_core/cleanbot
- window_id = "autoclean"
- window_name = "Automatic Station Cleaner v1.4"
- pass_flags = PASSMOB | PASSFLAPS
+ hackables = "cleaning software"
path_image_color = "#993299"
var/blood = 1
@@ -52,6 +51,13 @@
var/ascended = FALSE // if we have all the top titles, grant achievements to living mobs that gaze upon our cleanbot god
+/mob/living/simple_animal/bot/cleanbot/autopatrol
+ bot_mode_flags = BOT_MODE_ON | BOT_MODE_AUTOPATROL | BOT_MODE_REMOTE_ENABLED | BOT_MODE_PAI_CONTROLLABLE
+
+/mob/living/simple_animal/bot/cleanbot/medbay
+ name = "Scrubs, MD"
+ bot_core = /obj/machinery/bot_core/cleanbot/medbay
+ bot_mode_flags = ~(BOT_MODE_ON | BOT_MODE_REMOTE_ENABLED)
/mob/living/simple_animal/bot/cleanbot/proc/deputize(obj/item/W, mob/user)
if(in_range(src, user))
@@ -59,7 +65,7 @@
user.transferItemToLoc(W, src)
weapon = W
weapon_orig_force = weapon.force
- if(!emagged)
+ if(!(bot_cover_flags & BOT_COVER_EMAGGED))
weapon.force = weapon.force / 2
add_overlay(image(icon=weapon.lefthand_file,icon_state=weapon.inhand_icon_state))
@@ -103,7 +109,7 @@
chosen_name = name
get_targets()
- icon_state = "cleanbot[on]"
+ icon_state = "cleanbot[get_bot_flag(BOT_MODE_ON)]"
// Doing this hurts my soul, but simplebot access reworks are for another day.
var/datum/id_trim/job/jani_trim = SSid_access.trim_singletons_by_path[/datum/id_trim/job/janitor]
@@ -127,27 +133,22 @@
/mob/living/simple_animal/bot/cleanbot/turn_on()
..()
- icon_state = "cleanbot[on]"
+ icon_state = "cleanbot[get_bot_flag(BOT_MODE_ON)]"
bot_core.updateUsrDialog()
/mob/living/simple_animal/bot/cleanbot/turn_off()
..()
- icon_state = "cleanbot[on]"
+ icon_state = "cleanbot[get_bot_flag(BOT_MODE_ON)]"
bot_core.updateUsrDialog()
/mob/living/simple_animal/bot/cleanbot/bot_reset()
..()
- if(weapon && emagged)
+ if(weapon && bot_cover_flags & BOT_COVER_EMAGGED)
weapon.force = weapon_orig_force
ignore_list = list() //Allows the bot to clean targets it previously ignored due to being unreachable.
target = null
oldloc = null
-/mob/living/simple_animal/bot/cleanbot/set_custom_texts()
- text_hack = "You corrupt [name]'s cleaning software."
- text_dehack = "[name]'s software has been reset!"
- text_dehack_fail = "[name] does not seem to respond to your repair code!"
-
/mob/living/simple_animal/bot/cleanbot/proc/on_entered(datum/source, atom/movable/AM)
SIGNAL_HANDLER
@@ -166,13 +167,13 @@
/mob/living/simple_animal/bot/cleanbot/attackby(obj/item/W, mob/living/user, params)
if(W.GetID())
- if(bot_core.allowed(user) && !open && !emagged)
- locked = !locked
- to_chat(user, span_notice("You [ locked ? "lock" : "unlock"] \the [src] behaviour controls."))
+ if(bot_core.allowed(user) && !(bot_cover_flags & BOT_COVER_OPEN) && !(bot_cover_flags & BOT_COVER_EMAGGED))
+ bot_cover_flags ^= BOT_COVER_LOCKED
+ to_chat(user, span_notice("You [bot_cover_flags & BOT_COVER_LOCKED ? "lock" : "unlock"] \the [src] behaviour controls."))
else
- if(emagged)
+ if(bot_cover_flags & BOT_COVER_EMAGGED)
to_chat(user, span_warning("ERROR"))
- if(open)
+ if(bot_cover_flags & BOT_COVER_OPEN)
to_chat(user, span_warning("Please close the access panel before locking it."))
else
to_chat(user, span_notice("\The [src] doesn't seem to respect your authority."))
@@ -186,7 +187,7 @@
/mob/living/simple_animal/bot/cleanbot/emag_act(mob/user)
..()
- if(!emagged)
+ if(!(bot_cover_flags & BOT_COVER_EMAGGED))
return
if(weapon)
weapon.force = weapon_orig_force
@@ -208,7 +209,7 @@
if(mode == BOT_CLEANING)
return
- if(emagged) //Emag functions
+ if(bot_cover_flags & BOT_COVER_EMAGGED) //Emag functions
if(isopenturf(loc))
for(var/mob/living/carbon/victim in loc)
if(victim != target)
@@ -226,7 +227,7 @@
if(!process_scan(target))
target = null
- if(!target && emagged) // When emagged, target humans who slipped on the water and melt their faces off
+ if(!target && bot_cover_flags & BOT_COVER_EMAGGED) // When emagged, target humans who slipped on the water and melt their faces off
target = scan(/mob/living/carbon)
if(!target && pests) //Search for pests to exterminate first.
@@ -244,7 +245,7 @@
if(!target && trash) //Search for dead mices.
target = scan(/obj/item/food/deadmouse)
- if(!target && auto_patrol) //Search for cleanables it can see.
+ if(!target && bot_mode_flags & BOT_MODE_AUTOPATROL) //Search for cleanables it can see.
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
start_patrol()
@@ -330,7 +331,7 @@
target = null
mode = BOT_IDLE
- icon_state = "cleanbot[on]"
+ icon_state = "cleanbot[get_bot_flag(BOT_MODE_ON)]"
else if(istype(A, /obj/item) || istype(A, /obj/effect/decal/remains))
visible_message(span_danger("[src] sprays hydrofluoric acid at [A]!"))
playsound(src, 'sound/effects/spray2.ogg', 50, TRUE, -6)
@@ -343,7 +344,7 @@
living_target.death()
living_target = null
- else if(emagged) //Emag functions
+ else if(bot_cover_flags & BOT_COVER_EMAGGED) //Emag functions
if(istype(A, /mob/living/carbon))
var/mob/living/carbon/victim = A
if(victim.stat == DEAD)//cleanbots always finish the job
@@ -370,7 +371,7 @@
..()
/mob/living/simple_animal/bot/cleanbot/explode()
- on = FALSE
+ bot_mode_flags &= ~BOT_MODE_ON
visible_message(span_boldannounce("[src] blows apart!"))
var/atom/Tsec = drop_location()
@@ -378,17 +379,9 @@
new /obj/item/assembly/prox_sensor(Tsec)
- if(prob(50))
- drop_part(robot_arm, Tsec)
-
do_sparks(3, TRUE, src)
..()
-/mob/living/simple_animal/bot/cleanbot/medbay
- name = "Scrubs, MD"
- bot_core_type = /obj/machinery/bot_core/cleanbot/medbay
- on = FALSE
-
/obj/machinery/bot_core/cleanbot
req_one_access = list(ACCESS_JANITOR, ACCESS_ROBOTICS)
@@ -396,7 +389,7 @@
/mob/living/simple_animal/bot/cleanbot/ui_data(mob/user)
var/list/data = ..()
- if(!locked || issilicon(user)|| isAdminGhostAI(user))
+ if(!(bot_cover_flags & BOT_COVER_LOCKED) || issilicon(user)|| isAdminGhostAI(user))
data["custom_controls"]["clean_blood"] = blood
data["custom_controls"]["clean_trash"] = trash
data["custom_controls"]["clean_graffiti"] = drawn
@@ -406,7 +399,7 @@
// Actions received from TGUI
/mob/living/simple_animal/bot/cleanbot/ui_act(action, params)
. = ..()
- if(. || (locked && !usr.has_unlimited_silicon_privilege))
+ if(. || (bot_cover_flags & BOT_COVER_LOCKED && !usr.has_unlimited_silicon_privilege))
return
switch(action)
if("clean_blood")
diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm
index 29658f754cc..8cdea97a81d 100644
--- a/code/modules/mob/living/simple_animal/bot/construction.dm
+++ b/code/modules/mob/living/simple_animal/bot/construction.dm
@@ -118,7 +118,7 @@
icon_state = "ed209_hat"
build_step++
- if(5)
+ if(ASSEMBLY_SIXTH_STEP)
if(isprox(W))
if(!user.temporarilyRemoveItemFromInventory(W))
return
@@ -129,7 +129,7 @@
inhand_icon_state = "ed209_prox"
icon_state = "ed209_prox"
- if(6)
+ if(ASSEMBLY_SEVENTH_STEP)
if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/coil = W
if(coil.get_amount() < 1)
@@ -143,7 +143,7 @@
name = "wired ED-209 assembly"
build_step++
- if(7)
+ if(ASSEMBLY_EIGHTH_STEP)
if(istype(W, /obj/item/gun/energy/disabler))
if(!user.temporarilyRemoveItemFromInventory(W))
return
@@ -154,7 +154,7 @@
qdel(W)
build_step++
- if(8)
+ if(ASSEMBLY_NINTH_STEP)
if(W.tool_behaviour == TOOL_SCREWDRIVER)
to_chat(user, span_notice("You start attaching the gun to the frame..."))
if(W.use_tool(src, user, 40, volume=100))
@@ -372,7 +372,7 @@
to_chat(user, span_notice("You complete the Securitron! Beep boop."))
var/mob/living/simple_animal/bot/secbot/S = new(Tsec)
S.name = created_name
- S.weapon = I.type
+ S.baton_type = I.type
S.robot_arm = robot_arm
qdel(I)
qdel(src)
diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
index f838eefd657..6203c84e803 100644
--- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
@@ -9,10 +9,9 @@
environment_smash = ENVIRONMENT_SMASH_WALLS //Walls can't stop THE LAW
mob_size = MOB_SIZE_LARGE
- model = "ED-209"
bot_type = ADVANCED_SEC_BOT
- window_id = "autoed209"
- window_name = "Automatic Security Unit v2.6"
+ hackables = "combat inhibitors"
+
var/lastfired = 0
var/shot_delay = 15
var/shoot_sound = 'sound/weapons/laser.ogg'
@@ -27,14 +26,9 @@
..()
set_weapon()
-/mob/living/simple_animal/bot/secbot/ed209/set_custom_texts()
- text_hack = "You disable [name]'s combat inhibitor."
- text_dehack = "You restore [name]'s combat inhibitor."
- text_dehack_fail = "[name] ignores your attempts to restrict him!"
-
/mob/living/simple_animal/bot/secbot/ed209/emag_act(mob/user)
..()
- icon_state = "ed209[on]"
+ icon_state = "ed209[get_bot_flag(BOT_MODE_ON)]"
set_weapon()
/mob/living/simple_animal/bot/secbot/ed209/handle_automated_action()
@@ -59,7 +53,7 @@
/mob/living/simple_animal/bot/secbot/ed209/proc/set_weapon() //used to update the projectile type and firing sound
shoot_sound = 'sound/weapons/laser.ogg'
- if(emagged)
+ if(bot_cover_flags & BOT_COVER_EMAGGED)
projectile = /obj/projectile/beam
else
projectile = /obj/projectile/beam/disabler
@@ -102,11 +96,11 @@
var/mob/toshoot = pick(targets)
if(toshoot)
targets -= toshoot
- if(prob(50) && !emagged) // Temporarily emags it
- emagged = TRUE
+ if(prob(50) && !(bot_cover_flags & BOT_COVER_EMAGGED)) // Temporarily emags it
+ bot_cover_flags |= BOT_COVER_EMAGGED
set_weapon()
shoot_at(toshoot)
- emagged = FALSE
+ bot_cover_flags &= ~BOT_COVER_EMAGGED
set_weapon()
else
shoot_at(toshoot)
@@ -118,6 +112,6 @@
mode = BOT_HUNT
/mob/living/simple_animal/bot/secbot/ed209/RangedAttack(atom/A)
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
return
shoot_at(A)
diff --git a/code/modules/mob/living/simple_animal/bot/firebot.dm b/code/modules/mob/living/simple_animal/bot/firebot.dm
index d1975393f65..30cb6c6d450 100644
--- a/code/modules/mob/living/simple_animal/bot/firebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/firebot.dm
@@ -14,13 +14,11 @@
health = 25
maxHealth = 25
+ bot_core = /obj/machinery/bot_core/firebot
radio_key = /obj/item/encryptionkey/headset_eng
radio_channel = RADIO_CHANNEL_ENGINEERING
bot_type = FIRE_BOT
- model = "Firebot"
- bot_core = /obj/machinery/bot_core/firebot
- window_id = "autoextinguisher"
- window_name = "Mobile Fire Extinguisher v1.0"
+ hackables = "fire safety protocols"
path_image_color = "#FFA500"
var/atom/target_fire
@@ -62,7 +60,7 @@
internal_ext.refill()
/mob/living/simple_animal/bot/firebot/UnarmedAttack(atom/A, proximity_flag, list/modifiers)
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
return
if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
return
@@ -72,7 +70,7 @@
return ..()
/mob/living/simple_animal/bot/firebot/RangedAttack(atom/A, proximity_flag, list/modifiers)
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
return
if(internal_ext)
internal_ext.afterattack(A, src)
@@ -102,35 +100,31 @@
last_found = world.time
update_appearance()
-/mob/living/simple_animal/bot/firebot/set_custom_texts()
- text_hack = "You corrupt [name]'s safety protocols."
- text_dehack = "You detect errors in [name] and reset his programming."
- text_dehack_fail = "[name] is not responding to reset commands!"
-
/mob/living/simple_animal/bot/firebot/emag_act(mob/user)
..()
- if(emagged)
- if(user)
- to_chat(user, span_danger("[src] buzzes and beeps."))
- audible_message(span_danger("[src] buzzes oddly!"))
- playsound(src, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
- if(user)
- old_target_fire = user
- extinguish_fires = FALSE
- extinguish_people = TRUE
+ if(!(bot_cover_flags & BOT_COVER_EMAGGED))
+ return
+ if(user)
+ to_chat(user, span_danger("[src] buzzes and beeps."))
+ audible_message(span_danger("[src] buzzes oddly!"))
+ playsound(src, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
+ if(user)
+ old_target_fire = user
+ extinguish_fires = FALSE
+ extinguish_people = TRUE
- internal_ext = new /obj/item/extinguisher(src)
- internal_ext.chem = /datum/reagent/clf3 //Refill the internal extinguisher with liquid fire
- internal_ext.power = 3
- internal_ext.safety = FALSE
- internal_ext.precision = FALSE
- internal_ext.max_water = INFINITY
- internal_ext.refill()
+ internal_ext = new /obj/item/extinguisher(src)
+ internal_ext.chem = /datum/reagent/clf3 //Refill the internal extinguisher with liquid fire
+ internal_ext.power = 3
+ internal_ext.safety = FALSE
+ internal_ext.precision = FALSE
+ internal_ext.max_water = INFINITY
+ internal_ext.refill()
// Variables sent to TGUI
/mob/living/simple_animal/bot/firebot/ui_data(mob/user)
var/list/data = ..()
- if(!locked || issilicon(user) || isAdminGhostAI(user))
+ if(!(bot_cover_flags & BOT_COVER_LOCKED) || issilicon(user) || isAdminGhostAI(user))
data["custom_controls"]["extinguish_fires"] = extinguish_fires
data["custom_controls"]["extinguish_people"] = extinguish_people
data["custom_controls"]["stationary_mode"] = stationary_mode
@@ -139,7 +133,7 @@
// Actions received from TGUI
/mob/living/simple_animal/bot/firebot/ui_act(action, params)
. = ..()
- if(. || (locked && !usr.has_unlimited_silicon_privilege))
+ if(. || (bot_cover_flags & BOT_COVER_LOCKED && !usr.has_unlimited_silicon_privilege))
return
switch(action)
if("extinguish_fires")
@@ -154,7 +148,7 @@
/mob/living/simple_animal/bot/firebot/proc/is_burning(atom/target)
if(ismob(target))
var/mob/living/M = target
- if(M.on_fire || (emagged && !M.on_fire))
+ if(M.on_fire || (bot_cover_flags & BOT_COVER_EMAGGED && !M.on_fire))
return TRUE
else if(isturf(target))
@@ -202,7 +196,7 @@
old_target_fire = target_fire
// Target reached ENGAGE WATER CANNON
- if(target_fire && (get_dist(src, target_fire) <= (emagged ? 1 : 2))) // Make the bot spray water from afar when not emagged
+ if(target_fire && (get_dist(src, target_fire) <= (bot_cover_flags & BOT_COVER_EMAGGED ? 1 : 2))) // Make the bot spray water from afar when not emagged
if((speech_cooldown + SPEECH_INTERVAL) < world.time)
if(ishuman(target_fire))
speak("Stop, drop and roll!")
@@ -244,7 +238,7 @@
if(path.len > 8 && target_fire)
frustration++
- if(auto_patrol && !target_fire)
+ if(bot_mode_flags & BOT_MODE_AUTOPATROL && !target_fire)
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
start_patrol()
@@ -285,7 +279,7 @@
/mob/living/simple_animal/bot/firebot/update_icon_state()
. = ..()
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
icon_state = "firebot0"
return
if(IsStun() || IsParalyzed() || stationary_mode) //Bot has yellow light to indicate stationary mode.
@@ -295,7 +289,7 @@
/mob/living/simple_animal/bot/firebot/explode()
- on = FALSE
+ bot_mode_flags &= ~BOT_MODE_ON
visible_message(span_boldannounce("[src] blows apart!"))
var/atom/Tsec = drop_location()
@@ -309,9 +303,6 @@
var/turf/open/theturf = T
theturf.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
- if(prob(50))
- drop_part(robot_arm, Tsec)
-
do_sparks(3, TRUE, src)
..()
diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm
index 1929b271376..57bc2f2ddf2 100644
--- a/code/modules/mob/living/simple_animal/bot/floorbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm
@@ -8,13 +8,11 @@
health = 25
maxHealth = 25
+ bot_core = /obj/machinery/bot_core/floorbot
radio_key = /obj/item/encryptionkey/headset_eng
radio_channel = RADIO_CHANNEL_ENGINEERING
bot_type = FLOOR_BOT
- model = "Floorbot"
- bot_core = /obj/machinery/bot_core/floorbot
- window_id = "autofloor"
- window_name = "Automatic Station Floor Repairer v1.1"
+ hackables = "floor construction protocols"
path_image_color = "#FFA500"
var/process_type //Determines what to do when process_scan() receives a target. See process_scan() for details.
@@ -80,11 +78,6 @@
ignore_list = list()
toggle_magnet(FALSE)
-/mob/living/simple_animal/bot/floorbot/set_custom_texts()
- text_hack = "You corrupt [name]'s construction protocols."
- text_dehack = "You detect errors in [name] and reset his programming."
- text_dehack_fail = "[name] is not responding to reset commands!"
-
/mob/living/simple_animal/bot/floorbot/attackby(obj/item/W , mob/user, params)
if(istype(W, /obj/item/stack/tile/iron))
to_chat(user, span_notice("The floorbot can produce normal tiles itself."))
@@ -113,7 +106,7 @@
/mob/living/simple_animal/bot/floorbot/emag_act(mob/user)
..()
- if(!emagged)
+ if(!(bot_cover_flags & BOT_COVER_EMAGGED))
return
if(user)
to_chat(user, span_danger("[src] buzzes and beeps."))
@@ -134,7 +127,7 @@
// Variables sent to TGUI
/mob/living/simple_animal/bot/floorbot/ui_data(mob/user)
var/list/data = ..()
- if(!locked || issilicon(user) || isAdminGhostAI(user))
+ if(!(bot_cover_flags & BOT_COVER_LOCKED) || issilicon(user) || isAdminGhostAI(user))
data["custom_controls"]["tile_hull"] = autotile
data["custom_controls"]["place_tiles"] = placetiles
data["custom_controls"]["place_custom"] = replacetiles
@@ -151,7 +144,7 @@
// Actions received from TGUI
/mob/living/simple_animal/bot/floorbot/ui_act(action, params)
. = ..()
- if(. || (locked && !usr.has_unlimited_silicon_privilege))
+ if(. || (bot_cover_flags & BOT_COVER_LOCKED && !usr.has_unlimited_silicon_privilege))
return
switch(action)
if("place_custom")
@@ -193,7 +186,7 @@
audible_message("[src] makes an excited booping beeping sound!")
//Normal scanning procedure. We have tiles loaded, are not emagged.
- if(!target && !emagged)
+ if(!target && !(bot_cover_flags & BOT_COVER_EMAGGED))
if(targetdirection != null) //The bot is in line mode.
var/turf/T = get_step(src, targetdirection)
if(isspaceturf(T)) //Check for space
@@ -217,14 +210,14 @@
process_type = REPLACE_TILE //The target must be a tile. The floor must already have a floortile.
target = scan(/turf/open/floor)
- if(!target && emagged) //We are emagged! Time to rip up the floors!
+ if(!target && bot_cover_flags & BOT_COVER_EMAGGED) //We are emagged! Time to rip up the floors!
process_type = TILE_EMAG
target = scan(/turf/open/floor)
if(!target)
- if(auto_patrol)
+ if(bot_mode_flags & BOT_MODE_AUTOPATROL)
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
start_patrol()
@@ -239,9 +232,9 @@
target = null
path = list()
return
- if(isturf(target) && !emagged)
+ if(isturf(target) && !(bot_cover_flags & BOT_COVER_EMAGGED))
repair(target)
- else if(emagged && isfloorturf(target))
+ else if(bot_cover_flags & BOT_COVER_EMAGGED && isfloorturf(target))
var/turf/open/floor/F = target
toggle_magnet()
mode = BOT_REPAIRING
@@ -381,10 +374,10 @@
/mob/living/simple_animal/bot/floorbot/update_icon_state()
. = ..()
- icon_state = "[toolbox_color]floorbot[on]"
+ icon_state = "[toolbox_color]floorbot[get_bot_flag(BOT_MODE_ON)]"
/mob/living/simple_animal/bot/floorbot/explode()
- on = FALSE
+ bot_mode_flags &= ~BOT_MODE_ON
target = null
visible_message(span_boldannounce("[src] blows apart!"))
var/atom/Tsec = drop_location()
@@ -396,9 +389,6 @@
if(tilestack)
tilestack.forceMove(drop_location())
- if(prob(50))
- drop_part(robot_arm, Tsec)
-
new /obj/item/stack/tile/iron/base(Tsec, 1)
do_sparks(3, TRUE, src)
diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm
index 731ae36c6ee..8dbf7425af1 100644
--- a/code/modules/mob/living/simple_animal/bot/honkbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm
@@ -10,14 +10,12 @@
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
pass_flags = PASSMOB | PASSFLAPS
+ bot_core = /obj/machinery/bot_core/honkbot
radio_key = /obj/item/encryptionkey/headset_service //doesn't have security key
radio_channel = RADIO_CHANNEL_SERVICE //Doesn't even use the radio anyway.
bot_type = HONK_BOT
- model = "Honkbot"
- bot_core_type = /obj/machinery/bot_core/honkbot
- window_id = "autohonk"
- window_name = "Honkomatic Bike Horn Unit v1.0.7"
data_hud_type = DATA_HUD_SECURITY_BASIC // show jobs
+ hackables = "sound control systems"
path_image_color = "#FF69B4"
var/honksound = 'sound/items/bikehorn.ogg' //customizable sound
@@ -40,7 +38,7 @@
/mob/living/simple_animal/bot/honkbot/Initialize(mapload)
. = ..()
update_appearance()
- auto_patrol = TRUE
+ bot_mode_flags |= BOT_MODE_AUTOPATROL
// Doing this hurts my soul, but simplebot access reworks are for another day.
var/datum/id_trim/job/clown_trim = SSid_access.trim_singletons_by_path[/datum/id_trim/job/clown]
@@ -78,18 +76,12 @@
last_found = world.time
limiting_spam = FALSE
-/mob/living/simple_animal/bot/honkbot/set_custom_texts()
-
- text_hack = "You overload [name]'s sound control system"
- text_dehack = "You reboot [name] and restore the sound control system."
- text_dehack_fail = "[name] refuses to accept your authority!"
-
/mob/living/simple_animal/bot/honkbot/proc/judgement_criteria()
var/final = NONE
if(check_records)
- final = final|JUDGE_RECORDCHECK
- if(emagged)
- final = final|JUDGE_EMAGGED
+ final |= JUDGE_RECORDCHECK
+ if(bot_cover_flags & BOT_COVER_EMAGGED)
+ final |= JUDGE_EMAGGED
return final
/mob/living/simple_animal/bot/honkbot/proc/retaliate(mob/living/carbon/human/H)
@@ -115,7 +107,7 @@
/mob/living/simple_animal/bot/honkbot/emag_act(mob/user)
..()
- if(!emagged)
+ if(!(bot_cover_flags & BOT_COVER_EMAGGED))
return
if(user)
to_chat(user, span_danger("You short out [src]'s sound control system. It gives out an evil laugh!!"))
@@ -130,13 +122,13 @@
return ..()
/mob/living/simple_animal/bot/honkbot/UnarmedAttack(atom/A, proximity_flag, list/modifiers)
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
return
if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
return
if(iscarbon(A))
var/mob/living/carbon/C = A
- if(emagged)
+ if(bot_cover_flags & BOT_COVER_EMAGGED)
honk_attack(A)
else
if(!C.IsParalyzed() || arrest_type)
@@ -157,7 +149,7 @@
..()
/mob/living/simple_animal/bot/honkbot/proc/bike_horn() //use bike_horn
- if (emagged) //emagged honkbots will spam short and memorable sounds.
+ if (bot_cover_flags & BOT_COVER_EMAGGED) //emagged honkbots will spam short and memorable sounds.
if (!limiting_spam)
playsound(src, "honkbot_e", 50, FALSE)
limiting_spam = TRUE // prevent spam
@@ -193,7 +185,7 @@
var/mob/living/carbon/human/H = C
if(client) //prevent spam from players..
limiting_spam = TRUE
- if (emagged) // you really don't want to hit an emagged honkbot
+ if (bot_cover_flags & BOT_COVER_EMAGGED) // you really don't want to hit an emagged honkbot
threatlevel = 6 // will never let you go
else
//HONK once, then leave
@@ -223,7 +215,7 @@
walk_to(src,0)
look_for_perp()
- if(!mode && auto_patrol)
+ if(!mode && bot_mode_flags & BOT_MODE_AUTOPATROL)
mode = BOT_START_PATROL
if(BOT_HUNT)
@@ -321,8 +313,6 @@
visible_message(span_boldannounce("[src] blows apart!"))
var/atom/Tsec = drop_location()
//doesn't drop cardboard nor its assembly, since its a very frail material.
- if(prob(50))
- drop_part(robot_arm, Tsec)
new bikehorn(Tsec)
new /obj/item/assembly/prox_sensor(Tsec)
@@ -341,7 +331,7 @@
/mob/living/simple_animal/bot/honkbot/proc/on_entered(datum/source, atom/movable/AM)
SIGNAL_HANDLER
- if(ismob(AM) && (on)) //only if its online
+ if(ismob(AM) && (bot_mode_flags & BOT_MODE_ON)) //only if its online
if(prob(30)) //you're far more likely to trip on a honkbot
var/mob/living/carbon/C = AM
if(!istype(C) || !C || in_range(src, target))
diff --git a/code/modules/mob/living/simple_animal/bot/hygienebot.dm b/code/modules/mob/living/simple_animal/bot/hygienebot.dm
index a32fc01ceaa..13eb28c41f6 100644
--- a/code/modules/mob/living/simple_animal/bot/hygienebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/hygienebot.dm
@@ -5,21 +5,20 @@
icon = 'icons/mob/aibots.dmi'
icon_state = "hygienebot"
base_icon_state = "hygienebot"
+ pass_flags = PASSMOB | PASSFLAPS | PASSTABLE
+ layer = ABOVE_MOB_LAYER
density = FALSE
anchored = FALSE
health = 100
maxHealth = 100
+
+ bot_core = /obj/machinery/bot_core/hygienebot
radio_key = /obj/item/encryptionkey/headset_service
radio_channel = RADIO_CHANNEL_SERVICE //Service
+ bot_mode_flags = ~BOT_MODE_PAI_CONTROLLABLE
bot_type = HYGIENE_BOT
- model = "Cleanbot"
- bot_core_type = /obj/machinery/bot_core/hygienebot
- window_id = "autoclean"
- window_name = "Automatic Crew Cleaner X2"
- pass_flags = PASSMOB | PASSFLAPS | PASSTABLE
+ hackables = "cleaning service protocols"
path_image_color = "#993299"
- allow_pai = FALSE
- layer = ABOVE_MOB_LAYER
///The human target the bot is trying to wash.
var/mob/living/carbon/human/target
@@ -55,7 +54,7 @@
walk_to(src,0)
visible_message(span_boldannounce("[src] blows apart in a foamy explosion!"))
do_sparks(3, TRUE, src)
- on = FALSE
+ bot_mode_flags &= ~BOT_MODE_ON
new /obj/effect/particle_effect/foam(loc)
..()
@@ -67,16 +66,16 @@
/mob/living/simple_animal/bot/hygienebot/update_icon_state()
. = ..()
- icon_state = "[base_icon_state][on ? "-on" : null]"
+ icon_state = "[base_icon_state][bot_mode_flags & BOT_MODE_ON ? "-on" : null]"
/mob/living/simple_animal/bot/hygienebot/update_overlays()
. = ..()
- if(on)
+ if(bot_mode_flags & BOT_MODE_ON)
. += mutable_appearance(icon, "hygienebot-flame")
if(washing)
- . += mutable_appearance(icon, emagged ? "hygienebot-fire" : "hygienebot-water")
+ . += mutable_appearance(icon, bot_cover_flags & BOT_COVER_EMAGGED ? "hygienebot-fire" : "hygienebot-water")
/mob/living/simple_animal/bot/hygienebot/turn_off()
@@ -98,7 +97,7 @@
do_wash(loc)
for(var/AM in loc)
do_wash(AM)
- if(isopenturf(loc) && !emagged)
+ if(isopenturf(loc) && !(bot_cover_flags & BOT_COVER_EMAGGED))
var/turf/open/tile = loc
tile.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
@@ -106,11 +105,11 @@
if(BOT_IDLE) // idle
walk_to(src,0)
look_for_lowhygiene() // see if any disgusting fucks are in range
- if(!mode && auto_patrol) // still idle, and set to patrol
+ if(!mode && bot_mode_flags & BOT_MODE_AUTOPATROL) // still idle, and set to patrol
mode = BOT_START_PATROL // switch to patrol mode
if(BOT_HUNT) // hunting for stinkman
- if(emagged) //lol fuck em up
+ if(bot_cover_flags & BOT_COVER_EMAGGED) //lol fuck em up
currentspeed = 3.5
start_washing()
mad = TRUE
@@ -206,7 +205,7 @@
update_appearance()
/mob/living/simple_animal/bot/hygienebot/proc/check_purity(mob/living/L)
- if((emagged) && L.stat != DEAD)
+ if((bot_cover_flags & BOT_COVER_EMAGGED) && L.stat != DEAD)
return FALSE
for(var/X in list(ITEM_SLOT_HEAD, ITEM_SLOT_MASK, ITEM_SLOT_ICLOTHING, ITEM_SLOT_OCLOTHING, ITEM_SLOT_FEET))
@@ -217,7 +216,7 @@
return TRUE
/mob/living/simple_animal/bot/hygienebot/proc/do_wash(atom/A)
- if(emagged)
+ if(bot_cover_flags & BOT_COVER_EMAGGED)
A.fire_act() //lol pranked no cleaning besides that
else
A.wash(CLEAN_WASH)
diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm
index 8395ec2fe5f..f6cc89465e8 100644
--- a/code/modules/mob/living/simple_animal/bot/medbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/medbot.dm
@@ -20,19 +20,16 @@
health = 20
maxHealth = 20
pass_flags = PASSMOB | PASSFLAPS
-
status_flags = (CANPUSH | CANSTUN)
+ bot_core = /obj/machinery/bot_core/medbot
radio_key = /obj/item/encryptionkey/headset_med
radio_channel = RADIO_CHANNEL_MEDICAL
-
bot_type = MED_BOT
- model = "Medibot"
- bot_core_type = /obj/machinery/bot_core/medbot
- window_id = "automed"
- window_name = "Automatic Medical Unit v1.1"
data_hud_type = DATA_HUD_MEDICAL_ADVANCED
+ hackables = "health processor circuits"
path_image_color = "#DDDDFF"
+
/// drop determining variable
var/healthanalyzer = /obj/item/healthanalyzer
/// drop determining variable
@@ -71,6 +68,9 @@
///Cooldown to track last time we were tipped/righted and said a voice line, to avoid spam
COOLDOWN_DECLARE(last_tipping_action_voice)
+/mob/living/simple_animal/bot/medbot/autopatrol
+ bot_mode_flags = BOT_MODE_ON | BOT_MODE_AUTOPATROL | BOT_MODE_REMOTE_ENABLED | BOT_MODE_PAI_CONTROLLABLE
+
/mob/living/simple_animal/bot/medbot/mysterious
name = "\improper Mysterious Medibot"
desc = "International Medibot of mystery."
@@ -89,7 +89,7 @@
/mob/living/simple_animal/bot/medbot/update_icon_state()
. = ..()
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
icon_state = "[base_icon_state]0"
return
if(HAS_TRAIT(src, TRAIT_INCAPACITATED))
@@ -143,19 +143,13 @@
last_found = world.time
update_appearance()
-/mob/living/simple_animal/bot/medbot/set_custom_texts()
-
- text_hack = "You corrupt [name]'s healing processor circuits."
- text_dehack = "You reset [name]'s healing processor circuits."
- text_dehack_fail = "[name] seems damaged and does not respond to reprogramming!"
-
/mob/living/simple_animal/bot/medbot/attack_paw(mob/user, list/modifiers)
return attack_hand(user, modifiers)
// Variables sent to TGUI
/mob/living/simple_animal/bot/medbot/ui_data(mob/user)
var/list/data = ..()
- if(!locked || issilicon(user) || isAdminGhostAI(user))
+ if(!(bot_cover_flags & BOT_COVER_LOCKED) || issilicon(user) || isAdminGhostAI(user))
data["custom_controls"]["heal_threshold"] = heal_threshold
data["custom_controls"]["speaker"] = !shut_up
data["custom_controls"]["crit_alerts"] = declare_crit
@@ -166,7 +160,7 @@
// Actions received from TGUI
/mob/living/simple_animal/bot/medbot/ui_act(action, params)
. = ..()
- if(. || (locked && !usr.has_unlimited_silicon_privilege))
+ if(. || (bot_cover_flags & BOT_COVER_LOCKED && !usr.has_unlimited_silicon_privilege))
return
switch(action)
if("heal_threshold")
@@ -196,7 +190,6 @@
heal_amount = (round(tech_boosters/2,0.1)*initial(heal_amount))+initial(heal_amount) //every 2 tend wounds tech gives you an extra 100% healing, adjusting for unique branches (combo is bonus)
if(oldheal_amount < heal_amount)
speak("New knowledge found! Surgical efficacy improved to [round(heal_amount/initial(heal_amount)*100)]%!")
- return
/mob/living/simple_animal/bot/medbot/attackby(obj/item/W as obj, mob/user as mob, params)
var/current_health = health
@@ -206,7 +199,7 @@
/mob/living/simple_animal/bot/medbot/emag_act(mob/user)
..()
- if(!emagged)
+ if(!(bot_cover_flags & BOT_COVER_EMAGGED))
return
declare_crit = FALSE
if(user)
@@ -360,7 +353,7 @@
if(QDELETED(patient))
if(!shut_up && prob(1))
- if(emagged && prob(30))
+ if(bot_cover_flags & BOT_COVER_EMAGGED && prob(30))
var/list/i_need_scissors = list('sound/voice/medbot/fuck_you.ogg', 'sound/voice/medbot/turn_off.ogg', 'sound/voice/medbot/im_different.ogg', 'sound/voice/medbot/close.ogg', 'sound/voice/medbot/shindemashou.ogg')
playsound(src, pick(i_need_scissors), 70)
else
@@ -407,7 +400,7 @@
if(path.len > 8 && patient)
frustration++
- if(auto_patrol && !stationary_mode && !patient)
+ if(bot_mode_flags & BOT_MODE_AUTOPATROL && !stationary_mode && !patient)
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
start_patrol()
@@ -430,7 +423,7 @@
if(C.suiciding)
return FALSE //Kevorkian school of robotic medical assistants.
- if(emagged) //Everyone needs our medicine. (Our medicine is toxins)
+ if(bot_cover_flags & BOT_COVER_EMAGGED) //Everyone needs our medicine. (Our medicine is toxins)
return TRUE
if(HAS_TRAIT(C,TRAIT_MEDIBOTCOMINGTHROUGH) && !HAS_TRAIT_FROM(C,TRAIT_MEDIBOTCOMINGTHROUGH,tag)) //the early medbot gets the worm (or in this case the patient)
@@ -485,7 +478,7 @@
chemscan(src, A)
/mob/living/simple_animal/bot/medbot/proc/medicate_patient(mob/living/carbon/C)
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
return
if(!istype(C))
@@ -527,7 +520,7 @@
if(damagetype_healer == "all" && potential_methods.len)
treatment_method = pick(potential_methods)
- if(!treatment_method && !emagged) //If they don't need any of that they're probably cured!
+ if(!treatment_method && !(bot_cover_flags & BOT_COVER_EMAGGED)) //If they don't need any of that they're probably cured!
if(C.maxHealth - C.get_organic_health() < heal_threshold)
to_chat(src, span_notice("[C] is healthy! Your programming prevents you from tending the wounds of anyone without at least [heal_threshold] damage of any one type ([heal_threshold + 5] for oxygen damage.)"))
@@ -542,12 +535,12 @@
span_userdanger("[src] is trying to tend your wounds!"))
if(do_mob(src, patient, 20)) //Slightly faster than default tend wounds, but does less HPS
- if((get_dist(src, patient) <= 1) && (on) && assess_patient(patient))
+ if((get_dist(src, patient) <= 1) && (bot_mode_flags & BOT_MODE_ON) && assess_patient(patient))
var/healies = heal_amount
var/obj/item/storage/firstaid/FA = firstaid
if(treatment_method == BRUTE && initial(FA.damagetype_healed) == BRUTE) //specialized brute gets a bit of bonus, as a snack.
healies *= 1.1
- if(emagged)
+ if(bot_cover_flags & BOT_COVER_EMAGGED)
patient.reagents.add_reagent(/datum/reagent/toxin/chloralhydrate, 5)
patient.apply_damage_type((healies*1),treatment_method)
log_combat(src, patient, "pretended to tend wounds on", "internal tools", "([uppertext(treatment_method)]) (EMAGGED)")
@@ -571,7 +564,7 @@
tending = FALSE
/mob/living/simple_animal/bot/medbot/explode()
- on = FALSE
+ bot_mode_flags &= ~BOT_MODE_ON
visible_message(span_boldannounce("[src] blows apart!"))
var/atom/Tsec = drop_location()
@@ -579,10 +572,7 @@
new /obj/item/assembly/prox_sensor(Tsec)
drop_part(healthanalyzer, Tsec)
- if(prob(50))
- drop_part(robot_arm, Tsec)
-
- if(emagged && prob(25))
+ if(bot_cover_flags & BOT_COVER_EMAGGED && prob(25))
playsound(src, 'sound/voice/medbot/insult.ogg', 50)
do_sparks(3, TRUE, src)
@@ -592,7 +582,7 @@
if(declare_cooldown > world.time)
return
var/area/location = get_area(src)
- speak("Medical emergency! [crit_patient || "A patient"] is in critical condition at [location]!",radio_channel)
+ speak("Medical emergency! [crit_patient || "A patient"] is in critical condition at [location]!", radio_channel)
declare_cooldown = world.time + 200
/obj/machinery/bot_core/medbot
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index 3aafd45cbd2..1431605eb6e 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -25,20 +25,16 @@
mob_size = MOB_SIZE_LARGE
buckle_prevents_pull = TRUE // No pulling loaded shit
+ bot_core = /obj/machinery/bot_core/mulebot
radio_key = /obj/item/encryptionkey/headset_cargo
radio_channel = RADIO_CHANNEL_SUPPLY
-
bot_type = MULE_BOT
- model = "MULE"
- bot_core_type = /obj/machinery/bot_core/mulebot
- hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_PATH_HUD = HUD_LIST_LIST) //Diagnostic HUD views
+ path_image_color = "#7F5200"
var/network_id = NETWORK_BOTS_CARGO
/// unique identifier in case there are multiple mulebots.
var/id
- path_image_color = "#7F5200"
-
var/base_icon = "mulebot" /// icon_state to use in update_icon_state
var/atom/movable/load /// what we're transporting
var/mob/living/passenger /// who's riding us
@@ -47,6 +43,8 @@
var/home_destination = "" /// tag of home delivery beacon
var/reached_target = TRUE ///true if already reached the target
+ ///Number of times retried a blocked path
+ var/blockcount = 0
var/auto_return = TRUE /// true if auto return to home beacon after unload
var/auto_pickup = TRUE /// true if auto-pickup at beacon
@@ -103,7 +101,7 @@
/mob/living/simple_animal/bot/mulebot/examine(mob/user)
. = ..()
- if(open)
+ if(bot_cover_flags & BOT_COVER_OPEN)
if(cell)
. += span_notice("It has \a [cell] installed.")
. += span_info("You can use a crowbar to remove it.")
@@ -135,9 +133,7 @@
/mob/living/simple_animal/bot/mulebot/proc/set_id(new_id)
id = new_id
- if(paicard)
- bot_name = "[initial(name)] ([new_id])"
- else
+ if(!paicard)
name = "[initial(name)] ([new_id])"
/mob/living/simple_animal/bot/mulebot/bot_reset()
@@ -148,7 +144,7 @@
if(I.tool_behaviour == TOOL_SCREWDRIVER)
. = ..()
update_appearance()
- else if(istype(I, /obj/item/stock_parts/cell) && open)
+ else if(istype(I, /obj/item/stock_parts/cell) && bot_cover_flags & BOT_COVER_OPEN)
if(cell)
to_chat(user, span_warning("[src] already has a power cell!"))
return
@@ -158,7 +154,7 @@
diag_hud_set_mulebotcell()
visible_message(span_notice("[user] inserts \a [cell] into [src]."),
span_notice("You insert [cell] into [src]."))
- else if(I.tool_behaviour == TOOL_CROWBAR && open && !user.combat_mode)
+ else if(I.tool_behaviour == TOOL_CROWBAR && bot_cover_flags & BOT_COVER_OPEN && !user.combat_mode)
if(!cell)
to_chat(user, span_warning("[src] doesn't have a power cell!"))
return
@@ -171,7 +167,7 @@
span_notice("You pry [cell] out of [src]."))
cell = null
diag_hud_set_mulebotcell()
- else if(is_wire_tool(I) && open)
+ else if(is_wire_tool(I) && bot_cover_flags & BOT_COVER_OPEN)
return attack_hand(user)
else if(load && ismob(load)) // chance to knock off rider
if(prob(1 + I.force * 2))
@@ -185,21 +181,21 @@
return ..()
/mob/living/simple_animal/bot/mulebot/emag_act(mob/user)
- if(!emagged)
- emagged = TRUE
- if(!open)
- locked = !locked
- to_chat(user, span_notice("You [locked ? "lock" : "unlock"] [src]'s controls!"))
+ if(!(bot_cover_flags & BOT_COVER_EMAGGED))
+ bot_cover_flags |= BOT_COVER_EMAGGED
+ if(!(bot_cover_flags & BOT_COVER_OPEN))
+ bot_cover_flags ^= BOT_COVER_LOCKED
+ to_chat(user, span_notice("You [bot_cover_flags & BOT_COVER_LOCKED ? "lock" : "unlock"] [src]'s controls!"))
flick("[base_icon]-emagged", src)
playsound(src, "sparks", 100, FALSE, SHORT_RANGE_SOUND_EXTRARANGE)
/mob/living/simple_animal/bot/mulebot/update_icon_state() //if you change the icon_state names, please make sure to update /datum/wires/mulebot/on_pulse() as well. <3
. = ..()
- icon_state = "[base_icon][on ? wires.is_cut(WIRE_AVOIDANCE) : 0]"
+ icon_state = "[base_icon][bot_mode_flags & BOT_MODE_ON ? wires.is_cut(WIRE_AVOIDANCE) : 0]"
/mob/living/simple_animal/bot/mulebot/update_overlays()
. = ..()
- if(open)
+ if(bot_cover_flags & BOT_COVER_OPEN)
. += "[base_icon]-hatch"
if(!load || ismob(load)) //mob offsets and such are handled by the riding component / buckling
return
@@ -229,7 +225,7 @@
wires.cut_random()
/mob/living/simple_animal/bot/mulebot/interact(mob/user)
- if(open && !isAI(user))
+ if(bot_cover_flags & BOT_COVER_OPEN && !isAI(user))
wires.interact(user)
else
if(wires.is_cut(WIRE_RX) && isAI(user))
@@ -244,8 +240,8 @@
/mob/living/simple_animal/bot/mulebot/ui_data(mob/user)
var/list/data = list()
- data["on"] = on
- data["locked"] = locked
+ data["on"] = get_bot_flag(BOT_MODE_ON)
+ data["locked"] = get_bot_flag(BOT_COVER_LOCKED)
data["siliconUser"] = user.has_unlimited_silicon_privilege
data["mode"] = mode ? mode_name[mode] : "Ready"
data["modeStatus"] = ""
@@ -272,18 +268,18 @@
/mob/living/simple_animal/bot/mulebot/ui_act(action, params)
. = ..()
- if(. || (locked && !usr.has_unlimited_silicon_privilege))
+ if(. || (bot_cover_flags & BOT_COVER_LOCKED && !usr.has_unlimited_silicon_privilege))
return
switch(action)
if("lock")
if(usr.has_unlimited_silicon_privilege)
- locked = !locked
+ bot_cover_flags ^= BOT_COVER_LOCKED
. = TRUE
if("power")
- if(on)
+ if(bot_mode_flags & BOT_MODE_ON)
turn_off()
- else if(open)
+ else if(bot_cover_flags & BOT_COVER_OPEN)
to_chat(usr, span_warning("[name]'s maintenance panel is open!"))
return
else if(cell)
@@ -475,7 +471,7 @@
if(path?.len)
target = ai_waypoint //Target is the end point of the path, the waypoint set by the AI.
destination = get_area_name(target, TRUE)
- pathset = 1 //Indicates the AI's custom path is initialized.
+ pathset = TRUE //Indicates the AI's custom path is initialized.
start()
/mob/living/simple_animal/bot/mulebot/Move(atom/newloc, direct) //handle leaving bloody tracks. can't be done via Moved() since that can end up putting the tracks somewhere BEFORE we get bloody.
@@ -499,7 +495,7 @@
diag_hud_set_mulebotcell()
/mob/living/simple_animal/bot/mulebot/handle_automated_action()
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
return
if(!has_power())
turn_off()
@@ -516,7 +512,7 @@
START_PROCESSING(SSfastprocess, src)
/mob/living/simple_animal/bot/mulebot/process()
- if(!on || client || (num_steps <= 0) || !has_power())
+ if(!(bot_mode_flags & BOT_MODE_ON) || client || (num_steps <= 0) || !has_power())
return PROCESS_KILL
num_steps--
@@ -609,7 +605,7 @@
// starts bot moving to current destination
/mob/living/simple_animal/bot/mulebot/proc/start()
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
return
if(destination == home_destination)
mode = BOT_GO_HOME
@@ -620,7 +616,7 @@
// starts bot moving to home
// sends a beacon query to find
/mob/living/simple_animal/bot/mulebot/proc/start_home()
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
return
INVOKE_ASYNC(src, .proc/do_start_home)
@@ -716,7 +712,7 @@
//Update navigation data. Called when commanded to deliver, return home, or a route update is needed...
/mob/living/simple_animal/bot/mulebot/proc/get_nav()
- if(!on || wires.is_cut(WIRE_BEACON))
+ if(!(bot_mode_flags & BOT_MODE_ON) || wires.is_cut(WIRE_BEACON))
return
for(var/obj/machinery/navbeacon/NB in GLOB.deliverybeacons)
@@ -783,7 +779,7 @@
/mob/living/simple_animal/bot/mulebot/proc/check_pre_step(datum/source)
SIGNAL_HANDLER
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
return COMPONENT_MOB_BOT_BLOCK_PRE_STEP
if((cell && (cell.charge < cell_move_power_usage)) || !has_power())
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index 221e97f8d22..308eb3beba7 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -9,22 +9,21 @@
maxHealth = 25
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
pass_flags = PASSMOB | PASSFLAPS
+ combat_mode = TRUE
+ bot_core = /obj/machinery/bot_core/secbot
radio_key = /obj/item/encryptionkey/secbot //AI Priv + Security
radio_channel = RADIO_CHANNEL_SECURITY //Security channel
bot_type = SEC_BOT
- model = "Securitron"
- bot_core_type = /obj/machinery/bot_core/secbot
- window_id = "autosec"
- window_name = "Automatic Security Unit v1.6"
- allow_pai = FALSE
+ bot_mode_flags = ~BOT_MODE_PAI_CONTROLLABLE
data_hud_type = DATA_HUD_SECURITY_ADVANCED
+ hackables = "target identification systems"
path_image_color = "#FF0000"
- combat_mode = TRUE
-
- ///The tool this Secbot will use to make arrests
- var/obj/item/weapon = /obj/item/melee/baton/security
+ ///The type of baton this Secbot will use
+ var/baton_type = /obj/item/melee/baton/security
+ ///The weapon (from baton_type) that will be used to make arrests.
+ var/obj/item/weapon
///Their current target
var/mob/living/carbon/target
///Name of their last target to prevent spamming
@@ -44,7 +43,7 @@
var/fair_market_price_arrest = 25
///Charged each time the violator is stunned on detain
var/fair_market_price_detain = 5
- /// Force of the harmbaton used on them
+ ///Force of the harmbaton used on them
var/weapon_force = 20
///The department the secbot will deposit collected money into
var/payment_department = ACCOUNT_SEC
@@ -52,13 +51,18 @@
/mob/living/simple_animal/bot/secbot/beepsky
name = "Commander Beep O'sky"
desc = "It's Commander Beep O'sky! Officially the superior officer of all bots on station, Beepsky remains as humble and dedicated to the law as the day he was first fabricated."
- auto_patrol = TRUE
+ bot_mode_flags = BOT_MODE_ON | BOT_MODE_AUTOPATROL | BOT_MODE_REMOTE_ENABLED
commissioned = TRUE
+/mob/living/simple_animal/bot/secbot/beepsky/officer
+ name = "Officer Beepsky"
+ desc = "It's Officer Beepsky! Powered by a potato and a shot of whiskey, and with a sturdier reinforced chassis, too."
+ health = 45
+
/mob/living/simple_animal/bot/secbot/beepsky/armsky
name = "Sergeant-At-Armsky"
health = 45
- auto_patrol = FALSE
+ bot_mode_flags = ~BOT_MODE_AUTOPATROL
security_mode_flags = SECBOT_DECLARE_ARRESTS | SECBOT_CHECK_IDS | SECBOT_CHECK_RECORDS
/mob/living/simple_animal/bot/secbot/beepsky/jr
@@ -76,6 +80,13 @@
desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment."
radio_channel = RADIO_CHANNEL_AI_PRIVATE
+/mob/living/simple_animal/bot/secbot/genesky
+ name = "Officer Genesky"
+ desc = "A beefy variant of the standard securitron model."
+ health = 50
+ faction = list("nanotrasenprivate")
+ bot_mode_flags = BOT_MODE_ON
+ bot_cover_flags = BOT_COVER_LOCKED | BOT_COVER_EMAGGED
/mob/living/simple_animal/bot/secbot/beepsky/explode()
var/atom/Tsec = drop_location()
@@ -86,7 +97,7 @@
/mob/living/simple_animal/bot/secbot/Initialize(mapload)
. = ..()
- weapon = new weapon()
+ weapon = new baton_type()
update_appearance(UPDATE_ICON)
// Doing this hurts my soul, but simplebot access reworks are for another day.
@@ -131,15 +142,10 @@
playsound(src, 'sound/machines/defib_zap.ogg', 50)
visible_message(span_warning("[src] shakes and speeds up!"))
-/mob/living/simple_animal/bot/secbot/set_custom_texts()
- text_hack = "You overload [name]'s target identification system."
- text_dehack = "You reboot [name] and restore the target identification."
- text_dehack_fail = "[name] refuses to accept your authority!"
-
// Variables sent to TGUI
/mob/living/simple_animal/bot/secbot/ui_data(mob/user)
var/list/data = ..()
- if(!locked || issilicon(user) || isAdminGhostAI(user))
+ if(!(bot_cover_flags & BOT_COVER_LOCKED) || issilicon(user) || isAdminGhostAI(user))
data["custom_controls"]["check_id"] = security_mode_flags & SECBOT_CHECK_IDS
data["custom_controls"]["check_weapons"] = security_mode_flags & SECBOT_CHECK_WEAPONS
data["custom_controls"]["check_warrants"] = security_mode_flags & SECBOT_CHECK_RECORDS
@@ -150,7 +156,7 @@
// Actions received from TGUI
/mob/living/simple_animal/bot/secbot/ui_act(action, params)
. = ..()
- if(. || (locked && !usr.has_unlimited_silicon_privilege))
+ if(. || (bot_cover_flags & BOT_COVER_LOCKED && !usr.has_unlimited_silicon_privilege))
return
switch(action)
if("check_id")
@@ -175,7 +181,7 @@
/mob/living/simple_animal/bot/secbot/proc/judgement_criteria()
var/final = FALSE
- if(emagged)
+ if(bot_cover_flags & BOT_COVER_EMAGGED)
final |= JUDGE_EMAGGED
if(bot_type == ADVANCED_SEC_BOT)
final |= JUDGE_IGNOREMONKEYS
@@ -209,7 +215,7 @@
/mob/living/simple_animal/bot/secbot/attackby(obj/item/attacking_item, mob/living/user, params)
..()
- if(!on) // Bots won't remember if you hit them while they're off.
+ if(!(bot_mode_flags & BOT_MODE_ON)) // Bots won't remember if you hit them while they're off.
return
if(attacking_item.tool_behaviour == TOOL_WELDER && !user.combat_mode) // Any intent but harm will heal, so we shouldn't get angry.
return
@@ -219,7 +225,7 @@
/mob/living/simple_animal/bot/secbot/emag_act(mob/user)
..()
- if(!emagged)
+ if(!(bot_cover_flags & BOT_COVER_EMAGGED))
return
if(user)
to_chat(user, span_danger("You short out [src]'s target assessment circuits."))
@@ -236,7 +242,7 @@
return ..()
/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers)
- if(!on)
+ if(!(bot_mode_flags & BOT_MODE_ON))
return
if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
return
@@ -268,7 +274,7 @@
addtimer(CALLBACK(src, .proc/handcuff_target, target), 60)
/mob/living/simple_animal/bot/secbot/proc/handcuff_target(mob/living/carbon/current_target)
- if(!on || !Adjacent(current_target) || !isturf(current_target.loc)) //if he's in a closet or not adjacent, we cancel cuffing.
+ if(!(bot_mode_flags & BOT_MODE_ON) || !Adjacent(current_target) || !isturf(current_target.loc)) //if he's in a closet or not adjacent, we cancel cuffing.
return
if(!current_target.handcuffed)
current_target.set_handcuffed(new /obj/item/restraints/handcuffs/cable/zipties/used(current_target))
@@ -280,7 +286,7 @@
var/judgement_criteria = judgement_criteria()
playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
icon_state = "[initial(icon_state)]-c"
- addtimer(CALLBACK(src, /atom/.proc/update_appearance), 0.2 SECONDS)
+ addtimer(CALLBACK(src, /atom.proc/update_appearance), 0.2 SECONDS)
var/threat = 5
if(harm)
@@ -312,7 +318,7 @@
if(BOT_IDLE) // idle
walk_to(src,0)
look_for_perp() // see if any criminals are in range
- if(!mode && auto_patrol) // still idle, and set to patrol
+ if(!mode && bot_mode_flags & BOT_MODE_AUTOPATROL) // still idle, and set to patrol
mode = BOT_START_PATROL // switch to patrol mode
if(BOT_HUNT) // hunting for perp
@@ -467,10 +473,7 @@
secbot_assembly.add_overlay("hs_hole")
secbot_assembly.created_name = name
new /obj/item/assembly/prox_sensor(Tsec)
- drop_part(weapon, Tsec)
-
- if(prob(50))
- drop_part(robot_arm, Tsec)
+ drop_part(baton_type, Tsec)
do_sparks(3, TRUE, src)
diff --git a/code/modules/mob/living/simple_animal/bot/vibebot.dm b/code/modules/mob/living/simple_animal/bot/vibebot.dm
index e4c437bf476..fd23e1615a5 100644
--- a/code/modules/mob/living/simple_animal/bot/vibebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/vibebot.dm
@@ -9,20 +9,18 @@
maxHealth = 25
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
pass_flags = PASSMOB | PASSFLAPS
-
- radio_key = /obj/item/encryptionkey/headset_service //doesn't have security key
- radio_channel = RADIO_CHANNEL_SERVICE //Doesn't even use the radio anyway.
- bot_type = VIBE_BOT
- model = "Vibebot"
- window_id = "vibebot"
- window_name = "Discomatic Vibe Bot v1.05"
- data_hud_type = DATA_HUD_DIAGNOSTIC_BASIC // show jobs
- path_image_color = "#2cac12"
- auto_patrol = TRUE
light_system = MOVABLE_LIGHT
light_range = 7
light_power = 3
+ hackables = "vibing scanners"
+ bot_mode_flags = ~BOT_MODE_PAI_CONTROLLABLE
+ radio_key = /obj/item/encryptionkey/headset_service //doesn't have security key
+ radio_channel = RADIO_CHANNEL_SERVICE //Doesn't even use the radio anyway.
+ bot_type = VIBE_BOT
+ data_hud_type = DATA_HUD_DIAGNOSTIC_BASIC // show jobs
+ path_image_color = "#2cac12"
+
/mob/living/simple_animal/bot/vibebot/Initialize(mapload)
. = ..()
@@ -43,19 +41,17 @@
/mob/living/simple_animal/bot/vibebot/handle_automated_action()
- if(!..())
+ . = ..()
+ if(!.)
return
- if(auto_patrol)
-
- if(mode == BOT_IDLE || mode == BOT_START_PATROL)
- start_patrol()
-
- if(mode == BOT_PATROL)
- bot_patrol()
-
- if(on)
+ if(bot_mode_flags & BOT_MODE_ON)
Vibe()
- else
- remove_atom_colour(TEMPORARY_COLOUR_PRIORITY)
+ if(!(bot_mode_flags & BOT_MODE_AUTOPATROL))
+ return
+
+ if(mode == BOT_IDLE || mode == BOT_START_PATROL)
+ start_patrol()
+ if(mode == BOT_PATROL)
+ bot_patrol()
diff --git a/code/modules/modular_computers/file_system/programs/robocontrol.dm b/code/modules/modular_computers/file_system/programs/robocontrol.dm
index 77d9a3aea35..51802b9e8f9 100644
--- a/code/modules/modular_computers/file_system/programs/robocontrol.dm
+++ b/code/modules/modular_computers/file_system/programs/robocontrol.dm
@@ -37,7 +37,7 @@
for(var/B in GLOB.bots_list)
var/mob/living/simple_animal/bot/Bot = B
- if(!Bot.on || Bot.z != zlevel || Bot.remote_disabled) //Only non-emagged bots on the same Z-level are detected!
+ if(!(Bot.bot_mode_flags & BOT_MODE_ON) || Bot.z != zlevel || !(Bot.bot_mode_flags & BOT_MODE_REMOTE_ENABLED)) //Only non-emagged bots on the same Z-level are detected!
continue
else if(computer) //Also, the inserted ID must have access to the bot type
var/obj/item/card/id/id_card = card_slot ? card_slot.stored_card : null
@@ -45,7 +45,7 @@
continue
else if(id_card && !Bot.bot_core.check_access(id_card))
continue
- var/list/newbot = list("name" = Bot.name, "mode" = Bot.get_mode_ui(), "model" = Bot.model, "locat" = get_area(Bot), "bot_ref" = REF(Bot), "mule_check" = FALSE)
+ var/list/newbot = list("name" = Bot.name, "mode" = Bot.get_mode_ui(), "model" = Bot.bot_type, "locat" = get_area(Bot), "bot_ref" = REF(Bot), "mule_check" = FALSE)
if(Bot.bot_type == MULE_BOT)
var/mob/living/simple_animal/bot/mulebot/MULE = Bot
mulelist += list(list("name" = MULE.name, "dest" = MULE.destination, "power" = MULE.cell ? MULE.cell.percent() : 0, "home" = MULE.home_destination, "autoReturn" = MULE.auto_return, "autoPickup" = MULE.auto_pickup, "reportDelivery" = MULE.report_delivery, "mule_ref" = REF(MULE)))