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