mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-29 06:57:42 +01:00
Bots refactor (#23550)
* ugh... bots refactor * everyone uses pathfind and eyes * most hunt logic to proc * Update code/modules/mob/living/simple_animal/bot/ed209bot.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/bot/ed209bot.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * Sirryan review * Update code/modules/mob/living/simple_animal/bot/honkbot.dm Co-authored-by: warriorstar-orion <orion@snowfrost.garden> * better var naming i guess? * Update code/modules/mob/living/simple_animal/bot/ed209bot.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/bot/griefsky.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/bot/secbot.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/bot/secbot.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/bot/secbot.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/bot/secbot.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/bot/secbot.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/bot/secbot.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * review * uh oh * Update code/modules/mob/living/simple_animal/bot/secbot.dm Co-authored-by: Deniz <66401072+Oyu07@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/bot/secbot.dm Co-authored-by: Deniz <66401072+Oyu07@users.noreply.github.com> * return FALSE --------- Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> Co-authored-by: warriorstar-orion <orion@snowfrost.garden> Co-authored-by: Deniz <66401072+Oyu07@users.noreply.github.com>
This commit is contained in:
co-authored by
Ryan
warriorstar-orion
Deniz
parent
ac32162dbc
commit
ba98eb4d16
@@ -96,6 +96,11 @@
|
||||
|
||||
hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD)//Diagnostic HUD views
|
||||
|
||||
/// storing last chased target known location
|
||||
var/turf/last_target_location
|
||||
/// will be true if we lost target we were chasing
|
||||
var/lost_target = FALSE
|
||||
|
||||
/obj/item/radio/headset/bot
|
||||
requires_tcomms = FALSE
|
||||
canhear_range = 0
|
||||
@@ -110,6 +115,36 @@
|
||||
B.radio_config["[B.radio_channel]"] = 1
|
||||
config(B.radio_config)
|
||||
|
||||
/mob/living/simple_animal/bot/proc/try_chasing_target(mob/target)
|
||||
if(target in view(12, src))
|
||||
if(lost_target)
|
||||
frustration = 0
|
||||
lost_target = FALSE
|
||||
last_target_location = get_turf(target)
|
||||
var/dist = get_dist(src, target)
|
||||
walk_to(src, target, 1, 4)
|
||||
if(get_dist(src, target) >= dist)
|
||||
frustration++
|
||||
return
|
||||
|
||||
if(!lost_target)
|
||||
walk_to(src, 0)
|
||||
lost_target = TRUE
|
||||
frustration = 0
|
||||
|
||||
if(get_turf(src) == last_target_location)
|
||||
frustration += 2
|
||||
return
|
||||
|
||||
if(!bot_move(last_target_location, move_speed = 6))
|
||||
var/last_target_pos_path = get_path_to(src, last_target_location, id = access_card, skip_first = TRUE)
|
||||
if(length(last_target_pos_path) == 0)
|
||||
frustration = 10
|
||||
return
|
||||
set_path(last_target_pos_path)
|
||||
bot_move(last_target_location, move_speed = 6)
|
||||
frustration++
|
||||
|
||||
/mob/living/simple_animal/bot/proc/get_mode()
|
||||
if(client) //Player bots do not have modes, thus the override. Also an easy way for PDA users/AI to know when a bot is a player.
|
||||
if(paicard)
|
||||
@@ -605,6 +640,8 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
deltimer(reset_access_timer_id)
|
||||
reset_access_timer_id = null
|
||||
set_path(null)
|
||||
last_target_location = null
|
||||
lost_target = FALSE
|
||||
summon_target = null
|
||||
pathset = FALSE
|
||||
access_card.access = prev_access
|
||||
|
||||
@@ -40,14 +40,16 @@
|
||||
var/idcheck = FALSE //If true, arrest people with no IDs
|
||||
var/weapons_check = TRUE //If true, arrest people for weapons if they don't have access
|
||||
var/check_records = TRUE //Does it check security records?
|
||||
var/arrest_type = FALSE //If true, don't handcuff
|
||||
var/no_handcuffs = FALSE //If true, don't handcuff
|
||||
var/projectile = /obj/item/projectile/beam/disabler //Holder for projectile type
|
||||
var/shoot_sound = 'sound/weapons/taser.ogg'
|
||||
var/baton_delayed = FALSE
|
||||
|
||||
var/obj/item/melee/baton/infinite_cell/baton = null // stunbaton bot uses to melee attack
|
||||
var/currently_cuffing = FALSE // TRUE if we're cuffing someone right now
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/Initialize(mapload, created_name, created_lasercolor)
|
||||
. = ..()
|
||||
baton = new(src)
|
||||
if(created_name)
|
||||
name = created_name
|
||||
if(created_lasercolor)
|
||||
@@ -59,7 +61,7 @@
|
||||
if(lasercolor)
|
||||
shot_delay = 6 //Longer shot delay because JESUS CHRIST
|
||||
check_records = FALSE //Don't actively target people set to arrest
|
||||
arrest_type = TRUE //Don't even try to cuff
|
||||
no_handcuffs = TRUE //Don't even try to cuff
|
||||
declare_arrests = FALSE // Don't spam sec
|
||||
req_access = list(ACCESS_MAINT_TUNNELS, ACCESS_THEATRE, ACCESS_ROBOTICS)
|
||||
|
||||
@@ -69,6 +71,10 @@
|
||||
else if(lasercolor == "r")
|
||||
name = pick("RED RAMPAGE","RED ROVER","RED KILLDEATH MURDERBOT")
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/Destroy()
|
||||
QDEL_NULL(baton)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/setup_access()
|
||||
if(access_card)
|
||||
var/datum/job/detective/J = new/datum/job/detective
|
||||
@@ -89,6 +95,7 @@
|
||||
target = null
|
||||
oldtarget_name = null
|
||||
anchored = FALSE
|
||||
currently_cuffing = FALSE
|
||||
walk_to(src,0)
|
||||
set_path(null)
|
||||
last_found = world.time
|
||||
@@ -116,7 +123,7 @@
|
||||
data["check_id"] = idcheck
|
||||
data["check_weapons"] = weapons_check
|
||||
data["check_warrant"] = check_records
|
||||
data["arrest_mode"] = arrest_type // detain or arrest
|
||||
data["arrest_mode"] = no_handcuffs // detain or arrest
|
||||
data["arrest_declare"] = declare_arrests // announce arrests on radio
|
||||
return data
|
||||
|
||||
@@ -148,7 +155,7 @@
|
||||
if("authwarrant")
|
||||
check_records = !check_records
|
||||
if("arrtype")
|
||||
arrest_type = !arrest_type
|
||||
no_handcuffs = !no_handcuffs
|
||||
if("arrdeclare")
|
||||
declare_arrests = !declare_arrests
|
||||
if("ejectpai")
|
||||
@@ -240,40 +247,36 @@
|
||||
walk_to(src,0)
|
||||
set_path(null)
|
||||
if(!lasercolor) //lasertag bots don't want to arrest anyone
|
||||
look_for_perp() // see if any criminals are in range
|
||||
if(find_new_target())
|
||||
return // 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)
|
||||
walk_to(src, 0)
|
||||
set_path(null)
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(target) // make sure target exists
|
||||
if(Adjacent(target) && isturf(target.loc) && !baton_delayed) // if right next to perp
|
||||
stun_attack(target)
|
||||
if(!lasercolor)
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = TRUE
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
else
|
||||
mode = BOT_HUNT
|
||||
target = null
|
||||
target_lastloc = null
|
||||
return
|
||||
|
||||
else if(!disabled) // 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) && !baton_delayed) // if right next to perp
|
||||
stun_attack(target)
|
||||
if(!lasercolor)
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = TRUE
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
mode = BOT_HUNT
|
||||
target = null
|
||||
target_lastloc = null
|
||||
return
|
||||
|
||||
try_chasing_target(target)
|
||||
|
||||
if(BOT_PREP_ARREST) // preparing to arrest target
|
||||
|
||||
@@ -282,42 +285,43 @@
|
||||
back_to_hunt()
|
||||
return
|
||||
|
||||
if(iscarbon(target) && target.canBeHandcuffed())
|
||||
if(!arrest_type)
|
||||
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
|
||||
start_cuffing(target)
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
else
|
||||
if(no_handcuffs) // should we not cuff?
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(BOT_ARREST)
|
||||
if(!target)
|
||||
anchored = FALSE
|
||||
mode = BOT_IDLE
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
if(!(iscarbon(target) && target.canBeHandcuffed()))
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(target.handcuffed) //no target or target cuffed? back to idle.
|
||||
if(currently_cuffing)
|
||||
return
|
||||
|
||||
if(!target.handcuffed)
|
||||
cuff(target)
|
||||
return
|
||||
|
||||
back_to_idle()
|
||||
|
||||
if(BOT_ARREST)
|
||||
if(!target || target.handcuffed)
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && world.time - target.stam_regen_start_time < 4 SECONDS && target.getStaminaLoss() <= 100)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
|
||||
back_to_hunt()
|
||||
return
|
||||
else
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = FALSE
|
||||
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = FALSE
|
||||
|
||||
if(BOT_START_PATROL)
|
||||
look_for_perp()
|
||||
if(find_new_target())
|
||||
return
|
||||
start_patrol()
|
||||
|
||||
if(BOT_PATROL)
|
||||
look_for_perp()
|
||||
if(find_new_target())
|
||||
return
|
||||
bot_patrol()
|
||||
|
||||
|
||||
@@ -339,9 +343,9 @@
|
||||
|
||||
// look for a criminal in view of the bot
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/look_for_perp()
|
||||
/mob/living/simple_animal/bot/ed209/proc/find_new_target()
|
||||
if(disabled)
|
||||
return
|
||||
return FALSE
|
||||
anchored = FALSE
|
||||
threatlevel = 0
|
||||
for(var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
|
||||
@@ -353,20 +357,18 @@
|
||||
|
||||
threatlevel = C.assess_threat(src, lasercolor)
|
||||
|
||||
if(!threatlevel)
|
||||
if(!threatlevel || threatlevel < 4)
|
||||
continue
|
||||
|
||||
else if(threatlevel >= 4)
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
speak("Level [threatlevel] infraction alert!")
|
||||
playsound(loc, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, 0)
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_automated_action))
|
||||
break
|
||||
else
|
||||
continue
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
speak("Level [threatlevel] infraction alert!")
|
||||
playsound(loc, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, FALSE)
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_automated_action))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/check_for_weapons(obj/item/slot_item)
|
||||
if(slot_item && slot_item.needs_permit)
|
||||
@@ -541,10 +543,10 @@
|
||||
return
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
if(!C.IsStunned() || arrest_type && !baton_delayed)
|
||||
if(!C.IsStunned() || no_handcuffs && !baton_delayed)
|
||||
stun_attack(A)
|
||||
else if(C.canBeHandcuffed() && !C.handcuffed)
|
||||
start_cuffing(A)
|
||||
cuff(A)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -562,37 +564,33 @@
|
||||
shootAt(A)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/stun_attack(mob/living/carbon/C)
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
var/threat = C.assess_threat(src)
|
||||
var/prev_intent = a_intent
|
||||
a_intent = INTENT_HELP
|
||||
baton.attack(C, src)
|
||||
a_intent = prev_intent
|
||||
baton_delayed = TRUE
|
||||
addtimer(VARSET_CALLBACK(src, baton_delayed, FALSE), BATON_COOLDOWN)
|
||||
icon_state = "[lasercolor]ed209-c"
|
||||
addtimer(VARSET_CALLBACK(src, icon_state, "[lasercolor]ed209[on]"), 2)
|
||||
var/threat = C.assess_threat(src)
|
||||
C.SetStuttering(10 SECONDS)
|
||||
C.apply_damage(60, STAMINA)
|
||||
baton_delayed = TRUE
|
||||
C.apply_status_effect(STATUS_EFFECT_DELAYED, 2.5 SECONDS, CALLBACK(C, TYPE_PROC_REF(/mob/living/, KnockDown), 10 SECONDS), COMSIG_LIVING_CLEAR_STUNS)
|
||||
addtimer(VARSET_CALLBACK(src, baton_delayed, FALSE), BATON_COOLDOWN)
|
||||
add_attack_logs(src, C, "batoned")
|
||||
if(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 class='danger'>[src] has stunned [C]!</span>",\
|
||||
"<span class='userdanger'>[src] has stunned you!</span>")
|
||||
speak("[no_handcuffs ? "Detaining" : "Arresting"] level [threat] scumbag <b>[C]</b> in [location].", radio_channel)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/start_cuffing(mob/living/carbon/C)
|
||||
/mob/living/simple_animal/bot/ed209/proc/cuff(mob/living/carbon/C)
|
||||
mode = BOT_ARREST
|
||||
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
|
||||
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
|
||||
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
|
||||
|
||||
addtimer(CALLBACK(src, PROC_REF(cuff_target), C), 6 SECONDS)
|
||||
INVOKE_ASYNC(src, PROC_REF(cuff_callback), C)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/proc/cuff_target(mob/living/carbon/C)
|
||||
if(!Adjacent(C)|| !isturf(C.loc)) //if he's in a closet or not adjacent, we cancel cuffing.
|
||||
/mob/living/simple_animal/bot/ed209/proc/cuff_callback(mob/living/carbon/C)
|
||||
if(!do_after(src, 6 SECONDS, target = C))
|
||||
return
|
||||
|
||||
if(!C.handcuffed)
|
||||
if(!C.handcuffed && on)
|
||||
C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.update_handcuffed()
|
||||
back_to_idle()
|
||||
back_to_idle()
|
||||
|
||||
#undef BATON_COOLDOWN
|
||||
|
||||
@@ -110,7 +110,8 @@
|
||||
icon_state = "griefsky1"
|
||||
walk_to(src,0)
|
||||
set_path(null)
|
||||
look_for_perp() // see if any criminals are in range
|
||||
if(find_new_target())
|
||||
return // 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
|
||||
@@ -121,38 +122,38 @@
|
||||
set_path(null)
|
||||
back_to_idle()
|
||||
return
|
||||
if(target) // make sure target exists
|
||||
if(target.stat == !DEAD)
|
||||
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
|
||||
target_lastloc = target.loc
|
||||
sword_attack(target)
|
||||
anchored = TRUE
|
||||
frustration++
|
||||
return
|
||||
else // not next to perp
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
walk_to(src, target,1,3) //he's a fast fucker
|
||||
if((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
else
|
||||
back_to_idle()
|
||||
speak("You fool")
|
||||
else
|
||||
|
||||
if(!target) // make sure target exists
|
||||
back_to_idle()
|
||||
speak("You fool")
|
||||
return
|
||||
|
||||
if(target.stat == DEAD)
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
|
||||
target_lastloc = target.loc
|
||||
sword_attack(target)
|
||||
anchored = TRUE
|
||||
frustration++
|
||||
return // not next to perp
|
||||
|
||||
try_chasing_target(target)
|
||||
|
||||
if(BOT_START_PATROL)
|
||||
look_for_perp()
|
||||
if(find_new_target())
|
||||
return
|
||||
start_patrol()
|
||||
|
||||
if(BOT_PATROL)
|
||||
icon_state = "griefsky1"
|
||||
look_for_perp()
|
||||
if(find_new_target())
|
||||
return
|
||||
bot_patrol()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/griefsky/look_for_perp()
|
||||
/mob/living/simple_animal/bot/secbot/griefsky/find_new_target()
|
||||
anchored = FALSE
|
||||
for(var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
|
||||
if((C.stat) || (C.handcuffed))
|
||||
@@ -163,22 +164,20 @@
|
||||
|
||||
threatlevel = C.assess_threat(src)
|
||||
|
||||
if(!threatlevel)
|
||||
if(!threatlevel || threatlevel < 4)
|
||||
continue
|
||||
|
||||
else if(threatlevel >= 4)
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
speak("You are a bold one")
|
||||
playsound(src,'sound/weapons/saberon.ogg',50,TRUE,-1)
|
||||
visible_message("[src] ignites his energy swords!")
|
||||
icon_state = "griefsky-c"
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_automated_action))
|
||||
break
|
||||
else
|
||||
continue
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
speak("You are a bold one")
|
||||
playsound(src,'sound/weapons/saberon.ogg', 50, TRUE, -1)
|
||||
visible_message("[src] ignites his energy swords!")
|
||||
icon_state = "griefsky-c"
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_automated_action))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/griefsky/explode()
|
||||
walk_to(src,0)
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
|
||||
var/honksound = 'sound/items/bikehorn.ogg' //customizable sound
|
||||
var/spam_flag = FALSE
|
||||
var/cooldowntime = 30
|
||||
var/cooldowntimehorn = 10
|
||||
var/cooldowntime = 3 SECONDS
|
||||
var/cooldowntimehorn = 1 SECONDS
|
||||
var/mob/living/carbon/target
|
||||
var/oldtarget_name
|
||||
var/target_lastloc = FALSE //Loc of target when arrested.
|
||||
var/last_found = FALSE //There's a delay
|
||||
var/threatlevel = FALSE
|
||||
var/arrest_type = FALSE
|
||||
var/no_handcuffs = FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -37,9 +37,6 @@
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/proc/spam_flag_false() //used for addtimer
|
||||
spam_flag = FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/proc/sensor_blink()
|
||||
icon_state = "honkbot-c"
|
||||
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 5, TIMER_OVERRIDE|TIMER_UNIQUE)
|
||||
@@ -49,7 +46,7 @@
|
||||
playsound(src, 'sound/machines/ping.ogg', 50, TRUE, -1) //the first sound upon creation!
|
||||
spam_flag = TRUE
|
||||
sensor_blink()
|
||||
addtimer(CALLBACK(src, PROC_REF(spam_flag_false)), 18) // calibrates before starting the honk
|
||||
addtimer(VARSET_CALLBACK(src, spam_flag, FALSE), 1.8 SECONDS)
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/proc/react_buzz()
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE, -1)
|
||||
@@ -146,7 +143,7 @@
|
||||
if(!emagged)
|
||||
honk_attack(A)
|
||||
else
|
||||
if(!C.IsStunned() || arrest_type)
|
||||
if(!C.IsStunned() || no_handcuffs)
|
||||
stun_attack(A)
|
||||
..()
|
||||
else if(!spam_flag) //honking at the ground
|
||||
@@ -167,21 +164,21 @@
|
||||
playsound(src, honksound, 50, TRUE, -1)
|
||||
spam_flag = TRUE //prevent spam
|
||||
sensor_blink()
|
||||
addtimer(CALLBACK(src, PROC_REF(spam_flag_false)), cooldowntimehorn)
|
||||
else if(emagged) //emagged honkbots will spam short and memorable sounds.
|
||||
addtimer(VARSET_CALLBACK(src, spam_flag, FALSE), cooldowntimehorn)
|
||||
else //emagged honkbots will spam short and memorable sounds.
|
||||
if(!spam_flag)
|
||||
playsound(src, "honkbot_e", 50, 0)
|
||||
spam_flag = TRUE // prevent spam
|
||||
icon_state = "honkbot-e"
|
||||
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon)), 30, TIMER_OVERRIDE|TIMER_UNIQUE)
|
||||
addtimer(CALLBACK(src, PROC_REF(spam_flag_false)), cooldowntimehorn)
|
||||
addtimer(VARSET_CALLBACK(src, spam_flag, FALSE), cooldowntimehorn)
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/proc/honk_attack(mob/living/carbon/C) // horn attack
|
||||
if(!spam_flag)
|
||||
playsound(loc, honksound, 50, TRUE, -1)
|
||||
spam_flag = TRUE // prevent spam
|
||||
sensor_blink()
|
||||
addtimer(CALLBACK(src, PROC_REF(spam_flag_false)), cooldowntimehorn)
|
||||
addtimer(VARSET_CALLBACK(src, spam_flag, FALSE), cooldowntimehorn)
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/proc/stun_attack(mob/living/carbon/C) // airhorn stun
|
||||
if(!spam_flag)
|
||||
@@ -203,14 +200,14 @@
|
||||
target = oldtarget_name
|
||||
else // you really don't want to hit an emagged honkbot
|
||||
threatlevel = 6 // will never let you go
|
||||
addtimer(CALLBACK(src, PROC_REF(spam_flag_false)), cooldowntime)
|
||||
addtimer(VARSET_CALLBACK(src, spam_flag, FALSE), cooldowntimehorn)
|
||||
add_attack_logs(src, C, "honked by [src]")
|
||||
C.visible_message("<span class='danger'>[src] has honked [C]!</span>",\
|
||||
"<span class='userdanger'>[src] has honked you!</span>")
|
||||
else
|
||||
C.Stuttering(40 SECONDS)
|
||||
C.Stun(20 SECONDS)
|
||||
addtimer(CALLBACK(src, PROC_REF(spam_flag_false)), cooldowntime)
|
||||
addtimer(VARSET_CALLBACK(src, spam_flag, FALSE), cooldowntimehorn)
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/handle_automated_action()
|
||||
@@ -219,7 +216,8 @@
|
||||
switch(mode)
|
||||
if(BOT_IDLE) // idle
|
||||
walk_to(src, 0)
|
||||
look_for_perp()
|
||||
if(find_new_target())
|
||||
return
|
||||
if(!mode && auto_patrol)
|
||||
mode = BOT_START_PATROL
|
||||
if(BOT_HUNT)
|
||||
@@ -229,33 +227,31 @@
|
||||
playsound(loc, 'sound/misc/sadtrombone.ogg', 25, 1, -1)
|
||||
back_to_idle()
|
||||
return
|
||||
if(target) // make sure target exists
|
||||
if(Adjacent(target) && isturf(target.loc))
|
||||
if(threatlevel <= 4)
|
||||
honk_attack(target)
|
||||
else
|
||||
if(threatlevel >= 6)
|
||||
set waitfor = 0
|
||||
stun_attack(target)
|
||||
anchored = FALSE
|
||||
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(threatlevel <= 4)
|
||||
honk_attack(target)
|
||||
else
|
||||
if(threatlevel >= 6)
|
||||
stun_attack(target)
|
||||
anchored = FALSE
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
|
||||
try_chasing_target(target)
|
||||
|
||||
if(BOT_START_PATROL)
|
||||
look_for_perp()
|
||||
if(find_new_target())
|
||||
return
|
||||
start_patrol()
|
||||
|
||||
if(BOT_PATROL)
|
||||
look_for_perp()
|
||||
if(find_new_target())
|
||||
return
|
||||
bot_patrol()
|
||||
return
|
||||
|
||||
@@ -273,7 +269,7 @@
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_automated_action)) // responds quickly
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/proc/look_for_perp()
|
||||
/mob/living/simple_animal/bot/honkbot/proc/find_new_target()
|
||||
anchored = FALSE
|
||||
for(var/mob/living/carbon/C in view(7, src))
|
||||
if((C.stat) || (C.handcuffed))
|
||||
@@ -282,24 +278,26 @@
|
||||
if((C.name == oldtarget_name) && (world.time < last_found + 100))
|
||||
continue
|
||||
|
||||
if(threatlevel <= 3 && !emagged)
|
||||
if(C in view(4, src)) //keep the range short for patrolling
|
||||
if(!spam_flag)
|
||||
bike_horn()
|
||||
else if(threatlevel >= 4)
|
||||
if(!spam_flag || emagged)
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
if(threatlevel < 4)
|
||||
if(emagged) // actually emagged
|
||||
bike_horn()
|
||||
speak("Honk!")
|
||||
visible_message("<b>[src]</b> starts chasing [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_automated_action))
|
||||
break
|
||||
else
|
||||
continue
|
||||
else if(emagged)
|
||||
bike_horn() //just spam the shit outta this
|
||||
if(C in view(4, src) && !spam_flag) //keep the range short for patrolling
|
||||
bike_horn()
|
||||
continue
|
||||
|
||||
if(spam_flag && !emagged)
|
||||
continue
|
||||
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
bike_horn()
|
||||
speak("Honk!")
|
||||
visible_message("<b>[src]</b> starts chasing [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_automated_action))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/honkbot/explode() //doesn't drop cardboard nor its assembly, since its a very frail material.
|
||||
walk_to(src, 0)
|
||||
|
||||
@@ -32,12 +32,27 @@
|
||||
var/idcheck = FALSE //If true, arrest people with no IDs
|
||||
var/weapons_check = 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/no_handcuffs = FALSE //If true, don't handcuff
|
||||
var/harmbaton = FALSE //If true, beat instead of stun
|
||||
var/flashing_lights = FALSE //If true, flash lights
|
||||
var/baton_delayed = FALSE
|
||||
var/prev_flashing_lights = FALSE
|
||||
allow_pai = FALSE
|
||||
var/obj/item/melee/baton/infinite_cell/baton = null // stunbaton bot uses to melee attack
|
||||
var/currently_cuffing = FALSE // TRUE if we're cuffing someone right now
|
||||
var/played_sound_this_hunt = FALSE // used to make beepsky beep when it lost its target
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Initialize(mapload)
|
||||
. = ..()
|
||||
baton = new(src)
|
||||
icon_state = "[base_icon][on]"
|
||||
var/datum/job/detective/J = new/datum/job/detective
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Destroy()
|
||||
QDEL_NULL(baton)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky
|
||||
name = "Officer Beepsky"
|
||||
@@ -72,7 +87,7 @@
|
||||
base_icon = "rustbot"
|
||||
icon_state = "rustbot0"
|
||||
declare_arrests = FALSE
|
||||
arrest_type = TRUE
|
||||
no_handcuffs = TRUE
|
||||
harmbaton = TRUE
|
||||
emagged = TRUE
|
||||
|
||||
@@ -81,16 +96,9 @@
|
||||
health = 100
|
||||
maxHealth = 100
|
||||
idcheck = TRUE
|
||||
arrest_type = TRUE
|
||||
no_handcuffs = TRUE
|
||||
weapons_check = TRUE
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Initialize(mapload)
|
||||
. = ..()
|
||||
icon_state = "[base_icon][on]"
|
||||
|
||||
var/datum/job/detective/J = new/datum/job/detective
|
||||
access_card.access += J.get_access()
|
||||
prev_access = access_card.access
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/turn_on()
|
||||
..()
|
||||
@@ -102,6 +110,8 @@
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/bot_reset()
|
||||
..()
|
||||
currently_cuffing = FALSE
|
||||
played_sound_this_hunt = FALSE
|
||||
target = null
|
||||
oldtarget_name = null
|
||||
anchored = FALSE
|
||||
@@ -131,7 +141,7 @@
|
||||
data["check_id"] = idcheck
|
||||
data["check_weapons"] = weapons_check
|
||||
data["check_warrant"] = check_records
|
||||
data["arrest_mode"] = arrest_type // detain or arrest
|
||||
data["arrest_mode"] = no_handcuffs // detain or arrest
|
||||
data["arrest_declare"] = declare_arrests // announce arrests on radio
|
||||
return data
|
||||
|
||||
@@ -163,7 +173,7 @@
|
||||
if("authwarrant")
|
||||
check_records = !check_records
|
||||
if("arrtype")
|
||||
arrest_type = !arrest_type
|
||||
no_handcuffs = !no_handcuffs
|
||||
if("arrdeclare")
|
||||
declare_arrests = !declare_arrests
|
||||
if("ejectpai")
|
||||
@@ -214,7 +224,7 @@
|
||||
return
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
if((!C.IsWeakened() || arrest_type) && !baton_delayed)
|
||||
if((!C.IsWeakened() || no_handcuffs) && !baton_delayed)
|
||||
stun_attack(A)
|
||||
else if(C.canBeHandcuffed() && !C.handcuffed)
|
||||
cuff(A)
|
||||
@@ -239,34 +249,30 @@
|
||||
INVOKE_ASYNC(src, PROC_REF(cuff_callback), C)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/cuff_callback(mob/living/carbon/C)
|
||||
if(do_after(src, 60, target = C))
|
||||
if(!C.handcuffed && on)
|
||||
C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.update_handcuffed()
|
||||
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
|
||||
back_to_idle()
|
||||
currently_cuffing = TRUE
|
||||
if(!do_after(src, 6 SECONDS, target = C))
|
||||
currently_cuffing = FALSE
|
||||
return
|
||||
currently_cuffing = FALSE
|
||||
if(!C.handcuffed && on)
|
||||
C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
|
||||
C.update_handcuffed()
|
||||
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, FALSE)
|
||||
back_to_idle()
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C)
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
if(harmbaton)
|
||||
playsound(loc, 'sound/weapons/genhit1.ogg', 50, 1, -1)
|
||||
do_attack_animation(C)
|
||||
var/threat = C.assess_threat(src)
|
||||
var/prev_intent = a_intent
|
||||
a_intent = harmbaton ? INTENT_HARM : INTENT_HELP
|
||||
baton.attack(C, src)
|
||||
a_intent = prev_intent
|
||||
baton_delayed = TRUE
|
||||
addtimer(VARSET_CALLBACK(src, baton_delayed, FALSE), BATON_COOLDOWN)
|
||||
icon_state = "[base_icon]-c"
|
||||
addtimer(VARSET_CALLBACK(src, icon_state, "[base_icon][on]"), 2)
|
||||
var/threat = C.assess_threat(src)
|
||||
if(ishuman(C) && harmbaton) // Bots with harmbaton enabled become shitcurity. - Dave
|
||||
C.apply_damage(10, BRUTE)
|
||||
C.SetStuttering(10 SECONDS)
|
||||
C.apply_damage(60, STAMINA)
|
||||
baton_delayed = TRUE
|
||||
C.apply_status_effect(STATUS_EFFECT_DELAYED, 2.5 SECONDS, CALLBACK(C, TYPE_PROC_REF(/mob/living/, KnockDown), 10 SECONDS), COMSIG_LIVING_CLEAR_STUNS)
|
||||
addtimer(VARSET_CALLBACK(src, baton_delayed, FALSE), BATON_COOLDOWN)
|
||||
add_attack_logs(src, C, "batoned")
|
||||
if(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 class='danger'>[src] has [harmbaton ? "beaten" : "stunned"] [C]!</span>",\
|
||||
"<span class='userdanger'>[src] has [harmbaton ? "beaten" : "stunned"] you!</span>")
|
||||
speak("[no_handcuffs ? "Detaining" : "Arresting"] level [threat] scumbag <b>[C]</b> in [location].", radio_channel)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/Life(seconds, times_fired)
|
||||
. = ..()
|
||||
@@ -289,6 +295,15 @@
|
||||
|
||||
flashing_lights = !flashing_lights
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/try_chasing_target()
|
||||
. = ..()
|
||||
if(lost_target && !played_sound_this_hunt && frustration > 2)
|
||||
playsound(loc, 'sound/machines/synth_no.ogg', 50, FALSE)
|
||||
played_sound_this_hunt = TRUE
|
||||
if(!lost_target && played_sound_this_hunt)
|
||||
playsound(loc, 'sound/machines/synth_yes.ogg', 50, FALSE)
|
||||
played_sound_this_hunt = FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
@@ -297,84 +312,80 @@
|
||||
|
||||
switch(mode)
|
||||
if(BOT_IDLE) // idle
|
||||
walk_to(src,0)
|
||||
walk_to(src, 0)
|
||||
set_path(null)
|
||||
look_for_perp() // see if any criminals are in range
|
||||
if(find_new_target()) // see if any criminals are in range
|
||||
return
|
||||
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)
|
||||
playsound(loc, 'sound/machines/buzz-two.ogg', 25, FALSE)
|
||||
walk_to(src, 0)
|
||||
set_path(null)
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(target) // make sure target exists
|
||||
if(Adjacent(target) && isturf(target.loc) && !baton_delayed) // if right next to perp
|
||||
stun_attack(target)
|
||||
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = TRUE
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
|
||||
else // not next to perp
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
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) && !baton_delayed) // if right next to perp
|
||||
stun_attack(target)
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = TRUE
|
||||
target_lastloc = target.loc
|
||||
return
|
||||
|
||||
try_chasing_target(target)
|
||||
|
||||
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) || world.time - target.stam_regen_start_time < 4 SECONDS && target.getStaminaLoss() <= 100)
|
||||
back_to_hunt()
|
||||
return
|
||||
|
||||
if(iscarbon(target) && target.canBeHandcuffed())
|
||||
if(!arrest_type)
|
||||
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
|
||||
cuff(target)
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
else
|
||||
// target is stunned and nearby
|
||||
if(no_handcuffs) // should we not cuff?
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(BOT_ARREST)
|
||||
if(!target)
|
||||
anchored = FALSE
|
||||
mode = BOT_IDLE
|
||||
last_found = world.time
|
||||
frustration = 0
|
||||
if(!(iscarbon(target) && target.canBeHandcuffed()))
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(target.handcuffed) //no target or target cuffed? back to idle.
|
||||
if(currently_cuffing)
|
||||
return
|
||||
|
||||
if(!target.handcuffed)
|
||||
cuff(target)
|
||||
return
|
||||
|
||||
back_to_idle()
|
||||
|
||||
if(BOT_ARREST)
|
||||
if(!target || target.handcuffed)
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.AmountWeakened() < 4 SECONDS)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
|
||||
back_to_hunt()
|
||||
return
|
||||
else //Try arresting again if the target escapes.
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = FALSE
|
||||
//Try arresting again if the target escapes.
|
||||
mode = BOT_PREP_ARREST
|
||||
anchored = FALSE
|
||||
|
||||
if(BOT_START_PATROL)
|
||||
look_for_perp()
|
||||
if(find_new_target())
|
||||
return
|
||||
start_patrol()
|
||||
|
||||
if(BOT_PATROL)
|
||||
look_for_perp()
|
||||
if(find_new_target())
|
||||
return
|
||||
bot_patrol()
|
||||
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/back_to_idle()
|
||||
@@ -392,7 +403,7 @@
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_automated_action))
|
||||
// look for a criminal in view of the bot
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/look_for_perp()
|
||||
/mob/living/simple_animal/bot/secbot/proc/find_new_target()
|
||||
anchored = FALSE
|
||||
for(var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
|
||||
if((C.stat) || (C.handcuffed))
|
||||
@@ -403,20 +414,19 @@
|
||||
|
||||
threatlevel = C.assess_threat(src)
|
||||
|
||||
if(!threatlevel)
|
||||
if(!threatlevel || threatlevel < 4)
|
||||
continue
|
||||
|
||||
else if(threatlevel >= 4)
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
speak("Level [threatlevel] infraction alert!")
|
||||
playsound(loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0)
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_automated_action))
|
||||
break
|
||||
else
|
||||
continue
|
||||
target = C
|
||||
oldtarget_name = C.name
|
||||
speak("Level [threatlevel] infraction alert!")
|
||||
playsound(loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, FALSE)
|
||||
visible_message("<b>[src]</b> points at [C.name]!")
|
||||
mode = BOT_HUNT
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_automated_action))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/check_for_weapons(obj/item/slot_item)
|
||||
if(slot_item && slot_item.needs_permit)
|
||||
return 1
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
maxHealth = 300
|
||||
declare_arrests = FALSE
|
||||
idcheck = TRUE
|
||||
arrest_type = TRUE
|
||||
no_handcuffs = TRUE
|
||||
auto_patrol = TRUE
|
||||
emagged = TRUE
|
||||
faction = list("syndicate")
|
||||
@@ -72,6 +72,11 @@
|
||||
/mob/living/simple_animal/bot/ed209/syndicate/emag_act(mob/user)
|
||||
to_chat(user, "<span class='warning'>[src] has no card reader slot!</span>")
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/syndicate/try_chasing_target()
|
||||
. = ..()
|
||||
if(!lost_target)
|
||||
shootAt(target)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/syndicate/ed209_ai()
|
||||
var/turf/current_turf = get_turf(src)
|
||||
if(saved_turf && current_turf != saved_turf)
|
||||
@@ -86,39 +91,42 @@
|
||||
if(BOT_IDLE)
|
||||
walk_to(src,0)
|
||||
set_path(null)
|
||||
look_for_perp()
|
||||
if(find_new_target())
|
||||
return
|
||||
if(!mode && auto_patrol)
|
||||
mode = BOT_START_PATROL
|
||||
|
||||
if(BOT_HUNT)
|
||||
if(frustration >= 8)
|
||||
walk_to(src,0)
|
||||
set_path(null)
|
||||
back_to_idle()
|
||||
if(target)
|
||||
if(isliving(target))
|
||||
if(target.stat == DEAD)
|
||||
back_to_idle()
|
||||
return
|
||||
shootAt(target)
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
walk_to(src, target,1,4)
|
||||
if((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
else
|
||||
return
|
||||
|
||||
if(!target)
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(isliving(target) && target.stat == DEAD)
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
try_chasing_target(target)
|
||||
|
||||
if(BOT_START_PATROL)
|
||||
look_for_perp()
|
||||
if(find_new_target())
|
||||
return
|
||||
start_patrol()
|
||||
|
||||
if(BOT_PATROL)
|
||||
look_for_perp()
|
||||
if(find_new_target())
|
||||
return
|
||||
bot_patrol()
|
||||
else
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/syndicate/look_for_perp()
|
||||
/mob/living/simple_animal/bot/ed209/syndicate/find_new_target()
|
||||
if(disabled)
|
||||
return
|
||||
for(var/mob/M in view(7, src))
|
||||
@@ -133,9 +141,9 @@
|
||||
target = M
|
||||
oldtarget_name = M.name
|
||||
mode = BOT_HUNT
|
||||
spawn(0)
|
||||
handle_automated_action()
|
||||
break
|
||||
INVOKE_ASYNC(src, PROC_REF(handle_automated_action))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/syndicate/shootAt(atom/target)
|
||||
@@ -178,7 +186,7 @@
|
||||
return
|
||||
shootAt(A)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/syndicate/start_cuffing(mob/living/carbon/C)
|
||||
/mob/living/simple_animal/bot/ed209/syndicate/cuff(mob/living/carbon/C)
|
||||
shootAt(C)
|
||||
|
||||
/mob/living/simple_animal/bot/ed209/syndicate/stun_attack(mob/living/carbon/C)
|
||||
|
||||
Reference in New Issue
Block a user