mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 20:48:56 +01:00
Beepsky refactor and Bot code improvement (#62510)
This commit is contained in:
@@ -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"))
|
||||
|
||||
Reference in New Issue
Block a user