diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm
index d22b50c2168..5116abf32e6 100644
--- a/code/modules/crafting/recipes.dm
+++ b/code/modules/crafting/recipes.dm
@@ -81,6 +81,19 @@
time = 60
category = CAT_ROBOT
+/datum/crafting_recipe/griefsky
+ name = "General Griefsky"
+ result = /mob/living/simple_animal/bot/secbot/griefsky
+ reqs = list(/obj/item/assembly/signaler = 1,
+ /obj/item/clothing/head/helmet = 1,
+ /obj/item/melee/energy/sword = 4,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/robot_parts/r_arm = 2,
+ /obj/item/robot_parts/l_arm = 2)
+ tools = list(/obj/item/weldingtool)
+ time = 120
+ category = CAT_ROBOT
+
/datum/crafting_recipe/cleanbot
name = "Cleanbot"
result = /mob/living/simple_animal/bot/cleanbot
diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm
index 9c11a3d872c..1de103cbf8b 100644
--- a/code/modules/mob/living/simple_animal/bot/construction.dm
+++ b/code/modules/mob/living/simple_animal/bot/construction.dm
@@ -389,8 +389,8 @@
icon = 'icons/obj/aibots.dmi'
icon_state = "helmet_signaler"
item_state = "helmet"
+ var/created_name = "Griefsky" //To preserve the name if it's a unique securitron I guess
var/build_step = 0
- var/created_name = "Securitron" //To preserve the name if it's a unique securitron I guess
/obj/item/clothing/head/helmet/attackby(obj/item/assembly/signaler/S, mob/user, params)
..()
@@ -481,6 +481,68 @@
to_chat(user, "You remove the robot arm from [src].")
build_step--
+//General Griefsky
+
+ else if((istype(I, /obj/item/wrench)) && (build_step == 3))
+ var/obj/item/griefsky_assembly/A = new /obj/item/griefsky_assembly
+ user.put_in_hands(A)
+ to_chat(user, "You adjust the arm slots for extra weapons!.")
+ user.unEquip(src, 1)
+ qdel(src)
+
+/obj/item/griefsky_assembly
+ name = "\improper Griefsky assembly"
+ desc = "Some sort of bizarre assembly."
+ icon = 'icons/obj/aibots.dmi'
+ icon_state = "griefsky_assembly"
+ item_state = "griefsky_assembly"
+ var/build_step = 0
+ var/toy_step = 0
+
+/obj/item/griefsky_assembly/attackby(obj/item/I, mob/user, params)
+ ..()
+ if((istype(I, /obj/item/melee/energy/sword)) && (build_step < 3 ))
+ if(!user.unEquip(I))
+ return
+ build_step++
+ to_chat(user, "You add an energy sword to [src]!.")
+ qdel(I)
+
+ else if((istype(I, /obj/item/melee/energy/sword)) && (build_step == 3))
+ if(!user.unEquip(I))
+ return
+ to_chat(user, "You complete General Griefsky!.")
+ var/mob/living/simple_animal/bot/secbot/griefsky/S = new /mob/living/simple_animal/bot/secbot/griefsky
+ S.forceMove(get_turf(src))
+ qdel(I)
+ qdel(src)
+
+ else if((istype(I, /obj/item/toy/sword)) && (toy_step < 3 ))
+ if(!user.unEquip(I))
+ return
+ toy_step++
+ to_chat(user, "You add a toy sword to [src]!.")
+ qdel(I)
+
+ else if((istype(I, /obj/item/toy/sword)) && (toy_step == 3))
+ if(!user.unEquip(I))
+ return
+ to_chat(user, "You complete Genewul Giftskee!.")
+ var/mob/living/simple_animal/bot/secbot/griefsky/toy/S = new /mob/living/simple_animal/bot/secbot/griefsky/toy
+ S.forceMove(get_turf(src))
+ qdel(I)
+ qdel(src)
+
+ else if(istype(I, /obj/item/screwdriver))
+ if((build_step == 1) || (build_step == 2) || (build_step == 3) || (build_step == 4))
+ new /obj/item/melee/energy/sword(get_turf(src))
+ to_chat(user, "You detach the energy sword from [src].")
+ build_step--
+ else if((toy_step == 1) || (toy_step == 2) || (toy_step == 3) || (toy_step == 4))
+ new /obj/item/toy/sword(get_turf(src))
+ to_chat(user, "You detach the toy sword from [src].")
+ toy_step--
+
//Honkbot Assembly
/obj/item/storage/box/clown/attackby(obj/item/W, mob/user, params)
if(!istype(W, /obj/item/robot_parts/l_arm) && !istype(W, /obj/item/robot_parts/r_arm))
diff --git a/code/modules/mob/living/simple_animal/bot/griefsky.dm b/code/modules/mob/living/simple_animal/bot/griefsky.dm
new file mode 100644
index 00000000000..1e91beb580f
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/bot/griefsky.dm
@@ -0,0 +1,231 @@
+/mob/living/simple_animal/bot/secbot/griefsky //This bot is powerful. If you managed to get 4 eswords somehow, you deserve this horror. Emag him for best results.
+ name = "\improper General Griefsky"
+ desc = "Is that a secbot with four eswords in its arms...?"
+ icon_state = "griefsky0"
+ health = 100
+ maxHealth = 100
+ base_icon = "griefsky"
+ window_name = "Automatic Security Unit v3.0"
+
+ var/spin_icon = "griefsky-c" // griefsky and griefsky junior have dif icons
+ var/weapon = /obj/item/melee/energy/sword
+ var/block_chance = 50 //block attacks
+ var/reflect_chance = 80 // chance to reflect projectiles
+ var/dmg = 30 //esword dmg
+ var/block_chance_melee = 50
+ var/block_chance_ranged = 90
+ var/stun_chance = 50
+ var/spam_flag = 0
+
+/mob/living/simple_animal/bot/secbot/griefsky/toy //A toy version of general griefsky!
+ name = "Genewul Giftskee"
+ desc = "An adorable looking secbot with four toy swords taped to its arms"
+ spin_icon = "griefskyj-c"
+ health = 50
+ maxHealth = 50
+ radio_channel = "Service" //we dont report sec anymore!
+ dmg = 0
+ block_chance_melee = 1
+ block_chance_ranged = 1
+ stun_chance = 0
+ bot_core_type = /obj/machinery/bot_core/toy
+ weapon = /obj/item/toy/sword
+
+/obj/machinery/bot_core/toy
+ req_access = list(access_maint_tunnels, access_theatre, access_robotics)
+
+/mob/living/simple_animal/bot/secbot/griefsky/proc/spam_flag_false() //used for addtimer to not spam comms
+ spam_flag = 0
+
+/mob/living/simple_animal/bot/secbot/griefsky/back_to_idle()
+ ..()
+ playsound(loc, 'sound/weapons/saberoff.ogg', 50, 1, -1)
+
+/mob/living/simple_animal/bot/secbot/griefsky/emag_act(mob/user)
+ ..()
+ light_color = LIGHT_COLOR_PURE_RED //if you see a red one. RUN!!
+
+/mob/living/simple_animal/bot/secbot/griefsky/Crossed(atom/movable/AM)
+ ..()
+ if(ismob(AM) && AM == target)
+ var/mob/living/carbon/C = AM
+ visible_message("[src] flails his swords and pushes [C] out of it's way!" )
+ C.Weaken(2)
+
+/mob/living/simple_animal/bot/secbot/griefsky/New()
+ ..()
+
+/mob/living/simple_animal/bot/secbot/griefsky/Destroy()
+ QDEL_NULL(weapon)
+ return ..()
+
+/mob/living/simple_animal/bot/secbot/griefsky/UnarmedAttack(atom/A) //like secbots its only possible with admin intervention
+ if(!on)
+ return
+ if(iscarbon(A))
+ var/mob/living/carbon/C = A
+ sword_attack(C)
+
+/mob/living/simple_animal/bot/secbot/griefsky/bullet_act(obj/item/projectile/P) //so uncivilized
+ retaliate(P.firer)
+ if((icon_state == spin_icon) && (prob(block_chance_ranged))) //only when the eswords are on
+ visible_message("[src] deflects [P] with its energy swords!")
+ playsound(loc, 'sound/weapons/blade1.ogg', 50, 1, 0)
+ else
+ ..()
+
+/mob/living/simple_animal/bot/secbot/griefsky/proc/sword_attack(mob/living/carbon/C) // esword attack
+ src.do_attack_animation(C)
+ playsound(loc, 'sound/weapons/blade1.ogg', 50, 1, -1)
+ spawn(2)
+ icon_state = spin_icon
+ var/threat = C.assess_threat(src)
+ if(ishuman(C))
+ C.apply_damage(dmg, BRUTE)
+ if(prob(stun_chance))
+ C.Weaken(5)
+ add_attack_logs(src, C, "sliced")
+ if(declare_arrests)
+ var/area/location = get_area(src)
+ if(!spam_flag)
+ speak("Back away! I will deal with this level [threat] swine [C] in [location] myself!.", radio_channel)
+ spam_flag = 1
+ addtimer(CALLBACK(src, .proc/spam_flag_false), 100) //to avoid spamming comms of sec for each hit
+ visible_message("[src] flails his swords and cuts [C]!")
+
+
+/mob/living/simple_animal/bot/secbot/griefsky/handle_automated_action()
+ if(!on)
+ return
+
+ switch(mode)
+ if(BOT_IDLE) // idle
+ icon_state = "griefsky1"
+ 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
+ icon_state = spin_icon
+ playsound(loc,'sound/effects/spinsabre.ogg',100,1,-1)
+ if(frustration >= 15) // general beepsky doesn't give up so easily, jedi scum
+ walk_to(src,0)
+ 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
+ back_to_idle()
+
+ if(BOT_START_PATROL)
+ look_for_perp()
+ start_patrol()
+
+ if(BOT_PATROL)
+ icon_state = "griefsky1"
+ look_for_perp()
+ bot_patrol()
+ return
+
+/mob/living/simple_animal/bot/secbot/griefsky/look_for_perp()
+ anchored = 0
+ 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(src)
+
+ if(!threatlevel)
+ 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("[src] points at [C.name]!")
+ mode = BOT_HUNT
+ INVOKE_ASYNC(src, .proc/handle_automated_action)
+ break
+ else
+ continue
+
+/mob/living/simple_animal/bot/secbot/griefsky/explode()
+ walk_to(src,0)
+ visible_message("[src] lets out a huge cough as it blows apart!")
+ var/turf/Tsec = get_turf(src)
+ new /obj/item/assembly/prox_sensor(Tsec)
+ if(prob(50))
+ new /obj/item/robot_parts/r_arm(Tsec)
+ if(prob(50)) //most of the time weapon will be destroyed
+ new weapon(Tsec)
+ if(prob(25))
+ new weapon(Tsec)
+ if(prob(10))
+ new weapon(Tsec)
+ if(prob(5))
+ new weapon(Tsec)
+ do_sparks(3, 1, src)
+ new /obj/effect/decal/cleanable/blood/oil(loc)
+ ..()
+
+//this section is blocking attack
+
+/mob/living/simple_animal/bot/secbot/griefsky/bullet_act(obj/item/projectile/P) //so uncivilized
+ retaliate(P.firer)
+ if((icon_state == spin_icon) && (prob(block_chance_ranged))) //only when the eswords are on
+ visible_message("[src] deflects [P] with its energy swords!")
+ playsound(loc, 'sound/weapons/blade1.ogg', 50, 1, 0)
+ else
+ ..()
+
+/mob/living/simple_animal/bot/secbot/griefsky/proc/special_retaliate_after_attack(mob/user) //allows special actions to take place after being attacked.
+ return
+
+/mob/living/simple_animal/bot/secbot/griefsky/special_retaliate_after_attack(mob/user)
+ if(icon_state != spin_icon)
+ return
+ if(prob(block_chance_melee))
+ visible_message("[src] deflects [user]'s attack with his energy swords!")
+ playsound(loc, 'sound/weapons/blade1.ogg', 50, TRUE, -1)
+ return TRUE
+
+/mob/living/simple_animal/bot/secbot/griefsky/attack_hand(mob/living/carbon/human/H)
+ if((H.a_intent == INTENT_HARM) || (H.a_intent == INTENT_DISARM))
+ retaliate(H)
+ if(special_retaliate_after_attack(H))
+ return
+ return ..()
+
+/mob/living/simple_animal/bot/secbot/griefsky/attackby(obj/item/W, mob/user, params) //cant touch or attack him while spinning
+ if(src.icon_state == spin_icon)
+ if(prob(block_chance_melee))
+ user.changeNext_move(CLICK_CD_MELEE)
+ user.do_attack_animation(src)
+ visible_message("[src] deflects [user]'s move with his energy swords!")
+ playsound(loc, 'sound/weapons/blade1.ogg', 50, TRUE, -1)
+ else
+ ..()
+ else
+ ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index 84ab158504d..e14972a985d 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -121,7 +121,7 @@
dat += hack(user)
dat += showpai(user)
dat += text({"
-Securitron v1.6 controls
+[window_name]
Status: []
Behaviour controls are [locked ? "locked" : "unlocked"]
Maintenance panel panel is [open ? "opened" : "closed"]"},
diff --git a/icons/obj/aibots.dmi b/icons/obj/aibots.dmi
index 14ac2d95ac9..273fbf77133 100644
Binary files a/icons/obj/aibots.dmi and b/icons/obj/aibots.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 9704404193e..1797502126f 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1848,6 +1848,7 @@
#include "code\modules\mob\living\simple_animal\bot\ed209bot.dm"
#include "code\modules\mob\living\simple_animal\bot\emote.dm"
#include "code\modules\mob\living\simple_animal\bot\floorbot.dm"
+#include "code\modules\mob\living\simple_animal\bot\griefsky.dm"
#include "code\modules\mob\living\simple_animal\bot\honkbot.dm"
#include "code\modules\mob\living\simple_animal\bot\medbot.dm"
#include "code\modules\mob\living\simple_animal\bot\mulebot.dm"
diff --git a/sound/effects/spinsabre.ogg b/sound/effects/spinsabre.ogg
new file mode 100644
index 00000000000..ad1f2abd3a6
Binary files /dev/null and b/sound/effects/spinsabre.ogg differ