diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 7879b992b238e..2fa79e0611c0d 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -8297,14 +8297,7 @@
/area/maintenance/disposal)
"bkA" = (
/obj/effect/landmark/event_spawn,
-/mob/living/simple_animal/bot/secbot{
- arrest_type = 1;
- health = 45;
- icon_state = "secbot1";
- idcheck = 1;
- name = "Sergeant-at-Armsky";
- weaponscheck = 1
- },
+/mob/living/simple_animal/bot/secbot/beepsky/armsky,
/turf/open/floor/plasteel,
/area/ai_monitored/security/armory)
"bkB" = (
diff --git a/_maps/map_files/CorgStation/CorgStation.dmm b/_maps/map_files/CorgStation/CorgStation.dmm
index 56e6ad1257c2a..259ac7ee7fbae 100644
--- a/_maps/map_files/CorgStation/CorgStation.dmm
+++ b/_maps/map_files/CorgStation/CorgStation.dmm
@@ -43,14 +43,7 @@
dir = 1
},
/obj/effect/turf_decal/stripes/line,
-/mob/living/simple_animal/bot/secbot{
- arrest_type = 1;
- health = 45;
- icon_state = "secbot1";
- idcheck = 1;
- name = "Sergeant-at-Armsky";
- weaponscheck = 1
- },
+/mob/living/simple_animal/bot/secbot/beepsky/armsky,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/security/armory)
"aaf" = (
diff --git a/_maps/map_files/FlandStation/FlandStation.dmm b/_maps/map_files/FlandStation/FlandStation.dmm
index 179620e1fe6b3..56cbb62c7c5a7 100644
--- a/_maps/map_files/FlandStation/FlandStation.dmm
+++ b/_maps/map_files/FlandStation/FlandStation.dmm
@@ -89471,14 +89471,7 @@
/obj/effect/turf_decal/trimline/red/filled/corner{
dir = 8
},
-/mob/living/simple_animal/bot/secbot{
- arrest_type = 1;
- health = 45;
- icon_state = "secbot1";
- idcheck = 1;
- name = "Sergeant-at-Armsky";
- weaponscheck = 1
- },
+/mob/living/simple_animal/bot/secbot/beepsky/armsky,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/security/armory)
"wAI" = (
diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm
index c97481150b60e..470b178e4dd41 100644
--- a/_maps/map_files/KiloStation/KiloStation.dmm
+++ b/_maps/map_files/KiloStation/KiloStation.dmm
@@ -78801,14 +78801,7 @@
/obj/structure/cable/yellow{
icon_state = "1-2"
},
-/mob/living/simple_animal/bot/secbot{
- arrest_type = 1;
- health = 45;
- icon_state = "secbot1";
- idcheck = 1;
- name = "Warden Armsky";
- weaponscheck = 1
- },
+/mob/living/simple_animal/bot/secbot/beepsky/armsky/warden,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer2{
dir = 1
},
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 4f3ed05d19d57..e1186e1d7991e 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -37136,14 +37136,7 @@
/turf/open/floor/plasteel,
/area/hallway/primary/port)
"gLe" = (
-/mob/living/simple_animal/bot/secbot{
- arrest_type = 1;
- health = 45;
- icon_state = "secbot1";
- idcheck = 1;
- name = "Sergeant-at-Armsky";
- weaponscheck = 1
- },
+/mob/living/simple_animal/bot/secbot/beepsky/armsky,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{
dir = 8
},
diff --git a/_maps/map_files/RadStation/RadStation.dmm b/_maps/map_files/RadStation/RadStation.dmm
index c3c12a8d19479..5046180a68878 100644
--- a/_maps/map_files/RadStation/RadStation.dmm
+++ b/_maps/map_files/RadStation/RadStation.dmm
@@ -17678,14 +17678,7 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{
dir = 4
},
-/mob/living/simple_animal/bot/secbot{
- arrest_type = 1;
- health = 45;
- icon_state = "secbot1";
- idcheck = 1;
- name = "Sergeant-at-Armsky";
- weaponscheck = 1
- },
+/mob/living/simple_animal/bot/secbot/beepsky/armsky,
/obj/structure/cable/yellow{
icon_state = "4-8"
},
diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm
index 0db4411562eb2..498359757d303 100644
--- a/code/__DEFINES/robots.dm
+++ b/code/__DEFINES/robots.dm
@@ -1,41 +1,152 @@
-/*ALL DEFINES FOR AIS, CYBORGS, AND SIMPLE ANIMAL BOTS*/
+/** AI defines */
#define DEFAULT_AI_LAWID "default"
+#define LAW_VALENTINES "valentines"
+#define LAW_DEVIL "devil"
+#define LAW_ZEROTH "zeroth"
+#define LAW_INHERENT "inherent"
+#define LAW_SUPPLIED "supplied"
+#define LAW_ION "ion"
+#define LAW_HACKED "hacked"
+
+//AI notification defines
+///Alert when a new Cyborg is created.
+#define AI_NOTIFICATION_NEW_BORG 1
+///Alert when a Cyborg selects a model.
+#define AI_NOTIFICATION_NEW_MODEL 2
+///Alert when a Cyborg changes their name.
+#define AI_NOTIFICATION_CYBORG_RENAMED 3
+///Alert when an AI disconnects themselves from their shell.
+#define AI_NOTIFICATION_AI_SHELL 4
+///Alert when a Cyborg gets disconnected from their AI.
+#define AI_NOTIFICATION_CYBORG_DISCONNECTED 5
+
+/** Cyborg defines */
+
+/// Special value to reset cyborg's lamp_cooldown
+#define BORG_LAMP_CD_RESET -1
+
+//Module slot define
+///The third module slots is disabed.
+#define BORG_MODULE_THREE_DISABLED (1<<0)
+///The second module slots is disabed.
+#define BORG_MODULE_TWO_DISABLED (1<<1)
+///All modules slots are disabled.
+#define BORG_MODULE_ALL_DISABLED (1<<2)
+
+//Cyborg module selection
+///First Borg module slot.
+#define BORG_CHOOSE_MODULE_ONE 1
+///Second Borg module slot.
+#define BORG_CHOOSE_MODULE_TWO 2
+///Third Borg module slot.
+#define BORG_CHOOSE_MODULE_THREE 3
+
+#define SKIN_ICON "skin_icon"
+#define SKIN_ICON_STATE "skin_icon_state"
+#define SKIN_PIXEL_X "skin_pixel_x"
+#define SKIN_PIXEL_Y "skin_pixel_y"
+#define SKIN_LIGHT_KEY "skin_light_key"
+#define SKIN_HAT_OFFSET "skin_hat_offset"
+#define SKIN_TRAITS "skin_traits"
+
+/** Simple Animal BOT 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
+#define ASSEMBLY_SIXTH_STEP 5
+#define ASSEMBLY_SEVENTH_STEP 6
+#define ASSEMBLY_EIGHTH_STEP 7
+#define ASSEMBLY_NINTH_STEP 8
//Bot defines, placed here so they can be read by other things!
-#define BOT_STEP_DELAY 4 //Delay between movemements
-#define BOT_STEP_MAX_RETRIES 5 //Maximum times a bot will retry to step from its position
+/// 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
-#define DEFAULT_SCAN_RANGE 7 //default view range for finding targets.
+//Bot types
+/// Secutritrons (Beepsky)
+#define SEC_BOT (1<<0)
+/// ED-209s
+#define ADVANCED_SEC_BOT (1<<1)
+/// MULEbots
+#define MULE_BOT (1<<2)
+/// Floorbots
+#define FLOOR_BOT (1<<3)
+/// Cleanbots
+#define CLEAN_BOT (1<<4)
+/// Medibots
+#define MED_BOT (1<<5)
+/// Honkbots & ED-Honks
+#define HONK_BOT (1<<6)
+/// Firebots
+#define FIRE_BOT (1<<7)
+/// Hygienebots
+//#define HYGIENE_BOT (1<<8)
+/// Vibe bots
+#define VIBE_BOT (1<<9)
//Mode defines
-#define BOT_IDLE 0 //! idle
-#define BOT_HUNT 1 //! found target, hunting
-#define BOT_PREP_ARREST 2 //! at target, preparing to arrest
-#define BOT_ARREST 3 //! arresting target
-#define BOT_START_PATROL 4 //! start patrol
-#define BOT_PATROL 5 //! patrolling
-#define BOT_SUMMON 6 //! summoned by PDA
-#define BOT_CLEANING 7 //! cleaning (cleanbots)
-#define BOT_REPAIRING 8 //! repairing hull breaches (floorbots)
-#define BOT_MOVING 9 //! for clean/floor/med bots, when moving.
-#define BOT_HEALING 10 //! healing people (medbots)
-#define BOT_RESPONDING 11 //! responding to a call from the AI
-#define BOT_DELIVER 12 //! moving to deliver
-#define BOT_GO_HOME 13 //! returning to home
-#define BOT_BLOCKED 14 //! blocked
-#define BOT_NAV 15 //! computing navigation
-#define BOT_WAIT_FOR_NAV 16 //! waiting for nav computation
-#define BOT_NO_ROUTE 17 //! no destination beacon found (or no route)
+/// Idle
+#define BOT_IDLE 0
+/// Found target, hunting
+#define BOT_HUNT 1
+/// Currently tipped over.
+#define BOT_TIPPED 2
+/// Start patrol
+#define BOT_START_PATROL 3
+/// Patrolling
+#define BOT_PATROL 4
+/// Summoned to a location
+#define BOT_SUMMON 5
+/// Currently moving
+#define BOT_MOVING 6
+/// Secbot - At target, preparing to arrest
+#define BOT_PREP_ARREST 7
+/// Secbot - Arresting target
+#define BOT_ARREST 8
-//Bot types
-#define SEC_BOT (1<<0) //! Secutritrons (Beepsky) and ED-209s
-#define MULE_BOT (1<<1) //! MULEbots
-#define FLOOR_BOT (1<<2) //! Floorbots
-#define CLEAN_BOT (1<<3) //! Cleanbots
-#define MED_BOT (1<<4) //! Medibots
-#define HONK_BOT (1<<5) //! Honkbots & ED-Honks
-#define FIRE_BOT (1<<6) //! Firebots
+/// Cleanbot - Cleaning
+#define BOT_CLEANING 9
+/// Hygienebot - Cleaning unhygienic humans
+//#define BOT_SHOWERSTANCE 10
+/// Floorbots - Repairing hull breaches
+#define BOT_REPAIRING 11
+/// Medibots - Healing people
+#define BOT_HEALING 12
+/// Responding to a call from the AI
+#define BOT_RESPONDING 13
+/// MULEbot - Moving to deliver
+#define BOT_DELIVER 14
+/// MULEbot - Returning to home
+#define BOT_GO_HOME 15
+/// MULEbot - Blocked
+#define BOT_BLOCKED 16
+/// MULEbot - Computing navigation
+#define BOT_NAV 17
+/// MULEbot - Waiting for nav computation
+#define BOT_WAIT_FOR_NAV 18
+/// MULEbot - No destination beacon found (or no route)
+#define BOT_NO_ROUTE 19
+
+//SecBOT defines on arresting
+///Whether arrests should be broadcasted over the Security radio
+#define SECBOT_DECLARE_ARRESTS (1<<0)
+///Will arrest people who lack an ID card
+#define SECBOT_CHECK_IDS (1<<1)
+///Will check for weapons, taking Weapons access into account
+#define SECBOT_CHECK_WEAPONS (1<<2)
+///Will check Security record on whether to arrest
+#define SECBOT_CHECK_RECORDS (1<<3)
+///Whether we will stun & cuff or endlessly stun
+#define SECBOT_HANDCUFF_TARGET (1<<4)
//transfer_ai() defines. Main proc in ai_core.dm
///Downloading AI to InteliCard
@@ -46,15 +157,13 @@
#define AI_MECH_HACK 3
//AI notification defines
-#define NEW_BORG 1
-#define NEW_MODULE 2
-#define RENAME 3
-#define AI_SHELL 4
-#define DISCONNECT 5
-
-//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
+///Alert when a new Cyborg is created.
+#define NEW_BORG 1
+///Alert when a Cyborg selects a model.
+#define NEW_MODULE 2
+///Alert when a Cyborg changes their name.
+#define RENAME 3
+///Alert when an AI disconnects themselves from their shell.
+#define AI_SHELL 4
+///Alert when a Cyborg gets disconnected from their AI.
+#define DISCONNECT 5
diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm
index b2708f99042f3..99818cc05f7df 100644
--- a/code/controllers/subsystem/traumas.dm
+++ b/code/controllers/subsystem/traumas.dm
@@ -36,7 +36,7 @@ SUBSYSTEM_DEF(traumas)
)
phobia_mobs = list("spiders" = typecacheof(list(/mob/living/simple_animal/hostile/poison/giant_spider)),
- "security" = typecacheof(list(/mob/living/simple_animal/bot/secbot, /mob/living/simple_animal/bot/ed209)),
+ "security" = typecacheof(list(/mob/living/simple_animal/bot/secbot)),
"lizards" = typecacheof(list(/mob/living/simple_animal/hostile/lizard)),
"skeletons" = typecacheof(list(/mob/living/simple_animal/hostile/skeleton)),
"snakes" = typecacheof(list(/mob/living/simple_animal/hostile/retaliate/poison/snake)),
@@ -46,7 +46,7 @@ SUBSYSTEM_DEF(traumas)
"the supernatural" = typecacheof(list(/mob/living/simple_animal/hostile/construct,
/mob/living/simple_animal/revenant, /mob/living/simple_animal/shade)),
"aliens" = typecacheof(list(/mob/living/carbon/alien, /mob/living/simple_animal/slime)),
- "conspiracies" = typecacheof(list(/mob/living/simple_animal/bot/secbot, /mob/living/simple_animal/bot/ed209, /mob/living/simple_animal/drone,
+ "conspiracies" = typecacheof(list(/mob/living/simple_animal/bot/secbot, /mob/living/simple_animal/drone,
/mob/living/simple_animal/pet/penguin)),
"birds" = typecacheof(list(/mob/living/simple_animal/parrot, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken,
/mob/living/simple_animal/pet/penguin)),
diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm
index 2d2b6344ccf2d..83b8711b397ea 100644
--- a/code/datums/ai_laws.dm
+++ b/code/datums/ai_laws.dm
@@ -1,11 +1,3 @@
-#define LAW_VALENTINES "valentines"
-#define LAW_DEVIL "devil"
-#define LAW_ZEROTH "zeroth"
-#define LAW_INHERENT "inherent"
-#define LAW_SUPPLIED "supplied"
-#define LAW_ION "ion"
-#define LAW_HACKED "hacked"
-
/datum/ai_laws
var/name = "Unknown Laws"
diff --git a/code/datums/components/crafting/recipes.dm b/code/datums/components/crafting/recipes.dm
index 64c2a5ce940f0..129af4f1284e7 100644
--- a/code/datums/components/crafting/recipes.dm
+++ b/code/datums/components/crafting/recipes.dm
@@ -158,7 +158,7 @@
/datum/crafting_recipe/ed209
name = "ED209"
- result = /mob/living/simple_animal/bot/ed209
+ result = /mob/living/simple_animal/bot/secbot/ed209
reqs = list(/obj/item/robot_suit = 1,
/obj/item/clothing/head/helmet = 1,
/obj/item/clothing/suit/armor/vest = 1,
@@ -166,8 +166,7 @@
/obj/item/bodypart/r_leg/robot = 1,
/obj/item/stack/sheet/iron = 1,
/obj/item/stack/cable_coil = 1,
- /obj/item/gun/energy/e_gun/dragnet = 1,
- /obj/item/stock_parts/cell = 1,
+ /obj/item/gun/energy/disabler = 1,
/obj/item/assembly/prox_sensor = 1)
tools = list(TOOL_WELDER, TOOL_SCREWDRIVER)
time = 60
diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm
index 37a5b4b5abce3..2dfac76e34e4c 100644
--- a/code/datums/wires/robot.dm
+++ b/code/datums/wires/robot.dm
@@ -36,13 +36,13 @@
new_ai = select_active_ai(user)
else
new_ai = select_active_ai(R)
- R.notify_ai(DISCONNECT)
+ R.notify_ai(AI_NOTIFICATION_CYBORG_DISCONNECTED)
if(new_ai && (new_ai != R.connected_ai))
log_combat(usr, R, "synced cyborg [R.connected_ai ? "from [ADMIN_LOOKUP(R.connected_ai)]": "false"] to [ADMIN_LOOKUP(new_ai)]")
R.connected_ai = new_ai
if(R.shell)
R.undeploy() //If this borg is an AI shell, disconnect the controlling AI and assign ti to a new AI
- R.notify_ai(AI_SHELL)
+ R.notify_ai(AI_NOTIFICATION_AI_SHELL)
else
R.notify_ai(TRUE)
if(WIRE_CAMERA) // Pulse to disable the camera.
@@ -71,7 +71,7 @@
switch(wire)
if(WIRE_AI) // Cut the AI wire to reset AI control.
if(!mend)
- R.notify_ai(DISCONNECT)
+ R.notify_ai(AI_NOTIFICATION_AI_SHELL)
log_combat(usr, R, "cut AI wire on cyborg[R.connected_ai ? " and disconnected from [ADMIN_LOOKUP(R.connected_ai)]": ""]")
if(R.shell)
R.undeploy()
diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm
index e9884d629b4e9..4b0f0a0bf191e 100644
--- a/code/game/machinery/transformer.dm
+++ b/code/game/machinery/transformer.dm
@@ -107,4 +107,4 @@
sleep(30)
if(R)
R.SetLockdown(FALSE)
- R.notify_ai(NEW_BORG)
+ R.notify_ai(AI_NOTIFICATION_NEW_BORG)
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index 1434c998ed1e5..e2da919b498f2 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -25,11 +25,11 @@
if(user_unbuckle_mob(buckled_mobs[1],user))
return TRUE
-/atom/movable/attackby(obj/item/W, mob/user, params)
- if(!can_buckle || !istype(W, /obj/item/riding_offhand) || !user.Adjacent(src))
+/atom/movable/attackby(obj/item/attacking_item, mob/user, params)
+ if(!can_buckle || !istype(attacking_item, /obj/item/riding_offhand) || !user.Adjacent(src))
return ..()
- var/obj/item/riding_offhand/riding_item = W
+ var/obj/item/riding_offhand/riding_item = attacking_item
var/mob/living/carried_mob = riding_item.rider
if(carried_mob == user) //Piggyback user.
return
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index d593e23866fdd..056a2289e10ac 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -293,7 +293,7 @@
lawsync = 0
O.connected_ai = null
else
- O.notify_ai(NEW_BORG)
+ O.notify_ai(AI_NOTIFICATION_NEW_BORG)
if(forced_ai)
O.connected_ai = forced_ai
if(!lawsync)
@@ -354,7 +354,7 @@
else
if(forced_ai)
O.connected_ai = forced_ai
- O.notify_ai(AI_SHELL)
+ O.notify_ai(AI_NOTIFICATION_AI_SHELL)
if(!lawsync)
O.lawupdate = FALSE
O.make_laws()
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index 9094c2668aa7e..8e458a26aaf8c 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -53,7 +53,7 @@
R.custom_name = heldname
R.updatename()
if(oldname == R.real_name)
- R.notify_ai(RENAME, oldname, R.real_name)
+ R.notify_ai(AI_NOTIFICATION_CYBORG_RENAMED, oldname, R.real_name)
log_game("[key_name(user)] have used a cyborg reclassification board to rename [oldkeyname] to [key_name(R)] at [loc_name(user)]")
/obj/item/borg/upgrade/restart
@@ -564,7 +564,7 @@
if (.)
if(R.shell)
R.undeploy()
- R.notify_ai(AI_SHELL)
+ R.notify_ai(AI_NOTIFICATION_AI_SHELL)
/obj/item/borg/upgrade/expand
name = "borg expander"
diff --git a/code/modules/admin/verbs/borgpanel.dm b/code/modules/admin/verbs/borgpanel.dm
index 77e2b5acb12bc..e30c6e4e3bfaf 100644
--- a/code/modules/admin/verbs/borgpanel.dm
+++ b/code/modules/admin/verbs/borgpanel.dm
@@ -200,7 +200,7 @@
if ("slavetoai")
var/mob/living/silicon/ai/newai = locate(params["slavetoai"]) in GLOB.ai_list
if (newai && newai != borg.connected_ai)
- borg.notify_ai(DISCONNECT)
+ borg.notify_ai(AI_NOTIFICATION_CYBORG_DISCONNECTED)
if(borg.shell)
borg.undeploy()
borg.connected_ai = newai
@@ -208,7 +208,7 @@
message_admins("[key_name_admin(user)] slaved [ADMIN_LOOKUPFLW(borg)] to the AI [ADMIN_LOOKUPFLW(newai)].")
log_admin("[key_name(user)] slaved [key_name(borg)] to the AI [key_name(newai)].")
else if (params["slavetoai"] == "null")
- borg.notify_ai(DISCONNECT)
+ borg.notify_ai(AI_NOTIFICATION_CYBORG_DISCONNECTED)
if(borg.shell)
borg.undeploy()
borg.connected_ai = null
diff --git a/code/modules/jobs/job_types/cyborg.dm b/code/modules/jobs/job_types/cyborg.dm
index 3a46423433e18..e732bca9677a6 100644
--- a/code/modules/jobs/job_types/cyborg.dm
+++ b/code/modules/jobs/job_types/cyborg.dm
@@ -24,11 +24,12 @@
CRASH("dynamic preview is unsupported")
return H.Robotize(FALSE, latejoin)
-/datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, mob/M, latejoin = FALSE, client/preference_source, on_dummy = FALSE)
+/datum/job/cyborg/after_spawn(mob/living/silicon/robot/spawned_robot, mob/M, latejoin = FALSE, client/preference_source, on_dummy = FALSE)
if(!M.client || on_dummy)
return
- R.updatename(M.client)
- R.gender = NEUTER
+ spawned_robot.updatename(M.client)
+ spawned_robot.gender = NEUTER
+ spawned_robot.notify_ai(AI_NOTIFICATION_NEW_BORG)
/datum/job/cyborg/radio_help_message(mob/M)
to_chat(M, "Prefix your message with :b to speak with other cyborgs and AI.")
diff --git a/code/modules/mob/dead/observer/login.dm b/code/modules/mob/dead/observer/login.dm
index 9bb48f0c46380..6374b269b6a7b 100644
--- a/code/modules/mob/dead/observer/login.dm
+++ b/code/modules/mob/dead/observer/login.dm
@@ -6,7 +6,7 @@
var/preferred_form = null
if(IsAdminGhost(src))
- has_unlimited_silicon_privilege = 1
+ has_unlimited_silicon_privilege = TRUE
if(client.prefs.unlock_content)
preferred_form = client.prefs.read_player_preference(/datum/preference/choiced/ghost_form)
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 9f38adbc636d0..a08a8abf89877 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -933,15 +933,15 @@
if(!connected_ai)
return
switch(notifytype)
- if(NEW_BORG) //New Cyborg
+ if(AI_NOTIFICATION_NEW_BORG) //New Cyborg
to_chat(connected_ai, "
NOTICE - New cyborg connection detected: [name]
")
- if(NEW_MODULE) //New Module
+ if(AI_NOTIFICATION_NEW_MODEL) //New Model
to_chat(connected_ai, "
NOTICE - Cyborg module change detected: [name] has loaded the [designation] module.
")
- if(RENAME) //New Name
+ if(AI_NOTIFICATION_CYBORG_RENAMED) //New Name
to_chat(connected_ai, "
NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].
")
- if(AI_SHELL) //New Shell
+ if(AI_NOTIFICATION_AI_SHELL) //New Shell
to_chat(connected_ai, "
NOTICE - New cyborg shell detected: [name]
")
- if(DISCONNECT) //Tampering with the wires
+ if(AI_NOTIFICATION_CYBORG_DISCONNECTED) //Tampering with the wires
to_chat(connected_ai, "
NOTICE - Remote telemetry lost with [name].
")
/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close=FALSE, no_dexterity=FALSE, no_tk=FALSE)
@@ -1043,14 +1043,14 @@
builtInCamera.toggle_cam(src,0)
if(admin_revive)
locked = TRUE
- notify_ai(NEW_BORG)
+ notify_ai(AI_NOTIFICATION_NEW_BORG)
wires.ui_update()
. = 1
/mob/living/silicon/robot/fully_replace_character_name(oldname, newname)
..()
if(oldname != real_name)
- notify_ai(RENAME, oldname, newname)
+ notify_ai(AI_NOTIFICATION_CYBORG_RENAMED, oldname, newname)
if(!QDELETED(builtInCamera))
builtInCamera.c_tag = real_name
modularInterface.saved_identification = real_name
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index faa7cffbacbd7..19e4c715974ee 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -238,7 +238,7 @@
R.anchored = FALSE
R.notransform = FALSE
R.update_icons()
- R.notify_ai(NEW_MODULE)
+ R.notify_ai(AI_NOTIFICATION_NEW_MODEL)
if(R.hud_used)
R.hud_used.update_robot_modules_display()
SSblackbox.record_feedback("tally", "cyborg_modules", 1, R.module)
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 4ed9a04c30f0d..511bbc43d4a84 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -1,6 +1,6 @@
/mob/living/silicon
gender = NEUTER
- has_unlimited_silicon_privilege = 1
+ has_unlimited_silicon_privilege = TRUE
verb_say = "states"
verb_ask = "queries"
verb_exclaim = "declares"
diff --git a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm
index 671f5bf797887..225a34b609911 100644
--- a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm
+++ b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm
@@ -5,12 +5,12 @@
icon_state = "grievous"
health = 150
maxHealth = 150
+
baton_type = /obj/item/melee/transforming/energy/sword/saber
base_speed = 4 //he's a fast fucker
- var/obj/item/weapon
- var/block_chance = 50
- noloot = FALSE
+ weapon_force = 30
+ var/block_chance = 50
/mob/living/simple_animal/bot/secbot/grievous/toy //A toy version of general beepsky!
name = "Genewul Bweepskee"
@@ -18,17 +18,7 @@
health = 50
maxHealth = 50
baton_type = /obj/item/toy/sword
-
-/mob/living/simple_animal/bot/secbot/grievous/nullcrate
- name = "General Griefsky"
- desc = "The Syndicate sends their regards."
- emagged = 2
- noloot = TRUE
- faction = list(FACTION_SYNDICATE)
-
-/mob/living/simple_animal/bot/secbot/grievous/nullcrate/ComponentInitialize()
- . = ..()
- AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_CONTENTS | EMP_PROTECT_WIRES)
+ weapon_force = 0
/mob/living/simple_animal/bot/secbot/grievous/bullet_act(obj/projectile/P)
visible_message("[src] deflects [P] with its energy swords!")
@@ -44,8 +34,7 @@
/mob/living/simple_animal/bot/secbot/grievous/Initialize(mapload)
. = ..()
- weapon = new baton_type(src)
- weapon.attack_self(src)
+ INVOKE_ASYNC(weapon, TYPE_PROC_REF(/obj/item, attack_self), src)
/mob/living/simple_animal/bot/secbot/grievous/Destroy()
QDEL_NULL(weapon)
@@ -71,27 +60,27 @@
if(!on)
return
switch(mode)
- if(BOT_IDLE) // idle
- update_icon()
+ if(BOT_IDLE) // idle
+ update_appearance()
SSmove_manager.stop_looping(src)
look_for_perp() // see if any criminals are in range
- if(!mode && auto_patrol) // still idle, and set to patrol
- mode = BOT_START_PATROL // switch to patrol mode
- if(BOT_HUNT) // hunting for perp
- update_icon()
+ if(!mode && auto_patrol) // still idle, and set to patrol
+ mode = BOT_START_PATROL // switch to patrol mode
+ if(BOT_HUNT) // hunting for perp
+ update_appearance()
playsound(src,'sound/effects/beepskyspinsabre.ogg',100,TRUE,-1)
// general beepsky doesn't give up so easily, jedi scum
if(frustration >= 20)
SSmove_manager.stop_looping(src)
back_to_idle()
return
- if(target) // make sure target exists
- if(Adjacent(target) && isturf(target.loc)) // if right next to perp
+ if(target) // make sure target exists
+ if(Adjacent(target) && isturf(target.loc)) // if right next to perp
target_lastloc = target.loc //stun_attack() can clear the target if they're dead, so this needs to be set first
stun_attack(target)
anchored = TRUE
return
- else // not next to perp
+ else // not next to perp
var/turf/olddist = get_dist(src, target)
SSmove_manager.move_to(src, target, 1, 4)
if((get_dist(src, target)) >= (olddist))
@@ -111,7 +100,7 @@
/mob/living/simple_animal/bot/secbot/grievous/look_for_perp()
anchored = FALSE
- var/judgment_criteria = judgment_criteria()
+ var/judgement_criteria = judgement_criteria()
for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
if((C.stat) || (C.handcuffed))
continue
@@ -119,7 +108,7 @@
if((C.name == oldtarget_name) && (world.time < last_found + 100))
continue
- threatlevel = C.assess_threat(judgment_criteria, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
+ threatlevel = C.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
if(!threatlevel)
continue
@@ -130,7 +119,7 @@
speak("Level [threatlevel] infraction alert!")
playsound(src, pick('sound/voice/beepsky/criminal.ogg', 'sound/voice/beepsky/justice.ogg', 'sound/voice/beepsky/freeze.ogg'), 50, FALSE)
playsound(src,'sound/weapons/saberon.ogg',50,TRUE,-1)
- visible_message("[src] ignites his energy swords!")
+ visible_message("[src] ignites his energy swords!")
icon_state = "grievous-c"
visible_message("[src] points at [C.name]!")
mode = BOT_HUNT
@@ -141,22 +130,9 @@
/mob/living/simple_animal/bot/secbot/grievous/explode()
-
+ ..()
visible_message("[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)
- if(!noloot)
- for(var/IS = 0 to 4)
- drop_part(baton_type, Tsec)
- new /obj/effect/decal/cleanable/oil(Tsec)
- qdel(src)
+ //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)
diff --git a/code/modules/mob/living/simple_animal/bot/atmosbot.dm b/code/modules/mob/living/simple_animal/bot/atmosbot.dm
index 6a42640d86618..2e830bcb8058d 100644
--- a/code/modules/mob/living/simple_animal/bot/atmosbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/atmosbot.dm
@@ -383,8 +383,5 @@
if(deployed_holobarrier)
qdel(deployed_holobarrier.resolve())
- if(prob(50))
- drop_part(robot_arm, Tsec)
-
do_sparks(3, TRUE, src)
..()
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 458afe1cceac6..0202b5b405504 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -10,7 +10,7 @@
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
maxbodytemp = INFINITY
minbodytemp = 0
- has_unlimited_silicon_privilege = 1
+ has_unlimited_silicon_privilege = TRUE
sentience_type = SENTIENCE_ARTIFICIAL
status_flags = NONE //no default canpush
verb_say = "states"
@@ -37,7 +37,8 @@
var/window_width = 0 //0 for default size
var/window_height = 0
var/obj/item/paicard/paicard // Inserted pai card.
- var/allow_pai = 1 // Are we even allowed to insert a pai card.
+ ///If a pAI is allowed to be inserted into this bot.
+ var/allow_pai = TRUE
var/bot_name
var/list/player_access = list() //Additonal access the bots gets when player controlled
@@ -48,7 +49,8 @@
var/boot_delay = 4 SECONDS //how long the bot takes to turn on from the control panel
var/open = FALSE//Maint panel
var/locked = TRUE
- var/hacked = FALSE //Used to differentiate between being hacked by silicons and emagged by humans.
+ ///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.
@@ -61,7 +63,7 @@
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 = 0 //If enabled, the AI cannot *Remotely* control a bot. It can still control it through cameras.
+ 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
@@ -87,7 +89,7 @@
var/beacon_freq = FREQ_NAV_BEACON
var/model = "" //The type of bot it is.
- var/bot_type = 0 //The type of bot it is, for radio control.
+ 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.
var/list/mode_name = list("In Pursuit","Preparing to Arrest", "Arresting", \
@@ -222,6 +224,9 @@
/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/proc/should_emag(atom/target, mob/user)
SIGNAL_HANDLER
@@ -247,8 +252,8 @@
to_chat(user, "You bypass [src]'s controls.")
return
//Bot panel is unlocked by ID or emag, and the panel is screwed open. Ready for emagging.
- emagged = 2
- remote_disabled = 1 //Manually emagging the bot locks out the AI built in panel.
+ emagged = TRUE
+ remote_disabled = TRUE //Manually emagging the bot locks out the AI built in panel.
locked = TRUE //Access denied forever!
bot_reset()
turn_on() //The bot automatically turns on when emagged, unless recently hit with EMP.
@@ -293,15 +298,15 @@
ignorelistcleanuptimer++
if(!on || client)
- return
+ return FALSE
switch(mode) //High-priority overrides are processed first. Bots can do nothing else while under direct command.
- if(BOT_RESPONDING) //Called by the AI.
+ if(BOT_RESPONDING) //Called by the AI.
call_mode()
- return
- if(BOT_SUMMON) //Called by PDA
+ return FALSE
+ if(BOT_SUMMON) //Called to a location
bot_summon()
- return
+ return FALSE
return TRUE //Successful completion. Used to prevent child process() continuing if this one is ended early.
@@ -332,29 +337,29 @@
else
to_chat(user, "Access denied.")
-/mob/living/simple_animal/bot/attackby(obj/item/W, mob/user, params)
- if(W.tool_behaviour == TOOL_SCREWDRIVER)
+/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, "The maintenance panel is now [open ? "opened" : "closed"].")
else
to_chat(user, "The maintenance panel is locked.")
- else if(istype(W, /obj/item/card/id) || istype(W, /obj/item/modular_computer/tablet/pda))
+ else if(istype(attacking_item, /obj/item/card/id) || istype(attacking_item, /obj/item/modular_computer/tablet/pda))
togglelock(user)
- else if(istype(W, /obj/item/paicard))
- insertpai(user, W)
- else if((W.tool_behaviour == TOOL_HEMOSTAT) && paicard)
+ else if(istype(attacking_item, /obj/item/paicard))
+ insertpai(user, attacking_item)
+ else if((attacking_item.tool_behaviour == TOOL_HEMOSTAT) && paicard)
if(open)
to_chat(user, "Close the access panel before manipulating the personality slot!")
else
to_chat(user, "You attempt to pull [paicard] free...")
if(do_after(user, 30, target = src))
if (paicard)
- user.visible_message("[user] uses [W] to pull [paicard] out of [bot_name]!","You pull [paicard] out of [bot_name] with [W].")
+ user.visible_message("[user] uses [attacking_item] to pull [paicard] out of [bot_name]!","You pull [paicard] out of [bot_name] with [attacking_item].")
ejectpai(user)
else
user.changeNext_move(CLICK_CD_MELEE)
- if(W.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM)
+ if(attacking_item.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM)
if(health >= maxHealth)
to_chat(user, "[src] does not need a repair!")
return
@@ -362,11 +367,11 @@
to_chat(user, "Unable to repair with the maintenance panel closed!")
return
- if(W.use_tool(src, user, 0, volume=40))
+ if(attacking_item.use_tool(src, user, 0, volume=40))
adjustHealth(-10)
user.visible_message("[user] repairs [src]!","You repair [src].")
else
- if(W.force) //if force is non-zero
+ if(attacking_item.force) //if force is non-zero
do_sparks(5, TRUE, src)
..()
@@ -426,26 +431,24 @@
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_icon()
+ 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_icon()
+ dropped_gun.update_appearance()
//Generalized behavior code, override where needed!
@@ -778,7 +781,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 == 2 || remote_disabled) //Emagged bots do not respect anyone's authority! Bots with their remote controls off cannot get commands.
+ if(!on || emagged || remote_disabled) //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)
@@ -944,8 +947,8 @@ Pass a positive integer as an argument to override a bot's default speed.
if("hack")
if(!issilicon(usr) && !IsAdminGhost(usr))
return TRUE
- if(emagged != 2)
- emagged = 2
+ if(!emagged)
+ emagged = TRUE
hacked = TRUE
locked = TRUE
to_chat(usr, "[text_hack]")
@@ -1009,7 +1012,7 @@ 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 == 2) //An emagged bot cannot be controlled by humans, silicons can if one hacked it.
+ 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.
return TRUE
else if(!issilicon(user) && !IsAdminGhost(user)) //Bot is hacked, so only silicons and admins are allowed access.
@@ -1019,7 +1022,7 @@ Pass a positive integer as an argument to override a bot's default speed.
/mob/living/simple_animal/bot/proc/hack(mob/user)
var/hack
if(issilicon(user) || IsAdminGhost(user)) //Allows silicons or admins to toggle the emag status of a bot.
- hack += "[emagged == 2 ? "Software compromised! Unit may exhibit dangerous or erratic behavior." : "Unit operating normally. Release safety lock?"]
"
+ hack += "[emagged ? "Software compromised! Unit may exhibit dangerous or erratic behavior." : "Unit operating normally. Release safety lock?"]
"
hack += "Harm Prevention Safety System: [emagged ? "DANGER" : "Engaged"]
"
else if(!locked) //Humans with access can use this option to hide a bot from the AI's remote control panel and PDA control.
hack += "Remote network control radio: [remote_disabled ? "Disconnected" : "Connected"]
"
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index 316551de4f536..37fda4e3c47e1 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -85,9 +85,10 @@
/mob/living/simple_animal/bot/cleanbot/on_emag(atom/target, mob/user)
..()
- if(emagged == 2)
- if(user)
- to_chat(user, "[src] buzzes and beeps.")
+ if(!emagged)
+ return
+ if(user)
+ to_chat(user, "[src] buzzes and beeps.")
/mob/living/simple_animal/bot/cleanbot/process_scan(atom/A)
if(iscarbon(A))
@@ -104,9 +105,8 @@
if(mode == BOT_CLEANING)
return
- if(emagged == 2) //Emag functions
+ if(emagged) //Emag functions
if(isopenturf(loc))
-
for(var/mob/living/carbon/victim in loc)
if(victim != target)
UnarmedAttack(victim) // Acid spray
@@ -123,7 +123,7 @@
if(!process_scan(target))
target = null
- if(!target && emagged == 2) // When emagged, target humans who slipped on the water and melt their faces off
+ if(!target && 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.
@@ -227,7 +227,7 @@
M.death()
target = null
- else if(emagged == 2) //Emag functions
+ else if(emagged) //Emag functions
if(istype(A, /mob/living/carbon))
var/mob/living/carbon/victim = A
if(victim.stat == DEAD)//cleanbots always finish the job
@@ -275,9 +275,6 @@
new /obj/item/assembly/prox_sensor(Tsec)
- if(prob(50))
- drop_part(robot_arm, Tsec)
-
do_sparks(3, TRUE, src)
..()
@@ -341,7 +338,7 @@
M.death()
target = null
- else if(emagged == 2) //Emag functions
+ else if(emagged) //Emag functions
if(istype(A, /mob/living/carbon))
var/mob/living/carbon/victim = A
if(victim.stat == DEAD)//cleanbots always finish the job
@@ -408,8 +405,6 @@
new /obj/item/larryframe(Tsec)
new /obj/item/assembly/prox_sensor(Tsec)
- if(prob(50))
- drop_part(robot_arm, Tsec)
if(knife && prob(50))
new knife(Tsec)
diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm
index effb609e29453..cefbcea041807 100644
--- a/code/modules/mob/living/simple_animal/bot/construction.dm
+++ b/code/modules/mob/living/simple_animal/bot/construction.dm
@@ -100,21 +100,14 @@
build_step++
if(ASSEMBLY_THIRD_STEP)
- var/newcolor = ""
- if(istype(W, /obj/item/clothing/suit/redtag))
- newcolor = "r"
- else if(istype(W, /obj/item/clothing/suit/bluetag))
- newcolor = "b"
- if(newcolor || istype(W, /obj/item/clothing/suit/armor/vest))
+ if(istype(W, /obj/item/clothing/suit/armor/vest))
if(!user.temporarilyRemoveItemFromInventory(W))
return
- lasercolor = newcolor
- vest_type = W.type
to_chat(user, "You add [W] to [src].")
qdel(W)
name = "vest/legs/frame assembly"
- item_state = "[lasercolor]ed209_shell"
- icon_state = "[lasercolor]ed209_shell"
+ item_state = "ed209_shell"
+ icon_state = "ed209_shell"
build_step++
if(ASSEMBLY_FOURTH_STEP)
@@ -125,29 +118,17 @@
build_step++
if(ASSEMBLY_FIFTH_STEP)
- switch(lasercolor)
- if("b")
- if(!istype(W, /obj/item/clothing/head/helmet/bluetaghelm))
- return
-
- if("r")
- if(!istype(W, /obj/item/clothing/head/helmet/redtaghelm))
- return
-
- if("")
- if(!istype(W, /obj/item/clothing/head/helmet))
- return
+ if(istype(W, /obj/item/clothing/head/helmet))
+ if(!user.temporarilyRemoveItemFromInventory(W))
+ return
+ to_chat(user, "You add [W] to [src].")
+ qdel(W)
+ name = "covered and shielded frame assembly"
+ item_state = "ed209_hat"
+ icon_state = "ed209_hat"
+ build_step++
- if(!user.temporarilyRemoveItemFromInventory(W))
- return
- to_chat(user, "You add [W] to [src].")
- qdel(W)
- name = "covered and shielded frame assembly"
- item_state = "[lasercolor]ed209_hat"
- icon_state = "[lasercolor]ed209_hat"
- build_step++
-
- if(5)
+ if(ASSEMBLY_SIXTH_STEP)
if(isprox(W))
if(!user.temporarilyRemoveItemFromInventory(W))
return
@@ -155,10 +136,10 @@
to_chat(user, "You add [W] to [src].")
qdel(W)
name = "covered, shielded and sensored frame assembly"
- item_state = "[lasercolor]ed209_prox"
- icon_state = "[lasercolor]ed209_prox"
+ item_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)
@@ -166,35 +147,24 @@
return
to_chat(user, "You start to wire [src]...")
if(do_after(user, 40, target = src))
- if(coil.get_amount() >= 1 && build_step == 6)
+ if(coil.get_amount() >= 1 && build_step == ASSEMBLY_SEVENTH_STEP)
coil.use(1)
to_chat(user, "You wire [src].")
name = "wired ED-209 assembly"
build_step++
- if(7)
- switch(lasercolor)
- if("b")
- if(!istype(W, /obj/item/gun/energy/laser/bluetag))
- return
- if("r")
- if(!istype(W, /obj/item/gun/energy/laser/redtag))
- return
- if("")
- if(!istype(W, /obj/item/gun/energy/disabler))
- return
- else
+ if(ASSEMBLY_EIGHTH_STEP)
+ if(istype(W, /obj/item/gun/energy/disabler))
+ if(!user.temporarilyRemoveItemFromInventory(W))
return
- if(!user.temporarilyRemoveItemFromInventory(W))
- return
- name = "[W.name] ED-209 assembly"
- to_chat(user, "You add [W] to [src].")
- item_state = "[lasercolor]ed209_taser"
- icon_state = "[lasercolor]ed209_taser"
- qdel(W)
- build_step++
-
- if(8)
+ name = "[W.name] ED-209 assembly"
+ to_chat(user, "You add [W] to [src].")
+ item_state = "ed209_taser"
+ icon_state = "ed209_taser"
+ qdel(W)
+ build_step++
+
+ if(ASSEMBLY_NINTH_STEP)
if(W.tool_behaviour == TOOL_SCREWDRIVER)
to_chat(user, "You start attaching the gun to the frame...")
if(W.use_tool(src, user, 40, volume=100))
@@ -206,13 +176,10 @@
if(istype(W, /obj/item/stock_parts/cell))
if(!can_finish_build(W, user))
return
- var/mob/living/simple_animal/bot/ed209/B = new(drop_location(),created_name,lasercolor)
+ var/mob/living/simple_animal/bot/secbot/ed209/B = new(drop_location())
+ B.name = created_name
to_chat(user, "You complete the ED-209.")
- B.cell_type = W.type
- qdel(W)
- B.vest_type = vest_type
- qdel(src)
-
+ qdel(src) //make sure to delete the unfinished recipe when spawning in the actual mob
//Floorbot assemblies
/obj/item/bot_assembly/floorbot
@@ -337,7 +304,7 @@
to_chat(user, "You add the [I] to [src]! Honk!")
var/mob/living/simple_animal/bot/honkbot/S = new(drop_location())
S.name = created_name
- S.spam_flag = TRUE // only long enough to hear the first ping.
+ S.limiting_spam = TRUE // only long enough to hear the first ping.
addtimer(CALLBACK (S, TYPE_PROC_REF(/mob/living/simple_animal/bot/honkbot, react_ping)), 5)
S.bikehorn = I.type
qdel(I)
@@ -411,7 +378,7 @@
to_chat(user, "You complete the Securitron! Beep boop.")
var/mob/living/simple_animal/bot/secbot/S = new(Tsec)
S.name = created_name
- S.baton_type = I.type
+ S.weapon = 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 9ac10801ed956..8dd9d576641c7 100644
--- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
@@ -1,430 +1,71 @@
-/mob/living/simple_animal/bot/ed209
+/mob/living/simple_animal/bot/secbot/ed209
name = "\improper ED-209 Security Robot"
- desc = "A security robot. He looks less than thrilled."
- icon = 'icons/mob/aibots.dmi'
- icon_state = "ed2090"
+ desc = "A security robot. He looks less than thrilled."
+ icon_state = "ed209"
density = TRUE
- anchored = FALSE
health = 100
maxHealth = 100
- damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
obj_damage = 60
environment_smash = ENVIRONMENT_SMASH_WALLS //Walls can't stop THE LAW
mob_size = MOB_SIZE_LARGE
- radio_key = /obj/item/encryptionkey/headset_sec
- radio_channel = RADIO_CHANNEL_SECURITY
- bot_type = SEC_BOT
model = "ED-209"
- bot_core_type = /obj/machinery/bot_core/secbot
+ bot_type = ADVANCED_SEC_BOT
window_id = "autoed209"
window_name = "Automatic Security Unit v2.6"
- allow_pai = 0
- data_hud_type = DATA_HUD_SECURITY_ADVANCED
- path_image_color = "#FF0000"
- carryable = FALSE
var/lastfired = 0
var/shot_delay = 15
- var/lasercolor = ""
- var/disabled = FALSE //A holder for if it needs to be disabled, if true it will not seach for targets, shoot at targets, or move, currently only used for lasertag
-
-
- var/mob/living/carbon/target
- var/oldtarget_name
- var/threatlevel = 0
- var/target_lastloc //Loc of target when arrested.
- var/last_found //There's a delay
- var/declare_arrests = TRUE //When making an arrest, should it notify everyone wearing sechuds?
- var/idcheck = TRUE //If true, arrest people with no IDs
- var/weaponscheck = TRUE //If true, arrest people for weapons if they don't have access
- var/check_records = TRUE //Does it check security records?
- var/arrest_type = FALSE //If true, don't handcuff
- var/projectile = /obj/projectile/energy/electrode //Holder for projectile type
- var/shoot_sound = 'sound/weapons/taser2.ogg'
- var/cell_type = /obj/item/stock_parts/cell
- var/vest_type = /obj/item/clothing/suit/armor/vest
-
+ var/shoot_sound = 'sound/weapons/laser.ogg'
+ var/projectile = /obj/projectile/beam/disabler
do_footstep = TRUE
-/mob/living/simple_animal/bot/ed209/Initialize(mapload,created_name,created_lasercolor)
+/mob/living/simple_animal/bot/secbot/ed209/Initialize(mapload)
. = ..()
- if(created_name)
- name = created_name
- if(created_lasercolor)
- lasercolor = created_lasercolor
- icon_state = "[lasercolor]ed209[on]"
set_weapon() //giving it the right projectile and firing sound.
- var/datum/job/J = SSjob.GetJob(JOB_NAME_DETECTIVE)
- access_card.access = J.get_access()
- prev_access = access_card.access.Copy()
- if(lasercolor)
- shot_delay = 6//Longer shot delay because JESUS CHRIST
- check_records = 0//Don't actively target people set to arrest
- arrest_type = 1//Don't even try to cuff
- bot_core.req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE)
- arrest_type = 1
- if((lasercolor == "b") && (name == "\improper ED-209 Security Robot"))//Picks a name if there isn't already a custome one
- name = pick("BLUE BALLER","SANIC","BLUE KILLDEATH MURDERBOT")
- if((lasercolor == "r") && (name == "\improper ED-209 Security Robot"))
- name = pick("RED RAMPAGE","RED ROVER","RED KILLDEATH MURDERBOT")
-
- //SECHUD
- var/datum/atom_hud/secsensor = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
- secsensor.add_hud_to(src)
-
-/mob/living/simple_animal/bot/ed209/turn_on()
- . = ..()
- icon_state = "[lasercolor]ed209[on]"
- mode = BOT_IDLE
-
-/mob/living/simple_animal/bot/ed209/turn_off()
- ..()
- icon_state = "[lasercolor]ed209[on]"
-
-/mob/living/simple_animal/bot/ed209/bot_reset()
+/mob/living/simple_animal/bot/secbot/ed209/bot_reset()
..()
- target = null
- oldtarget_name = null
- anchored = FALSE
- SSmove_manager.stop_looping(src)
- last_found = world.time
set_weapon()
-/mob/living/simple_animal/bot/ed209/electrocute_act(shock_damage, source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
- return 0
-
-/mob/living/simple_animal/bot/ed209/set_custom_texts()
+/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/ed209/get_controls(mob/user)
- var/dat
- dat += hack(user)
- dat += showpai(user)
- dat += "Security Unit v2.6 controls
"
- dat += "
Status: [on ? "On" : "Off"]"
- dat += "
Behaviour controls are [locked ? "locked" : "unlocked"]"
- dat += "
Maintenance panel panel is [open ? "opened" : "closed"]"
-
- if(!locked || issilicon(user)|| IsAdminGhost(user))
- if(!lasercolor)
- dat += "
"
- dat += "
Arrest Unidentifiable Persons: [idcheck ? "Yes" : "No"]"
- dat += "
Arrest for Unauthorized Weapons: [weaponscheck ? "Yes" : "No"]"
- dat += "
Arrest for Warrant: [check_records ? "Yes" : "No"]"
- dat += "
Operating Mode: [arrest_type ? "Detain" : "Arrest"]"
- dat += "
Report Arrests [declare_arrests ? "Yes" : "No"]"
- dat += "
Auto Patrol [auto_patrol ? "On" : "Off"]"
- return dat
-
-/mob/living/simple_animal/bot/ed209/Topic(href, href_list)
- if(lasercolor && ishuman(usr))
- var/mob/living/carbon/human/H = usr
- if((lasercolor == "b") && (istype(H.wear_suit, /obj/item/clothing/suit/redtag)))//Opposing team cannot operate it
- return
- else if((lasercolor == "r") && (istype(H.wear_suit, /obj/item/clothing/suit/bluetag)))
- return
- if(..())
- return 1
-
- switch(href_list["operation"])
- if("idcheck")
- idcheck = !idcheck
- update_controls()
- if("weaponscheck")
- weaponscheck = !weaponscheck
- update_controls()
- if("ignorerec")
- check_records = !check_records
- update_controls()
- if("switchmode")
- arrest_type = !arrest_type
- update_controls()
- if("declarearrests")
- declare_arrests = !declare_arrests
- update_controls()
-
-/mob/living/simple_animal/bot/ed209/proc/judgment_criteria()
- var/final = FALSE
- if(idcheck)
- final = final|JUDGE_IDCHECK
- if(check_records)
- final = final|JUDGE_RECORDCHECK
- if(weaponscheck)
- final = final|JUDGE_WEAPONCHECK
- if(emagged == 2)
- final = final|JUDGE_EMAGGED
- //ED209's ignore monkeys
- final = final|JUDGE_IGNOREMONKEYS
- return final
-
-/mob/living/simple_animal/bot/ed209/proc/retaliate(mob/living/carbon/human/H)
- var/judgment_criteria = judgment_criteria()
- threatlevel = H.assess_threat(judgment_criteria, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
- threatlevel += 6
- if(threatlevel >= 4)
- target = H
- mode = BOT_HUNT
-
-/mob/living/simple_animal/bot/ed209/attack_hand(mob/living/carbon/human/H)
- if(H.a_intent == INTENT_HARM)
- retaliate(H)
- return ..()
-
-/mob/living/simple_animal/bot/ed209/attackby(obj/item/W, mob/user, params)
+/mob/living/simple_animal/bot/secbot/ed209/on_emag(atom/target, mob/user)
..()
- if(W.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry.
- return
- if(W.tool_behaviour != TOOL_SCREWDRIVER && (!target)) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
- if(W.force && W.damtype != STAMINA)//If force is non-zero and damage type isn't stamina.
- retaliate(user)
- if(lasercolor)//To make up for the fact that lasertag bots don't hunt
- shootAt(user)
-
-/mob/living/simple_animal/bot/ed209/on_emag(atom/target, mob/user)
- ..()
- if(emagged == 2)
- if(user)
- to_chat(user, "You short out [src]'s target assessment circuits.")
- oldtarget_name = user.name
- audible_message("[src] buzzes oddly!")
- declare_arrests = FALSE
- icon_state = "[lasercolor]ed209[on]"
- set_weapon()
-
-/mob/living/simple_animal/bot/ed209/bullet_act(obj/projectile/Proj)
- if(istype(Proj , /obj/projectile/beam/laser)||istype(Proj, /obj/projectile/bullet))
- if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
- if(!Proj.nodamage && Proj.damage < src.health && ishuman(Proj.firer))
- retaliate(Proj.firer)
- return ..()
-
-/mob/living/simple_animal/bot/ed209/handle_automated_action()
- if(!..())
- return
-
- if(disabled)
- return
+ icon_state = "ed209[on]"
+ set_weapon()
- var/judgment_criteria = judgment_criteria()
+/mob/living/simple_animal/bot/secbot/ed209/handle_automated_action()
+ var/judgement_criteria = judgement_criteria()
var/list/targets = list()
- for(var/mob/living/carbon/C in view(7,src)) //Let's find us a target
+ for(var/mob/living/carbon/nearby_carbon in view(7, src)) //Let's find us a target
var/threatlevel = 0
- if(C.incapacitated())
+ if(nearby_carbon.incapacitated())
continue
- threatlevel = C.assess_threat(judgment_criteria, lasercolor, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
- //speak(C.real_name + ": threat: [threatlevel]")
+ threatlevel = nearby_carbon.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
if(threatlevel < 4 )
continue
-
- var/dst = get_dist(src, C)
+ var/dst = get_dist(src, nearby_carbon)
if(dst <= 1 || dst > 7)
continue
-
- targets += C
- if(targets.len>0)
- var/mob/living/carbon/t = pick(targets)
- if(t.stat != DEAD && (t.mobility_flags & MOBILITY_STAND) && !t.handcuffed) //we don't shoot people who are dead, cuffed or lying down.
- shootAt(t)
- switch(mode)
-
- if(BOT_IDLE) // idle
- SSmove_manager.stop_looping(src)
- if(!lasercolor) //lasertag bots don't want to arrest anyone
- look_for_perp() // see if any criminals are in range
- if(!mode && auto_patrol) // still idle, and set to patrol
- mode = BOT_START_PATROL // switch to patrol mode
-
- if(BOT_HUNT) // hunting for perp
- // if can't reach perp for long enough, go idle
- if(frustration >= 8)
- SSmove_manager.stop_looping(src)
- back_to_idle()
-
- if(target) // make sure target exists
- if(Adjacent(target) && isturf(target.loc)) // if right next to perp
- stun_attack(target)
-
- mode = BOT_PREP_ARREST
- anchored = TRUE
- target_lastloc = target.loc
- return
-
- else // not next to perp
- var/turf/olddist = get_dist(src, target)
- SSmove_manager.move_to(src, target, 1, 4)
- if((get_dist(src, target)) >= (olddist))
- frustration++
- else
- frustration = 0
- else
- back_to_idle()
-
- if(BOT_PREP_ARREST) // preparing to arrest target
-
- // see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
- if(!Adjacent(target) || !isturf(target.loc) || target.AmountParalyzed() < 40)
- back_to_hunt()
- return
-
- if(iscarbon(target) && target.canBeHandcuffed())
- if(!arrest_type)
- if(!target.handcuffed) //he's not cuffed? Try to cuff him!
- cuff(target)
- else
- back_to_idle()
- return
- else
- back_to_idle()
- return
-
- if(BOT_ARREST)
- if(!target)
- anchored = FALSE
- mode = BOT_IDLE
- last_found = world.time
- frustration = 0
- return
-
- if(target.handcuffed) //no target or target cuffed? back to idle.
- back_to_idle()
- return
-
- if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.AmountParalyzed() < 40)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
- back_to_hunt()
- return
- else
- mode = BOT_PREP_ARREST
- anchored = FALSE
-
- if(BOT_START_PATROL)
- look_for_perp()
- start_patrol()
-
- if(BOT_PATROL)
- look_for_perp()
- bot_patrol()
-
-
- return
-
-/mob/living/simple_animal/bot/ed209/proc/back_to_idle()
- anchored = FALSE
- mode = BOT_IDLE
- target = null
- last_found = world.time
- frustration = 0
- INVOKE_ASYNC(src, PROC_REF(handle_automated_action)) //ensure bot quickly responds
-
-/mob/living/simple_animal/bot/ed209/proc/back_to_hunt()
- anchored = FALSE
- frustration = 0
- mode = BOT_HUNT
- INVOKE_ASYNC(src, PROC_REF(handle_automated_action)) //ensure bot quickly responds
-
-// look for a criminal in view of the bot
-
-/mob/living/simple_animal/bot/ed209/proc/look_for_perp()
- if(disabled)
- return
- anchored = FALSE
- threatlevel = 0
- var/judgment_criteria = judgment_criteria()
- for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
- if((C.stat) || (C.handcuffed))
- continue
-
- if((C.name == oldtarget_name) && (world.time < last_found + 100))
- continue
-
- threatlevel = C.assess_threat(judgment_criteria, lasercolor, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
-
- if(!threatlevel)
- continue
-
- else if(threatlevel >= 4)
- target = C
- oldtarget_name = C.name
- speak("Level [threatlevel] infraction alert!")
- playsound(src, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, FALSE)
- visible_message("[src] points at [C.name]!")
- mode = BOT_HUNT
- spawn(0)
- handle_automated_action() // ensure bot quickly responds to a perp
- break
- else
- continue
-
-/mob/living/simple_animal/bot/ed209/proc/check_for_weapons(var/obj/item/slot_item)
- if(slot_item && (slot_item.item_flags & NEEDS_PERMIT))
- return 1
- return 0
-
-/mob/living/simple_animal/bot/ed209/explode()
- SSmove_manager.stop_looping(src)
- visible_message("[src] blows apart!")
- var/atom/Tsec = drop_location()
-
- var/obj/item/bot_assembly/ed209/Sa = new (Tsec)
- Sa.build_step = 1
- Sa.add_overlay("hs_hole")
- Sa.created_name = name
- new /obj/item/assembly/prox_sensor(Tsec)
- drop_part(cell_type, Tsec)
-
- if(!lasercolor)
- var/obj/item/gun/energy/disabler/G = new (Tsec)
- G.cell.charge = 0
- G.update_icon()
- else if(lasercolor == "b")
- var/obj/item/gun/energy/laser/bluetag/G = new (Tsec)
- G.cell.charge = 0
- G.update_icon()
- else if(lasercolor == "r")
- var/obj/item/gun/energy/laser/redtag/G = new (Tsec)
- G.cell.charge = 0
- G.update_icon()
-
- if(prob(50))
- new /obj/item/bodypart/l_leg/robot(Tsec)
- if(prob(25))
- new /obj/item/bodypart/r_leg/robot(Tsec)
- if(prob(25))//50% chance for a helmet OR vest
- if(prob(50))
- new /obj/item/clothing/head/helmet(Tsec)
- else
- if(!lasercolor)
- drop_part(vest_type, Tsec)
- if(lasercolor == "b")
- new /obj/item/clothing/suit/bluetag(Tsec)
- if(lasercolor == "r")
- new /obj/item/clothing/suit/redtag(Tsec)
-
- do_sparks(3, TRUE, src)
-
- new /obj/effect/decal/cleanable/oil(loc)
+ targets += nearby_carbon
+ if(targets.len > 0)
+ var/mob/living/carbon/all_targets = pick(targets)
+ if(all_targets.stat != DEAD && !all_targets.handcuffed) //we don't shoot people who are dead, cuffed or lying down.
+ shoot_at(all_targets)
..()
-/mob/living/simple_animal/bot/ed209/proc/set_weapon() //used to update the projectile type and firing sound
+/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 == 2)
- if(lasercolor)
- projectile = /obj/projectile/beam/lasertag
- else
- projectile = /obj/projectile/beam
+ if(emagged)
+ projectile = /obj/projectile/beam
else
- if(!lasercolor)
- shoot_sound = 'sound/weapons/laser.ogg'
- projectile = /obj/projectile/beam/disabler
- else if(lasercolor == "b")
- projectile = /obj/projectile/beam/lasertag/bluetag
- else if(lasercolor == "r")
- projectile = /obj/projectile/beam/lasertag/redtag
+ projectile = /obj/projectile/beam/disabler
-/mob/living/simple_animal/bot/ed209/proc/shootAt(mob/target)
+/mob/living/simple_animal/bot/secbot/ed209/proc/shoot_at(mob/target)
if(world.time <= lastfired + shot_delay)
return
lastfired = world.time
@@ -434,142 +75,50 @@
return
if(!isturf(T))
return
-
if(!projectile)
return
- var/obj/projectile/A = new projectile (loc)
+ var/obj/projectile/fired_bullet = new projectile(loc)
playsound(src, shoot_sound, 50, TRUE)
- A.preparePixelProjectile(target, src)
- A.fire()
-
-/mob/living/simple_animal/bot/ed209/attack_alien(mob/living/carbon/alien/user)
- ..()
- if(!isalien(target))
- target = user
- mode = BOT_HUNT
-
+ fired_bullet.preparePixelProjectile(target, src)
+ fired_bullet.fire()
-/mob/living/simple_animal/bot/ed209/emp_act(severity)
+/mob/living/simple_animal/bot/secbot/ed209/emp_act(severity)
if(severity == 2 && prob(70))
severity = 1
. = ..()
if(. & EMP_PROTECT_SELF)
return
- if (severity >= 2)
- new /obj/effect/temp_visual/emp(loc)
- var/list/mob/living/carbon/targets = new
- for(var/mob/living/carbon/C in view(12,src))
- if(C.stat==DEAD)
- continue
- targets += C
- if(targets.len)
- if(prob(50))
- var/mob/toshoot = pick(targets)
- if(toshoot)
- targets-=toshoot
- if(prob(50) && emagged < 2)
- emagged = 2
- set_weapon()
- shootAt(toshoot)
- emagged = FALSE
- set_weapon()
- else
- shootAt(toshoot)
- else if(prob(50))
- if(targets.len)
- var/mob/toarrest = pick(targets)
- if(toarrest)
- target = toarrest
- mode = BOT_HUNT
-
-
-/mob/living/simple_animal/bot/ed209/bullet_act(obj/projectile/Proj)
- if(!disabled)
- var/lasertag_check = 0
- if((lasercolor == "b"))
- if(istype(Proj, /obj/projectile/beam/lasertag/redtag))
- lasertag_check++
- else if((lasercolor == "r"))
- if(istype(Proj, /obj/projectile/beam/lasertag/bluetag))
- lasertag_check++
- if(lasertag_check)
- icon_state = "[lasercolor]ed2090"
- disabled = TRUE
- target = null
- addtimer(CALLBACK(src, PROC_REF(reenable)), 100)
- return BULLET_ACT_HIT
- else
- . = ..()
- else
- . = ..()
-
-/mob/living/simple_animal/bot/ed209/proc/reenable()
- disabled = FALSE
- icon_state = "[lasercolor]ed2091"
-
-/mob/living/simple_animal/bot/ed209/bluetag
- lasercolor = "b"
-
-/mob/living/simple_animal/bot/ed209/redtag
- lasercolor = "r"
-
-/mob/living/simple_animal/bot/ed209/UnarmedAttack(atom/A)
- if(!on)
+ if(severity <= 1)
return
- if(iscarbon(A))
- var/mob/living/carbon/C = A
- if(!C.IsStun() || !C.IsParalyzed() || arrest_type)
- stun_attack(A)
- else if(C.canBeHandcuffed() && !C.handcuffed)
- cuff(A)
- else
- ..()
-
-/mob/living/simple_animal/bot/ed209/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
- if(istype(AM, /obj/item))
- var/obj/item/I = AM
- if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby))
- var/mob/living/carbon/human/H = I.thrownby
- retaliate(H)
- ..()
-
-/mob/living/simple_animal/bot/ed209/RangedAttack(atom/A)
- if(!on)
+ new /obj/effect/temp_visual/emp(loc)
+ var/list/mob/living/carbon/targets = list()
+ for(var/mob/living/carbon/nearby_carbons in view(12,src))
+ if(nearby_carbons.stat == DEAD)
+ continue
+ targets += nearby_carbons
+ if(!targets.len)
return
- shootAt(A)
-
-/mob/living/simple_animal/bot/ed209/proc/stun_attack(mob/living/carbon/C)
- playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
- icon_state = "[lasercolor]ed209-c"
- spawn(2)
- icon_state = "[lasercolor]ed209[on]"
- var/threat = 5
- C.Paralyze(100)
- C.stuttering = 5
- if(ishuman(C))
- var/mob/living/carbon/human/H = C
- var/judgment_criteria = judgment_criteria()
- threat = H.assess_threat(judgment_criteria, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
- log_combat(src,C,"stunned")
- if(declare_arrests)
- var/area/location = get_area(src)
- speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag [C] in [location].", radio_channel)
- C.visible_message("[src] has stunned [C]!",\
- "[src] has stunned you!")
-
-/mob/living/simple_animal/bot/ed209/proc/cuff(mob/living/carbon/C)
- mode = BOT_ARREST
- playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2)
- C.visible_message("[src] is trying to put zipties on [C]!",\
- "[src] is trying to put zipties on you!")
- addtimer(CALLBACK(src, PROC_REF(attempt_handcuff), C), 60)
+ if(prob(50))
+ var/mob/toshoot = pick(targets)
+ if(toshoot)
+ targets -= toshoot
+ if(prob(50) && !emagged) // Temporarily emags it
+ emagged = TRUE
+ set_weapon()
+ shoot_at(toshoot)
+ emagged = FALSE
+ set_weapon()
+ else
+ shoot_at(toshoot)
+ else if(prob(50))
+ if(targets.len)
+ var/mob/to_arrest = pick(targets)
+ if(to_arrest)
+ target = to_arrest
+ mode = BOT_HUNT
-/mob/living/simple_animal/bot/ed209/proc/attempt_handcuff(mob/living/carbon/C)
- if(!on || !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
+/mob/living/simple_animal/bot/secbot/ed209/RangedAttack(atom/A)
+ if(!on)
return
- if(!C.handcuffed)
- C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
- C.update_handcuffed()
- playsound(src, "law", 50, 0)
- back_to_idle()
+ 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 d3d56fbdb8ed8..f9b9b85428f39 100644
--- a/code/modules/mob/living/simple_animal/bot/firebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/firebot.dm
@@ -122,7 +122,7 @@
/mob/living/simple_animal/bot/firebot/on_emag(atom/target, mob/user)
..()
- if(emagged == 2)
+ if(emagged)
if(user)
to_chat(user, "[src] buzzes and beeps.")
audible_message("[src] buzzes oddly!")
@@ -158,7 +158,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 == 2 && !M.on_fire))
+ if(M.on_fire || (emagged && !M.on_fire))
return TRUE
else if(isturf(target))
@@ -206,7 +206,7 @@
old_target_fire = target_fire
// Target reached ENGAGE WATER CANNON
- if(target_fire && (get_dist(src, target_fire) <= (emagged == 2 ? 1 : 2))) // Make the bot spray water from afar when not emagged
+ if(target_fire && (get_dist(src, target_fire) <= (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!")
@@ -312,9 +312,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 54a1cd0b48476..9273232699613 100644
--- a/code/modules/mob/living/simple_animal/bot/floorbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm
@@ -131,9 +131,10 @@
/mob/living/simple_animal/bot/floorbot/on_emag(atom/target, mob/user)
..()
- if(emagged == 2)
- if(user)
- to_chat(user, "[src] buzzes and beeps.")
+ if(!emagged)
+ return
+ if(user)
+ to_chat(user, "[src] buzzes and beeps.")
/mob/living/simple_animal/bot/floorbot/Topic(href, href_list)
if(..())
@@ -185,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 < 2)
+ if(!target && emagged)
if(targetdirection != null) //The bot is in line mode.
var/turf/T = get_step(src, targetdirection)
if(isspaceturf(T)) //Check for space
@@ -210,7 +211,7 @@
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 == 2) //We are emagged! Time to rip up the floors!
+ if(!target && emagged) //We are emagged! Time to rip up the floors!
process_type = TILE_EMAG
target = scan(/turf/open/floor)
@@ -232,9 +233,9 @@
target = null
path = list()
return
- if(isturf(target) && emagged < 2)
+ if(isturf(target) && !emagged)
repair(target)
- else if(emagged == 2 && isfloorturf(target))
+ else if(emagged && isfloorturf(target))
var/turf/open/floor/F = target
anchored = TRUE
mode = BOT_REPAIRING
@@ -381,9 +382,6 @@
if(specialtiles && tiletype != null)
empty_tiles()
- if(prob(50))
- drop_part(robot_arm, Tsec)
-
new /obj/item/stack/tile/plasteel(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 ba476701562af..cc2babb610675 100644
--- a/code/modules/mob/living/simple_animal/bot/honkbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm
@@ -21,7 +21,7 @@
path_image_color = "#FF69B4"
var/honksound = 'sound/items/bikehorn.ogg' //customizable sound
- var/spam_flag = FALSE
+ var/limiting_spam = FALSE
var/cooldowntime = 30
var/cooldowntimehorn = 10
var/mob/living/carbon/target
@@ -51,8 +51,8 @@
)
AddElement(/datum/element/connect_loc, loc_connections)
-/mob/living/simple_animal/bot/honkbot/proc/spam_flag_false() //used for addtimer
- spam_flag = FALSE
+/mob/living/simple_animal/bot/honkbot/proc/limiting_spam_false() //used for addtimer
+ limiting_spam = FALSE
/mob/living/simple_animal/bot/honkbot/proc/sensor_blink()
icon_state = "honkbot-c"
@@ -61,9 +61,9 @@
//honkbots react with sounds.
/mob/living/simple_animal/bot/honkbot/proc/react_ping()
playsound(src, 'sound/machines/ping.ogg', 50, TRUE, -1) //the first sound upon creation!
- spam_flag = TRUE
+ limiting_spam = TRUE
sensor_blink()
- addtimer(CALLBACK(src, PROC_REF(spam_flag_false)), 18) // calibrates before starting the honk
+ addtimer(CALLBACK(src, PROC_REF(limiting_spam_false)), 18) // calibrates before starting the honk
/mob/living/simple_animal/bot/honkbot/proc/react_buzz()
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE, -1)
@@ -76,7 +76,7 @@
anchored = FALSE
SSmove_manager.stop_looping(src)
last_found = world.time
- spam_flag = FALSE
+ limiting_spam = FALSE
/mob/living/simple_animal/bot/honkbot/set_custom_texts()
@@ -98,17 +98,17 @@
dat += "
Auto Patrol: [auto_patrol ? "On" : "Off"]"
return dat
-/mob/living/simple_animal/bot/honkbot/proc/judgment_criteria()
+/mob/living/simple_animal/bot/honkbot/proc/judgement_criteria()
var/final = NONE
if(check_records)
final = final|JUDGE_RECORDCHECK
- if(emagged == 2)
+ if(emagged)
final = final|JUDGE_EMAGGED
return final
/mob/living/simple_animal/bot/honkbot/proc/retaliate(mob/living/carbon/human/H)
- var/judgment_criteria = judgment_criteria()
- threatlevel = H.assess_threat(judgment_criteria)
+ var/judgement_criteria = judgement_criteria()
+ threatlevel = H.assess_threat(judgement_criteria)
threatlevel += 6
if(threatlevel >= 4)
target = H
@@ -129,13 +129,14 @@
/mob/living/simple_animal/bot/honkbot/on_emag(atom/target, mob/user)
..()
- if(emagged == 2)
- if(user)
- user << "You short out [src]'s sound control system. It gives out an evil laugh!!"
- oldtarget_name = user.name
- audible_message("[src] gives out an evil laugh!")
- playsound(src, 'sound/machines/honkbot_evil_laugh.ogg', 75, 1, -1) // evil laughter
- update_icon()
+ if(!emagged)
+ return
+ if(user)
+ to_chat(user,"You short out [src]'s sound control system. It gives out an evil laugh!!")
+ oldtarget_name = user.name
+ audible_message("[src] gives out an evil laugh!")
+ playsound(src, 'sound/machines/honkbot_evil_laugh.ogg', 75, 1, -1) // evil laughter
+ update_icon()
/mob/living/simple_animal/bot/honkbot/bullet_act(obj/projectile/Proj)
if((istype(Proj,/obj/projectile/beam)) || (istype(Proj,/obj/projectile/bullet) && (Proj.damage_type == BURN))||(Proj.damage_type == BRUTE) && (!Proj.nodamage && Proj.damage < health && ishuman(Proj.firer)))
@@ -147,13 +148,13 @@
return
if(iscarbon(A))
var/mob/living/carbon/C = A
- if (emagged <= 1)
+ if(emagged)
honk_attack(A)
else
if(!C.IsParalyzed() || arrest_type)
stun_attack(A)
..()
- else if (!spam_flag) //honking at the ground
+ else if (!limiting_spam) //honking at the ground
bike_horn(A)
@@ -168,32 +169,32 @@
..()
/mob/living/simple_animal/bot/honkbot/proc/bike_horn() //use bike_horn
- if (emagged <= 1)
- if (!spam_flag)
- playsound(src, honksound, 50, TRUE, -1)
- spam_flag = TRUE //prevent spam
- sensor_blink()
- addtimer(CALLBACK(src, PROC_REF(spam_flag_false)), cooldowntimehorn)
- else if (emagged == 2) //emagged honkbots will spam short and memorable sounds.
- if (!spam_flag)
+ if (emagged) //emagged honkbots will spam short and memorable sounds.
+ if (!limiting_spam)
playsound(src, "honkbot_e", 50, 0)
- spam_flag = TRUE // prevent spam
+ limiting_spam = TRUE // prevent spam
icon_state = "honkbot-e"
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 30, TIMER_OVERRIDE|TIMER_UNIQUE)
- addtimer(CALLBACK(src, PROC_REF(spam_flag_false)), cooldowntimehorn)
+ addtimer(CALLBACK(src, PROC_REF(limiting_spam_false)), cooldowntimehorn)
+ return
+ if (!limiting_spam)
+ playsound(src, honksound, 50, TRUE, -1)
+ limiting_spam = TRUE //prevent spam
+ sensor_blink()
+ addtimer(CALLBACK(src, PROC_REF(limiting_spam_false), cooldowntimehorn))
/mob/living/simple_animal/bot/honkbot/proc/honk_attack(mob/living/carbon/C) // horn attack
- if(!spam_flag)
+ if(!limiting_spam)
playsound(loc, honksound, 50, TRUE, -1)
- spam_flag = TRUE // prevent spam
+ limiting_spam = TRUE // prevent spam
sensor_blink()
- addtimer(CALLBACK(src, PROC_REF(spam_flag_false)), cooldowntimehorn)
+ addtimer(CALLBACK(src, PROC_REF(limiting_spam_false)), cooldowntimehorn)
/mob/living/simple_animal/bot/honkbot/proc/stun_attack(mob/living/carbon/C) // airhorn stun
- if(!spam_flag)
+ if(!limiting_spam)
playsound(src, 'sound/items/AirHorn.ogg', 100, TRUE, -1) //HEEEEEEEEEEEENK!!
sensor_blink()
- if(spam_flag == 0)
+ if(limiting_spam == 0)
if(ishuman(C))
C.stuttering = 20
C.adjustEarDamage(0, 5) //far less damage than the H.O.N.K.
@@ -201,15 +202,16 @@
C.Paralyze(60)
var/mob/living/carbon/human/H = C
if(client) //prevent spam from players..
- spam_flag = TRUE
- if (emagged <= 1) //HONK once, then leave
- var/judgment_criteria = judgment_criteria()
- threatlevel = H.assess_threat(judgment_criteria)
+ limiting_spam = TRUE
+ if (emagged) // you really don't want to hit an emagged honkbot
+ threatlevel = 6 // will never let you go
+ else
+ //HONK once, then leave
+ var/judgement_criteria = judgement_criteria()
+ threatlevel = H.assess_threat(judgement_criteria)
threatlevel -= 6
target = oldtarget_name
- else // you really don't want to hit an emagged honkbot
- threatlevel = 6 // will never let you go
- addtimer(CALLBACK(src, PROC_REF(spam_flag_false)), cooldowntime)
+ addtimer(CALLBACK(src, PROC_REF(limiting_spam_false)), cooldowntime)
log_combat(src,C,"honked")
@@ -218,7 +220,7 @@
else
C.stuttering = 20
C.Paralyze(80)
- addtimer(CALLBACK(src, PROC_REF(spam_flag_false)), cooldowntime)
+ addtimer(CALLBACK(src, PROC_REF(limiting_spam_false)), cooldowntime)
/mob/living/simple_animal/bot/honkbot/handle_automated_action()
@@ -299,17 +301,17 @@
if((C.name == oldtarget_name) && (world.time < last_found + 100))
continue
- var/judgment_criteria = judgment_criteria()
- threatlevel = C.assess_threat(judgment_criteria)
+ var/judgement_criteria = judgement_criteria()
+ threatlevel = C.assess_threat(judgement_criteria)
- if(threatlevel <= 3 && get_dist(C, src) <= 4 && !spam_flag)
+ if(threatlevel <= 3 && get_dist(C, src) <= 4 && !limiting_spam)
bike_horn()
else if(threatlevel >= 10)
bike_horn() //just spam the shit outta this
else if(threatlevel >= 4)
- if(!spam_flag)
+ if(!limiting_spam)
target = C
oldtarget_name = C.name
bike_horn()
@@ -322,11 +324,10 @@
continue
/mob/living/simple_animal/bot/honkbot/explode()
+
visible_message("[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)
diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm
index 95ae8ca007059..991aa584dbc54 100644
--- a/code/modules/mob/living/simple_animal/bot/medbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/medbot.dm
@@ -219,15 +219,16 @@ GLOBAL_VAR(medibot_unique_id_gen)
/mob/living/simple_animal/bot/medbot/on_emag(atom/target, mob/user)
..()
- if(emagged == 2)
- declare_crit = 0
- if(user)
- to_chat(user, "You short out [src]'s reagent synthesis circuits.")
- audible_message("[src] buzzes oddly!")
- flick("medibot_spark", src)
- playsound(src, "sparks", 75, TRUE)
- if(user)
- oldpatient = user
+ if(!emagged)
+ return
+ declare_crit = FALSE
+ if(user)
+ to_chat(user, "You short out [src]'s reagent synthesis circuits.")
+ audible_message("[src] buzzes oddly!")
+ flick("medibot_spark", src)
+ playsound(src, "sparks", 75, SHORT_RANGE_SOUND_EXTRARANGE)
+ if(user)
+ oldpatient = user
/mob/living/simple_animal/bot/medbot/process_scan(mob/living/carbon/human/H)
if(H.stat == DEAD)
@@ -427,10 +428,10 @@ GLOBAL_VAR(medibot_unique_id_gen)
if(istype(C.dna.species, /datum/species/ipc))
return FALSE
- if(emagged == 2) //Everyone needs our medicine. (Our medicine is toxins)
+ if(emagged) //Everyone needs our medicine. (Our medicine is toxins)
return TRUE
- if(HAS_TRAIT(C,TRAIT_MEDIBOTCOMINGTHROUGH) && !HAS_TRAIT_FROM(C,TRAIT_MEDIBOTCOMINGTHROUGH,medibot_counter)) //someone is healing them already sweetie
+ if(HAS_TRAIT(C, TRAIT_MEDIBOTCOMINGTHROUGH) && !HAS_TRAIT_FROM(C, TRAIT_MEDIBOTCOMINGTHROUGH, medibot_counter)) //someone is healing them already sweetie
return FALSE
if(ishuman(C))
@@ -530,7 +531,7 @@ GLOBAL_VAR(medibot_unique_id_gen)
else if(C.getToxLoss() >= heal_threshold)
treatment_method = TOX
- if(!treatment_method && emagged != 2) //If they don't need any of that they're probably cured!
+ if(!treatment_method && !emagged) //If they don't need any of that they're probably cured!
if(C.maxHealth - C.health < heal_threshold)
to_chat(src, "[C] is healthy! Your programming prevents you from injecting anyone without at least [heal_threshold] damage of any one type ([heal_threshold + 5] for oxygen damage.)")
var/list/messagevoice = list("All patched up!" = 'sound/voice/medbot/patchedup.ogg',"An apple a day keeps me away." = 'sound/voice/medbot/apple.ogg',"Feel better soon!" = 'sound/voice/medbot/feelbetter.ogg')
@@ -551,7 +552,7 @@ GLOBAL_VAR(medibot_unique_id_gen)
healies *= 1.5
if(treatment_method == TOX && HAS_TRAIT(patient, TRAIT_TOXINLOVER))
healies *= -1.5
- if(emagged == 2)
+ if(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)")
@@ -581,9 +582,6 @@ GLOBAL_VAR(medibot_unique_id_gen)
new /obj/item/assembly/prox_sensor(Tsec)
drop_part(healthanalyzer, Tsec)
- if(prob(50))
- drop_part(robot_arm, Tsec)
-
if(emagged && prob(25))
playsound(src, 'sound/voice/medbot/insult.ogg', 50)
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index a53a04f99a3e2..59f83f911a4d0 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -1,6 +1,6 @@
/mob/living/simple_animal/bot/secbot
name = "\improper Securitron"
- desc = "A little security robot. He looks less than thrilled."
+ desc = "A little security robot. He looks less than thrilled."
icon = 'icons/mob/aibots.dmi'
icon_state = "secbot"
density = FALSE
@@ -17,31 +17,51 @@
bot_core_type = /obj/machinery/bot_core/secbot
window_id = "autosec"
window_name = "Automatic Security Unit v1.6"
- allow_pai = 0
+ allow_pai = FALSE
data_hud_type = DATA_HUD_SECURITY_ADVANCED
path_image_color = "#FF0000"
boot_delay = 8 SECONDS
- var/noloot = FALSE
+ ///The type of baton this Secbot will use
var/baton_type = /obj/item/melee/baton
+ ///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
var/oldtarget_name
- var/threatlevel = FALSE
- var/target_lastloc //Loc of target when arrested.
- var/last_found //There's a delay
- var/declare_arrests = TRUE //When making an arrest, should it notify everyone on the security channel?
- var/idcheck = FALSE //If true, arrest people with no IDs
- var/weaponscheck = FALSE //If true, arrest people for weapons if they lack access
- var/check_records = TRUE //Does it check security records?
- var/arrest_type = FALSE //If true, don't handcuff
+ ///The threat level of the BOT, will arrest anyone at threatlevel 4 or above
+ var/threatlevel = 0
+ ///The last location their target was seen at
+ var/target_lastloc
+ ///Time since last seeing their perpetrator
+ var/last_found
+
+ ///Flags SecBOTs use on what to check on targets when arresting, and whether they should announce it to security/handcuff their target
+ var/security_mode_flags = SECBOT_DECLARE_ARRESTS | SECBOT_CHECK_RECORDS | SECBOT_HANDCUFF_TARGET
+ //Selections: SECBOT_DECLARE_ARRESTS | SECBOT_CHECK_IDS | SECBOT_CHECK_WEAPONS | SECBOT_CHECK_RECORDS | SECBOT_HANDCUFF_TARGET
+
+ /// Force of the harmbaton used on them
+ var/weapon_force = 20
+ ///The department the secbot will deposit collected money into
/mob/living/simple_animal/bot/secbot/beepsky
name = "Officer Beep O'sky"
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
- idcheck = FALSE
- weaponscheck = FALSE
auto_patrol = TRUE
+/mob/living/simple_animal/bot/secbot/beepsky/armsky
+ name = "Sergeant-At-Armsky"
+ health = 45
+ auto_patrol = FALSE
+ security_mode_flags = SECBOT_DECLARE_ARRESTS | SECBOT_CHECK_IDS | SECBOT_CHECK_RECORDS
+
+/mob/living/simple_animal/bot/secbot/beepsky/armsky/warden
+ name = "Warden Armsky"
+ health = 45
+ auto_patrol = FALSE
+ security_mode_flags = SECBOT_DECLARE_ARRESTS | SECBOT_CHECK_IDS | SECBOT_CHECK_RECORDS
+
/mob/living/simple_animal/bot/secbot/beepsky/jr
name = "Officer Pipsqueak"
desc = "It's Officer Beep O'sky's smaller, just-as aggressive cousin, Pipsqueak."
@@ -51,23 +71,24 @@
resize = 0.8
update_transform()
+/mob/living/simple_animal/bot/secbot/pingsky
+ name = "Officer Pingsky"
+ 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/beepsky/explode()
var/atom/Tsec = drop_location()
new /obj/item/stock_parts/cell/potato(Tsec)
- var/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/S = new(Tsec)
- S.reagents.add_reagent(/datum/reagent/consumable/ethanol/whiskey, 15)
- S.on_reagent_change(ADD_REAGENT)
+ var/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/drinking_oil = new(Tsec)
+ drinking_oil.reagents.add_reagent(/datum/reagent/consumable/ethanol/whiskey, 15)
+ drinking_oil.on_reagent_change(ADD_REAGENT)
..()
-/mob/living/simple_animal/bot/secbot/pingsky
- name = "Officer Pingsky"
- 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/Initialize(mapload)
. = ..()
- update_icon()
+ weapon = new baton_type()
+ update_appearance(UPDATE_ICON)
+
var/datum/job/J = SSjob.GetJob(JOB_NAME_DETECTIVE)
access_card.access = J.get_access()
prev_access = access_card.access.Copy()
@@ -80,11 +101,15 @@
)
AddElement(/datum/element/connect_loc, loc_connections)
-/mob/living/simple_animal/bot/secbot/update_icon()
+/mob/living/simple_animal/bot/secbot/Destroy()
+ QDEL_NULL(weapon)
+ return ..()
+
+/mob/living/simple_animal/bot/secbot/update_icon_state()
if(mode == BOT_HUNT)
icon_state = "[initial(icon_state)]-c"
return
- ..()
+ return ..()
/mob/living/simple_animal/bot/secbot/turn_off()
..()
@@ -115,55 +140,57 @@
if(!locked || issilicon(user) || IsAdminGhost(user))
dat += "
"
- dat += "
Arrest Unidentifiable Persons: [idcheck ? "Yes" : "No"]"
- dat += "
Arrest for Unauthorized Weapons: [weaponscheck ? "Yes" : "No"]"
- dat += "
Arrest for Warrant: [check_records ? "Yes" : "No"]"
- dat += "
Operating Mode: [arrest_type ? "Detain" : "Arrest"]"
- dat += "
Report Arrests [declare_arrests ? "Yes" : "No"]"
+ dat += "
Arrest Unidentifiable Persons: [security_mode_flags & SECBOT_CHECK_IDS ? "Yes" : "No"]"
+ dat += "
Arrest for Unauthorized Weapons: [security_mode_flags & SECBOT_CHECK_WEAPONS ? "Yes" : "No"]"
+ dat += "
Arrest for Warrant: [security_mode_flags & SECBOT_CHECK_RECORDS ? "Yes" : "No"]"
+ dat += "
Operating Mode: [security_mode_flags & SECBOT_HANDCUFF_TARGET ? "Arrest" : "Detain"]"
+ dat += "
Report Arrests [security_mode_flags & SECBOT_DECLARE_ARRESTS ? "Yes" : "No"]"
dat += "
Auto Patrol: [auto_patrol ? "On" : "Off"]"
return dat
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
- if(..())
+ . = ..()
+ if(.)
return TRUE
+
if(!issilicon(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
return TRUE
+
switch(href_list["operation"])
if("idcheck")
- idcheck = !idcheck
- update_controls()
+ security_mode_flags ^= SECBOT_CHECK_IDS
if("weaponscheck")
- weaponscheck = !weaponscheck
- update_controls()
+ security_mode_flags ^= SECBOT_CHECK_WEAPONS
if("ignorerec")
- check_records = !check_records
- update_controls()
+ security_mode_flags ^= SECBOT_CHECK_RECORDS
if("switchmode")
- arrest_type = !arrest_type
- update_controls()
+ security_mode_flags ^= SECBOT_HANDCUFF_TARGET
if("declarearrests")
- declare_arrests = !declare_arrests
- update_controls()
+ security_mode_flags ^= SECBOT_DECLARE_ARRESTS
+
+ update_controls()
-/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H)
- var/judgment_criteria = judgment_criteria()
- threatlevel = H.assess_threat(judgment_criteria, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
+/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/attacking_human)
+ var/judgement_criteria = judgement_criteria()
+ threatlevel = attacking_human.assess_threat(judgement_criteria, weaponcheck = CALLBACK(src, PROC_REF(check_for_weapons)))
threatlevel += 6
if(threatlevel >= 4)
- target = H
+ target = attacking_human
mode = BOT_HUNT
-/mob/living/simple_animal/bot/secbot/proc/judgment_criteria()
- var/final = FALSE
- if(idcheck)
- final = final|JUDGE_IDCHECK
- if(check_records)
- final = final|JUDGE_RECORDCHECK
- if(weaponscheck)
- final = final|JUDGE_WEAPONCHECK
- if(emagged == 2)
- final = final|JUDGE_EMAGGED
- return final
+/mob/living/simple_animal/bot/secbot/proc/judgement_criteria()
+ var/final = FALSE
+ if(emagged)
+ final |= JUDGE_EMAGGED
+ if(bot_type == ADVANCED_SEC_BOT)
+ final |= JUDGE_IGNOREMONKEYS
+ if(security_mode_flags & SECBOT_CHECK_IDS)
+ final |= JUDGE_IDCHECK
+ if(security_mode_flags & SECBOT_CHECK_RECORDS)
+ final |= JUDGE_RECORDCHECK
+ if(security_mode_flags & SECBOT_CHECK_WEAPONS)
+ final |= JUDGE_WEAPONCHECK
+ return final
/mob/living/simple_animal/bot/secbot/proc/special_retaliate_after_attack(mob/user) //allows special actions to take place after being attacked.
return
@@ -176,24 +203,24 @@
return ..()
-/mob/living/simple_animal/bot/secbot/attackby(obj/item/W, mob/user, params)
+/mob/living/simple_animal/bot/secbot/attackby(obj/item/attacking_item, mob/user, params)
..()
- if(W.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry.
+ if(attacking_item.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry.
return
- if(W.tool_behaviour != TOOL_SCREWDRIVER && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
+ if(attacking_item.tool_behaviour != TOOL_SCREWDRIVER && (attacking_item.force) && (!target) && (attacking_item.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
retaliate(user)
- if(special_retaliate_after_attack(user))
- return
+ special_retaliate_after_attack(user)
/mob/living/simple_animal/bot/secbot/on_emag(atom/target, mob/user)
..()
- if(emagged == 2)
- if(user)
- to_chat(user, "You short out [src]'s target assessment circuits.")
- oldtarget_name = user.name
- audible_message("[src] buzzes oddly!")
- declare_arrests = FALSE
- update_icon()
+ if(!emagged)
+ return
+ if(user)
+ to_chat(user, "You short out [src]'s target assessment circuits.")
+ oldtarget_name = user.name
+ audible_message("[src] buzzes oddly!")
+ security_mode_flags &= ~SECBOT_DECLARE_ARRESTS
+ update_appearance()
/mob/living/simple_animal/bot/secbot/bullet_act(obj/projectile/Proj)
if(istype(Proj , /obj/projectile/beam)||istype(Proj, /obj/projectile/bullet))
@@ -202,127 +229,123 @@
retaliate(Proj.firer)
return ..()
-/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A)
+/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers)
if(!on)
return
- if(iscarbon(A))
- var/mob/living/carbon/C = A
- if(!C.IsParalyzed() || arrest_type)
- stun_attack(A)
- else if(C.canBeHandcuffed() && !C.handcuffed)
- cuff(A)
- else
- ..()
-
-/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
- if(istype(AM, /obj/item))
- var/obj/item/I = AM
- var/mob/thrown_by = I.thrownby?.resolve()
- if(I.throwforce < src.health && thrown_by && ishuman(thrown_by))
- var/mob/living/carbon/human/H = thrown_by
- retaliate(H)
+ if(!iscarbon(attack_target))
+ return ..()
+ var/mob/living/carbon/carbon_target = attack_target
+ if(!carbon_target.IsParalyzed() || !(security_mode_flags & SECBOT_HANDCUFF_TARGET))
+ stun_attack(attack_target)
+ else if(carbon_target.canBeHandcuffed() && !carbon_target.handcuffed)
+ start_handcuffing(attack_target)
+
+/mob/living/simple_animal/bot/secbot/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
+ if(istype(hitting_atom, /obj/item))
+ var/obj/item/item_hitby = hitting_atom
+ var/mob/thrown_by = item_hitby.thrownby?.resolve()
+ if(item_hitby.throwforce < src.health && thrown_by && ishuman(thrown_by))
+ var/mob/living/carbon/human/human_throwee = thrown_by
+ retaliate(human_throwee)
..()
-/mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C)
+/mob/living/simple_animal/bot/secbot/proc/start_handcuffing(mob/living/carbon/current_target)
mode = BOT_ARREST
playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2)
- C.visible_message("[src] is trying to put zipties on [C]!",\
+ current_target.visible_message("[src] is trying to put zipties on [current_target]!",\
"[src] is trying to put zipties on you!")
- addtimer(CALLBACK(src, PROC_REF(attempt_handcuff), C), 60)
+ addtimer(CALLBACK(src, PROC_REF(handcuff_target), target), 60)
-/mob/living/simple_animal/bot/secbot/proc/attempt_handcuff(mob/living/carbon/C)
- if( !on || !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
+/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.
return
- if(!C.handcuffed)
- C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
- C.update_handcuffed()
- playsound(src, "law", 50, 0)
+ if(!current_target.handcuffed)
+ current_target.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(current_target)
+ current_target.update_handcuffed()
+ playsound(src, "law", 50, FALSE)
back_to_idle()
-/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C)
- var/judgment_criteria = judgment_criteria()
+/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/current_target)
+ var/judgement_criteria = judgement_criteria()
var/threat = 5
- if(ishuman(C))
- var/mob/living/carbon/human/H = C
- if(H.check_shields(src, 0))
+ if(ishuman(current_target))
+ var/mob/living/carbon/human/human_target = current_target
+ if(human_target.check_shields(src, 0))
return
- threat = H.assess_threat(judgment_criteria, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
+ threat = human_target.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
else
- threat = C.assess_threat(judgment_criteria, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
- if(declare_arrests)
+ threat = current_target.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
+ if(security_mode_flags & SECBOT_DECLARE_ARRESTS)
var/area/location = get_area(src)
- speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag [C] in [location].", radio_channel)
+ speak("[security_mode_flags & SECBOT_HANDCUFF_TARGET ? "Arresting" : "Detaining"] level [threat] scumbag [current_target] in [location].", radio_channel)
- var/armor_block = C.run_armor_check(BODY_ZONE_CHEST, "stamina")
- C.apply_damage(85, STAMINA, BODY_ZONE_CHEST, armor_block)
- C.apply_effect(EFFECT_STUTTER, 50)
- C.visible_message(
- "[src] has stunned [C]!",\
+ var/armor_block = current_target.run_armor_check(BODY_ZONE_CHEST, "stamina")
+ current_target.apply_damage(85, STAMINA, BODY_ZONE_CHEST, armor_block)
+ current_target.apply_effect(EFFECT_STUTTER, 50)
+ current_target.visible_message(
+ "[src] has stunned [current_target]!",\
"[src] has stunned you!"
)
- log_combat(src, C, "stunned")
+ log_combat(src, target, "stunned")
playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
icon_state = "[initial(icon_state)]-c"
- addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 2)
+ addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_appearance)), 0.2 SECONDS)
/mob/living/simple_animal/bot/secbot/handle_automated_action()
- if(!..())
+ . = ..()
+ if(!.)
return
switch(mode)
- if(BOT_IDLE) // idle
-
+ if(BOT_IDLE) // idle
SSmove_manager.stop_looping(src)
look_for_perp() // see if any criminals are in range
if(!mode && auto_patrol) // still idle, and set to patrol
mode = BOT_START_PATROL // switch to patrol mode
- if(BOT_HUNT) // hunting for perp
-
+ if(BOT_HUNT) // hunting for perp
// if can't reach perp for long enough, go idle
if(frustration >= 8)
SSmove_manager.stop_looping(src)
back_to_idle()
return
- if(target) // make sure target exists
- if(Adjacent(target) && isturf(target.loc)) // if right next to perp
- stun_attack(target)
+ if(!target) // make sure target exists
+ back_to_idle()
+ return
+ if(Adjacent(target) && isturf(target.loc)) // if right next to perp
+ stun_attack(target)
- mode = BOT_PREP_ARREST
- anchored = TRUE
- target_lastloc = target.loc
- return
+ mode = BOT_PREP_ARREST
+ anchored = TRUE
+ target_lastloc = target.loc
+ return
- else // not next to perp
- var/turf/olddist = get_dist(src, target)
- SSmove_manager.move_to(src, target, 1, 4)
- if((get_dist(src, target)) >= (olddist))
- frustration++
- else
- frustration = 0
+ // not next to perp
+ var/turf/olddist = get_dist(src, target)
+ SSmove_manager.move_to(src, target, 1, 4)
+ if((get_dist(src, target)) >= (olddist))
+ frustration++
else
- back_to_idle()
-
- if(BOT_PREP_ARREST) // preparing to arrest target
+ frustration = 0
+ if(BOT_PREP_ARREST) // preparing to arrest target
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
- if( !Adjacent(target) || !isturf(target.loc) || target.getStaminaLoss() < 100)
+ if(!Adjacent(target) || !isturf(target.loc) || target.getStaminaLoss() < 100)
back_to_hunt()
return
- if(iscarbon(target) && target.canBeHandcuffed())
- if(!arrest_type)
- if(!target.handcuffed) //he's not cuffed? Try to cuff him!
- cuff(target)
- else
- back_to_idle()
- return
- else
+ if(!iscarbon(target) || !target.canBeHandcuffed())
back_to_idle()
return
+ if(security_mode_flags & SECBOT_HANDCUFF_TARGET)
+ if(!target.handcuffed) //he's not cuffed? Try to cuff him!
+ start_handcuffing(target)
+ else
+ back_to_idle()
+ return
if(BOT_ARREST)
if(!target)
@@ -351,9 +374,6 @@
look_for_perp()
bot_patrol()
-
- return
-
/mob/living/simple_animal/bot/secbot/proc/back_to_idle()
anchored = FALSE
mode = BOT_IDLE
@@ -371,30 +391,31 @@
/mob/living/simple_animal/bot/secbot/proc/look_for_perp()
anchored = FALSE
- var/judgment_criteria = judgment_criteria()
- for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
- if((C.stat) || (C.handcuffed))
+ var/judgement_criteria = judgement_criteria()
+ for(var/mob/living/carbon/nearby_carbons in view(7,src)) //Let's find us a criminal
+ if((nearby_carbons.stat) || (nearby_carbons.handcuffed))
continue
- if((C.name == oldtarget_name) && (world.time < last_found + 100))
+ if((nearby_carbons.name == oldtarget_name) && (world.time < last_found + 100))
continue
- threatlevel = C.assess_threat(judgment_criteria, weaponcheck=CALLBACK(src, PROC_REF(check_for_weapons)))
+ threatlevel = nearby_carbons.assess_threat(judgement_criteria, weaponcheck = CALLBACK(src, PROC_REF(check_for_weapons)))
if(!threatlevel)
continue
else if(threatlevel >= 4)
- target = C
- oldtarget_name = C.name
+ target = nearby_carbons
+ oldtarget_name = nearby_carbons.name
speak("Level [threatlevel] infraction alert!")
- playsound(loc, pick('sound/voice/beepsky/criminal.ogg', 'sound/voice/beepsky/justice.ogg', 'sound/voice/beepsky/freeze.ogg'), 50, FALSE)
- visible_message("[src] points at [C.name]!")
+ if(bot_type == ADVANCED_SEC_BOT)
+ playsound(src, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, FALSE)
+ else
+ playsound(src, pick('sound/voice/beepsky/criminal.ogg', 'sound/voice/beepsky/justice.ogg', 'sound/voice/beepsky/freeze.ogg'), 50, FALSE)
+ visible_message("[src] points at [nearby_carbons.name]!")
mode = BOT_HUNT
INVOKE_ASYNC(src, PROC_REF(handle_automated_action))
break
- else
- continue
/mob/living/simple_animal/bot/secbot/proc/check_for_weapons(var/obj/item/slot_item)
if(slot_item && (slot_item.item_flags & NEEDS_PERMIT))
@@ -402,20 +423,35 @@
return FALSE
/mob/living/simple_animal/bot/secbot/explode()
+
visible_message("[src] 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(!noloot)
+ if(bot_type == ADVANCED_SEC_BOT)
+ var/obj/item/bot_assembly/ed209/ed_assembly = new(Tsec)
+ ed_assembly.build_step = ASSEMBLY_FIRST_STEP
+ ed_assembly.add_overlay("hs_hole")
+ ed_assembly.created_name = name
+ new /obj/item/assembly/prox_sensor(Tsec)
+ var/obj/item/gun/energy/disabler/disabler_gun = new(Tsec)
+ disabler_gun.cell.charge = 0
+ disabler_gun.update_appearance()
+ if(prob(50))
+ new /obj/item/bodypart/l_leg/robot(Tsec)
+ if(prob(25))
+ new /obj/item/bodypart/r_leg/robot(Tsec)
+ if(prob(25))//50% chance for a helmet OR vest
+ if(prob(50))
+ new /obj/item/clothing/head/helmet(Tsec)
+ else
+ new /obj/item/clothing/suit/armor/vest(Tsec)
+ else
+ var/obj/item/bot_assembly/secbot/secbot_assembly = new(Tsec)
+ secbot_assembly.build_step = ASSEMBLY_FIRST_STEP
+ secbot_assembly.add_overlay("hs_hole")
+ secbot_assembly.created_name = name
+ new /obj/item/assembly/prox_sensor(Tsec)
drop_part(baton_type, Tsec)
- if(prob(50))
- drop_part(robot_arm, Tsec)
-
do_sparks(3, TRUE, src)
new /obj/effect/decal/cleanable/oil(loc)
@@ -435,7 +471,6 @@
if(!istype(C) || !C || in_range(src, target))
return
knockOver(C)
- return
/obj/machinery/bot_core/secbot
req_access = list(ACCESS_SECURITY)
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index 9ab732c688f15..f69b7bed8e58d 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -40,7 +40,7 @@
bubble_icon = "machine"
initial_language_holder = /datum/language_holder/drone
mob_size = MOB_SIZE_SMALL
- has_unlimited_silicon_privilege = 1
+ has_unlimited_silicon_privilege = TRUE
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD)
unique_name = TRUE
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 6deecca18e823..b10c6544f5712 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -175,7 +175,7 @@
var/image/digitaldisguise = null
/// Can they interact with station electronics
- var/has_unlimited_silicon_privilege = 0
+ var/has_unlimited_silicon_privilege = FALSE
///Used by admins to possess objects. All mobs should have this var
var/obj/control_object
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index ab40fc979c7db..3d513a1aa0269 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -540,7 +540,7 @@
if(R.mmi)
R.mmi.transfer_identity(src)
- R.notify_ai(NEW_BORG)
+ R.notify_ai(AI_NOTIFICATION_NEW_BORG)
. = R
if(R.ckey && is_banned_from(R.ckey, JOB_NAME_CYBORG))
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index 91bd35daf915d..158c9779d4aa2 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -175,7 +175,7 @@
Robot.undeploy() // disconnect any AI shells first
if(Robot.mmi)
qdel(Robot.mmi)
- Robot.notify_ai(NEW_BORG)
+ Robot.notify_ai(AI_NOTIFICATION_NEW_BORG)
else
for(var/obj/item/W in contents)
if(!M.dropItemToGround(W))
diff --git a/code/modules/spells/spell_types/conjure.dm b/code/modules/spells/spell_types/conjure.dm
index b705d6c3b776a..4aa6beff3de24 100644
--- a/code/modules/spells/spell_types/conjure.dm
+++ b/code/modules/spells/spell_types/conjure.dm
@@ -10,7 +10,7 @@
var/summon_ignore_density = FALSE //if set to TRUE, adds dense tiles to possible spawn places
var/summon_ignore_prev_spawn_points = TRUE //if set to TRUE, each new object is summoned on a new spawn point
- var/list/newVars = list() //vars of the summoned objects will be replaced with those where they meet
+ var/list/new_vars = list() //vars of the summoned objects will be replaced with those where they meet
//should have format of list("emagged" = 1,"name" = "Wizard's Justicebot"), for example
var/cast_sound = 'sound/items/welder.ogg'
@@ -38,9 +38,9 @@
else
var/atom/summoned_object = new summoned_object_type(spawn_place)
- for(var/varName in newVars)
- if(varName in newVars)
- summoned_object.vv_edit_var(varName, newVars[varName])
+ for(var/varName in new_vars)
+ if(varName in new_vars)
+ summoned_object.vv_edit_var(varName, new_vars[varName])
summoned_object.flags_1 |= ADMIN_SPAWNED_1
if(summon_lifespan)
QDEL_IN(summoned_object, summon_lifespan)
@@ -54,10 +54,17 @@
name = "Dispense Wizard Justice"
desc = "This spell dispenses wizard justice."
- summon_type = list(/mob/living/simple_animal/bot/ed209)
+ summon_type = list(/mob/living/simple_animal/bot/secbot/ed209)
summon_amt = 10
range = 3
- newVars = list("emagged" = 2, "remote_disabled" = 1,"shoot_sound" = 'sound/weapons/laser.ogg',"projectile" = /obj/projectile/beam/laser, "declare_arrests" = 0,"name" = "Wizard's Justicebot")
+ new_vars = list(
+ "emagged" = 2,
+ "remote_disabled" = 1,
+ "shoot_sound" = 'sound/weapons/laser.ogg',
+ "projectile" = /obj/projectile/beam/laser,
+ "security_mode_flags" = ~(SECBOT_DECLARE_ARRESTS),
+ "name" = "Wizard's Justicebot"
+ )
/obj/effect/proc_holder/spell/aoe_turf/conjure/linkWorlds
name = "Link Worlds"
diff --git a/code/modules/spells/spell_types/shapeshift.dm b/code/modules/spells/spell_types/shapeshift.dm
index f924410198597..dd68ad4ec034b 100644
--- a/code/modules/spells/spell_types/shapeshift.dm
+++ b/code/modules/spells/spell_types/shapeshift.dm
@@ -20,7 +20,7 @@
var/list/possible_shapes = list(/mob/living/simple_animal/mouse,\
/mob/living/simple_animal/pet/dog/corgi,\
/mob/living/simple_animal/hostile/carp/ranged/chaos,\
- /mob/living/simple_animal/bot/ed209,\
+ /mob/living/simple_animal/bot/secbot/ed209,\
/mob/living/simple_animal/hostile/poison/giant_spider/hunter/viper/wizard,\
/mob/living/simple_animal/hostile/construct/armored)
diff --git a/icons/mob/aibots.dmi b/icons/mob/aibots.dmi
index 84deedc5c5c4b..710686d82e66d 100644
Binary files a/icons/mob/aibots.dmi and b/icons/mob/aibots.dmi differ