Adds in a new type of securitron (#39382)

* foolish jedi

* do not underestimate general beepsky

* adds death handling so you don't lose his eswords :)

* changes .loc to Tsec

* oversight

* src, TRUE, src, FALSE

* src

* Adds a toy sword variant. Fixes formatting

* oops

* fixes stuff for beepsky

* makes grievous beepsky block all projectiles.

* Fixes & cleanup

* cyberboss pt.1

* cyberboss pt2.
This commit is contained in:
Kmc2000
2018-08-03 17:07:12 +01:00
committed by Joe Schmoe
parent 24432c7222
commit 3fbfc4fbff
7 changed files with 248 additions and 34 deletions

View File

@@ -0,0 +1,150 @@
/mob/living/simple_animal/bot/secbot/grievous //This bot is powerful. If you managed to get 4 eswords somehow, you deserve this horror. Emag him for best results.
name = "General Beepsky"
desc = "Is that a secbot with four eswords in its arms...?"
icon = 'icons/mob/aibots.dmi'
icon_state = "grievous"
health = 150
maxHealth = 150
baton_type = /obj/item/melee/transforming/energy/sword
base_speed = 4 //he's a fast fucker
var/obj/item/weapon
var/block_chance = 50
/mob/living/simple_animal/bot/secbot/grievous/toy //A toy version of general beepsky!
name = "Genewul Bweepskee"
desc = "An adorable looking secbot with four toy swords taped to its arms"
health = 50
maxHealth = 50
baton_type = /obj/item/toy/sword
/mob/living/simple_animal/bot/secbot/grievous/bullet_act(obj/item/projectile/P)
visible_message("[src] deflects [P] with its energy swords!")
playsound(src, 'sound/weapons/blade1.ogg', 50, TRUE)
return FALSE
/mob/living/simple_animal/bot/secbot/grievous/Crossed(atom/movable/AM)
..()
if(ismob(AM) && AM == target)
visible_message("[src] flails his swords and cuts [AM]!")
playsound(src,'sound/effects/beepskyspinsabre.ogg',100,TRUE,-1)
stun_attack(AM)
/mob/living/simple_animal/bot/secbot/grievous/Initialize()
. = ..()
weapon = new baton_type(src)
weapon.attack_self(src)
/mob/living/simple_animal/bot/secbot/grievous/Destroy()
QDEL_NULL(weapon)
return ..()
/mob/living/simple_animal/bot/secbot/grievous/special_retaliate_after_attack(mob/user)
if(mode != BOT_HUNT)
return
if(prob(block_chance))
visible_message("[src] deflects [user]'s attack with his energy swords!")
playsound(src, 'sound/weapons/blade1.ogg', 50, TRUE, -1)
return TRUE
/mob/living/simple_animal/bot/secbot/grievous/stun_attack(mob/living/carbon/C) //Criminals don't deserve to live
weapon.attack(C, src)
playsound(src, 'sound/weapons/blade1.ogg', 50, TRUE, -1)
if(C.stat == DEAD)
addtimer(CALLBACK(src, .proc/update_icon), 2)
back_to_idle()
/mob/living/simple_animal/bot/secbot/grievous/handle_automated_action()
if(!on)
return
switch(mode)
if(BOT_IDLE) // idle
update_icon()
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
update_icon()
playsound(src,'sound/effects/beepskyspinsabre.ogg',100,TRUE,-1)
// general beepsky doesn't give up so easily, jedi scum
if(frustration >= 20)
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
target_lastloc = target.loc //stun_attack() can clear the target if they're dead, so this needs to be set first
stun_attack(target)
anchored = TRUE
return
else // not next to perp
var/turf/olddist = get_dist(src, target)
walk_to(src, target,1,4)
if((get_dist(src, target)) >= (olddist))
frustration++
else
frustration = 0
else
back_to_idle()
if(BOT_START_PATROL)
look_for_perp()
start_patrol()
if(BOT_PATROL)
look_for_perp()
bot_patrol()
/mob/living/simple_animal/bot/secbot/grievous/look_for_perp()
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))
continue
if((C.name == oldtarget_name) && (world.time < last_found + 100))
continue
threatlevel = C.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons))
if(!threatlevel)
continue
else if(threatlevel >= 4)
target = C
oldtarget_name = C.name
speak("Level [threatlevel] infraction alert!")
playsound(src, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, FALSE)
playsound(src,'sound/weapons/saberon.ogg',50,TRUE,-1)
visible_message("[src] ignites his energy swords!")
icon_state = "grievous-c"
visible_message("<b>[src]</b> points at [C.name]!")
mode = BOT_HUNT
INVOKE_ASYNC(src, .proc/handle_automated_action)
break
else
continue
/mob/living/simple_animal/bot/secbot/grievous/explode()
walk_to(src,0)
visible_message("<span class='boldannounce'>[src] lets out a huge cough as it blows apart!</span>")
var/atom/Tsec = drop_location()
var/obj/item/bot_assembly/secbot/Sa = new (Tsec)
Sa.build_step = 1
Sa.add_overlay("hs_hole")
Sa.created_name = name
new /obj/item/assembly/prox_sensor(Tsec)
if(prob(50))
drop_part(robot_arm, Tsec)
do_sparks(3, TRUE, src)
for(var/IS = 0 to 4)
drop_part(baton_type, Tsec)
new /obj/effect/decal/cleanable/oil(Tsec)
qdel(src)

View File

@@ -379,6 +379,8 @@
icon_state = "helmet_signaler" icon_state = "helmet_signaler"
item_state = "helmet" item_state = "helmet"
created_name = "Securitron" //To preserve the name if it's a unique securitron I guess created_name = "Securitron" //To preserve the name if it's a unique securitron I guess
var/swordamt = 0 //If you're converting it into a grievousbot, how many swords have you attached
var/toyswordamt = 0 //honk
/obj/item/bot_assembly/secbot/attackby(obj/item/I, mob/user, params) /obj/item/bot_assembly/secbot/attackby(obj/item/I, mob/user, params)
..() ..()
@@ -441,6 +443,29 @@
S.robot_arm = robot_arm S.robot_arm = robot_arm
qdel(I) qdel(I)
qdel(src) qdel(src)
if(istype(I, /obj/item/wrench))
to_chat(user, "You adjust [src]'s arm slots to mount extra weapons")
build_step ++
return
if(istype(I, /obj/item/toy/sword))
if(toyswordamt < 3 && swordamt <= 0)
if(!user.temporarilyRemoveItemFromInventory(I))
return
created_name = "General Beepsky"
name = "helmet/signaler/prox sensor/robot arm/toy sword assembly"
icon_state = "grievous_assembly"
to_chat(user, "<span class='notice'>You superglue [I] onto one of [src]'s arm slots.</span>")
qdel(I)
toyswordamt ++
else
if(!can_finish_build(I, user))
return
to_chat(user, "<span class='notice'>You complete the Securitron!...Something seems a bit wrong with it..?</span>")
var/mob/living/simple_animal/bot/secbot/grievous/toy/S = new(Tsec)
S.name = created_name
S.robot_arm = robot_arm
qdel(I)
qdel(src)
else if(istype(I, /obj/item/screwdriver)) //deconstruct else if(istype(I, /obj/item/screwdriver)) //deconstruct
cut_overlay("hs_arm") cut_overlay("hs_arm")
@@ -448,3 +473,35 @@
robot_arm = null robot_arm = null
to_chat(user, "<span class='notice'>You remove [dropped_arm] from [src].</span>") to_chat(user, "<span class='notice'>You remove [dropped_arm] from [src].</span>")
build_step-- build_step--
if(toyswordamt > 0 || toyswordamt)
icon_state = initial(icon_state)
to_chat(user, "<span class='notice'>The superglue binding [src]'s toy swords to its chassis snaps!</span>")
for(var/IS in 1 to toyswordamt)
new /obj/item/toy/sword(Tsec)
if(ASSEMBLY_FIFTH_STEP)
if(istype(I, /obj/item/melee/transforming/energy/sword/saber))
if(swordamt < 3)
if(!user.temporarilyRemoveItemFromInventory(I))
return
created_name = "General Beepsky"
name = "helmet/signaler/prox sensor/robot arm/energy sword assembly"
icon_state = "grievous_assembly"
to_chat(user, "<span class='notice'>You bolt [I] onto one of [src]'s arm slots.</span>")
qdel(I)
swordamt ++
else
if(!can_finish_build(I, user))
return
to_chat(user, "<span class='notice'>You complete the Securitron!...Something seems a bit wrong with it..?</span>")
var/mob/living/simple_animal/bot/secbot/grievous/S = new(Tsec)
S.name = created_name
S.robot_arm = robot_arm
qdel(I)
qdel(src)
else if(istype(I, /obj/item/screwdriver)) //deconstruct
build_step--
icon_state = initial(icon_state)
to_chat(user, "<span class='notice'>You unbolt [src]'s energy swords</span>")
for(var/IS in 1 to swordamt)
new /obj/item/melee/transforming/energy/sword/saber(Tsec)

View File

@@ -26,7 +26,7 @@
var/lastfired = 0 var/lastfired = 0
var/shot_delay = 15 var/shot_delay = 15
var/lasercolor = "" var/lasercolor = ""
var/disabled = 0//A holder for if it needs to be disabled, if true it will not seach for targets, shoot at targets, or move, currently only used for lasertag var/disabled = FALSE //A holder for if it needs to be disabled, if true it will not seach for targets, shoot at targets, or move, currently only used for lasertag
var/mob/living/carbon/target var/mob/living/carbon/target
@@ -34,11 +34,11 @@
var/threatlevel = 0 var/threatlevel = 0
var/target_lastloc //Loc of target when arrested. var/target_lastloc //Loc of target when arrested.
var/last_found //There's a delay var/last_found //There's a delay
var/declare_arrests = 1 //When making an arrest, should it notify everyone wearing sechuds? var/declare_arrests = TRUE //When making an arrest, should it notify everyone wearing sechuds?
var/idcheck = 1 //If true, arrest people with no IDs var/idcheck = TRUE //If true, arrest people with no IDs
var/weaponscheck = 1 //If true, arrest people for weapons if they don't have access var/weaponscheck = TRUE //If true, arrest people for weapons if they don't have access
var/check_records = 1 //Does it check security records? var/check_records = TRUE //Does it check security records?
var/arrest_type = 0 //If true, don't handcuff var/arrest_type = FALSE //If true, don't handcuff
var/projectile = /obj/item/projectile/energy/electrode //Holder for projectile type var/projectile = /obj/item/projectile/energy/electrode //Holder for projectile type
var/shoot_sound = 'sound/weapons/taser.ogg' var/shoot_sound = 'sound/weapons/taser.ogg'
var/cell_type = /obj/item/stock_parts/cell var/cell_type = /obj/item/stock_parts/cell
@@ -199,7 +199,7 @@ Auto Patrol[]"},
to_chat(user, "<span class='warning'>You short out [src]'s target assessment circuits.</span>") to_chat(user, "<span class='warning'>You short out [src]'s target assessment circuits.</span>")
oldtarget_name = user.name oldtarget_name = user.name
audible_message("<span class='danger'>[src] buzzes oddly!</span>") audible_message("<span class='danger'>[src] buzzes oddly!</span>")
declare_arrests = 0 declare_arrests = FALSE
icon_state = "[lasercolor]ed209[on]" icon_state = "[lasercolor]ed209[on]"
set_weapon() set_weapon()
@@ -357,7 +357,7 @@ Auto Patrol[]"},
target = C target = C
oldtarget_name = C.name oldtarget_name = C.name
speak("Level [threatlevel] infraction alert!") speak("Level [threatlevel] infraction alert!")
playsound(loc, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, 0) playsound(src, pick('sound/voice/ed209_20sec.ogg', 'sound/voice/edplaceholder.ogg'), 50, FALSE)
visible_message("<b>[src]</b> points at [C.name]!") visible_message("<b>[src]</b> points at [C.name]!")
mode = BOT_HUNT mode = BOT_HUNT
spawn(0) spawn(0)
@@ -447,7 +447,7 @@ Auto Patrol[]"},
return return
var/obj/item/projectile/A = new projectile (loc) var/obj/item/projectile/A = new projectile (loc)
playsound(loc, shoot_sound, 50, 1) playsound(src, shoot_sound, 50, TRUE)
A.preparePixelProjectile(target, src) A.preparePixelProjectile(target, src)
A.fire() A.fire()
@@ -538,7 +538,7 @@ Auto Patrol[]"},
shootAt(A) shootAt(A)
/mob/living/simple_animal/bot/ed209/proc/stun_attack(mob/living/carbon/C) /mob/living/simple_animal/bot/ed209/proc/stun_attack(mob/living/carbon/C)
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
icon_state = "[lasercolor]ed209-c" icon_state = "[lasercolor]ed209-c"
spawn(2) spawn(2)
icon_state = "[lasercolor]ed209[on]" icon_state = "[lasercolor]ed209[on]"
@@ -558,7 +558,7 @@ Auto Patrol[]"},
/mob/living/simple_animal/bot/ed209/proc/cuff(mob/living/carbon/C) /mob/living/simple_animal/bot/ed209/proc/cuff(mob/living/carbon/C)
mode = BOT_ARREST mode = BOT_ARREST
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2)
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\ 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>") "<span class='userdanger'>[src] is trying to put zipties on you!</span>")

View File

@@ -2,7 +2,7 @@
name = "\improper Securitron" name = "\improper Securitron"
desc = "A little security robot. He looks less than thrilled." desc = "A little security robot. He looks less than thrilled."
icon = 'icons/mob/aibots.dmi' icon = 'icons/mob/aibots.dmi'
icon_state = "secbot0" icon_state = "secbot"
density = FALSE density = FALSE
anchored = FALSE anchored = FALSE
health = 25 health = 25
@@ -24,21 +24,21 @@
var/baton_type = /obj/item/melee/baton var/baton_type = /obj/item/melee/baton
var/mob/living/carbon/target var/mob/living/carbon/target
var/oldtarget_name var/oldtarget_name
var/threatlevel = 0 var/threatlevel = FALSE
var/target_lastloc //Loc of target when arrested. var/target_lastloc //Loc of target when arrested.
var/last_found //There's a delay var/last_found //There's a delay
var/declare_arrests = 1 //When making an arrest, should it notify everyone on the security channel? var/declare_arrests = TRUE //When making an arrest, should it notify everyone on the security channel?
var/idcheck = 0 //If true, arrest people with no IDs var/idcheck = FALSE //If true, arrest people with no IDs
var/weaponscheck = 0 //If true, arrest people for weapons if they lack access var/weaponscheck = FALSE //If true, arrest people for weapons if they lack access
var/check_records = 1 //Does it check security records? var/check_records = TRUE //Does it check security records?
var/arrest_type = 0 //If true, don't handcuff var/arrest_type = FALSE //If true, don't handcuff
/mob/living/simple_animal/bot/secbot/beepsky /mob/living/simple_animal/bot/secbot/beepsky
name = "Officer Beep O'sky" name = "Officer Beep O'sky"
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey." desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
idcheck = 0 idcheck = FALSE
weaponscheck = 0 weaponscheck = FALSE
auto_patrol = 1 auto_patrol = TRUE
/mob/living/simple_animal/bot/secbot/beepsky/jr /mob/living/simple_animal/bot/secbot/beepsky/jr
name = "Officer Pipsqueak" name = "Officer Pipsqueak"
@@ -65,7 +65,7 @@
/mob/living/simple_animal/bot/secbot/Initialize() /mob/living/simple_animal/bot/secbot/Initialize()
. = ..() . = ..()
icon_state = "secbot[on]" update_icon()
var/datum/job/detective/J = new/datum/job/detective var/datum/job/detective/J = new/datum/job/detective
access_card.access += J.get_access() access_card.access += J.get_access()
prev_access = access_card.access prev_access = access_card.access
@@ -74,13 +74,15 @@
var/datum/atom_hud/secsensor = GLOB.huds[DATA_HUD_SECURITY_ADVANCED] var/datum/atom_hud/secsensor = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
secsensor.add_hud_to(src) secsensor.add_hud_to(src)
/mob/living/simple_animal/bot/secbot/turn_on() /mob/living/simple_animal/bot/secbot/update_icon()
if(mode == BOT_HUNT)
icon_state = "[initial(icon_state)]-c"
return
..() ..()
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/turn_off() /mob/living/simple_animal/bot/secbot/turn_off()
..() ..()
icon_state = "secbot[on]" mode = BOT_IDLE
/mob/living/simple_animal/bot/secbot/bot_reset() /mob/living/simple_animal/bot/secbot/bot_reset()
..() ..()
@@ -167,9 +169,14 @@ Auto Patrol: []"},
final = final|JUDGE_EMAGGED final = final|JUDGE_EMAGGED
return final return final
/mob/living/simple_animal/bot/secbot/proc/special_retaliate_after_attack(mob/user) //allows special actions to take place after being attacked.
return
/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H) /mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H)
if((H.a_intent == INTENT_HARM) || (H.a_intent == INTENT_DISARM)) if((H.a_intent == INTENT_HARM) || (H.a_intent == INTENT_DISARM))
retaliate(H) retaliate(H)
if(special_retaliate_after_attack(H))
return
return ..() return ..()
@@ -179,6 +186,8 @@ Auto Patrol: []"},
return return
if(!istype(W, /obj/item/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass. if(!istype(W, /obj/item/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
retaliate(user) retaliate(user)
if(special_retaliate_after_attack(user))
return
/mob/living/simple_animal/bot/secbot/emag_act(mob/user) /mob/living/simple_animal/bot/secbot/emag_act(mob/user)
..() ..()
@@ -187,8 +196,8 @@ Auto Patrol: []"},
to_chat(user, "<span class='danger'>You short out [src]'s target assessment circuits.</span>") to_chat(user, "<span class='danger'>You short out [src]'s target assessment circuits.</span>")
oldtarget_name = user.name oldtarget_name = user.name
audible_message("<span class='danger'>[src] buzzes oddly!</span>") audible_message("<span class='danger'>[src] buzzes oddly!</span>")
declare_arrests = 0 declare_arrests = FALSE
icon_state = "secbot[on]" update_icon()
/mob/living/simple_animal/bot/secbot/bullet_act(obj/item/projectile/Proj) /mob/living/simple_animal/bot/secbot/bullet_act(obj/item/projectile/Proj)
if(istype(Proj , /obj/item/projectile/beam)||istype(Proj, /obj/item/projectile/bullet)) if(istype(Proj , /obj/item/projectile/beam)||istype(Proj, /obj/item/projectile/bullet))
@@ -222,7 +231,7 @@ Auto Patrol: []"},
/mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C) /mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C)
mode = BOT_ARREST mode = BOT_ARREST
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2) playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2)
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\ 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>") "<span class='userdanger'>[src] is trying to put zipties on you!</span>")
addtimer(CALLBACK(src, .proc/attempt_handcuff, C), 60) addtimer(CALLBACK(src, .proc/attempt_handcuff, C), 60)
@@ -236,14 +245,11 @@ Auto Patrol: []"},
playsound(src, "law", 50, 0) playsound(src, "law", 50, 0)
back_to_idle() back_to_idle()
/mob/living/simple_animal/bot/secbot/proc/update_onsprite()
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C) /mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C)
var/judgement_criteria = judgement_criteria() var/judgement_criteria = judgement_criteria()
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
icon_state = "secbot-c" icon_state = "secbot-c"
addtimer(CALLBACK(src, .proc/update_onsprite), 2) addtimer(CALLBACK(src, .proc/update_icon), 2)
var/threat = 5 var/threat = 5
if(ishuman(C)) if(ishuman(C))
C.stuttering = 5 C.stuttering = 5
@@ -384,7 +390,7 @@ Auto Patrol: []"},
target = C target = C
oldtarget_name = C.name oldtarget_name = C.name
speak("Level [threatlevel] infraction alert!") speak("Level [threatlevel] infraction alert!")
playsound(loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0) playsound(src, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, FALSE)
visible_message("<b>[src]</b> points at [C.name]!") visible_message("<b>[src]</b> points at [C.name]!")
mode = BOT_HUNT mode = BOT_HUNT
INVOKE_ASYNC(src, .proc/handle_automated_action) INVOKE_ASYNC(src, .proc/handle_automated_action)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

View File

@@ -1983,6 +1983,7 @@
#include "code\modules\mob\living\simple_animal\bot\medbot.dm" #include "code\modules\mob\living\simple_animal\bot\medbot.dm"
#include "code\modules\mob\living\simple_animal\bot\mulebot.dm" #include "code\modules\mob\living\simple_animal\bot\mulebot.dm"
#include "code\modules\mob\living\simple_animal\bot\secbot.dm" #include "code\modules\mob\living\simple_animal\bot\secbot.dm"
#include "code\modules\mob\living\simple_animal\bot\SuperBeepsky.dm"
#include "code\modules\mob\living\simple_animal\friendly\butterfly.dm" #include "code\modules\mob\living\simple_animal\friendly\butterfly.dm"
#include "code\modules\mob\living\simple_animal\friendly\cat.dm" #include "code\modules\mob\living\simple_animal\friendly\cat.dm"
#include "code\modules\mob\living\simple_animal\friendly\cockroach.dm" #include "code\modules\mob\living\simple_animal\friendly\cockroach.dm"