From 5be6f5a1b2a523500c5f67996330e9bf8d84daef Mon Sep 17 00:00:00 2001 From: Mykhailo Bykhovtsev Date: Mon, 27 Aug 2018 12:21:31 -0700 Subject: [PATCH] Beepsky update (#5075) Beepsky uses walk_to() instead of step_to() Beepsky has variable of his speed that is used by walk_to() Beepsky now targets person who attacks them. Beepsky now reports if they are being attacked. Beepsky uses better and shorter patrol paths --- code/modules/mob/living/bot/secbot.dm | 179 +++++++++++++++++++++----- html/changelogs/Sindorman-beepsky.yml | 14 ++ 2 files changed, 160 insertions(+), 33 deletions(-) create mode 100644 html/changelogs/Sindorman-beepsky.yml diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index 088cb96f434..df75e165ab8 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -1,3 +1,11 @@ +#define SECBOT_IDLE 0 // idle +#define SECBOT_HUNT 1 // found target, hunting +#define SECBOT_ARREST 2 // arresting target +#define SECBOT_START_PATROL 3 // start patrol +#define SECBOT_WAIT_PATROL 4 // waiting for signals +#define SECBOT_PATROL 5 // patrolling +#define SECBOT_SUMMON 6 // summoned by PDA + /mob/living/bot/secbot name = "Securitron" desc = "A little security robot. He looks less than thrilled." @@ -17,13 +25,7 @@ var/auto_patrol = 0 // If true, patrols on its own var/mode = 0 -#define SECBOT_IDLE 0 // idle -#define SECBOT_HUNT 1 // found target, hunting -#define SECBOT_ARREST 2 // arresting target -#define SECBOT_START_PATROL 3 // start patrol -#define SECBOT_WAIT_PATROL 4 // waiting for signals -#define SECBOT_PATROL 5 // patrolling -#define SECBOT_SUMMON 6 // summoned by PDA + var/is_attacking = 0 var/is_ranged = 0 var/awaiting_surrender = 0 @@ -55,6 +57,7 @@ ) var/datum/callback/patrol_callback // this is here so we don't constantly recreate this datum, it being identical each time. + var/move_to_delay = 4 //delay for the automated movement. /mob/living/bot/secbot/beepsky name = "Officer Beepsky" @@ -70,9 +73,6 @@ SSradio.add_object(listener, control_freq, filter = RADIO_SECBOT) SSradio.add_object(listener, beacon_freq, filter = RADIO_NAVBEACONS) - if (!patrol_callback) - patrol_callback = CALLBACK(src, .proc/patrol_step) - /mob/living/bot/secbot/Destroy() QDEL_NULL(listener) target = null @@ -202,11 +202,7 @@ if(is_ranged) RangedAttack(target) else - step_towards(src, target) // Melee bots chase a bit faster - - var/cb = CALLBACK(src, .proc/step_nonadjacent, target) - addtimer(cb, 8) - addtimer(cb, 16) + walk_to(src, target, 1, move_to_delay) // Melee bots chase a bit faster if(SECBOT_ARREST) // Target is next to us - attack it if(!target) @@ -216,6 +212,7 @@ mode = SECBOT_HUNT return var/threat = check_threat(target) + walk_to(src, src, 0, move_to_delay) if(threat < 4) target = null awaiting_surrender = 0 @@ -265,19 +262,12 @@ if(SECBOT_PATROL) patrol_step() - addtimer(patrol_callback, 10) return if(SECBOT_SUMMON) patrol_step() - addtimer(patrol_callback, 8) - addtimer(patrol_callback, 16) return -/mob/living/bot/secbot/proc/step_nonadjacent(target) - if (!Adjacent(target)) - step_towards(src, target) - /mob/living/bot/secbot/UnarmedAttack(var/mob/M, var/proximity) if(!..()) return @@ -311,7 +301,7 @@ C.update_inv_handcuffed() if(preparing_arrest_sounds.len) playsound(loc, pick(preparing_arrest_sounds), 50, 0) - else if(istype(M, /mob/living/simple_animal) && !istype(M, /mob/living/simple_animal/hostile/commanded)) + else if(istype(M, /mob/living/simple_animal) && !istype(M, /mob/living/bot/secbot)) var/mob/living/simple_animal/S = M S.adjustBruteLoss(15) do_attack_animation(M) @@ -369,8 +359,29 @@ /mob/living/bot/secbot/proc/calc_path(var/turf/avoid = null) path = AStar(loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=avoid) - if(!path) - path = list() + if(!path.len) + return + var/list/path_new = list() + var/turf/last = path[path.len] + path_new.Add(path[1]) + for(var/i = 2, i < path.len, i++) + if((path[i + 1].x == path[i].x) || (path[i + 1].y == path[i].y)) // we have a straight line, scan for more to cut down + path_new.Add(path[i]) + for(var/j = i + 1, j < path.len, j++) + if((path[j + 1].x != path[j - 1].x) && (path[j + 1].y != path[j - 1].y)) // This is a corner and end point of our line + path_new.Add(path[j]) + i = j + 1 + break + else if(j == path.len - 1) + path = list() + path = path_new.Copy() + path.Add(last) + return + else + path_new.Add(path[i]) + path = list() + path = path_new.Copy() + path.Add(last) /mob/living/bot/secbot/proc/check_threat(var/mob/living/M) if(!M || !istype(M) || M.stat || src == M) @@ -386,25 +397,21 @@ patrol_target = null path = list() mode = SECBOT_IDLE + walk_to(src, src, 0, move_to_delay + 2) return if(path.len && patrol_target) var/turf/next = path[1] if(loc == next) path -= next + walk_to(src, src, 0, move_to_delay + 2) return - var/moved = step_towards(src, next) - if(moved) - path -= next - frustration = 0 - else - ++frustration - if(frustration > 5) // Make a new path - mode = SECBOT_START_PATROL + walk_to(src, next, 0, move_to_delay + 2) return else mode = SECBOT_START_PATROL + /mob/living/bot/secbot/proc/find_patrol_target() send_status() nearest_beacon = null @@ -510,6 +517,112 @@ secbot.next_destination = signal.data["next_patrol"] secbot.closest_dist = dist +/mob/living/bot/secbot/attack_hand(mob/living/carbon/human/M as mob) + ..() + + if(M.a_intent == I_HURT ) //assume he wants to hurt us. + idcheck = TRUE + target = M + mode = SECBOT_HUNT + var/mob/living/carbon/human/H = M + var/perpname = H.name + var/obj/item/weapon/card/id/id = H.GetIdCard() + if(id) + perpname = id.registered_name + + var/datum/data/record/R = find_security_record("name", perpname) + if(R) + R.fields["criminal"] = "*Arrest*" + else + check_records = TRUE + broadcast_security_hud_message("[src] is under attack by [target], [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect in [get_area(src)]. Requesting backup", src) + +/mob/living/bot/secbot/attack_generic(var/mob/user, var/damage, var/attack_message) + ..() + + target = user + mode = SECBOT_HUNT + if(ishuman(user)) + idcheck = TRUE + var/mob/living/carbon/human/H = user + var/perpname = H.name + var/obj/item/weapon/card/id/id = H.GetIdCard() + if(id) + perpname = id.registered_name + + var/datum/data/record/R = find_security_record("name", perpname) + if(R) + R.fields["criminal"] = "*Arrest*" + else + check_records = TRUE + broadcast_security_hud_message("[src] is under attack by [target], [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect in [get_area(src)]. Requesting backup", src) + +/mob/living/bot/secbot/bullet_act(var/obj/item/projectile/P, var/def_zone) + ..() + + if (ismob(P.firer)) + target = P.firer + mode = SECBOT_HUNT + if(ishuman(P.firer)) + idcheck = TRUE + var/mob/living/carbon/human/H = P.firer + var/perpname = H.name + var/obj/item/weapon/card/id/id = H.GetIdCard() + if(id) + perpname = id.registered_name + + var/datum/data/record/R = find_security_record("name", perpname) + if(R) + R.fields["criminal"] = "*Arrest*" + else + check_records = TRUE + broadcast_security_hud_message("[src] was shot with [P], projectile came from [target], [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect in [get_area(src)]. Requesting backup", src) + +/mob/living/bot/secbot/attackby(var/obj/item/O, var/mob/user) + ..() + if(istype(O, /obj/item/weapon/card/id)) + return + + target = user + mode = SECBOT_HUNT + if(ishuman(user)) + idcheck = TRUE + var/mob/living/carbon/human/H = user + var/perpname = H.name + var/obj/item/weapon/card/id/id = H.GetIdCard() + if(id) + perpname = id.registered_name + + var/datum/data/record/R = find_security_record("name", perpname) + if(R) + R.fields["criminal"] = "*Arrest*" + else + check_records = TRUE + broadcast_security_hud_message("[src] is under attack by [target] with [O], [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect in [get_area(src)]. Requesting backup", src) + +/mob/living/bot/secbot/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR) + ..() + + if(istype(AM,/obj/)) + var/obj/O = AM + if(ismob(O.thrower)) + target = O.thrower + mode = SECBOT_HUNT + if(ishuman(O.thrower)) + idcheck = TRUE + var/mob/living/carbon/human/H = O.thrower + var/perpname = H.name + var/obj/item/weapon/card/id/id = H.GetIdCard() + if(id) + perpname = id.registered_name + + var/datum/data/record/R = find_security_record("name", perpname) + if(R) + R.fields["criminal"] = "*Arrest*" + else + check_records = TRUE + broadcast_security_hud_message("[src] is under attack by [target] with [O], [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect in [get_area(src)]. Requesting backup", src) + //Secbot Construction /obj/item/clothing/head/helmet/attackby(var/obj/item/device/assembly/signaler/S, mob/user as mob) diff --git a/html/changelogs/Sindorman-beepsky.yml b/html/changelogs/Sindorman-beepsky.yml new file mode 100644 index 00000000000..d0ca3c2ad70 --- /dev/null +++ b/html/changelogs/Sindorman-beepsky.yml @@ -0,0 +1,14 @@ +author: PoZe + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - tweak: "Beepsky/ED209 now uses different method of movement. Making it waay faster at moving" + - rscadd: "Beepsky/ED209 now arrests/detains person who attacks them. Reporting arrest/detaintion, who attacked them, what weapon was used and location" + - tweak: "Beepsky/ED209 uses better paths between beacons, so it moves faster. But it still moved between mostly two beacons, I will change it next dev cycle"