mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-25 22:19:30 +01:00
Beepsky refactor and Bot code improvement (#62510)
This commit is contained in:
@@ -13698,6 +13698,7 @@
|
||||
/obj/effect/turf_decal/tile/neutral{
|
||||
dir = 8
|
||||
},
|
||||
/mob/living/simple_animal/bot/secbot/beepsky/armsky,
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/ai_monitored/security/armory)
|
||||
"caa" = (
|
||||
|
||||
@@ -7125,14 +7125,7 @@
|
||||
/area/maintenance/starboard)
|
||||
"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/iron,
|
||||
/area/ai_monitored/security/armory)
|
||||
"bkD" = (
|
||||
|
||||
@@ -23512,14 +23512,7 @@
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable,
|
||||
/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,
|
||||
/turf/open/floor/iron/showroomfloor,
|
||||
/area/ai_monitored/security/armory)
|
||||
"cwe" = (
|
||||
|
||||
@@ -786,14 +786,7 @@
|
||||
/area/ai_monitored/security/armory)
|
||||
"agc" = (
|
||||
/obj/effect/turf_decal/bot,
|
||||
/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/iron/dark,
|
||||
/area/ai_monitored/security/armory)
|
||||
"agd" = (
|
||||
|
||||
@@ -11582,15 +11582,8 @@
|
||||
/obj/effect/turf_decal/stripes/corner,
|
||||
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
|
||||
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
|
||||
/mob/living/simple_animal/bot/secbot{
|
||||
arrest_type = 1;
|
||||
health = 45;
|
||||
icon_state = "secbot1";
|
||||
idcheck = 1;
|
||||
name = "Sergeant-at-Armsky";
|
||||
weaponscheck = 1
|
||||
},
|
||||
/obj/structure/cable,
|
||||
/mob/living/simple_animal/bot/secbot/beepsky/armsky,
|
||||
/turf/open/floor/iron,
|
||||
/area/ai_monitored/security/armory)
|
||||
"cBm" = (
|
||||
|
||||
+78
-58
@@ -1,4 +1,4 @@
|
||||
/*ALL DEFINES FOR AIS, CYBORGS, AND SIMPLE ANIMAL BOTS*/
|
||||
/** AI defines */
|
||||
|
||||
#define DEFAULT_AI_LAWID "default"
|
||||
#define LAW_ZEROTH "zeroth"
|
||||
@@ -7,6 +7,49 @@
|
||||
#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 */
|
||||
|
||||
//Bot defines, placed here so they can be read by other things!
|
||||
/// Delay between movemements
|
||||
#define BOT_STEP_DELAY 4
|
||||
@@ -16,6 +59,28 @@
|
||||
/// Default view range for finding targets.
|
||||
#define DEFAULT_SCAN_RANGE 7
|
||||
|
||||
//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. If you add a new one make sure you update mode_name in /mob/living/simple_animal/bot
|
||||
/// Idle
|
||||
#define BOT_IDLE 0
|
||||
@@ -58,37 +123,19 @@
|
||||
/// MULEbot - No destination beacon found (or no route)
|
||||
#define BOT_NO_ROUTE 19
|
||||
|
||||
//Bot types
|
||||
/// Secutritrons (Beepsky) and ED-209s
|
||||
#define SEC_BOT (1<<0)
|
||||
/// MULEbots
|
||||
#define MULE_BOT (1<<1)
|
||||
/// Floorbots
|
||||
#define FLOOR_BOT (1<<2)
|
||||
/// Cleanbots
|
||||
#define CLEAN_BOT (1<<3)
|
||||
/// Medibots
|
||||
#define MED_BOT (1<<4)
|
||||
/// Honkbots & ED-Honks
|
||||
#define HONK_BOT (1<<5)
|
||||
/// Firebots
|
||||
#define FIRE_BOT (1<<6)
|
||||
/// Hygienebots
|
||||
#define HYGIENE_BOT (1<<7)
|
||||
/// Vibe bots
|
||||
#define VIBE_BOT (1<<8)
|
||||
//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)
|
||||
|
||||
//AI notification defines
|
||||
///Alert when a new Cyborg is created.
|
||||
#define NEW_BORG 1
|
||||
///Alert when a Cyborg selects a model.
|
||||
#define NEW_MODEL 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
|
||||
/** Misc Robot defines */
|
||||
|
||||
//Assembly defines
|
||||
#define ASSEMBLY_FIRST_STEP 0
|
||||
@@ -96,30 +143,3 @@
|
||||
#define ASSEMBLY_THIRD_STEP 2
|
||||
#define ASSEMBLY_FOURTH_STEP 3
|
||||
#define ASSEMBLY_FIFTH_STEP 4
|
||||
|
||||
/// 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"
|
||||
|
||||
@@ -147,11 +147,11 @@
|
||||
/obj/attackby(obj/item/I, mob/living/user, params)
|
||||
return ..() || ((obj_flags & CAN_BE_HIT) && I.attack_atom(src, user, params))
|
||||
|
||||
/mob/living/attackby(obj/item/I, mob/living/user, params)
|
||||
/mob/living/attackby(obj/item/attacking_item, mob/living/user, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
return I.attack(src, user, params)
|
||||
return attacking_item.attack(src, user, params)
|
||||
|
||||
/mob/living/attackby_secondary(obj/item/weapon, mob/living/user, params)
|
||||
var/result = weapon.attack_secondary(src, user, params)
|
||||
|
||||
@@ -39,13 +39,13 @@
|
||||
new_ai = select_active_ai(user, R.z)
|
||||
else
|
||||
new_ai = select_active_ai(R, R.z)
|
||||
R.notify_ai(DISCONNECT)
|
||||
R.notify_ai(AI_NOTIFICATION_CYBORG_DISCONNECTED)
|
||||
if(new_ai && (new_ai != R.connected_ai))
|
||||
R.set_connected_ai(new_ai)
|
||||
log_combat(usr, R, "synced cyborg [R.connected_ai ? "from [ADMIN_LOOKUP(R.connected_ai)]": ""] to [ADMIN_LOOKUP(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.
|
||||
@@ -73,7 +73,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_CYBORG_DISCONNECTED)
|
||||
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()
|
||||
|
||||
@@ -108,4 +108,4 @@
|
||||
sleep(30)
|
||||
if(R)
|
||||
R.SetLockdown(FALSE)
|
||||
R.notify_ai(NEW_BORG)
|
||||
R.notify_ai(AI_NOTIFICATION_NEW_BORG)
|
||||
|
||||
@@ -26,11 +26,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
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
var/remote_door_id = ""
|
||||
|
||||
var/bot_access_flags = 0 //Bit flags. Selection: SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT | VIBE_BOT
|
||||
var/bot_access_flags = 0 //Bit flags. Selection: SEC_BOT | ADVANCED_SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT | VIBE_BOT
|
||||
var/spam_enabled = 0 //Enables "Send to All" Option
|
||||
|
||||
var/obj/item/pda/host_pda = null
|
||||
@@ -66,13 +66,13 @@
|
||||
name = "\improper R.O.B.U.S.T. cartridge"
|
||||
icon_state = "cart-s"
|
||||
access = CART_SECURITY | CART_MANIFEST
|
||||
bot_access_flags = SEC_BOT
|
||||
bot_access_flags = SEC_BOT | ADVANCED_SEC_BOT
|
||||
|
||||
/obj/item/cartridge/detective
|
||||
name = "\improper D.E.T.E.C.T. cartridge"
|
||||
icon_state = "cart-s"
|
||||
access = CART_SECURITY | CART_MEDICAL | CART_MANIFEST
|
||||
bot_access_flags = SEC_BOT
|
||||
bot_access_flags = SEC_BOT | ADVANCED_SEC_BOT
|
||||
|
||||
/obj/item/cartridge/janitor
|
||||
name = "\improper CustodiPRO cartridge"
|
||||
@@ -136,7 +136,7 @@
|
||||
name = "\improper R.O.B.U.S.T. DELUXE cartridge"
|
||||
icon_state = "cart-hos"
|
||||
access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_SECURITY
|
||||
bot_access_flags = SEC_BOT
|
||||
bot_access_flags = SEC_BOT | ADVANCED_SEC_BOT
|
||||
|
||||
|
||||
/obj/item/cartridge/ce
|
||||
@@ -166,7 +166,7 @@
|
||||
desc = "Now with 350% more value!" //Give the Captain...EVERYTHING! (Except Mime, Clown, and Syndie)
|
||||
icon_state = "cart-c"
|
||||
access = ~(CART_CLOWN | CART_MIME | CART_REMOTE_DOOR)
|
||||
bot_access_flags = SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT | VIBE_BOT
|
||||
bot_access_flags = SEC_BOT | ADVANCED_SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT | VIBE_BOT
|
||||
spam_enabled = 1
|
||||
|
||||
/obj/item/cartridge/captain/Initialize(mapload)
|
||||
|
||||
@@ -279,7 +279,7 @@
|
||||
lawsync = FALSE
|
||||
O.set_connected_ai(null)
|
||||
else
|
||||
O.notify_ai(NEW_BORG)
|
||||
O.notify_ai(AI_NOTIFICATION_NEW_BORG)
|
||||
if(forced_ai)
|
||||
O.set_connected_ai(forced_ai)
|
||||
if(!lawsync)
|
||||
@@ -337,7 +337,7 @@
|
||||
else
|
||||
if(forced_ai)
|
||||
O.set_connected_ai(forced_ai)
|
||||
O.notify_ai(AI_SHELL)
|
||||
O.notify_ai(AI_NOTIFICATION_AI_SHELL)
|
||||
if(!lawsync)
|
||||
O.lawupdate = FALSE
|
||||
O.make_laws()
|
||||
|
||||
@@ -51,7 +51,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/disablercooler
|
||||
@@ -543,7 +543,7 @@
|
||||
if (.)
|
||||
if(R.shell)
|
||||
R.undeploy()
|
||||
R.notify_ai(DISCONNECT)
|
||||
R.notify_ai(AI_NOTIFICATION_AI_SHELL)
|
||||
|
||||
/obj/item/borg/upgrade/expand
|
||||
name = "borg expander"
|
||||
|
||||
@@ -195,7 +195,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.set_connected_ai(newai)
|
||||
@@ -203,7 +203,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.set_connected_ai(null)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
return
|
||||
spawned.gender = NEUTER
|
||||
var/mob/living/silicon/robot/robot_spawn = spawned
|
||||
robot_spawn.notify_ai(NEW_BORG)
|
||||
robot_spawn.notify_ai(AI_NOTIFICATION_NEW_BORG)
|
||||
|
||||
|
||||
/datum/job/cyborg/radio_help_message(mob/M)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
var/preferred_form = null
|
||||
|
||||
if(isAdminGhostAI(src))
|
||||
has_unlimited_silicon_privilege = 1
|
||||
has_unlimited_silicon_privilege = TRUE
|
||||
|
||||
if(client.prefs.unlock_content)
|
||||
preferred_form = client.prefs.read_preference(/datum/preference/choiced/ghost_form)
|
||||
|
||||
@@ -1208,7 +1208,7 @@
|
||||
Robot.connected_ai.disconnect_shell()
|
||||
if(Robot.mmi)
|
||||
qdel(Robot.mmi)
|
||||
Robot.notify_ai(NEW_BORG)
|
||||
Robot.notify_ai(AI_NOTIFICATION_NEW_BORG)
|
||||
else
|
||||
for(var/obj/item/item in src)
|
||||
if(!dropItemToGround(item))
|
||||
|
||||
@@ -524,15 +524,15 @@
|
||||
if(!connected_ai)
|
||||
return
|
||||
switch(notifytype)
|
||||
if(NEW_BORG) //New Cyborg
|
||||
if(AI_NOTIFICATION_NEW_BORG) //New Cyborg
|
||||
to_chat(connected_ai, "<br><br>[span_notice("NOTICE - New cyborg connection detected: <a href='?src=[REF(connected_ai)];track=[html_encode(name)]'>[name]</a>")]<br>")
|
||||
if(NEW_MODEL) //New Model
|
||||
if(AI_NOTIFICATION_NEW_MODEL) //New Model
|
||||
to_chat(connected_ai, "<br><br>[span_notice("NOTICE - Cyborg model change detected: [name] has loaded the [designation] model.")]<br>")
|
||||
if(RENAME) //New Name
|
||||
if(AI_NOTIFICATION_CYBORG_RENAMED) //New Name
|
||||
to_chat(connected_ai, "<br><br>[span_notice("NOTICE - Cyborg reclassification detected: [oldname] is now designated as [newname].")]<br>")
|
||||
if(AI_SHELL) //New Shell
|
||||
if(AI_NOTIFICATION_AI_SHELL) //New Shell
|
||||
to_chat(connected_ai, "<br><br>[span_notice("NOTICE - New cyborg shell detected: <a href='?src=[REF(connected_ai)];track=[html_encode(name)]'>[name]</a>")]<br>")
|
||||
if(DISCONNECT) //Tampering with the wires
|
||||
if(AI_NOTIFICATION_CYBORG_DISCONNECTED) //Tampering with the wires
|
||||
to_chat(connected_ai, "<br><br>[span_notice("NOTICE - Remote telemetry lost with [name].")]<br>")
|
||||
|
||||
/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close=FALSE, no_dexterity=FALSE, no_tk=FALSE, need_hands = FALSE, floor_okay=FALSE)
|
||||
@@ -647,7 +647,7 @@
|
||||
builtInCamera.toggle_cam(src,0)
|
||||
if(admin_revive)
|
||||
locked = TRUE
|
||||
notify_ai(NEW_BORG)
|
||||
notify_ai(AI_NOTIFICATION_NEW_BORG)
|
||||
. = TRUE
|
||||
toggle_headlamp(FALSE, TRUE) //This will reenable borg headlamps if doomsday is currently going on still.
|
||||
|
||||
@@ -656,7 +656,7 @@
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
notify_ai(RENAME, oldname, newname)
|
||||
notify_ai(AI_NOTIFICATION_CYBORG_RENAMED, oldname, newname)
|
||||
if(!QDELETED(builtInCamera))
|
||||
builtInCamera.c_tag = real_name
|
||||
custom_name = newname
|
||||
|
||||
@@ -252,7 +252,7 @@
|
||||
cyborg.notransform = FALSE
|
||||
cyborg.updatehealth()
|
||||
cyborg.update_icons()
|
||||
cyborg.notify_ai(NEW_MODEL)
|
||||
cyborg.notify_ai(AI_NOTIFICATION_NEW_MODEL)
|
||||
if(cyborg.hud_used)
|
||||
cyborg.hud_used.update_robot_modules_display()
|
||||
SSblackbox.record_feedback("tally", "cyborg_modules", 1, cyborg.model)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
icon_state = "grievous"
|
||||
health = 150
|
||||
maxHealth = 150
|
||||
baton_type = /obj/item/melee/energy/sword/saber
|
||||
weapon = /obj/item/melee/energy/sword/saber
|
||||
base_speed = 4 //he's a fast fucker
|
||||
var/block_chance = 50
|
||||
weapon_force = 30
|
||||
@@ -16,7 +16,7 @@
|
||||
desc = "An adorable looking secbot with four toy swords taped to its arms"
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
baton_type = /obj/item/toy/sword
|
||||
weapon = /obj/item/toy/sword
|
||||
weapon_force = 0
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/grievous/bullet_act(obj/projectile/P)
|
||||
@@ -145,6 +145,6 @@
|
||||
|
||||
do_sparks(3, TRUE, src)
|
||||
for(var/IS = 0 to 4)
|
||||
drop_part(baton_type, Tsec)
|
||||
drop_part(weapon, Tsec)
|
||||
new /obj/effect/decal/cleanable/oil(Tsec)
|
||||
qdel(src)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
maxbodytemp = INFINITY
|
||||
minbodytemp = 0
|
||||
has_unlimited_silicon_privilege = 1
|
||||
has_unlimited_silicon_privilege = TRUE
|
||||
sentience_type = SENTIENCE_ARTIFICIAL
|
||||
status_flags = NONE //no default canpush
|
||||
pass_flags = PASSFLAPS
|
||||
@@ -45,7 +45,8 @@
|
||||
var/on = TRUE
|
||||
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.
|
||||
@@ -58,7 +59,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
|
||||
@@ -79,7 +80,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. This is in order of the defines for the mode defines in robots.dm, in order
|
||||
var/list/mode_name = list("In Pursuit","Preparing to Arrest", "Arresting", \
|
||||
@@ -209,12 +210,11 @@
|
||||
/mob/living/simple_animal/bot/emag_act(mob/user)
|
||||
if(locked) //First emag application unlocks the bot's interface. Apply a screwdriver to use the emag again.
|
||||
locked = FALSE
|
||||
emagged = 1
|
||||
to_chat(user, span_notice("You bypass [src]'s controls."))
|
||||
return
|
||||
if(!locked && open) //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.
|
||||
@@ -274,7 +274,7 @@
|
||||
ignorelistcleanuptimer++
|
||||
|
||||
if(!on || client)
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(commissioned && COOLDOWN_FINISHED(src, next_salute_check))
|
||||
COOLDOWN_START(src, next_salute_check, salute_delay)
|
||||
@@ -286,10 +286,10 @@
|
||||
switch(mode) //High-priority overrides are processed first. Bots can do nothing else while under direct command.
|
||||
if(BOT_RESPONDING) //Called by the AI.
|
||||
call_mode()
|
||||
return
|
||||
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.
|
||||
|
||||
|
||||
@@ -330,29 +330,29 @@
|
||||
to_chat(user, span_notice("Controls are now [locked ? "locked" : "unlocked"]."))
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/bot/attackby(obj/item/W, mob/living/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, span_notice("The maintenance panel is now [open ? "opened" : "closed"]."))
|
||||
else
|
||||
to_chat(user, span_warning("The maintenance panel is locked!"))
|
||||
else if(W.GetID())
|
||||
else if(attacking_item.GetID())
|
||||
unlock_with_id(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, span_warning("Close the access panel before manipulating the personality slot!"))
|
||||
else
|
||||
to_chat(user, span_notice("You attempt to pull [paicard] free..."))
|
||||
if(do_after(user, 30, target = src))
|
||||
if (paicard)
|
||||
user.visible_message(span_notice("[user] uses [W] to pull [paicard] out of [bot_name]!"),span_notice("You pull [paicard] out of [bot_name] with [W]."))
|
||||
user.visible_message(span_notice("[user] uses [attacking_item] to pull [paicard] out of [bot_name]!"),span_notice("You pull [paicard] out of [bot_name] with [attacking_item]."))
|
||||
ejectpai(user)
|
||||
else
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
if(W.tool_behaviour == TOOL_WELDER && !user.combat_mode)
|
||||
if(attacking_item.tool_behaviour == TOOL_WELDER && !user.combat_mode)
|
||||
if(health >= maxHealth)
|
||||
to_chat(user, span_warning("[src] does not need a repair!"))
|
||||
return
|
||||
@@ -360,11 +360,11 @@
|
||||
to_chat(user, span_warning("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(span_notice("[user] repairs [src]!"),span_notice("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)
|
||||
..()
|
||||
|
||||
@@ -728,7 +728,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)
|
||||
@@ -871,8 +871,8 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
if("remote")
|
||||
remote_disabled = !remote_disabled
|
||||
if("hack")
|
||||
if(emagged != 2)
|
||||
emagged = 2
|
||||
if(!emagged)
|
||||
emagged = TRUE
|
||||
hacked = TRUE
|
||||
locked = TRUE
|
||||
to_chat(usr, span_warning("[text_hack]"))
|
||||
@@ -911,7 +911,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) && !isAdminGhostAI(user)) //Bot is hacked, so only silicons and admins are allowed access.
|
||||
@@ -921,7 +921,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) || isAdminGhostAI(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?"]<BR>"
|
||||
hack += "[emagged ? "Software compromised! Unit may exhibit dangerous or erratic behavior." : "Unit operating normally. Release safety lock?"]<BR>"
|
||||
hack += "Harm Prevention Safety System: <A href='?src=[REF(src)];operation=hack'>[emagged ? "<span class='bad'>DANGER</span>" : "Engaged"]</A><BR>"
|
||||
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: <A href='?src=[REF(src)];operation=remote'>[remote_disabled ? "Disconnected" : "Connected"]</A><BR>"
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/bot_reset()
|
||||
..()
|
||||
if(weapon && emagged == 2)
|
||||
if(weapon && emagged)
|
||||
weapon.force = weapon_orig_force
|
||||
ignore_list = list() //Allows the bot to clean targets it previously ignored due to being unreachable.
|
||||
target = null
|
||||
@@ -186,11 +186,12 @@
|
||||
/mob/living/simple_animal/bot/cleanbot/emag_act(mob/user)
|
||||
..()
|
||||
|
||||
if(emagged == 2)
|
||||
if(weapon)
|
||||
weapon.force = weapon_orig_force
|
||||
if(user)
|
||||
to_chat(user, span_danger("[src] buzzes and beeps."))
|
||||
if(!emagged)
|
||||
return
|
||||
if(weapon)
|
||||
weapon.force = weapon_orig_force
|
||||
if(user)
|
||||
to_chat(user, span_danger("[src] buzzes and beeps."))
|
||||
|
||||
/mob/living/simple_animal/bot/cleanbot/process_scan(atom/A)
|
||||
if(iscarbon(A))
|
||||
@@ -207,9 +208,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
|
||||
@@ -226,7 +226,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.
|
||||
@@ -295,8 +295,8 @@
|
||||
/obj/effect/decal/cleanable/greenglow,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/effect/decal/cleanable/insectguts,
|
||||
/obj/effect/decal/remains
|
||||
)
|
||||
/obj/effect/decal/remains,
|
||||
)
|
||||
|
||||
if(blood)
|
||||
target_types += /obj/effect/decal/cleanable/xenoblood
|
||||
@@ -343,7 +343,7 @@
|
||||
living_target.death()
|
||||
living_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
|
||||
@@ -397,9 +397,9 @@
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += text({"
|
||||
Status: <A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A><BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"})
|
||||
Status: <A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A><BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"})
|
||||
if(!locked || issilicon(user)|| isAdminGhostAI(user))
|
||||
dat += "<BR>Clean Blood: <A href='?src=[REF(src)];operation=blood'>[blood ? "Yes" : "No"]</A>"
|
||||
dat += "<BR>Clean Trash: <A href='?src=[REF(src)];operation=trash'>[trash ? "Yes" : "No"]</A>"
|
||||
|
||||
@@ -372,7 +372,7 @@
|
||||
to_chat(user, span_notice("You complete the Securitron! Beep boop."))
|
||||
var/mob/living/simple_animal/bot/secbot/S = new(Tsec)
|
||||
S.name = created_name
|
||||
S.baton_type = I.type
|
||||
S.weapon = I.type
|
||||
S.robot_arm = robot_arm
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
|
||||
model = "ED-209"
|
||||
bot_type = ADVANCED_SEC_BOT
|
||||
window_id = "autoed209"
|
||||
window_name = "Automatic Security Unit v2.6"
|
||||
ranged = TRUE
|
||||
var/lastfired = 0
|
||||
var/shot_delay = 15
|
||||
var/shoot_sound = 'sound/weapons/laser.ogg'
|
||||
@@ -40,32 +40,31 @@
|
||||
/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(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons))
|
||||
//speak(C.real_name + text(": threat: []", threatlevel))
|
||||
threatlevel = nearby_carbon.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, .proc/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.handcuffed) //we don't shoot people who are dead, cuffed or lying down.
|
||||
shootAt(t)
|
||||
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/secbot/ed209/proc/set_weapon() //used to update the projectile type and firing sound
|
||||
shoot_sound = 'sound/weapons/laser.ogg'
|
||||
if(emagged == 2)
|
||||
if(emagged)
|
||||
projectile = /obj/projectile/beam
|
||||
else
|
||||
projectile = /obj/projectile/beam/disabler
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/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
|
||||
@@ -75,14 +74,13 @@
|
||||
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()
|
||||
fired_bullet.preparePixelProjectile(target, src)
|
||||
fired_bullet.fire()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/ed209/emp_act(severity)
|
||||
if(severity == 2 && prob(70))
|
||||
@@ -90,34 +88,36 @@
|
||||
. = ..()
|
||||
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(severity <= 1)
|
||||
return
|
||||
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
|
||||
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)
|
||||
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
|
||||
var/mob/to_arrest = pick(targets)
|
||||
if(to_arrest)
|
||||
target = to_arrest
|
||||
mode = BOT_HUNT
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/ed209/RangedAttack(atom/A)
|
||||
if(!on)
|
||||
return
|
||||
shootAt(A)
|
||||
shoot_at(A)
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
|
||||
/mob/living/simple_animal/bot/firebot/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(emagged)
|
||||
if(user)
|
||||
to_chat(user, span_danger("[src] buzzes and beeps."))
|
||||
audible_message(span_danger("[src] buzzes oddly!"))
|
||||
@@ -162,7 +162,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))
|
||||
@@ -210,7 +210,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!")
|
||||
|
||||
@@ -143,9 +143,10 @@
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
to_chat(user, span_danger("[src] buzzes and beeps."))
|
||||
if(!emagged)
|
||||
return
|
||||
if(user)
|
||||
to_chat(user, span_danger("[src] buzzes and beeps."))
|
||||
|
||||
///mobs should use move_resist instead of anchored.
|
||||
/mob/living/simple_animal/bot/floorbot/proc/toggle_magnet(engage = TRUE, change_icon = TRUE)
|
||||
@@ -205,7 +206,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
|
||||
@@ -229,7 +230,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)
|
||||
|
||||
@@ -251,9 +252,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
|
||||
toggle_magnet()
|
||||
mode = BOT_REPAIRING
|
||||
|
||||
@@ -106,7 +106,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
var/final = NONE
|
||||
if(check_records)
|
||||
final = final|JUDGE_RECORDCHECK
|
||||
if(emagged == 2)
|
||||
if(emagged)
|
||||
final = final|JUDGE_EMAGGED
|
||||
return final
|
||||
|
||||
@@ -133,13 +133,14 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
user << span_danger("You short out [src]'s sound control system. It gives out an evil laugh!!")
|
||||
oldtarget_name = user.name
|
||||
audible_message(span_danger("[src] gives out an evil laugh!"))
|
||||
playsound(src, 'sound/machines/honkbot_evil_laugh.ogg', 75, TRUE, -1) // evil laughter
|
||||
update_appearance()
|
||||
if(!emagged)
|
||||
return
|
||||
if(user)
|
||||
to_chat(user, span_danger("You short out [src]'s sound control system. It gives out an evil laugh!!"))
|
||||
oldtarget_name = user.name
|
||||
audible_message(span_danger("[src] gives out an evil laugh!"))
|
||||
playsound(src, 'sound/machines/honkbot_evil_laugh.ogg', 75, TRUE, -1) // evil laughter
|
||||
update_appearance()
|
||||
|
||||
/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)))
|
||||
@@ -153,7 +154,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
return
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
if (emagged <= 1)
|
||||
if(emagged)
|
||||
honk_attack(A)
|
||||
else
|
||||
if(!C.IsParalyzed() || arrest_type)
|
||||
@@ -174,19 +175,19 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/proc/bike_horn() //use bike_horn
|
||||
if (emagged <= 1)
|
||||
if (!limiting_spam)
|
||||
playsound(src, honksound, 50, TRUE, -1)
|
||||
limiting_spam = TRUE //prevent spam
|
||||
sensor_blink()
|
||||
addtimer(CALLBACK(src, .proc/limiting_spam_false), cooldowntimehorn)
|
||||
else if (emagged == 2) //emagged honkbots will spam short and memorable sounds.
|
||||
if (emagged) //emagged honkbots will spam short and memorable sounds.
|
||||
if (!limiting_spam)
|
||||
playsound(src, "honkbot_e", 50, FALSE)
|
||||
limiting_spam = TRUE // prevent spam
|
||||
icon_state = "honkbot-e"
|
||||
addtimer(CALLBACK(src, /atom/.proc/update_appearance), 3 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE)
|
||||
addtimer(CALLBACK(src, .proc/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/limiting_spam_false), cooldowntimehorn)
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/proc/honk_attack(mob/living/carbon/C) // horn attack
|
||||
if(!limiting_spam)
|
||||
@@ -210,13 +211,14 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(client) //prevent spam from players..
|
||||
limiting_spam = TRUE
|
||||
if (emagged <= 1) //HONK once, then leave
|
||||
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/limiting_spam_false), cooldowntime)
|
||||
|
||||
log_combat(src,C,"honked")
|
||||
|
||||
@@ -212,10 +212,10 @@
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += {"
|
||||
<TT><B>Hygienebot X2 controls</B></TT><BR><BR>
|
||||
Status: ["<A href='?src=[REF(src)];power=[TRUE]'>[on ? "On" : "Off"]</A>"]<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel is [open ? "opened" : "closed"]"}
|
||||
<TT><B>Hygienebot X2 controls</B></TT><BR><BR>
|
||||
Status: ["<A href='?src=[REF(src)];power=[TRUE]'>[on ? "On" : "Off"]</A>"]<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel is [open ? "opened" : "closed"]"}
|
||||
|
||||
if(!locked || issilicon(user) || isAdminGhostAI(user))
|
||||
dat += {"<BR> Auto Patrol: ["<A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>"]"}
|
||||
@@ -223,7 +223,7 @@ Maintenance panel is [open ? "opened" : "closed"]"}
|
||||
return dat.Join("")
|
||||
|
||||
/mob/living/simple_animal/bot/hygienebot/proc/check_purity(mob/living/L)
|
||||
if((emagged == 2) && L.stat != DEAD)
|
||||
if((emagged) && L.stat != DEAD)
|
||||
return FALSE
|
||||
|
||||
for(var/X in list(ITEM_SLOT_HEAD, ITEM_SLOT_MASK, ITEM_SLOT_ICLOTHING, ITEM_SLOT_OCLOTHING, ITEM_SLOT_FEET))
|
||||
|
||||
@@ -222,15 +222,16 @@
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
declare_crit = 0
|
||||
if(user)
|
||||
to_chat(user, span_notice("You short out [src]'s reagent synthesis circuits."))
|
||||
audible_message(span_danger("[src] buzzes oddly!"))
|
||||
flick("medibot_spark", src)
|
||||
playsound(src, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
if(user)
|
||||
oldpatient = user
|
||||
if(!emagged)
|
||||
return
|
||||
declare_crit = FALSE
|
||||
if(user)
|
||||
to_chat(user, span_notice("You short out [src]'s reagent synthesis circuits."))
|
||||
audible_message(span_danger("[src] buzzes oddly!"))
|
||||
flick("medibot_spark", src)
|
||||
playsound(src, "sparks", 75, TRUE, 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)
|
||||
@@ -445,7 +446,7 @@
|
||||
if(C.suiciding)
|
||||
return FALSE //Kevorkian school of robotic medical assistants.
|
||||
|
||||
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,tag)) //the early medbot gets the worm (or in this case the patient)
|
||||
@@ -542,7 +543,7 @@
|
||||
if(damagetype_healer == "all" && potential_methods.len)
|
||||
treatment_method = pick(potential_methods)
|
||||
|
||||
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.get_organic_health() < heal_threshold)
|
||||
to_chat(src, span_notice("[C] is healthy! Your programming prevents you from tending the wounds of anyone without at least [heal_threshold] damage of any one type ([heal_threshold + 5] for oxygen damage.)"))
|
||||
|
||||
@@ -562,7 +563,7 @@
|
||||
var/obj/item/storage/firstaid/FA = firstaid
|
||||
if(treatment_method == BRUTE && initial(FA.damagetype_healed) == BRUTE) //specialized brute gets a bit of bonus, as a snack.
|
||||
healies *= 1.1
|
||||
if(emagged == 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)")
|
||||
|
||||
@@ -23,34 +23,44 @@
|
||||
|
||||
combat_mode = TRUE
|
||||
|
||||
var/baton_type = /obj/item/melee/baton/security
|
||||
var/obj/item/weapon
|
||||
///The tool this Secbot will use to make arrests
|
||||
var/obj/item/weapon = /obj/item/melee/baton/security
|
||||
///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
|
||||
var/ranged = FALSE //used for EDs
|
||||
///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
|
||||
|
||||
var/fair_market_price_arrest = 25 // On arrest, charges the violator this much. If they don't have that much in their account, the securitron will beat them instead
|
||||
var/fair_market_price_detain = 5 // Charged each time the violator is stunned on detain
|
||||
var/weapon_force = 20 // Only used for NAP violation beatdowns on non-grievous securitrons
|
||||
var/market_verb = "Suspect"
|
||||
///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
|
||||
|
||||
///On arrest, charges the violator this much. If they don't have that much in their account, they will get beaten instead
|
||||
var/fair_market_price_arrest = 25
|
||||
///Charged each time the violator is stunned on detain
|
||||
var/fair_market_price_detain = 5
|
||||
/// Force of the harmbaton used on them
|
||||
var/weapon_force = 20
|
||||
///The department the secbot will deposit collected money into
|
||||
var/payment_department = ACCOUNT_SEC
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky
|
||||
name = "Commander Beep O'sky"
|
||||
desc = "It's Commander Beep O'sky! Officially the superior officer of all bots on station, Beepsky remains as humble and dedicated to the law as the day he was first fabricated."
|
||||
idcheck = FALSE
|
||||
weaponscheck = FALSE
|
||||
auto_patrol = TRUE
|
||||
commissioned = 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/jr
|
||||
name = "Officer Pipsqueak"
|
||||
desc = "It's Commander Beep O'sky's smaller, just-as aggressive cousin, Pipsqueak."
|
||||
@@ -61,22 +71,22 @@
|
||||
resize = 0.8
|
||||
update_transform()
|
||||
|
||||
|
||||
/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)
|
||||
..()
|
||||
|
||||
/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/drinking_oil = new(Tsec)
|
||||
drinking_oil.reagents.add_reagent(/datum/reagent/consumable/ethanol/whiskey, 15)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Initialize(mapload)
|
||||
. = ..()
|
||||
weapon = new baton_type()
|
||||
weapon = new weapon()
|
||||
update_appearance(UPDATE_ICON)
|
||||
|
||||
// Doing this hurts my soul, but simplebot access reworks are for another day.
|
||||
@@ -131,72 +141,70 @@
|
||||
dat += hack(user)
|
||||
dat += showpai(user)
|
||||
dat += text({"
|
||||
<TT><B>Securitron v1.6 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
<TT><B>Securitron v1.6 controls</B></TT><BR><BR>
|
||||
Status: []<BR>
|
||||
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
|
||||
Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
|
||||
"<A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A>" )
|
||||
"<A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A>")
|
||||
|
||||
if(!locked || issilicon(user) || isAdminGhostAI(user))
|
||||
dat += text({"<BR>
|
||||
Arrest Unidentifiable Persons: []<BR>
|
||||
Arrest for Unauthorized Weapons: []<BR>
|
||||
Arrest for Warrant: []<BR>
|
||||
Operating Mode: []<BR>
|
||||
Report Arrests[]<BR>
|
||||
Auto Patrol: []"},
|
||||
Arrest Unidentifiable Persons: []<BR>
|
||||
Arrest for Unauthorized Weapons: []<BR>
|
||||
Arrest for Warrant: []<BR>
|
||||
Operating Mode: []<BR>
|
||||
Report Arrests[]<BR>
|
||||
Auto Patrol: []"},
|
||||
|
||||
"<A href='?src=[REF(src)];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
|
||||
"<A href='?src=[REF(src)];operation=idcheck'>[security_mode_flags & SECBOT_CHECK_IDS ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=weaponscheck'>[security_mode_flags & SECBOT_CHECK_WEAPONS ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=ignorerec'>[security_mode_flags & SECBOT_CHECK_RECORDS ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=switchmode'>[security_mode_flags & SECBOT_HANDCUFF_TARGET ? "Arrest" : "Detain"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=declarearrests'>[security_mode_flags & SECBOT_DECLARE_ARRESTS ? "Yes" : "No"]</A>",
|
||||
"<A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>")
|
||||
|
||||
return dat
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
. = ..()
|
||||
if(.)
|
||||
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
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H)
|
||||
update_controls()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/attacking_human)
|
||||
var/judgement_criteria = judgement_criteria()
|
||||
threatlevel = H.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons))
|
||||
threatlevel = attacking_human.assess_threat(judgement_criteria, weaponcheck = CALLBACK(src, .proc/check_for_weapons))
|
||||
threatlevel += 6
|
||||
if(threatlevel >= 4)
|
||||
target = H
|
||||
target = attacking_human
|
||||
mode = BOT_HUNT
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/judgement_criteria()
|
||||
var/final = FALSE
|
||||
if(idcheck)
|
||||
final |= JUDGE_IDCHECK
|
||||
if(check_records)
|
||||
final |= JUDGE_RECORDCHECK
|
||||
if(weaponscheck)
|
||||
final |= JUDGE_WEAPONCHECK
|
||||
if(emagged == 2)
|
||||
if(emagged)
|
||||
final |= JUDGE_EMAGGED
|
||||
if(ranged)
|
||||
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.
|
||||
@@ -219,26 +227,26 @@ Auto Patrol: []"},
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/attackby(obj/item/W, mob/living/user, params)
|
||||
/mob/living/simple_animal/bot/secbot/attackby(obj/item/attacking_item, mob/living/user, params)
|
||||
..()
|
||||
if(!on) // Bots won't remember if you hit them while they're off.
|
||||
return
|
||||
if(W.tool_behaviour == TOOL_WELDER && !user.combat_mode) // Any intent but harm will heal, so we shouldn't get angry.
|
||||
if(attacking_item.tool_behaviour == TOOL_WELDER && !user.combat_mode) // 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/emag_act(mob/user)
|
||||
..()
|
||||
if(emagged == 2)
|
||||
if(user)
|
||||
to_chat(user, span_danger("You short out [src]'s target assessment circuits."))
|
||||
oldtarget_name = user.name
|
||||
audible_message(span_danger("[src] buzzes oddly!"))
|
||||
declare_arrests = FALSE
|
||||
update_appearance()
|
||||
if(!emagged)
|
||||
return
|
||||
if(user)
|
||||
to_chat(user, span_danger("You short out [src]'s target assessment circuits."))
|
||||
oldtarget_name = user.name
|
||||
audible_message(span_danger("[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))
|
||||
@@ -247,49 +255,48 @@ Auto Patrol: []"},
|
||||
retaliate(Proj.firer)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A, proximity_flag, list/modifiers)
|
||||
/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers)
|
||||
if(!on)
|
||||
return
|
||||
if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
|
||||
return
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
if(!C.IsParalyzed() || arrest_type)
|
||||
if(!check_nap_violations())
|
||||
stun_attack(A, TRUE)
|
||||
else
|
||||
stun_attack(A)
|
||||
else if(C.canBeHandcuffed() && !C.handcuffed)
|
||||
cuff(A)
|
||||
else
|
||||
..()
|
||||
if(!iscarbon(attack_target))
|
||||
return ..()
|
||||
var/mob/living/carbon/carbon_target = attack_target
|
||||
if(!carbon_target.IsParalyzed() || !(security_mode_flags & SECBOT_HANDCUFF_TARGET))
|
||||
if(!check_nap_violations())
|
||||
stun_attack(attack_target, TRUE)
|
||||
else
|
||||
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/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)
|
||||
/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(span_danger("[src] is trying to put zipties on [C]!"),\
|
||||
current_target.visible_message(span_danger("[src] is trying to put zipties on [current_target]!"),\
|
||||
span_userdanger("[src] is trying to put zipties on you!"))
|
||||
addtimer(CALLBACK(src, .proc/attempt_handcuff, C), 60)
|
||||
addtimer(CALLBACK(src, .proc/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.set_handcuffed(new /obj/item/restraints/handcuffs/cable/zipties/used(C))
|
||||
C.update_handcuffed()
|
||||
if(!current_target.handcuffed)
|
||||
current_target.set_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, harm = FALSE)
|
||||
/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/current_target, harm = FALSE)
|
||||
var/judgement_criteria = judgement_criteria()
|
||||
playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
|
||||
icon_state = "[initial(icon_state)]-c"
|
||||
@@ -297,84 +304,81 @@ Auto Patrol: []"},
|
||||
var/threat = 5
|
||||
|
||||
if(harm)
|
||||
weapon.attack(C, src)
|
||||
if(ishuman(C))
|
||||
C.stuttering = 5
|
||||
C.Paralyze(100)
|
||||
var/mob/living/carbon/human/H = C
|
||||
threat = H.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons))
|
||||
weapon.attack(current_target, src)
|
||||
if(ishuman(current_target))
|
||||
current_target.stuttering = 5
|
||||
current_target.Paralyze(100)
|
||||
var/mob/living/carbon/human/human_target = current_target
|
||||
threat = human_target.assess_threat(judgement_criteria, weaponcheck = CALLBACK(src, .proc/check_for_weapons))
|
||||
else
|
||||
C.Paralyze(100)
|
||||
C.stuttering = 5
|
||||
threat = C.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons))
|
||||
current_target.Paralyze(100)
|
||||
current_target.stuttering = 5
|
||||
threat = current_target.assess_threat(judgement_criteria, weaponcheck = CALLBACK(src, .proc/check_for_weapons))
|
||||
|
||||
log_combat(src,C,"stunned")
|
||||
if(declare_arrests)
|
||||
log_combat(src, target, "stunned")
|
||||
if(security_mode_flags & SECBOT_DECLARE_ARRESTS)
|
||||
var/area/location = get_area(src)
|
||||
speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag <b>[C]</b> in [location].", radio_channel)
|
||||
C.visible_message(span_danger("[src] stuns [C]!"),\
|
||||
speak("[security_mode_flags & SECBOT_HANDCUFF_TARGET ? "Arresting" : "Detaining"] level [threat] scumbag <b>[current_target]</b> in [location].", radio_channel)
|
||||
current_target.visible_message(span_danger("[src] stuns [current_target]!"),\
|
||||
span_userdanger("[src] stuns you!"))
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/handle_automated_action()
|
||||
if(!..())
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
switch(mode)
|
||||
|
||||
if(BOT_IDLE) // idle
|
||||
|
||||
walk_to(src,0)
|
||||
look_for_perp() // see if any criminals are in range
|
||||
if(!mode && auto_patrol) // still idle, and set to patrol
|
||||
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)
|
||||
walk_to(src,0)
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(target) // make sure target exists
|
||||
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
|
||||
if(!check_nap_violations())
|
||||
stun_attack(target, TRUE)
|
||||
else
|
||||
stun_attack(target)
|
||||
|
||||
mode = BOT_PREP_ARREST
|
||||
set_anchored(TRUE)
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
|
||||
else // not next to perp
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
walk_to(src, target,1,4)
|
||||
if((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
else
|
||||
if(!target) // make sure target exists
|
||||
back_to_idle()
|
||||
return
|
||||
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
|
||||
if(!check_nap_violations())
|
||||
stun_attack(target, TRUE)
|
||||
else
|
||||
stun_attack(target)
|
||||
|
||||
mode = BOT_PREP_ARREST
|
||||
set_anchored(TRUE)
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
|
||||
// not next to perp
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
walk_to(src, target,1,4)
|
||||
if((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
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.AmountParalyzed() < 40)
|
||||
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
|
||||
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)
|
||||
@@ -406,9 +410,6 @@ Auto Patrol: []"},
|
||||
look_for_perp()
|
||||
bot_patrol()
|
||||
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/back_to_idle()
|
||||
set_anchored(FALSE)
|
||||
mode = BOT_IDLE
|
||||
@@ -427,32 +428,30 @@ Auto Patrol: []"},
|
||||
/mob/living/simple_animal/bot/secbot/proc/look_for_perp()
|
||||
set_anchored(FALSE)
|
||||
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))
|
||||
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(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons))
|
||||
threatlevel = nearby_carbons.assess_threat(judgement_criteria, weaponcheck = CALLBACK(src, .proc/check_for_weapons))
|
||||
|
||||
if(!threatlevel)
|
||||
continue
|
||||
|
||||
else if(threatlevel >= 4)
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
if(threatlevel >= 4)
|
||||
target = nearby_carbons
|
||||
oldtarget_name = nearby_carbons.name
|
||||
speak("Level [threatlevel] infraction alert!")
|
||||
if(ranged)
|
||||
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("<b>[src]</b> points at [C.name]!")
|
||||
visible_message("<b>[src]</b> points at [nearby_carbons.name]!")
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, .proc/handle_automated_action)
|
||||
break
|
||||
else
|
||||
continue
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/check_for_weapons(obj/item/slot_item)
|
||||
if(slot_item && (slot_item.item_flags & NEEDS_PERMIT))
|
||||
@@ -461,18 +460,18 @@ Auto Patrol: []"},
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/explode()
|
||||
|
||||
walk_to(src,0)
|
||||
walk_to(src, 0)
|
||||
visible_message(span_boldannounce("[src] blows apart!"))
|
||||
var/atom/Tsec = drop_location()
|
||||
if(ranged)
|
||||
var/obj/item/bot_assembly/ed209/Sa = new (Tsec)
|
||||
Sa.build_step = 1
|
||||
Sa.add_overlay("hs_hole")
|
||||
Sa.created_name = name
|
||||
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/G = new (Tsec)
|
||||
G.cell.charge = 0
|
||||
G.update_appearance()
|
||||
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))
|
||||
@@ -483,12 +482,12 @@ Auto Patrol: []"},
|
||||
else
|
||||
new /obj/item/clothing/suit/armor/vest(Tsec)
|
||||
else
|
||||
var/obj/item/bot_assembly/secbot/Sa = new (Tsec)
|
||||
Sa.build_step = 1
|
||||
Sa.add_overlay("hs_hole")
|
||||
Sa.created_name = name
|
||||
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)
|
||||
drop_part(weapon, Tsec)
|
||||
|
||||
if(prob(50))
|
||||
drop_part(robot_arm, Tsec)
|
||||
@@ -511,7 +510,6 @@ Auto Patrol: []"},
|
||||
if(!istype(C) || !C || in_range(src, target))
|
||||
return
|
||||
knockOver(C)
|
||||
return
|
||||
|
||||
/obj/machinery/bot_core/secbot
|
||||
req_access = list(ACCESS_SECURITY)
|
||||
@@ -520,32 +518,31 @@ Auto Patrol: []"},
|
||||
/mob/living/simple_animal/bot/secbot/proc/check_nap_violations()
|
||||
if(!SSeconomy.full_ancap)
|
||||
return TRUE
|
||||
|
||||
if(target)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/obj/item/card/id/I = H.get_idcard(TRUE)
|
||||
if(I)
|
||||
var/datum/bank_account/insurance = I.registered_account
|
||||
if(!insurance)
|
||||
say("[market_verb] NAP Violation: No bank account found.")
|
||||
nap_violation(target)
|
||||
return FALSE
|
||||
else
|
||||
var/fair_market_price = (arrest_type ? fair_market_price_detain : fair_market_price_arrest)
|
||||
if(!insurance.adjust_money(-fair_market_price))
|
||||
say("[market_verb] NAP Violation: Unable to pay.")
|
||||
nap_violation(target)
|
||||
return FALSE
|
||||
var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department)
|
||||
say("Thank you for your compliance. Your account been charged [fair_market_price] credits.")
|
||||
if(D)
|
||||
D.adjust_money(fair_market_price)
|
||||
else
|
||||
say("[market_verb] NAP Violation: No ID card found.")
|
||||
nap_violation(target)
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(!target)
|
||||
return TRUE
|
||||
if(!ishuman(target))
|
||||
return TRUE
|
||||
var/mob/living/carbon/human/human_target = target
|
||||
var/obj/item/card/id/target_id = human_target.get_idcard()
|
||||
if(!target_id)
|
||||
say("Suspect NAP Violation: No ID card found.")
|
||||
nap_violation(target)
|
||||
return FALSE
|
||||
var/datum/bank_account/insurance = target_id.registered_account
|
||||
if(!insurance)
|
||||
say("Suspect NAP Violation: No bank account found.")
|
||||
nap_violation(target)
|
||||
return FALSE
|
||||
var/fair_market_price = (security_mode_flags & SECBOT_HANDCUFF_TARGET ? fair_market_price_detain : fair_market_price_arrest)
|
||||
if(!insurance.adjust_money(-fair_market_price))
|
||||
say("Suspect NAP Violation: Unable to pay.")
|
||||
nap_violation(target)
|
||||
return FALSE
|
||||
var/datum/bank_account/beepsky_department_account = SSeconomy.get_dep_account(payment_department)
|
||||
say("Thank you for your compliance. Your account been charged [fair_market_price] credits.")
|
||||
if(beepsky_department_account)
|
||||
beepsky_department_account.adjust_money(fair_market_price)
|
||||
return TRUE
|
||||
|
||||
/// Does nothing
|
||||
/mob/living/simple_animal/bot/secbot/proc/nap_violation(mob/violator)
|
||||
|
||||
@@ -39,7 +39,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
|
||||
|
||||
@@ -169,7 +169,7 @@
|
||||
var/status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH
|
||||
|
||||
/// 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
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
R.mmi.brainmob.name = real_name
|
||||
|
||||
R.job = "Cyborg"
|
||||
R.notify_ai(NEW_BORG)
|
||||
R.notify_ai(AI_NOTIFICATION_NEW_BORG)
|
||||
|
||||
. = R
|
||||
if(R.ckey && is_banned_from(R.ckey, "Cyborg"))
|
||||
|
||||
@@ -12,7 +12,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'
|
||||
@@ -37,9 +37,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)
|
||||
@@ -55,7 +55,14 @@
|
||||
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/link_worlds
|
||||
name = "Link Worlds"
|
||||
|
||||
Reference in New Issue
Block a user