Saboteur borg module (syndicate engiborg) (#40163)

* wip

* SPRITES

* wops typo

* make it available

* add borg chameleon module (wip)

* we ready boyes

* bump cost

* disable filter for now

* henk

* add to polymorph pool

* borgs don't generally throw their modules

* this too
This commit is contained in:
vuonojenmustaturska
2018-09-13 14:33:35 +03:00
committed by yogstation13-bot
parent 52e6bc57a8
commit b2abb01a74
14 changed files with 198 additions and 13 deletions

View File

@@ -413,6 +413,7 @@ RLD
no_ammo_message = "<span class='warning'>Insufficient charge.</span>"
desc = "A device used to rapidly build walls and floors."
canRturf = TRUE
var/energyfactor = 72
/obj/item/construction/rcd/borg/useResource(amount, mob/user)
@@ -423,7 +424,7 @@ RLD
if(user)
to_chat(user, no_ammo_message)
return 0
. = borgy.cell.use(amount * 72) //borgs get 1.3x the use of their RCDs
. = borgy.cell.use(amount * energyfactor) //borgs get 1.3x the use of their RCDs
if(!. && user)
to_chat(user, no_ammo_message)
return .
@@ -436,11 +437,16 @@ RLD
if(user)
to_chat(user, no_ammo_message)
return 0
. = borgy.cell.charge >= (amount * 72)
. = borgy.cell.charge >= (amount * energyfactor)
if(!. && user)
to_chat(user, no_ammo_message)
return .
/obj/item/construction/rcd/borg/syndicate
icon_state = "ircd"
item_state = "ircd"
energyfactor = 66
/obj/item/construction/rcd/loaded
matter = 160

View File

@@ -182,6 +182,10 @@
name = "syndicate medical teleporter"
borg_to_spawn = "Medical"
/obj/item/antag_spawner/nuke_ops/borg_tele/saboteur
name = "syndicate saboteur teleporter"
borg_to_spawn = "Saboteur"
/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T, kind, datum/mind/user)
var/mob/living/silicon/robot/R
var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE)
@@ -191,6 +195,8 @@
switch(borg_to_spawn)
if("Medical")
R = new /mob/living/silicon/robot/modules/syndicate/medical(T)
if("Saboteur")
R = new /mob/living/silicon/robot/modules/syndicate/saboteur(T)
else
R = new /mob/living/silicon/robot/modules/syndicate(T) //Assault borg by default

View File

@@ -0,0 +1,103 @@
/obj/item/borg_chameleon
name = "cyborg chameleon projector"
icon = 'icons/obj/device.dmi'
icon_state = "shield0"
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
var/friendlyName
var/savedName
var/active = FALSE
var/activationCost = 300
var/activationUpkeep = 50
var/disguise = "engineer"
var/datum/component/mobhook // need this to deal with unregistration properly
var/mob/living/silicon/robot/user // needed for process()
/obj/item/borg_chameleon/Initialize()
. = ..()
friendlyName = pick(GLOB.ai_names)
/obj/item/borg_chameleon/Destroy()
QDEL_NULL(mobhook)
return ..()
/obj/item/borg_chameleon/dropped(mob/user)
. = ..()
disrupt(user)
/obj/item/borg_chameleon/equipped(mob/user)
. = ..()
disrupt(user)
/obj/item/borg_chameleon/attack_self(mob/living/silicon/robot/user)
if (user && user.cell && user.cell.charge > activationCost)
if (isturf(user.loc))
toggle(user)
else
to_chat(user, "<span class='warning'>You can't use [src] while inside something!</span>")
else
to_chat(user, "<span class='warning'>You need at least [activationCost] charge in your cell to use [src]!</span>")
/obj/item/borg_chameleon/proc/toggle(mob/living/silicon/robot/user)
if(active)
playsound(src, 'sound/effects/pop.ogg', 100, 1, -6)
to_chat(user, "<span class='notice'>You deactivate \the [src].</span>")
deactivate(user)
else
to_chat(user, "<span class='notice'>You activate \the [src].</span>")
playsound(src, 'sound/effects/seedling_chargeup.ogg', 100, 1, -6)
if (do_after(user, 50, target=user) && user.cell.use(activationCost))
playsound(src, 'sound/effects/bamf.ogg', 100, 1, -6)
to_chat(user, "<span class='notice'>You are now disguised as the Nanotrasen engineering borg \"[friendlyName]\".</span>")
activate(user)
else
to_chat(user, "<span class='warning'>The chameleon field fizzles.</span>")
do_sparks(3, FALSE, user)
/obj/item/borg_chameleon/process()
if (user)
if (!user.cell || !user.cell.use(activationUpkeep))
disrupt(user)
else
return PROCESS_KILL
/obj/item/borg_chameleon/proc/activate(mob/living/silicon/robot/user)
START_PROCESSING(SSobj, src)
src.user = user
savedName = user.name
user.name = friendlyName
user.module.cyborg_base_icon = disguise
active = TRUE
if (mobhook && mobhook.parent != user)
QDEL_NULL(mobhook)
if (!mobhook)
var/callback = CALLBACK(src, .proc/disrupt, user) // push user into the callback so that it's guaranteed to be the first arg
mobhook = user.AddComponent(/datum/component/redirect, list( // list here all signals that should break the camouflage
COMSIG_PARENT_ATTACKBY = callback,
COMSIG_ATOM_ATTACK_HAND = callback,
COMSIG_MOVABLE_IMPACT_ZONE = callback,
COMSIG_ATOM_BULLET_ACT = callback,
COMSIG_ATOM_EX_ACT = callback,
COMSIG_ATOM_FIRE_ACT = callback,
COMSIG_ATOM_EMP_ACT = callback,
))
user.update_icons()
/obj/item/borg_chameleon/proc/deactivate(mob/living/silicon/robot/user)
STOP_PROCESSING(SSobj, src)
QDEL_NULL(mobhook)
do_sparks(5, FALSE, user)
user.name = savedName
user.module.cyborg_base_icon = initial(user.module.cyborg_base_icon)
active = FALSE
user.update_icons()
src.user = user
/obj/item/borg_chameleon/proc/disrupt(mob/living/silicon/robot/user)
if(active)
to_chat(user, "<span class='danger'>Your chameleon field deactivates.</span>")
deactivate(user)

View File

@@ -853,6 +853,17 @@
<i>Help the operatives secure the disk at all costs!</i></b>"
set_module = /obj/item/robot_module/syndicate_medical
/mob/living/silicon/robot/modules/syndicate/saboteur
icon_state = "synd_engi"
playstyle_string = "<span class='big bold'>You are a Syndicate saboteur cyborg!</span><br>\
<b>You are armed with robust engineering tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \
Your destination tagger will allow you to stealthily traverse the disposal network across the station \
Your welder will allow you to repair the operatives' exosuits, but also yourself and your fellow cyborgs \
Your cyborg chameleon projector allows you to assume the appearance and registered name of a Nanotrasen engineering borg, and undertake covert actions on the station \
Be aware that almost any physical contact or incidental damage will break your camouflage \
<i>Help the operatives secure the disk at all costs!</i></b>"
set_module = /obj/item/robot_module/saboteur
/mob/living/silicon/robot/proc/notify_ai(notifytype, oldname, newname)
if(!connected_ai)
return

View File

@@ -177,8 +177,8 @@
if (stat != DEAD)
adjustBruteLoss(30)
/mob/living/silicon/robot/bullet_act(var/obj/item/projectile/Proj)
..(Proj)
/mob/living/silicon/robot/bullet_act(var/obj/item/projectile/Proj, def_zone)
..()
updatehealth()
if(prob(75) && Proj.damage > 0)
spark_system.start()

View File

@@ -32,6 +32,7 @@
var/list/ride_offset_y = list("north" = 4, "south" = 4, "east" = 3, "west" = 3)
var/ride_allow_incapacitated = FALSE
var/allow_riding = TRUE
var/canDispose = FALSE // Whether the borg can stuff itself into disposal
/obj/item/robot_module/Initialize()
. = ..()
@@ -596,6 +597,40 @@
can_be_pushed = FALSE
hat_offset = 3
/obj/item/robot_module/saboteur
name = "Syndicate Saboteur"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/borg/sight/thermal,
/obj/item/construction/rcd/borg/syndicate,
/obj/item/pipe_dispenser,
/obj/item/extinguisher,
/obj/item/weldingtool/largetank/cyborg,
/obj/item/screwdriver/nuke,
/obj/item/wrench/cyborg,
/obj/item/crowbar/cyborg,
/obj/item/wirecutters/cyborg,
/obj/item/multitool/cyborg,
/obj/item/stack/sheet/metal/cyborg,
/obj/item/stack/sheet/glass/cyborg,
/obj/item/stack/sheet/rglass/cyborg,
/obj/item/stack/rods/cyborg,
/obj/item/stack/tile/plasteel/cyborg,
/obj/item/destTagger/borg,
/obj/item/stack/cable_coil/cyborg,
/obj/item/pinpointer/syndicate_cyborg,
/obj/item/borg_chameleon,
)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/engineer,
/obj/item/clockwork/replica_fabricator/cyborg)
cyborg_base_icon = "synd_engi"
moduleselect_icon = "malf"
can_be_pushed = FALSE
magpulsing = TRUE
hat_offset = -4
canDispose = TRUE
/datum/robot_energy_storage
var/name = "Generic energy storage"
var/max_energy = 30000

View File

@@ -65,6 +65,9 @@
//ATTACK HAND IGNORING PARENT RETURN VALUE
/mob/living/silicon/attack_hand(mob/living/carbon/human/M)
. = FALSE
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, M) & COMPONENT_NO_ATTACK_HAND)
. = TRUE
switch(M.a_intent)
if ("help")
M.visible_message("[M] pets [src].", \
@@ -76,7 +79,6 @@
playsound(src.loc, 'sound/effects/bang.ogg', 10, 1)
visible_message("<span class='danger'>[M] punches [src], but doesn't leave a dent.</span>", \
"<span class='warning'>[M] punches [src], but doesn't leave a dent.</span>", null, COMBAT_MESSAGE_RANGE)
return 0
/mob/living/silicon/attack_drone(mob/living/simple_animal/drone/M)
if(M.a_intent == INTENT_HARM)
@@ -108,7 +110,8 @@
M.visible_message("<span class='boldwarning'>[M] is thrown off of [src]!</span>")
flash_act(affect_silicon = 1)
/mob/living/silicon/bullet_act(obj/item/projectile/Proj)
/mob/living/silicon/bullet_act(obj/item/projectile/Proj, def_zone)
SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, Proj, def_zone)
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
adjustBruteLoss(Proj.damage)
if(prob(Proj.damage*1.5))

View File

@@ -153,6 +153,7 @@
var/robot = pick(200;/mob/living/silicon/robot,
/mob/living/silicon/robot/modules/syndicate,
/mob/living/silicon/robot/modules/syndicate/medical,
/mob/living/silicon/robot/modules/syndicate/saboteur,
200;/mob/living/simple_animal/drone/polymorphed)
new_mob = new robot(M.loc)
if(issilicon(new_mob))
@@ -510,5 +511,3 @@
var/turf/T = get_turf(target)
for(var/i=0, i<50, i+=10)
addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, T, -1, exp_heavy, exp_light, exp_flash, FALSE, FALSE, exp_fire), i)

View File

@@ -115,7 +115,12 @@
/obj/machinery/disposal/proc/stuff_mob_in(mob/living/target, mob/living/user)
if(!iscarbon(user) && !user.ventcrawler) //only carbon and ventcrawlers can climb into disposal by themselves.
return
if (iscyborg(user))
var/mob/living/silicon/robot/borg = user
if (!borg.module || !borg.module.canDispose)
return
else
return
if(!isturf(user.loc)) //No magically doing it from inside closets
return
if(target.buckled || target.has_buckled_mobs())

View File

@@ -52,9 +52,13 @@
if(istype(AM, /obj/structure/bigDelivery) && !hasmob)
var/obj/structure/bigDelivery/T = AM
src.destinationTag = T.sortTag
if(istype(AM, /obj/item/smallDelivery) && !hasmob)
else if(istype(AM, /obj/item/smallDelivery) && !hasmob)
var/obj/item/smallDelivery/T = AM
src.destinationTag = T.sortTag
else if(istype(AM, /mob/living/silicon/robot))
var/obj/item/destTagger/borg/tagger = locate() in AM
if (tagger)
src.destinationTag = tagger.currTag
// start the movement process

View File

@@ -154,6 +154,10 @@
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT
/obj/item/destTagger/borg
name = "cyborg destination tagger"
desc = "Used to fool the disposal mail network into thinking that you're a harmless parcel. Does actually work as a regular destination tagger as well."
/obj/item/destTagger/suicide_act(mob/living/user)
user.visible_message("<span class='suicide'>[user] begins tagging [user.p_their()] final destination! It looks like [user.p_theyre()] trying to commit suicide!</span>")
if (islizard(user))

View File

@@ -201,7 +201,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
cost = 10
surplus = 40
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/dangerous/carbine
name = "M-90gl Carbine"
desc = "A fully-loaded, specialized three-round burst carbine that fires 5.56mm ammunition from a 30 round magazine \
@@ -526,7 +526,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/storage/backpack/duffelbag/syndie/ammo/smg
cost = 20
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/carbine
name = "5.56mm Toploader Magazine"
desc = "An additional 30-round 5.56mm magazine; suitable for use with the M-90gl carbine. \
@@ -534,7 +534,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/ammo_box/magazine/m556
cost = 4
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/a40mm
name = "40mm Grenade"
desc = "A 40mm HE grenade for use with the M-90gl's under-barrel grenade launcher. \
@@ -642,6 +642,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
cost = 35
restricted = TRUE
/datum/uplink_item/support/reinforcement/saboteur_borg
name = "Syndicate Saboteur Cyborg"
desc = "A streamlined engineering cyborg, equipped with thermal vision and the ability to traverse Nanotrasen's disposal network. Also incapable of leaving the welder in the shuttle."
item = /obj/item/antag_spawner/nuke_ops/borg_tele/saboteur
refundable = TRUE
cost = 35
restricted = TRUE
/datum/uplink_item/support/gygax
name = "Gygax Exosuit"
desc = "A lightweight exosuit, painted in a dark scheme. Its speed and equipment selection make it excellent \

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

After

Width:  |  Height:  |  Size: 189 KiB

View File

@@ -1254,6 +1254,7 @@
#include "code\modules\antagonists\ninja\ninja.dm"
#include "code\modules\antagonists\nukeop\clownop.dm"
#include "code\modules\antagonists\nukeop\nukeop.dm"
#include "code\modules\antagonists\nukeop\equipment\borgchameleon.dm"
#include "code\modules\antagonists\nukeop\equipment\nuclear_challenge.dm"
#include "code\modules\antagonists\nukeop\equipment\nuclearbomb.dm"
#include "code\modules\antagonists\nukeop\equipment\pinpointer.dm"