Stealth and Steel: The Space Ninja (#31497)
* Space Ninja Antag Datum * Small fixes * Ninja outfit, ekatana, actions * Ninja scanner and spans * Ninja uplink implant * Ninja bombs * Ninja bomb flare grants * Ninja modsuit, objective payouts * Fixes objectives * Ninja stealth fix, modsuit sprites and final implementations * Lints * Ninja scanner sprites * Ninja Suit and Energy Shuriken Sprites * Fixes config, Adjusts stim ability, adds shuriken printer and e-shurikens, uplink stuff * Fixes a duplicate icon * Attack chain * Energy katana item sprite * Ninja net gun * Brazil * Spawning ninjas, ninja on traitor panel, ninja spawn sound * Linter * Objective stuff * Fixes n grey suits * Objectives * Trim intro sound * Event, spawn point * Ninja Outfits, Vox Check, Bug Fixes, Mirror at ninja spawn * Address code review * Oops * Uncomments an important thingy * Update: Gave space ninjas access to maints and an agent ID card. Updated net description. * Update scanner examine * Removes excess file * Makes ninja scanner fit in belts and ninja suits. Gives them NV goggles * Fixes modsuit sprite issue * Energy shuriken fixes * Scanner fix * Printer fix * Fixes some runtimes * Fixes capture teleport * Clothes rename * Buffs energy katana, adds soft no-drop to ekatana, buffs ninja modsuit, fixes equip bug * Adds research levels to ninja gear * Fixes ninja capture issue * Remaps ninja dojo * Better cuff removal * Forgor * Fixes action availability * Updates walls at dojo * Improves ninja modsuit * Windoors can now be opened with the katana * Adds advanced pinpointer to ninja uplink * Fixed energy nets sticking * Fixes slime people ninjas * Adds reroll to ninja capture if target is DNR. Prevents off Z-level targets * Oop * Adds reactor sabotage objective. * Fixes ninja cuffs * Removes Carp scroll from uplink. Adds Krav Implant to uplink
@@ -64,6 +64,7 @@
|
||||
#define SPECIAL_ROLE_TOURIST "Tourist"
|
||||
#define SPECIAL_ROLE_HERETIC "Heretic"
|
||||
#define SPECIAL_ROLE_EVENTMISC "Event Role"
|
||||
#define SPECIAL_ROLE_NINJA "Space Ninja"
|
||||
|
||||
// Constants used by code which checks the status of nuclear blasts during a
|
||||
// round, regardless of original game mode, e.g. setting the ending cinematic.
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#define ROLE_EVENTMISC "eventmisc"
|
||||
#define ROLE_GHOST "ghost role"
|
||||
#define ROLE_ELITE "lavaland elite"
|
||||
#define ROLE_NINJA "ninja"
|
||||
|
||||
// Misc jobban categories
|
||||
#define ROLEBAN_AHUD "AntagHUD"
|
||||
@@ -71,6 +72,7 @@ GLOBAL_LIST_INIT(special_roles_antags, list(
|
||||
ROLE_WIZARD = /datum/game_mode/wizard, // Wizard
|
||||
ROLE_MIND_FLAYER,
|
||||
ROLE_HERETIC,
|
||||
ROLE_NINJA,
|
||||
|
||||
// UNUSED/BROKEN ANTAGS
|
||||
// ROLE_HOG_GOD = /datum/game_mode/hand_of_god,
|
||||
|
||||
@@ -14,6 +14,7 @@ GLOBAL_LIST_INIT(antag_roles, list(
|
||||
ROLE_GUARDIAN,
|
||||
ROLE_MORPH,
|
||||
ROLE_TSPIDER,
|
||||
ROLE_NINJA,
|
||||
))
|
||||
|
||||
// Bannable other roles
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#define UPLINK_TYPE_TRAITOR "traitor"
|
||||
#define UPLINK_TYPE_NUCLEAR "nuclear"
|
||||
#define UPLINK_TYPE_NINJA "ninja"
|
||||
#define UPLINK_TYPE_SST "sst"
|
||||
#define UPLINK_TYPE_SIT "sit"
|
||||
#define UPLINK_TYPE_ADMIN "admin"
|
||||
|
||||
@@ -22,6 +22,7 @@ GLOBAL_LIST_EMPTY(newplayer_start)
|
||||
GLOBAL_LIST_EMPTY(latejoin)
|
||||
GLOBAL_LIST_EMPTY(prisonwarp) //prisoners go to these
|
||||
GLOBAL_LIST_EMPTY(syndieprisonwarp) //contractor targets go to these
|
||||
GLOBAL_LIST_EMPTY(ninjaprisonwarp) // ninja targets go to these
|
||||
GLOBAL_LIST_EMPTY(antagextractwarp) // exfiltrating antags go here
|
||||
GLOBAL_LIST_EMPTY(backroomswarp) //backrooms hallucinators go to these
|
||||
GLOBAL_LIST_EMPTY(xeno_spawn)//Aliens spawn at these.
|
||||
@@ -37,7 +38,6 @@ GLOBAL_LIST_EMPTY(aroomwarp)
|
||||
GLOBAL_LIST_EMPTY(prisonsecuritywarp) //prison security goes to these
|
||||
GLOBAL_LIST_EMPTY(prisonwarped) //list of players already warped
|
||||
GLOBAL_LIST_EMPTY(nukedisc_respawn)
|
||||
GLOBAL_LIST_EMPTY(ninjastart)
|
||||
GLOBAL_LIST_EMPTY(carplist) //list of all carp-spawn landmarks
|
||||
GLOBAL_LIST_EMPTY(syndicateofficer)
|
||||
GLOBAL_LIST_EMPTY(roundstart_observer_start)
|
||||
|
||||
@@ -408,6 +408,18 @@
|
||||
else
|
||||
. += "thrall|<b>NO</b>"
|
||||
|
||||
/datum/mind/proc/memory_edit_space_ninja(mob/living/carbon/human/H)
|
||||
. = _memory_edit_header("space_ninja")
|
||||
var/datum/antagonist/space_ninja/ninja = has_antag_datum(/datum/antagonist/space_ninja)
|
||||
if(ninja)
|
||||
. += "<b><font color='red'>SPACE NINJA</font></b>|<a href='byond://?src=[UID()];space_ninja=clear'>no</a>"
|
||||
if(!ninja.has_antag_objectives())
|
||||
. += "<br>Objectives are empty! <a href='byond://?src=[UID()];space_ninja=autoobjectives'>Randomize!</a>"
|
||||
else
|
||||
. += "<a href='byond://?src=[UID()];space_ninja=space_ninja'>space_ninja</a>|<b>NO</b>"
|
||||
|
||||
. += _memory_edit_role_enabled(ROLE_NINJA)
|
||||
|
||||
/datum/mind/proc/memory_edit_mind_flayer(mob/living/carbon/human/H)
|
||||
. = _memory_edit_header("mind_flayer")
|
||||
var/datum/antagonist/mindflayer/flayer = has_antag_datum(/datum/antagonist/mindflayer)
|
||||
@@ -605,6 +617,8 @@
|
||||
sections["changeling"] = memory_edit_changeling(H)
|
||||
/** VAMPIRE ***/
|
||||
sections["vampire"] = memory_edit_vampire(H)
|
||||
/** SPACE NINJA */
|
||||
sections["space_ninja"] = memory_edit_space_ninja(H)
|
||||
/** MINDFLAYER ***/
|
||||
sections["mind_flayer"] = memory_edit_mind_flayer(H)
|
||||
/** HERETIC ***/
|
||||
@@ -1169,6 +1183,19 @@
|
||||
log_admin("[key_name(usr)] has automatically forged objectives for [key_name(current)]")
|
||||
message_admins("[key_name_admin(usr)] has automatically forged objectives for [key_name_admin(current)]")
|
||||
|
||||
else if(href_list["space_ninja"])
|
||||
switch(href_list["space_ninja"])
|
||||
if("clear")
|
||||
if(has_antag_datum(/datum/antagonist/space_ninja))
|
||||
remove_antag_datum(/datum/antagonist/space_ninja)
|
||||
log_admin("[key_name(usr)] has de-ninja'd [key_name(current)].")
|
||||
message_admins("[key_name(usr)] has de-ninja'd [key_name(current)].")
|
||||
if("space_ninja")
|
||||
make_space_ninja()
|
||||
log_admin("[key_name(usr)] has ninja'd [key_name(current)].")
|
||||
to_chat(current, "<b><font color='red'>Your training awakens, and a myserious set of gear teleports in around you... You are a Space Ninja!</font></b>")
|
||||
message_admins("[key_name(usr)] has ninja'd [key_name(current)].")
|
||||
|
||||
else if(href_list["vampthrall"])
|
||||
switch(href_list["vampthrall"])
|
||||
if("clear")
|
||||
@@ -1826,6 +1853,11 @@
|
||||
add_antag_datum(/datum/antagonist/mindflayer)
|
||||
SSticker.mode.mindflayers |= src
|
||||
|
||||
/datum/mind/proc/make_space_ninja()
|
||||
if(!has_antag_datum(/datum/antagonist/space_ninja))
|
||||
add_antag_datum(/datum/antagonist/space_ninja)
|
||||
SSticker.mode.ninjas |= src
|
||||
|
||||
/datum/mind/proc/make_heretic()
|
||||
if(!has_antag_datum(/datum/antagonist/heretic))
|
||||
add_antag_datum(/datum/antagonist/heretic)
|
||||
|
||||
@@ -182,6 +182,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
/datum/uplink_item/dangerous
|
||||
category = "Highly Visible and Dangerous Weapons"
|
||||
excludefrom = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/dangerous/pistol
|
||||
name = "FK-69 Stechkin Pistol"
|
||||
@@ -243,7 +244,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
item = /obj/item/chainsaw/syndie
|
||||
cost = 65
|
||||
surplus = 0 // This has caused major problems with un-needed chainsaw massacres. Bwoink bait.
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_NINJA)
|
||||
can_discount = FALSE // Too gamer.
|
||||
|
||||
/datum/uplink_item/dangerous/universal_gun_kit
|
||||
@@ -275,6 +276,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
category = "Ammunition"
|
||||
surplus = 0 // Getting these in a discount or surplus is not a good time.
|
||||
can_discount = FALSE
|
||||
excludefrom = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/ammo/pistol
|
||||
name = "Stechkin - 10mm Magazine"
|
||||
@@ -317,6 +319,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
/datum/uplink_item/stealthy_weapons
|
||||
category = "Stealthy and Inconspicuous Weapons"
|
||||
excludefrom = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/garrote
|
||||
name = "Fiber Wire Garrote"
|
||||
@@ -325,6 +328,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
item = /obj/item/garrote
|
||||
reference = "GAR"
|
||||
cost = 30
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/cameraflash
|
||||
name = "Camera Flash"
|
||||
@@ -342,6 +346,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "STK"
|
||||
item = /obj/item/storage/box/syndie_kit/throwing_weapons
|
||||
cost = 15
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/edagger
|
||||
name = "Energy Dagger"
|
||||
@@ -349,6 +354,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "EDP"
|
||||
item = /obj/item/pen/edagger
|
||||
cost = 10
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/foampistol
|
||||
name = "Toy Gun (with Stun Darts)"
|
||||
@@ -387,6 +393,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
item = /obj/item/reagent_containers/glass/bottle/traitor
|
||||
cost = 10
|
||||
surplus = 0 // Requires another item to function.
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/silencer
|
||||
name = "Universal Suppressor"
|
||||
@@ -416,6 +423,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
/datum/uplink_item/explosives
|
||||
category = "Grenades and Explosives"
|
||||
excludefrom = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/explosives/plastic_explosives
|
||||
name = "Composition C-4"
|
||||
@@ -487,6 +495,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "TARG"
|
||||
item = /obj/item/grenade/chem_grenade/tar
|
||||
cost = 7
|
||||
excludefrom = list()
|
||||
|
||||
////////////////////////////////////////
|
||||
// MARK: STEALTHY TOOLS
|
||||
@@ -494,6 +503,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
/datum/uplink_item/stealthy_tools
|
||||
category = "Stealth and Camouflage Items"
|
||||
excludefrom = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/stealthy_tools/forgers_kit
|
||||
name = "Forger's Kit"
|
||||
@@ -526,6 +536,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "THIG"
|
||||
item = /obj/item/clothing/glasses/chameleon/thermal
|
||||
cost = 15
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/stealthy_tools/night
|
||||
name = "Nightvision Chameleon Glasses"
|
||||
@@ -533,6 +544,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "TNIG"
|
||||
item = /obj/item/clothing/glasses/chameleon/night
|
||||
cost = 5
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/stealthy_tools/agent_card
|
||||
name = "Agent ID Card"
|
||||
@@ -547,6 +559,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "CP"
|
||||
item = /obj/item/chameleon
|
||||
cost = 25
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/stealthy_tools/chameleon_counter
|
||||
name = "Chameleon Counterfeiter"
|
||||
@@ -562,6 +575,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
item = /obj/item/storage/box/syndie_kit/camera_bug
|
||||
cost = 5
|
||||
surplus = 90
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/stealthy_tools/dnascrambler
|
||||
name = "DNA Scrambler"
|
||||
@@ -569,6 +583,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "DNAS"
|
||||
item = /obj/item/dnascrambler
|
||||
cost = 7
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/stealthy_tools/smugglersatchel
|
||||
name = "Smuggler's Satchel"
|
||||
@@ -615,6 +630,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "HM"
|
||||
item = /obj/item/handheld_mirror
|
||||
cost = 5
|
||||
excludefrom = list()
|
||||
|
||||
////////////////////////////////////////
|
||||
// MARK: DEVICES AND TOOLS
|
||||
@@ -623,6 +639,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
/datum/uplink_item/device_tools
|
||||
category = "Devices and Tools"
|
||||
abstract = 1
|
||||
excludefrom = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/device_tools/emag
|
||||
name = "Cryptographic Sequencer"
|
||||
@@ -658,6 +675,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "NCAI"
|
||||
item = /obj/item/reagent_containers/hypospray/autoinjector/nanocalcium
|
||||
cost = 10
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/device_tools/syndicate_teleporter
|
||||
name = "Experimental Syndicate Teleporter"
|
||||
@@ -692,6 +710,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "TAR"
|
||||
item = /obj/item/reagent_containers/spray/sticky_tar
|
||||
cost = 10
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/device_tools/binary
|
||||
name = "Binary Translator Key"
|
||||
@@ -739,6 +758,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
name = "Advanced Pinpointer"
|
||||
desc = "A pinpointer that tracks any specified coordinates, DNA string, high value item or the nuclear authentication disk."
|
||||
reference = "ADVP"
|
||||
excludefrom = list()
|
||||
item = /obj/item/pinpointer/advpinpointer
|
||||
cost = 10
|
||||
can_discount = FALSE
|
||||
@@ -749,6 +769,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "AID"
|
||||
item = /obj/item/multitool/ai_detect
|
||||
cost = 5
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/device_tools/jammer
|
||||
name = "Radio Jammer"
|
||||
@@ -756,6 +777,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "RJ"
|
||||
item = /obj/item/jammer
|
||||
cost = 20
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/device_tools/decoy_nade
|
||||
name = "Decoy Grenade Kit"
|
||||
@@ -763,6 +785,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "DCY"
|
||||
item = /obj/item/storage/box/syndie_kit/decoy
|
||||
cost = 20
|
||||
excludefrom = list()
|
||||
|
||||
////////////////////////////////////////
|
||||
// MARK: SPACE SUITS AND HARDSUITS
|
||||
@@ -771,6 +794,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
/datum/uplink_item/suits
|
||||
category = "Space Suits and MODsuits"
|
||||
surplus = 10 //I am setting this to 10 as there are a bunch of modsuit parts in here that should be weighted to 10. Suits and modsuits adjusted below.
|
||||
excludefrom = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/suits/space_suit
|
||||
name = "Syndicate Space Suit"
|
||||
@@ -787,6 +811,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "MSTV"
|
||||
item = /obj/item/mod/module/visor/thermal
|
||||
cost = 15 // Don't forget, you need to get a modsuit to go with this
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/suits/night
|
||||
name = "MODsuit Night Visor Module"
|
||||
@@ -794,6 +819,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "MSNV"
|
||||
item = /obj/item/mod/module/visor/night
|
||||
cost = 5 // It's night vision, rnd pumps out those goggles for anyone man.
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/suits/plate_compression
|
||||
name = "MODsuit Plate Compression Module"
|
||||
@@ -809,6 +835,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "MSCM"
|
||||
item = /obj/item/mod/module/chameleon
|
||||
cost = 10
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/suits/noslip
|
||||
name = "MODsuit Anti-Slip Module"
|
||||
@@ -816,6 +843,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "MSNS"
|
||||
item = /obj/item/mod/module/noslip
|
||||
cost = 5
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/suits/springlock_module
|
||||
name = "Heavily Modified Springlock MODsuit Module"
|
||||
@@ -831,6 +859,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "FNAF"
|
||||
item = /obj/item/mod/module/springlock/bite_of_87
|
||||
cost = 5
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/suits/hidden_holster
|
||||
name = "Hidden Holster Module"
|
||||
@@ -845,6 +874,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "SGM"
|
||||
item = /obj/item/mod/module/dispenser/smoke
|
||||
cost = 10
|
||||
excludefrom = list()
|
||||
|
||||
////////////////////////////////////////
|
||||
// MARK: IMPLANTS
|
||||
@@ -852,6 +882,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
/datum/uplink_item/bio_chips
|
||||
category = "Bio-chips"
|
||||
excludefrom = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/bio_chips/freedom
|
||||
name = "Freedom Bio-chip"
|
||||
@@ -873,6 +904,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "ESI"
|
||||
item = /obj/item/bio_chip_implanter/storage
|
||||
cost = 40
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/bio_chips/mindslave
|
||||
name = "Mindslave Bio-chip"
|
||||
@@ -917,6 +949,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
/datum/uplink_item/cyber_implants
|
||||
category = "Cybernetic Implants"
|
||||
excludefrom = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/cyber_implants/hackerman_deck
|
||||
name = "Binyat Wireless Hacking System Autoimplanter"
|
||||
@@ -935,6 +968,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "RZR"
|
||||
item = /obj/item/autosurgeon/organ/syndicate/oneuse/razorwire
|
||||
cost = 20
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/cyber_implants/scope_eyes
|
||||
name = "Hardened Kaleido Optics Eyes Autoimplanter"
|
||||
@@ -944,6 +978,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
reference = "KOE"
|
||||
item = /obj/item/autosurgeon/organ/syndicate/oneuse/scope_eyes
|
||||
cost = 10
|
||||
excludefrom = list()
|
||||
|
||||
/datum/uplink_item/cyber_implants/mantis_kit
|
||||
name = "'Naginata' Mantis Blades Kit"
|
||||
@@ -956,7 +991,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
cost = 50
|
||||
surplus = 0
|
||||
can_discount = FALSE
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_NINJA)
|
||||
|
||||
////////////////////////////////////////
|
||||
// MARK: POINTLESS BADASSERY
|
||||
@@ -965,6 +1000,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
/datum/uplink_item/badass
|
||||
category = "(Pointless) Badassery"
|
||||
surplus = 0
|
||||
excludefrom = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/badass/pen
|
||||
name = "Syndicate Fountain Pen"
|
||||
@@ -1025,6 +1061,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
category = "Bundles and Telecrystals"
|
||||
surplus = 0
|
||||
can_discount = FALSE
|
||||
excludefrom = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/bundles_tc/telecrystal
|
||||
name = "Raw Telecrystal"
|
||||
|
||||
@@ -550,7 +550,7 @@
|
||||
reference = "KMI"
|
||||
item = /obj/item/bio_chip_implanter/krav_maga
|
||||
cost = 25
|
||||
uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/bio_chips/uplink/nuclear
|
||||
name = "Nuclear Uplink Bio-chip"
|
||||
@@ -661,34 +661,34 @@
|
||||
/datum/uplink_item/stealthy_weapons/cqc/nuke
|
||||
reference = "NCQC"
|
||||
cost = 40
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT)
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/explosives/syndicate_bomb/nuke
|
||||
reference = "NSB"
|
||||
cost = 55
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT)
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA)
|
||||
hijack_only = FALSE
|
||||
|
||||
/datum/uplink_item/explosives/emp_bomb/nuke
|
||||
reference = "NSBEMP"
|
||||
cost = 50
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT)
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/explosives/atmosfiregrenades/nuke
|
||||
reference = "NAPG"
|
||||
cost = 60
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT)
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/stealthy_tools/chameleon/nuke
|
||||
reference = "NCHAM"
|
||||
item = /obj/item/storage/box/syndie_kit/chameleon/nuke
|
||||
cost = 30
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT)
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/stealthy_tools/syndigaloshes/nuke
|
||||
reference = "NNSSS"
|
||||
cost = 20
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT)
|
||||
excludefrom = list(UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/explosives/detomatix/nuclear
|
||||
desc = "When inserted into a personal digital assistant, this cartridge gives you five opportunities to detonate PDAs of crew members who have their message feature enabled. The concussive effect from the explosion will knock the recipient out for a short period, and deafen them for longer. It has a chance to detonate your PDA. This version comes with a program to toggle your nuclear shuttle blast doors remotely."
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
category = "Special Offers"
|
||||
can_discount = FALSE
|
||||
surplus = 0
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_TRAITOR, UPLINK_TYPE_SIT, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/special/autosurgeon
|
||||
name = "Syndicate Autosurgeon"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/datum/uplink_item/jobspecific
|
||||
category = "Job Specific Tools"
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) // Stops the job specific category appearing for nukies
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) // Stops the job specific category appearing for nukies
|
||||
|
||||
//Clown
|
||||
/datum/uplink_item/jobspecific/clowngrenade
|
||||
@@ -347,7 +347,7 @@
|
||||
reference = "PP"
|
||||
item = /obj/item/storage/box/syndie_kit/poisoner
|
||||
cost = 10
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
job = list("Head of Personnel", "Quartermaster", "Cargo Technician", "Librarian", "Coroner", "Psychiatrist", "Virologist")
|
||||
|
||||
// Tarot card generator, librarian and Chaplain.
|
||||
@@ -368,7 +368,7 @@
|
||||
|
||||
/datum/uplink_item/species_restricted
|
||||
category = "Species Specific Gear"
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) // Stops the job specific category appearing for nukies
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) // Stops the job specific category appearing for nukies
|
||||
|
||||
//skrell
|
||||
/datum/uplink_item/species_restricted/lovepen
|
||||
@@ -469,7 +469,7 @@
|
||||
reference = "BLSG"
|
||||
item = /obj/item/gun/projectile/automatic/shotgun/bulldog/traitor
|
||||
cost = 50
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/ammo/bull_rubbershot
|
||||
name = "Bulldog - 12g Rubbershot Magazine"
|
||||
@@ -477,7 +477,7 @@
|
||||
reference = "12BRU"
|
||||
item = /obj/item/ammo_box/magazine/m12g/rubbershot
|
||||
cost = 10
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/dangerous/guardian
|
||||
name = "Holoparasites"
|
||||
@@ -485,7 +485,7 @@
|
||||
desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an organic host as a home base and source of fuel. \
|
||||
The holoparasites are unable to incoporate themselves to changeling and vampire agents."
|
||||
item = /obj/item/storage/box/syndie_kit/guardian/uplink
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
cost = 60
|
||||
refund_path = /obj/item/guardiancreator/tech/choose
|
||||
refundable = TRUE
|
||||
@@ -506,7 +506,7 @@
|
||||
reference = "SCS"
|
||||
item = /obj/item/sleeping_carp_scroll
|
||||
cost = 65
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
can_discount = FALSE
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/bearserk
|
||||
@@ -525,7 +525,7 @@
|
||||
reference = "SBM"
|
||||
item = /obj/item/storage/belt/military/traitor
|
||||
cost = 10
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/stealthy_tools/frame
|
||||
name = "F.R.A.M.E. PDA Cartridge"
|
||||
@@ -535,7 +535,7 @@
|
||||
telecrystals normally."
|
||||
reference = "FRAME"
|
||||
item = /obj/item/cartridge/frame
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
cost = 20
|
||||
|
||||
/datum/uplink_item/stealthy_tools/voice_modulator
|
||||
@@ -589,7 +589,7 @@
|
||||
reference = "CGM"
|
||||
item = /obj/item/clothing/gloves/color/black/krav_maga
|
||||
cost = 50
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/device_tools/extraction_beacon
|
||||
name = "Extraction Flare"
|
||||
@@ -597,7 +597,7 @@
|
||||
reference = "EXTF"
|
||||
item = /obj/item/wormhole_jaunter/extraction
|
||||
limited_stock = 1
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/device_tools/hyper_medipen
|
||||
name = "Hyper-regenerative Medipen"
|
||||
@@ -615,7 +615,7 @@
|
||||
item = /obj/item/thermal_drill/syndicate
|
||||
cost = 5
|
||||
surplus = 0 // I feel like its amazing for one objective and one objective only. Far too specific.
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/suits/modsuit
|
||||
name = "Syndicate MODsuit"
|
||||
@@ -628,7 +628,7 @@
|
||||
item = /obj/item/mod/control/pre_equipped/traitor
|
||||
cost = 30
|
||||
surplus = 60 //I have upped the chance of modsuits from 40, as I do feel they are much more worthwhile with the base modsuit no longer being 8 tc, and the high armor values of the elite.
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/suits/modsuit_elite
|
||||
name = "Syndicate Elite MODsuit"
|
||||
@@ -638,7 +638,7 @@
|
||||
item = /obj/item/mod/control/pre_equipped/traitor_elite
|
||||
cost = 45 //45 to start, no holopara / ebow.
|
||||
surplus = 60
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
/// Nukies get Nuclear Uplink Bio-chip instead
|
||||
/datum/uplink_item/bio_chips/uplink
|
||||
@@ -647,7 +647,7 @@
|
||||
reference = "UI"
|
||||
item = /obj/item/bio_chip_implanter/uplink
|
||||
cost = 70
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
surplus = 0
|
||||
can_discount = FALSE
|
||||
|
||||
@@ -661,7 +661,7 @@
|
||||
reference = "QLSC"
|
||||
item = /obj/item/autosurgeon/organ/syndicate/oneuse/sensory_enhancer
|
||||
cost = 40
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST) //No, nukies do not get to dodge bullets.
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA) //No, nukies do not get to dodge bullets.
|
||||
|
||||
/datum/uplink_item/species_restricted/skinmonger
|
||||
name = "Skinmonger Autoimplanter"
|
||||
@@ -680,7 +680,7 @@
|
||||
reference = "SPC"
|
||||
item = /obj/item/deck/cards/syndicate
|
||||
cost = 2
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
surplus = 40
|
||||
|
||||
/datum/uplink_item/badass/plasticbag
|
||||
@@ -689,7 +689,7 @@
|
||||
reference = "PBAG"
|
||||
item = /obj/item/storage/bag/plasticbag
|
||||
cost = 1
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/bundles_tc/contractor
|
||||
name = "Syndicate Contractor Kit"
|
||||
@@ -697,7 +697,7 @@
|
||||
reference = "SCOK"
|
||||
cost = 100
|
||||
item = /obj/item/storage/box/syndie_kit/contractor
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/bundles_tc/contractor/spawn_item(turf/loc, obj/item/uplink/U)
|
||||
var/datum/mind/mind = usr.mind
|
||||
@@ -729,7 +729,7 @@
|
||||
reference = "SYB"
|
||||
item = /obj/item/beacon/syndicate/bundle
|
||||
cost = 100
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/bundles_tc/surplus_crate
|
||||
name = "Syndicate Surplus Crate"
|
||||
@@ -737,7 +737,7 @@
|
||||
reference = "SYSC"
|
||||
cost = 100
|
||||
item = /obj/item/storage/box/syndie_kit/bundle
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
var/crate_value = 250
|
||||
uses_special_spawn = TRUE
|
||||
|
||||
@@ -768,7 +768,7 @@
|
||||
reference = "SB"
|
||||
item = /obj/item/beacon/syndicate/bomb
|
||||
cost = 40
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
surplus = 0
|
||||
hijack_only = TRUE
|
||||
|
||||
@@ -779,7 +779,7 @@
|
||||
reference = "SBEMP"
|
||||
item = /obj/item/beacon/syndicate/bomb/emp
|
||||
cost = 40
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
surplus = 0
|
||||
can_discount = FALSE
|
||||
|
||||
@@ -794,7 +794,7 @@
|
||||
reference = "APG"
|
||||
item = /obj/item/storage/box/syndie_kit/atmosfiregrenades
|
||||
cost = 50
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
surplus = 0
|
||||
hijack_only = TRUE
|
||||
|
||||
@@ -822,4 +822,4 @@
|
||||
reference = "DEPC"
|
||||
item = /obj/item/cartridge/syndicate
|
||||
cost = 30
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
|
||||
excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST, UPLINK_TYPE_NINJA)
|
||||
|
||||
@@ -74,6 +74,8 @@
|
||||
var/list/datum/mind/wizards = list()
|
||||
/// A list of all minds that are wizard apprentices
|
||||
var/list/datum/mind/apprentices = list()
|
||||
/// A list of all minds that are ninjas
|
||||
var/list/datum/mind/ninjas = list()
|
||||
|
||||
/// The cult team datum
|
||||
var/datum/team/cult/cult_team
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
#define NINJA_OBJECTIVE_EASY 10
|
||||
#define NINJA_OBJECTIVE_NORMAL 20
|
||||
#define NINJA_OBJECTIVE_HARD 40
|
||||
|
||||
/datum/objective/ninja
|
||||
/// Can you only roll this objective once?
|
||||
var/onlyone = FALSE
|
||||
/// Does this objective come with special gear
|
||||
var/special_equipment_path
|
||||
/// Rewarded currency for objective completion
|
||||
var/reward_tc = NINJA_OBJECTIVE_EASY
|
||||
|
||||
/datum/objective/ninja/New(text, datum/team/team_to_join, datum/mind/_owner)
|
||||
. = ..()
|
||||
if(special_equipment_path)
|
||||
addtimer(CALLBACK(src, PROC_REF(hand_out_equipment)), 3 SECONDS, TIMER_DELETE_ME)
|
||||
|
||||
/datum/objective/ninja/proc/hand_out_equipment()
|
||||
give_kit(special_equipment_path)
|
||||
|
||||
/datum/objective/ninja/is_invalid_target(datum/mind/possible_target)
|
||||
. = ..()
|
||||
if(possible_target.current)
|
||||
var/turf/current_location = get_turf(possible_target.current)
|
||||
if(current_location && !is_station_level(current_location.z))
|
||||
return TARGET_INVALID_UNREACHABLE
|
||||
|
||||
/datum/objective/ninja/proc/complete_objective()
|
||||
for(var/datum/mind/M in get_owners())
|
||||
var/mob/living/carbon/human/H = M.current
|
||||
if(!ishuman(H))
|
||||
continue
|
||||
var/obj/item/bio_chip/uplink/ninja/nuplink = locate(/obj/item/bio_chip/uplink/ninja) in H
|
||||
if(!nuplink)
|
||||
continue
|
||||
nuplink.hidden_uplink.uses += reward_tc
|
||||
completed = TRUE
|
||||
|
||||
/datum/objective/ninja/proc/check_objective_conditions()
|
||||
return TRUE
|
||||
|
||||
/datum/objective/ninja/kill
|
||||
name = "Kill a Target"
|
||||
reward_tc = NINJA_OBJECTIVE_NORMAL
|
||||
|
||||
/datum/objective/ninja/kill/update_explanation_text()
|
||||
if(target?.current)
|
||||
explanation_text = "Kill [target.current.real_name], the [target.assigned_role]. Scan the corpse with your scanner to verify that the deed is done."
|
||||
var/datum/job/target_job = SSjobs.GetJob(target.assigned_role)
|
||||
if(target_job.job_department_flags & DEP_FLAG_COMMAND || target_job.job_department_flags & DEP_FLAG_SECURITY)
|
||||
reward_tc = NINJA_OBJECTIVE_HARD
|
||||
|
||||
/datum/objective/ninja/capture
|
||||
name = "Capture a Target"
|
||||
reward_tc = NINJA_OBJECTIVE_NORMAL
|
||||
/// The kidnapee's belongings. Set upon capture.
|
||||
var/list/obj/item/victim_belongings = null
|
||||
/// Temporary objects that are available to the kidnapee during their time in jail. These are deleted when the victim is returned.
|
||||
var/list/obj/temp_objs = null
|
||||
/// Prisoner jail timer handle. On completion, returns the prisoner back to station.
|
||||
var/prisoner_timer_handle = null
|
||||
|
||||
/datum/objective/ninja/capture/update_explanation_text()
|
||||
if(target?.current)
|
||||
explanation_text = "Capture [target.current.real_name], the [target.assigned_role]. Use your energy net to capture them so that we can interrogate them at one of our many secret dojos."
|
||||
var/datum/job/target_job = SSjobs.GetJob(target.assigned_role)
|
||||
if(target_job.job_department_flags & DEP_FLAG_COMMAND || target_job.job_department_flags & DEP_FLAG_SECURITY)
|
||||
reward_tc = NINJA_OBJECTIVE_HARD
|
||||
if(target_job.job_department_flags & DEP_FLAG_SERVICE)
|
||||
reward_tc = NINJA_OBJECTIVE_EASY
|
||||
|
||||
/datum/objective/ninja/capture/proc/handle_capture(mob/living/sucker, turf/T)
|
||||
var/mob/living/carbon/human/H = sucker
|
||||
|
||||
// Prepare their return
|
||||
prisoner_timer_handle = addtimer(CALLBACK(src, PROC_REF(handle_target_return), sucker, T), rand(3 MINUTES, 5 MINUTES), TIMER_STOPPABLE)
|
||||
|
||||
LAZYSET(GLOB.prisoner_belongings.prisoners, sucker, src)
|
||||
|
||||
// Shove all of the victim's items in the secure locker.
|
||||
victim_belongings = list()
|
||||
var/list/obj/item/stuff_to_transfer = list()
|
||||
|
||||
// Cybernetic implants get removed first (to deal with NODROP stuff)
|
||||
for(var/obj/item/organ/internal/cyberimp/I in H.internal_organs)
|
||||
// Greys get to keep their implant
|
||||
if(isgrey(H) && istype(I, /obj/item/organ/internal/cyberimp/brain/speech_translator))
|
||||
continue
|
||||
// IPCs keep this implant, free of charge!
|
||||
if(ismachineperson(H) && istype(I, /obj/item/organ/internal/cyberimp/arm/power_cord))
|
||||
continue
|
||||
// Try removing it
|
||||
I = I.remove(H)
|
||||
if(I)
|
||||
stuff_to_transfer += I
|
||||
|
||||
// Skrell headpocket. They already have a check in place to limit what's placed in them.
|
||||
var/obj/item/organ/internal/headpocket/C = H.get_int_organ(/obj/item/organ/internal/headpocket)
|
||||
if(C?.held_item)
|
||||
GLOB.prisoner_belongings.give_item(C.held_item)
|
||||
victim_belongings += C.held_item
|
||||
C.held_item = null
|
||||
|
||||
if(sucker.back) // Lets not bork modsuits in funny ways.
|
||||
var/obj/modsuit_safety = sucker.back
|
||||
sucker.drop_item_to_ground(modsuit_safety)
|
||||
stuff_to_transfer += modsuit_safety
|
||||
// Regular items get removed in second
|
||||
for(var/obj/item/I in sucker)
|
||||
// Keep their uniform and shoes
|
||||
if(I == H.w_uniform || I == H.shoes)
|
||||
continue
|
||||
// Plasmamen are no use if they're crispy
|
||||
if(isplasmaman(H) && I == H.head)
|
||||
continue
|
||||
|
||||
// Any kind of implant gets potentially removed (mindshield, freedoms, etc)
|
||||
if(istype(I, /obj/item/bio_chip))
|
||||
if(istype(I, /obj/item/bio_chip/storage)) // Storage items are removed and placed in the confiscation locker before the implant is taken.
|
||||
var/obj/item/bio_chip/storage/storage_chip = I
|
||||
for(var/it in storage_chip.storage)
|
||||
storage_chip.storage.remove_from_storage(it)
|
||||
stuff_to_transfer += it
|
||||
qdel(I)
|
||||
continue
|
||||
|
||||
if(sucker.drop_item_to_ground(I))
|
||||
stuff_to_transfer += I
|
||||
|
||||
// Remove accessories from the suit if present
|
||||
if(length(H.w_uniform?.accessories))
|
||||
for(var/obj/item/clothing/accessory/A in H.w_uniform.accessories)
|
||||
H.w_uniform.detach_accessory(A, null)
|
||||
H.drop_item_to_ground(A)
|
||||
stuff_to_transfer += A
|
||||
|
||||
// Transfer it all (or drop it if not possible)
|
||||
for(var/obj/item/i as anything in stuff_to_transfer)
|
||||
if(GLOB.prisoner_belongings.give_item(i))
|
||||
victim_belongings += i
|
||||
else if(!((ABSTRACT|NODROP) in i.flags)) // Anything that can't be put on hold, just drop it on the ground
|
||||
i.forceMove(T)
|
||||
|
||||
// Give some species the necessary to survive. Courtesy of the Syndicate.
|
||||
if(istype(H))
|
||||
var/obj/item/tank/internals/emergency_oxygen/tank
|
||||
var/obj/item/clothing/mask/breath/mask
|
||||
if(isvox(H))
|
||||
tank = new /obj/item/tank/internals/emergency_oxygen/nitrogen(H)
|
||||
mask = new /obj/item/clothing/mask/breath/vox(H)
|
||||
else if(isplasmaman(H))
|
||||
tank = new /obj/item/tank/internals/emergency_oxygen/plasma(H)
|
||||
mask = new /obj/item/clothing/mask/breath(H)
|
||||
|
||||
if(tank)
|
||||
H.equip_to_appropriate_slot(tank)
|
||||
H.equip_to_appropriate_slot(mask)
|
||||
tank.toggle_internals(H, TRUE)
|
||||
|
||||
sucker.reagents.add_reagent("mutadone", 1) // 1u of mutadone for the Hulk:tm: experience
|
||||
sucker.update_icons()
|
||||
|
||||
// Supply them with some chow. How generous is the Syndicate?
|
||||
var/obj/item/food/sliced/bread/food = new(get_turf(sucker))
|
||||
food.name = "stale bread"
|
||||
food.desc = "Looks like your captors care for their prisoners as much as their bread."
|
||||
food.trash = null
|
||||
if(prob(10))
|
||||
// Mold adds a bit of spice to it
|
||||
food.name = "moldy bread"
|
||||
food.reagents.add_reagent("fungus", 1)
|
||||
|
||||
var/obj/item/reagent_containers/drinks/drinkingglass/drink = new(get_turf(sucker))
|
||||
drink.reagents.add_reagent("tea", 25) // British coders beware, tea in glasses
|
||||
|
||||
var/obj/item/coin/antagtoken/passingtime = new(get_turf(sucker))
|
||||
|
||||
temp_objs = list(food, drink, passingtime)
|
||||
|
||||
// Narrate their kidnapping and torturing experience.
|
||||
if(sucker.stat != DEAD)
|
||||
// Heal them up - gets them out of crit/soft crit.
|
||||
sucker.reagents.add_reagent("omnizine", 10)
|
||||
|
||||
to_chat(sucker, SPAN_WARNING("You feel strange..."))
|
||||
sucker.Paralyse(30 SECONDS)
|
||||
sucker.EyeBlind(35 SECONDS)
|
||||
sucker.EyeBlurry(35 SECONDS)
|
||||
sucker.AdjustConfused(35 SECONDS)
|
||||
|
||||
for(var/mob/living/simple_animal/hostile/guardian/G in GLOB.alive_mob_list)
|
||||
if(G.summoner == sucker)
|
||||
sucker.remove_guardian_actions()
|
||||
to_chat(G, SPAN_DANGER("You feel your body ripped to shreds as you're forcibly removed from your summoner!"))
|
||||
to_chat(sucker, SPAN_WARNING("You feel some part of you missing, you're not who you used to be..."))
|
||||
G.ghostize()
|
||||
qdel(G)
|
||||
|
||||
sleep(6 SECONDS)
|
||||
to_chat(sucker, SPAN_WARNING("That portal did something to you..."))
|
||||
|
||||
sleep(6.5 SECONDS)
|
||||
to_chat(sucker, SPAN_WARNING("Your head pounds... It feels like it's going to burst out your skull!"))
|
||||
|
||||
sleep(3 SECONDS)
|
||||
to_chat(sucker, SPAN_WARNING("Your head pounds..."))
|
||||
|
||||
sleep(10 SECONDS)
|
||||
to_chat(sucker, "<span class='specialnotice'>A million voices echo in your head... <i>\"Your mind held many valuable secrets - \
|
||||
we thank you for providing them. Your value is expended, and you will be ransomed back to your station. We always get paid, \
|
||||
so it's only a matter of time before we send you back...\"</i></span>")
|
||||
|
||||
to_chat(sucker, SPAN_DANGER("<font size=3>You have been kidnapped and interrogated for valuable information! You will be sent back to the station in a few minutes...</font>"))
|
||||
|
||||
/datum/objective/ninja/capture/proc/handle_target_return(mob/living/M, turf/T)
|
||||
// Make a closet to return the target and their items neatly
|
||||
var/obj/structure/closet/closet = new(T)
|
||||
|
||||
// Return their items
|
||||
for(var/i in victim_belongings)
|
||||
var/obj/item/I = GLOB.prisoner_belongings.remove_item(i)
|
||||
if(!I)
|
||||
continue
|
||||
I.forceMove(closet)
|
||||
|
||||
victim_belongings = list()
|
||||
|
||||
// Clean up
|
||||
var/obj/item/bio_chip/uplink/uplink_implant = locate() in M
|
||||
uplink_implant?.hidden_uplink?.is_jammed = FALSE
|
||||
|
||||
QDEL_LIST_CONTENTS(temp_objs)
|
||||
|
||||
// Injuries due to questioning
|
||||
injure_target(M)
|
||||
|
||||
// Return them a bit confused.
|
||||
M.visible_message(SPAN_NOTICE("[M] vanishes..."))
|
||||
M.forceMove(closet)
|
||||
M.Paralyse(3 SECONDS)
|
||||
M.EyeBlurry(5 SECONDS)
|
||||
M.AdjustConfused(5 SECONDS)
|
||||
M.Dizzy(70 SECONDS)
|
||||
do_sparks(4, FALSE, T)
|
||||
|
||||
prisoner_timer_handle = null
|
||||
GLOB.prisoner_belongings.prisoners[M] = null
|
||||
|
||||
/datum/objective/ninja/capture/proc/injure_target(mob/living/M)
|
||||
var/obj/item/organ/external/injury_target
|
||||
if(prob(20)) // See if they're !!!lucky!!! enough to just chop a hand or foot off first, or even !!LUCKIER!! that it chose an already amputated limb
|
||||
injury_target = M.get_organ(pick(BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT))
|
||||
if(!injury_target)
|
||||
return
|
||||
default_damage(M)
|
||||
injury_target.droplimb()
|
||||
to_chat(M, SPAN_WARNING("You were interrogated by your captors before being sent back! Oh god, something's missing!"))
|
||||
return
|
||||
// Species specific punishments first
|
||||
if(ismachineperson(M))
|
||||
M.emp_act(EMP_HEAVY)
|
||||
M.adjustBrainLoss(30)
|
||||
to_chat(M, SPAN_WARNING("You were interrogated by your captors before being sent back! You feel like some of your components are loose!"))
|
||||
return
|
||||
default_damage(M) // Now that we won't accidentally kill an IPC we can make everyone take damage
|
||||
if(isslimeperson(M))
|
||||
injury_target = M.get_organ(pick(BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT))
|
||||
if(!injury_target)
|
||||
return
|
||||
injury_target.cause_internal_bleeding()
|
||||
injury_target = M.get_organ(BODY_ZONE_CHEST)
|
||||
injury_target.cause_internal_bleeding()
|
||||
to_chat(M, SPAN_WARNING("You were interrogated by your captors before being sent back! You feel like your inner membrane has been punctured!"))
|
||||
return
|
||||
if(prob(25)) // You either get broken ribs, or a broken limb and IB if you made it this far
|
||||
injury_target = M.get_organ(BODY_ZONE_CHEST)
|
||||
injury_target.fracture()
|
||||
else
|
||||
injury_target = M.get_organ(pick(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_R_LEG))
|
||||
if(!injury_target)
|
||||
return
|
||||
injury_target.fracture()
|
||||
injury_target.cause_internal_bleeding()
|
||||
|
||||
/datum/objective/ninja/capture/proc/default_damage(mob/living/M)
|
||||
M.adjustBruteLoss(40)
|
||||
M.adjustBrainLoss(25)
|
||||
|
||||
/datum/objective/ninja/hack_rnd
|
||||
name = "Hack RnD"
|
||||
explanation_text = "A client wants access to Nanotrasen's research databank. Use your scanner on their servers to give them a way inside."
|
||||
needs_target = FALSE
|
||||
onlyone = TRUE
|
||||
|
||||
/datum/objective/ninja/interrogate_ai
|
||||
name = "Interrogate AI"
|
||||
explanation_text = "We wish to expunge some data from their AI system. Use your scanner on an active AI core to wirelessly transfer it to us for interrogation."
|
||||
needs_target = FALSE
|
||||
onlyone = TRUE
|
||||
reward_tc = NINJA_OBJECTIVE_HARD
|
||||
|
||||
/datum/objective/ninja/interrogate_ai/check_objective_conditions() // If there is no AI, you don't get the objective.
|
||||
if(!length(GLOB.ai_list))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/objective/ninja/steal_supermatter
|
||||
name = "Steal Supermatter"
|
||||
explanation_text = "Steal the supermatter crystal, using the net gun we have modified for you. The crystal will sell well to the highest bidder."
|
||||
needs_target = FALSE
|
||||
onlyone = TRUE
|
||||
reward_tc = NINJA_OBJECTIVE_HARD
|
||||
|
||||
/datum/objective/ninja/steal_supermatter/check_objective_conditions() // If there is no supermatter, you don't get the objective.
|
||||
return !isnull(GLOB.main_supermatter_engine)
|
||||
|
||||
/datum/objective/ninja/insert_spider_rod
|
||||
name = "Sabotage Fission Reactor"
|
||||
explanation_text = "Insert a spider-clan uranium 238 fuel rod into the station's fission reactor, then scan the reactor chamber while it is active."
|
||||
needs_target = FALSE
|
||||
onlyone = TRUE
|
||||
reward_tc = NINJA_OBJECTIVE_HARD
|
||||
special_equipment_path = /obj/item/beacon/ninja_rod_spawner
|
||||
|
||||
/datum/objective/ninja/insert_spider_rod/check_objective_conditions() // If there is no reactor, you don't get the objective.
|
||||
return !isnull(GLOB.main_fission_reactor)
|
||||
|
||||
/datum/objective/ninja/bomb_department
|
||||
name = "Bomb Department"
|
||||
needs_target = FALSE
|
||||
special_equipment_path = /obj/item/wormhole_jaunter/ninja_bomb
|
||||
explanation_text = "Use the special flare provided to call down and arm a spider bomb. The target department is inscribed on the flare."
|
||||
reward_tc = NINJA_OBJECTIVE_NORMAL
|
||||
|
||||
/datum/objective/ninja/bomb_department/emp
|
||||
name = "EMP Department"
|
||||
explanation_text = "Use the special flare provided to call down and arm an EMP bomb. The target department is inscribed on the flare."
|
||||
special_equipment_path = /obj/item/wormhole_jaunter/ninja_bomb/emp
|
||||
|
||||
/datum/objective/ninja/bomb_department/spiders
|
||||
name = "Spider Bomb Department"
|
||||
explanation_text = "Use the special flare provided to call down and arm a Spider bomb. The target department is inscribed on the flare."
|
||||
special_equipment_path = /obj/item/wormhole_jaunter/ninja_bomb/spiders
|
||||
|
||||
/datum/objective/ninja_exfiltrate
|
||||
name = "Exfiltrate"
|
||||
explanation_text = "Use your exfiltration flare to escape the station when your work is done."
|
||||
needs_target = FALSE
|
||||
|
||||
#undef NINJA_OBJECTIVE_EASY
|
||||
#undef NINJA_OBJECTIVE_NORMAL
|
||||
#undef NINJA_OBJECTIVE_HARD
|
||||
@@ -1014,6 +1014,17 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
|
||||
add_fingerprint(user)
|
||||
if(!headbutt_shock_check(user))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(istype(used, /obj/item/katana/energy) && user.a_intent == INTENT_HELP)
|
||||
if(locked)
|
||||
if(!do_after_once(user, 5 SECONDS, TRUE, src, allow_moving = FALSE, must_be_held = FALSE))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
unlock()
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
else
|
||||
if(!do_after_once(user, 2.5 SECONDS, TRUE, src, allow_moving = FALSE, must_be_held = FALSE))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
open()
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(panel_open)
|
||||
if(istype(used, /obj/item/kitchen/utensil/fork))
|
||||
return NONE
|
||||
|
||||
@@ -317,7 +317,11 @@
|
||||
//If it's in the process of opening/closing, ignore the click
|
||||
if(operating)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(istype(used, /obj/item/katana/energy) && user.a_intent == INTENT_HELP)
|
||||
if(!do_after_once(user, 2.5 SECONDS, TRUE, src, allow_moving = FALSE, must_be_held = FALSE))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
open()
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
add_fingerprint(user)
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -104,6 +104,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp
|
||||
name = "revenantspawn"
|
||||
icon_state = "Rev"
|
||||
|
||||
/obj/effect/landmark/spawner/ninja
|
||||
name = "ninjaspawn"
|
||||
|
||||
/obj/effect/landmark/spawner/bubblegum_arena
|
||||
name = "bubblegum_arena_human"
|
||||
icon_state = "Explorer"
|
||||
@@ -142,13 +145,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp
|
||||
spawner_list = GLOB.ertdirector
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/spawner/ninjastart
|
||||
name = "ninjastart"
|
||||
|
||||
/obj/effect/landmark/spawner/ninjastart/Initialize(mapload)
|
||||
spawner_list = GLOB.ninjastart
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/spawner/aroomwarp
|
||||
name = "aroomwarp"
|
||||
|
||||
@@ -198,6 +194,13 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp
|
||||
spawner_list = GLOB.syndieprisonwarp
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/spawner/ninja_prison_warp
|
||||
name = "ninja prison warp"
|
||||
|
||||
/obj/effect/landmark/spawner/ninja_prison_warp/Initialize(mapload)
|
||||
spawner_list = GLOB.ninjaprisonwarp
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/spawner/antag_extract_warp
|
||||
name = "antagextractwarp"
|
||||
|
||||
@@ -230,9 +233,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp
|
||||
/obj/effect/landmark/spawner/commando_manual
|
||||
name = "Deathsquad Commando Manual"
|
||||
|
||||
/obj/effect/landmark/spawner/holding_facility
|
||||
name = "Holding Facility"
|
||||
|
||||
/obj/effect/landmark/spawner/holocarp
|
||||
name = "Holocarp Spawn"
|
||||
|
||||
|
||||
@@ -44,6 +44,19 @@
|
||||
syndicate = TRUE
|
||||
emagged = TRUE
|
||||
|
||||
// Spawns a spider fuel rod for ninja objectives
|
||||
/obj/item/beacon/ninja_rod_spawner
|
||||
name = "spider clan beacon"
|
||||
desc = "A label on it reads: <i>Activate to have a spider clan brand fuel rod teleported to your location</i>."
|
||||
origin_tech = "bluespace=6;syndicate=3"
|
||||
|
||||
/obj/item/beacon/ninja_rod_spawner/attack_self__legacy__attackchain(mob/user)
|
||||
if(!user)
|
||||
return
|
||||
var/obj/item/nuclear_rod/fuel/uranium_238/spiders/new_rod = new(user.loc)
|
||||
qdel(src)
|
||||
user.put_in_hands(new_rod)
|
||||
|
||||
// SINGULO BEACON SPAWNER
|
||||
/obj/item/beacon/syndicate
|
||||
name = "suspicious beacon"
|
||||
|
||||
@@ -594,3 +594,34 @@
|
||||
playsound(src, pick('sound/weapons/bulletflyby.ogg','sound/weapons/bulletflyby2.ogg','sound/weapons/bulletflyby3.ogg'), 75, 1)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// MARK: KATANA
|
||||
/obj/item/katana
|
||||
name = "katana"
|
||||
desc = "Woefully underpowered in D20."
|
||||
icon = 'icons/obj/weapons/melee.dmi'
|
||||
icon_state = "katana"
|
||||
lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
|
||||
flags = CONDUCT
|
||||
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK
|
||||
flags_2 = ALLOW_BELT_NO_JUMPSUIT_2 // Look, you can strap it to your back. You can strap it to your waist too.
|
||||
force = 40
|
||||
throwforce = 10
|
||||
sharp = TRUE
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 50)
|
||||
resistance_flags = FIRE_PROOF
|
||||
needs_permit = TRUE
|
||||
|
||||
new_attack_chain = TRUE
|
||||
|
||||
/obj/item/katana/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES)
|
||||
|
||||
/obj/item/katana/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!</span>")
|
||||
return BRUTELOSS
|
||||
|
||||
@@ -78,34 +78,6 @@
|
||||
desc = "An engraved and fancy version of the claymore. It appears to be less sharp than it's more functional cousin."
|
||||
force = 20
|
||||
|
||||
/obj/item/katana
|
||||
name = "katana"
|
||||
desc = "Woefully underpowered in D20."
|
||||
icon = 'icons/obj/weapons/melee.dmi'
|
||||
icon_state = "katana"
|
||||
lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
|
||||
flags = CONDUCT
|
||||
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK
|
||||
flags_2 = ALLOW_BELT_NO_JUMPSUIT_2 //Look, you can strap it to your back. You can strap it to your waist too.
|
||||
force = 40
|
||||
throwforce = 10
|
||||
sharp = TRUE
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 50)
|
||||
resistance_flags = FIRE_PROOF
|
||||
needs_permit = TRUE
|
||||
|
||||
/obj/item/katana/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES)
|
||||
|
||||
/obj/item/katana/suicide_act(mob/user)
|
||||
user.visible_message(SPAN_SUICIDE("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!"))
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/harpoon
|
||||
name = "harpoon"
|
||||
desc = "Tharr she blows!"
|
||||
|
||||
@@ -76,35 +76,6 @@
|
||||
else
|
||||
icon_state = "signpost_wood"
|
||||
|
||||
/obj/structure/ninjatele
|
||||
name = "Long-Distance Teleportation Console"
|
||||
desc = "A console used to send a Spider Clan operative long distances rapidly."
|
||||
icon = 'icons/obj/ninjaobjects.dmi'
|
||||
icon_state = "teleconsole"
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/ninjatele/attack_hand(mob/user as mob)
|
||||
if(user.mind.special_role=="Ninja")
|
||||
switch(tgui_alert(user, "Phase Jaunt relay primed, target locked as [station_name()], initiate VOID-shift translocation? (Warning! Internals required!)", "Void Shift", list("Yes", "No")))
|
||||
if("Yes")
|
||||
if(user.z != src.z)
|
||||
return
|
||||
|
||||
user.loc.loc.Exited(user)
|
||||
user.loc = pick(GLOB.carplist) // In the future, possibly make specific NinjaTele landmarks, and give him an option to teleport to North/South/East/West of SS13 instead of just hijacking a carpspawn.
|
||||
|
||||
playsound(user.loc, 'sound/effects/phasein.ogg', 25, 1)
|
||||
playsound(user.loc, 'sound/effects/sparks2.ogg', 50, 1)
|
||||
new /obj/effect/temp_visual/dir_setting/ninja/phase(get_turf(user), user.dir)
|
||||
to_chat(user, "[SPAN_BOLDNOTICE("VOID-Shift")] translocation successful")
|
||||
|
||||
if("No")
|
||||
to_chat(user, SPAN_DANGER("Process aborted!"))
|
||||
return
|
||||
|
||||
else
|
||||
to_chat(user, "[SPAN_DANGER("FĆAL �Rr�R")]: ŧer nt recgnized, c-cntr-r䣧-ç äcked.")
|
||||
|
||||
/obj/structure/respawner
|
||||
name = "\improper Long-Distance Cloning Machine"
|
||||
desc = "Top-of-the-line Nanotrasen technology allows for cloning of crew members from off-station upon bluespace request."
|
||||
|
||||
@@ -433,8 +433,8 @@
|
||||
if(length(SSticker.mode.apprentices))
|
||||
dat += check_role_table("Apprentices", SSticker.mode.apprentices)
|
||||
|
||||
/*if(length(ticker.mode.ninjas))
|
||||
dat += check_role_table("Ninjas", ticker.mode.ninjas)*/
|
||||
if(length(SSticker.mode.ninjas))
|
||||
dat += check_role_table("Ninjas", SSticker.mode.ninjas)
|
||||
|
||||
if(SSticker.mode.cult_team)
|
||||
dat += check_role_table("Cultists", SSticker.mode.cult_team.members)
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
RESTRICT_TYPE(/datum/antagonist/space_ninja)
|
||||
|
||||
// Spider Clan Space Ninja
|
||||
/datum/antagonist/space_ninja
|
||||
name = "Space Ninja"
|
||||
roundend_category = "ninjas"
|
||||
job_rank = ROLE_NINJA
|
||||
special_role = SPECIAL_ROLE_NINJA
|
||||
antag_hud_name = "hud_ninja"
|
||||
antag_hud_type = ANTAG_HUD_NINJA
|
||||
clown_gain_text = "Your spider clan training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself."
|
||||
clown_removal_text = "You lose your spider clan training and return to your own clumsy, clownish self."
|
||||
wiki_page_name = "Space Ninja"
|
||||
var/give_uplink = TRUE
|
||||
blurb_r = 200
|
||||
blurb_a = 0.75
|
||||
boss_title = "Spider Clan Daimyo"
|
||||
/// Number of missions needed to complete
|
||||
var/mission_goal = 4
|
||||
|
||||
/datum/antagonist/space_ninja/on_gain()
|
||||
..()
|
||||
mission_goal = 4 + (length(GLOB.crew_list) / 10)
|
||||
SEND_SOUND(owner.current, sound('sound/ambience/antag/ninjaalert.ogg'))
|
||||
|
||||
/datum/antagonist/space_ninja/give_objectives()
|
||||
forge_objectives()
|
||||
|
||||
/datum/antagonist/space_ninja/exfiltrate(mob/living/carbon/human/extractor, obj/item/radio/radio)
|
||||
extractor.equipOutfit(/datum/outfit/admin/ghostbar_antag/space_ninja)
|
||||
radio.autosay("<b>--ZZZT!- Domo Ar!g@to, [extractor.real_name]. Your training paid -^%&!-ZZT!-</b>", "Spider Clan HQ", "Security")
|
||||
SSblackbox.record_feedback("tally", "successful_extraction", 1, "Space Ninja")
|
||||
|
||||
/datum/antagonist/space_ninja/finalize_antag()
|
||||
. = ..()
|
||||
equip_ninja()
|
||||
|
||||
/datum/antagonist/space_ninja/add_owner_to_gamemode()
|
||||
SSticker.mode.ninjas |= owner
|
||||
|
||||
/datum/antagonist/space_ninja/remove_owner_from_gamemode()
|
||||
SSticker.mode.ninjas -= owner
|
||||
|
||||
/datum/antagonist/space_ninja/proc/equip_ninja()
|
||||
if(!ishuman(owner.current))
|
||||
return
|
||||
var/mob/living/carbon/human/new_ninja = owner.current
|
||||
new_ninja.delete_equipment()
|
||||
if(isvox(new_ninja))
|
||||
new_ninja.equipOutfit(/datum/outfit/space_ninja/vox)
|
||||
else
|
||||
new_ninja.equipOutfit(/datum/outfit/space_ninja)
|
||||
|
||||
/datum/antagonist/space_ninja/proc/forge_objectives()
|
||||
var/list/moderate_objectives = list(
|
||||
/datum/objective/ninja/capture = 8,
|
||||
/datum/objective/ninja/kill = 8,
|
||||
/datum/objective/ninja/hack_rnd = 5,
|
||||
/datum/objective/ninja/bomb_department/emp = 3,
|
||||
/datum/objective/ninja/bomb_department/spiders = 3,
|
||||
)
|
||||
var/list/all_ninja_objectives = list(
|
||||
/datum/objective/ninja/capture = 8,
|
||||
/datum/objective/ninja/kill = 8,
|
||||
/datum/objective/ninja/hack_rnd = 4,
|
||||
/datum/objective/ninja/bomb_department = 3,
|
||||
/datum/objective/ninja/bomb_department/emp = 3,
|
||||
/datum/objective/ninja/bomb_department/spiders = 3,
|
||||
/datum/objective/ninja/steal_supermatter = 3,
|
||||
/datum/objective/ninja/insert_spider_rod = 3,
|
||||
/datum/objective/ninja/interrogate_ai = 3,
|
||||
)
|
||||
for(var/i in 1 to mission_goal)
|
||||
if(i <= mission_goal / 2) // This ensures some easier objectives are rolled to allow ninjas to work up to harder ones.
|
||||
forge_objective(moderate_objectives)
|
||||
continue
|
||||
forge_objective(all_ninja_objectives)
|
||||
add_antag_objective(/datum/objective/ninja_exfiltrate)
|
||||
|
||||
/datum/antagonist/space_ninja/proc/forge_objective(list/objective_list)
|
||||
|
||||
var/datum/objective/ninja/new_objective = pickweight(objective_list)
|
||||
var/datum/objective/ninja/obj_item = new new_objective() // Needed to do to check validity and reroll
|
||||
if(!obj_item.check_objective_conditions())
|
||||
forge_objective(objective_list)
|
||||
qdel(obj_item)
|
||||
return
|
||||
qdel(obj_item)
|
||||
if(new_objective.onlyone)
|
||||
var/list/current_objectives = get_antag_objectives()
|
||||
for(var/datum/objective/ninja/c_objective in current_objectives)
|
||||
if(istype(c_objective, new_objective))
|
||||
forge_objective(objective_list)
|
||||
return
|
||||
add_antag_objective(new_objective)
|
||||
@@ -7,6 +7,7 @@ GLOBAL_LIST_INIT(special_role_times, list(
|
||||
ROLE_TRAITOR = 7,
|
||||
ROLE_CHANGELING = 14,
|
||||
ROLE_WIZARD = 14,
|
||||
ROLE_NINJA = 14,
|
||||
ROLE_REV = 14,
|
||||
ROLE_VAMPIRE = 14,
|
||||
ROLE_BLOB = 14,
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
var/can_be_cut = 1
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/clothing/species/vox/gloves.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/skkulakin/gloves.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/vox/gloves.dmi',
|
||||
"Drask" = 'icons/mob/clothing/species/drask/gloves.dmi',
|
||||
"Grey" = 'icons/mob/clothing/species/grey/gloves.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/species/kidan/gloves.dmi',
|
||||
|
||||
@@ -177,7 +177,6 @@ GLOBAL_LIST_EMPTY(event_last_fired)
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/radiation_storm, 10, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/spider_infestation, 10, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/ion_storm, 10),
|
||||
//new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 15), TRUE),
|
||||
// NON-BAY EVENTS
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/mass_hallucination, 10),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/brand_intelligence, 5, TRUE),
|
||||
@@ -216,6 +215,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/demon_incursion, 10, TRUE, _first_run_time = 35 MINUTES),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/disease_outbreak, 8, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/revenant, 9),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/space_ninja, 9),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_morph, 16, is_one_shot = TRUE),
|
||||
//new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_floor_cluwne, 15, is_one_shot = TRUE)
|
||||
//new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_pulsedemon, 20, is_one_shot = TRUE)
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/datum/event/space_ninja
|
||||
name = "Space Ninja"
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 2)
|
||||
role_requirements = list(ASSIGNMENT_CREW = 20, ASSIGNMENT_SECURITY = 2)
|
||||
nominal_severity = EVENT_LEVEL_MAJOR
|
||||
|
||||
/datum/event/space_ninja/start()
|
||||
INVOKE_ASYNC(src, PROC_REF(poll_ninja))
|
||||
|
||||
/datum/event/space_ninja/proc/poll_ninja(list/potential_ninjas)
|
||||
var/list/candidates = list()
|
||||
if(!potential_ninjas)
|
||||
candidates = SSghost_spawns.poll_candidates("Do you want to play as a space ninja?", ROLE_NINJA, TRUE)
|
||||
else
|
||||
candidates = potential_ninjas
|
||||
if(!length(candidates))
|
||||
kill()
|
||||
return
|
||||
var/mob/new_ninja
|
||||
while(length(candidates))
|
||||
new_ninja = pick_n_take(candidates)
|
||||
if(jobban_isbanned(new_ninja, ROLE_TRAITOR))
|
||||
continue
|
||||
break
|
||||
if(!new_ninja)
|
||||
kill()
|
||||
return
|
||||
|
||||
var/gender_pref = input_async(new_ninja, "Please select a gender (10 seconds):", list("Male", "Female"))
|
||||
addtimer(CALLBACK(src, PROC_REF(get_species), candidates, new_ninja, gender_pref), 10 SECONDS)
|
||||
|
||||
/datum/event/space_ninja/proc/get_species(list/potential_ninjas, mob/new_ninja, datum/async_input/gender_pref)
|
||||
gender_pref.close()
|
||||
var/sel_gender = gender_pref.result
|
||||
if(!sel_gender) // Player was AFK and did not select a gender
|
||||
poll_ninja(potential_ninjas)
|
||||
return
|
||||
var/species_pref = input_async(new_ninja, "Please select a species (10 seconds):", list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin", "Nian", "Drask", "Kidan", "Grey", "Skkulakin", "Vox", "Slime", "Machine", "Random"))
|
||||
addtimer(CALLBACK(src, PROC_REF(create_ninja), potential_ninjas, new_ninja, sel_gender, species_pref), 10 SECONDS)
|
||||
|
||||
/datum/event/space_ninja/proc/create_ninja(list/potential_ninjas, mob/new_ninja, sel_gender, datum/async_input/species_pref)
|
||||
species_pref.close()
|
||||
var/sel_species = species_pref.result
|
||||
if(!sel_species) // Player was AFK and did not select a species
|
||||
poll_ninja(potential_ninjas)
|
||||
return
|
||||
if(!new_ninja || !new_ninja.client)
|
||||
poll_ninja(potential_ninjas)
|
||||
return
|
||||
|
||||
var/list/spawn_locs = list()
|
||||
for(var/obj/effect/landmark/spawner/ninja/N in GLOB.landmarks_list)
|
||||
spawn_locs += get_turf(N)
|
||||
if(!length(spawn_locs))
|
||||
message_admins("Unable to spawn ninja - no valid spawn locations.")
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/M = new(pick(spawn_locs))
|
||||
|
||||
M.ckey = new_ninja.ckey
|
||||
dust_if_respawnable(new_ninja)
|
||||
|
||||
if(sel_gender == "Male")
|
||||
M.change_gender(MALE)
|
||||
M.change_body_type(MALE)
|
||||
else
|
||||
M.change_gender(FEMALE)
|
||||
M.change_body_type(FEMALE)
|
||||
|
||||
if(sel_species == "Random")
|
||||
sel_species = pick("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin", "Nian", "Drask", "Kidan", "Grey", "Skkulakin", "Vox", "Slime", "Machine")
|
||||
if(sel_species == "Slime")
|
||||
sel_species = "Slime People"
|
||||
var/datum/species/S = GLOB.all_species[sel_species]
|
||||
var/species = S.type
|
||||
M.set_species(species, TRUE)
|
||||
M.dna.ready_dna(M)
|
||||
M.cleanSE()
|
||||
M.overeatduration = 0
|
||||
M.age = rand(23, 35)
|
||||
M.regenerate_icons()
|
||||
|
||||
M.mind = new
|
||||
M.mind.bind_to(M)
|
||||
M.mind.set_original_mob(M)
|
||||
M.mind.make_space_ninja()
|
||||
@@ -11,6 +11,11 @@
|
||||
permeability_coefficient = 0.01
|
||||
sprite_sheets = list(
|
||||
"Grey" = 'icons/mob/clothing/modsuit/species/grey_helmets.dmi',
|
||||
"Skrell" = 'icons/mob/clothing/modsuit/species/skrell_modsuits.dmi',
|
||||
"Nian" = 'icons/mob/clothing/modsuit/species/nian_modsuits.dmi',
|
||||
"Diona" = 'icons/mob/clothing/modsuit/species/diona_modsuits.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/modsuit/species/kidan_modsuits.dmi',
|
||||
"Drask" = 'icons/mob/clothing/modsuit/species/drask_modsuits.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/modsuit/species/vulp_modsuits.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/modsuit/species/taj_modsuits.dmi',
|
||||
"Unathi" = 'icons/mob/clothing/modsuit/species/unathi_modsuits.dmi',
|
||||
@@ -37,13 +42,17 @@
|
||||
insert_max = 0
|
||||
hide_tail_by_species = list("modsuit")
|
||||
sprite_sheets = list(
|
||||
"Skrell" = 'icons/mob/clothing/modsuit/species/skrell_modsuits.dmi',
|
||||
"Nian" = 'icons/mob/clothing/modsuit/species/nian_modsuits.dmi',
|
||||
"Diona" = 'icons/mob/clothing/modsuit/species/diona_modsuits.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/modsuit/species/kidan_modsuits.dmi',
|
||||
"Drask" = 'icons/mob/clothing/modsuit/species/drask_modsuits.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/modsuit/species/vulp_modsuits.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/modsuit/species/taj_modsuits.dmi',
|
||||
"Unathi" = 'icons/mob/clothing/modsuit/species/unathi_modsuits.dmi',
|
||||
"Vox" = 'icons/mob/clothing/modsuit/species/vox_modsuits.dmi'
|
||||
)
|
||||
|
||||
|
||||
/obj/item/clothing/gloves/mod
|
||||
name = "MOD gauntlets"
|
||||
desc = "A pair of gauntlets for a MODsuit."
|
||||
@@ -56,13 +65,17 @@
|
||||
cold_protection = HANDS|ARMS
|
||||
permeability_coefficient = 0.01
|
||||
sprite_sheets = list(
|
||||
"Skrell" = 'icons/mob/clothing/modsuit/species/skrell_modsuits.dmi',
|
||||
"Nian" = 'icons/mob/clothing/modsuit/species/nian_modsuits.dmi',
|
||||
"Diona" = 'icons/mob/clothing/modsuit/species/diona_modsuits.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/modsuit/species/kidan_modsuits.dmi',
|
||||
"Drask" = 'icons/mob/clothing/modsuit/species/drask_modsuits.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/modsuit/species/vulp_modsuits.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/modsuit/species/taj_modsuits.dmi',
|
||||
"Unathi" = 'icons/mob/clothing/modsuit/species/unathi_modsuits.dmi',
|
||||
"Vox" = 'icons/mob/clothing/modsuit/species/vox_modsuits.dmi'
|
||||
)
|
||||
|
||||
|
||||
/obj/item/clothing/shoes/mod
|
||||
name = "MOD boots"
|
||||
desc = "A pair of boots for a MODsuit."
|
||||
@@ -75,6 +88,11 @@
|
||||
cold_protection = FEET|LEGS
|
||||
permeability_coefficient = 0.01
|
||||
sprite_sheets = list(
|
||||
"Skrell" = 'icons/mob/clothing/modsuit/species/skrell_modsuits.dmi',
|
||||
"Nian" = 'icons/mob/clothing/modsuit/species/nian_modsuits.dmi',
|
||||
"Diona" = 'icons/mob/clothing/modsuit/species/diona_modsuits.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/modsuit/species/kidan_modsuits.dmi',
|
||||
"Drask" = 'icons/mob/clothing/modsuit/species/drask_modsuits.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/modsuit/species/vulp_modsuits.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/modsuit/species/taj_modsuits.dmi',
|
||||
"Unathi" = 'icons/mob/clothing/modsuit/species/unathi_modsuits.dmi',
|
||||
|
||||
@@ -1384,3 +1384,58 @@
|
||||
/// considering this should not be used, it's getting just DS armor, not infinity in everything.
|
||||
/obj/item/mod/armor/mod_theme_administrative
|
||||
armor = list(MELEE = 200, BULLET = 200, LASER = 50, ENERGY = 50, BOMB = INFINITY, RAD = INFINITY, FIRE = INFINITY, ACID = INFINITY)
|
||||
|
||||
/datum/mod_theme/ninja
|
||||
name = "'Shinobi' stealthsuit"
|
||||
desc = "A specialized modsuit worn by the spider clan's elite ninja operatives."
|
||||
default_skin = "ninja"
|
||||
armor_type_1 = /obj/item/mod/armor/mod_theme_ninja
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
flag_2_flags = RAD_PROTECT_CONTENTS_2
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
siemens_coefficient = 0
|
||||
slowdown_inactive = 1
|
||||
slowdown_active = 0.3
|
||||
ui_theme = "syndicate"
|
||||
allowed_suit_storage = list(
|
||||
/obj/item/katana/energy,
|
||||
/obj/item/wormhole_jaunter/ninja_bomb,
|
||||
/obj/item/throwing_star,
|
||||
/obj/item/restraints/legcuffs/bola,
|
||||
/obj/item/gun,
|
||||
/obj/item/ninja_scanner,
|
||||
)
|
||||
skins = list(
|
||||
"ninja" = list(
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_LAYER = null,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDMAGE | BLOCKHAIR,
|
||||
UNSEALED_INVISIBILITY = HIDEFACE,
|
||||
SEALED_INVISIBILITY = HIDEMASK | HIDEEYES | HIDEEARS | HIDEFACE,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH,
|
||||
SEALED_COVER = HEADCOVERSEYES,
|
||||
CAN_OVERSLOT = TRUE,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT | HIDETAIL,
|
||||
CAN_OVERSLOT = TRUE,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDMAGE,
|
||||
CAN_OVERSLOT = TRUE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDMAGE,
|
||||
CAN_OVERSLOT = TRUE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/obj/item/mod/armor/mod_theme_ninja
|
||||
|
||||
armor = list(MELEE = 50, BULLET = 35, LASER = 35, ENERGY = 30, BOMB = 25, RAD = 200, FIRE = INFINITY, ACID = INFINITY)
|
||||
|
||||
@@ -569,6 +569,25 @@
|
||||
/obj/item/mod/module/jetpack/advanced,
|
||||
)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/ninja
|
||||
icon_state = "ninja-control"
|
||||
theme = /datum/mod_theme/ninja
|
||||
starting_frequency = MODLINK_FREQ_SYNDICATE
|
||||
applied_cell = /obj/item/stock_parts/cell/bluespace
|
||||
applied_modules = list(
|
||||
/obj/item/mod/module/storage/syndicate,
|
||||
/obj/item/mod/module/jetpack/advanced,
|
||||
/obj/item/mod/module/dispenser/smoke,
|
||||
/obj/item/mod/module/shinobi_stealth,
|
||||
/obj/item/mod/module/shinobi_freedom,
|
||||
/obj/item/mod/module/shinobi_stims,
|
||||
/obj/item/mod/module/noslip,
|
||||
)
|
||||
default_pins = list(
|
||||
/obj/item/mod/module/jetpack/advanced,
|
||||
/obj/item/mod/module/dispenser/smoke,
|
||||
)
|
||||
|
||||
//these exist for the prefs menu
|
||||
/obj/item/mod/control/pre_equipped/empty
|
||||
starting_frequency = null
|
||||
|
||||
@@ -641,3 +641,77 @@
|
||||
/obj/item/mod/module/anomaly_locked/teslawall/prebuilt
|
||||
prebuilt = TRUE
|
||||
removable = FALSE // No switching it into another suit / no free anomaly core
|
||||
|
||||
/obj/item/mod/module/shinobi_stealth
|
||||
name = "MOD shinobi stealth module"
|
||||
desc = "An advanced module, designed by the Spider Clan, that replicates the advanced stealth technology in the classic ninja scarf."
|
||||
icon_state = "armor_booster"
|
||||
origin_tech = "combat=5;bluespace=6;syndicate=4"
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
|
||||
removable = FALSE
|
||||
/// Linked sneaking action
|
||||
var/datum/action/cooldown/ninja/ninja_cloak/cloak_action
|
||||
|
||||
/obj/item/mod/module/shinobi_stealth/Initialize(mapload)
|
||||
. = ..()
|
||||
cloak_action = new(src)
|
||||
|
||||
/obj/item/mod/module/shinobi_stealth/on_suit_activation()
|
||||
. = ..()
|
||||
cloak_action.Grant(mod.wearer)
|
||||
|
||||
/obj/item/mod/module/shinobi_stealth/on_suit_deactivation(deleting = FALSE)
|
||||
if(deleting)
|
||||
return
|
||||
cloak_action.stop_sneaking()
|
||||
cloak_action.Remove(mod.wearer)
|
||||
|
||||
/obj/item/mod/module/shinobi_freedom
|
||||
name = "MOD shinobi escape module"
|
||||
desc = "An advanced module, designed by the Spider Clan, that replicates the advanced escaping technology in the classic ninja boots."
|
||||
icon_state = "armor_booster"
|
||||
origin_tech = "combat=5;bluespace=6;syndicate=4"
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
|
||||
removable = FALSE
|
||||
/// Linked freedom action
|
||||
var/datum/action/cooldown/ninja/freedom_shoes/freedoms_action
|
||||
|
||||
/obj/item/mod/module/shinobi_freedom/Initialize(mapload)
|
||||
. = ..()
|
||||
freedoms_action = new(src)
|
||||
|
||||
/obj/item/mod/module/shinobi_freedom/on_suit_activation()
|
||||
. = ..()
|
||||
ADD_TRAIT(mod.wearer, TRAIT_GOTTAGONOTSOFAST, src)
|
||||
freedoms_action.Grant(mod.wearer)
|
||||
|
||||
/obj/item/mod/module/shinobi_freedom/on_suit_deactivation(deleting = FALSE)
|
||||
if(deleting)
|
||||
return
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_GOTTAGONOTSOFAST, src)
|
||||
freedoms_action.Remove(mod.wearer)
|
||||
|
||||
/obj/item/mod/module/shinobi_stims
|
||||
name = "MOD shinobi stimulant module"
|
||||
desc = "An advanced module, designed by the Spider Clan, that replicates the advanced stimulants technology in the classic ninja kabuto."
|
||||
icon_state = "armor_booster"
|
||||
origin_tech = "combat=5;bluespace=6;syndicate=4"
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
|
||||
removable = FALSE
|
||||
/// Linked stims action
|
||||
var/datum/action/cooldown/ninja/stim_suit/antistun_action
|
||||
|
||||
/obj/item/mod/module/shinobi_stims/Initialize(mapload)
|
||||
. = ..()
|
||||
antistun_action = new(src)
|
||||
|
||||
/obj/item/mod/module/shinobi_stims/on_suit_activation()
|
||||
. = ..()
|
||||
ADD_TRAIT(mod.wearer, TRAIT_GOTTAGONOTSOFAST, src)
|
||||
antistun_action.Grant(mod.wearer)
|
||||
|
||||
/obj/item/mod/module/shinobi_stims/on_suit_deactivation(deleting = FALSE)
|
||||
if(deleting)
|
||||
return
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_GOTTAGONOTSOFAST, src)
|
||||
antistun_action.Remove(mod.wearer)
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/obj/item/katana/energy
|
||||
name = "energy katana"
|
||||
desc = "A katana infused with a strong energy."
|
||||
icon = 'icons/obj/weapons/energy_melee.dmi'
|
||||
icon_state = "energy_katana"
|
||||
throwforce = 20
|
||||
armor_penetration_percentage = 50
|
||||
armor_penetration_flat = 10
|
||||
var/cooldown = 0 // Because spam aint cool, yo.
|
||||
var/datum/effect_system/spark_spread/spark_system
|
||||
|
||||
/obj/item/katana/energy/attack__legacy__attackchain(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
playsound(user, 'sound/weapons/blade1.ogg', 50, TRUE, -1)
|
||||
return ..()
|
||||
|
||||
/obj/item/katana/energy/afterattack__legacy__attackchain(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
if(!user || !target)
|
||||
return
|
||||
|
||||
if(proximity_flag && user.mind.special_role == "Ninja" && !cooldown && isobj(target))
|
||||
cooldown = 1
|
||||
spark_system.start()
|
||||
playsound(user, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
playsound(user, 'sound/weapons/blade1.ogg', 50, 1)
|
||||
user.visible_message(SPAN_DANGER("[user] masterfully slices [target]!"), SPAN_NOTICE("You masterfully slice [target]!"))
|
||||
target.emag_act(user)
|
||||
sleep(15)
|
||||
cooldown = 0
|
||||
|
||||
/*/obj/item/katana/energy/throw_impact(atom/hit_atom)
|
||||
if(ishuman(hit_atom))
|
||||
var/mob/living/carbon/human/H = hit_atom
|
||||
if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
|
||||
var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit
|
||||
if(SN.energyKatana && SN.energyKatana == src)
|
||||
returnToOwner(H, 0, 1)
|
||||
return
|
||||
..()*/
|
||||
|
||||
/obj/item/katana/energy/proc/returnToOwner(mob/living/carbon/human/user, doSpark = 1, caught = 0)
|
||||
if(!istype(user))
|
||||
return
|
||||
loc = get_turf(src)
|
||||
|
||||
if(doSpark)
|
||||
spark_system.start()
|
||||
playsound(get_turf(src), "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
|
||||
var/msg = ""
|
||||
|
||||
if(user.put_in_hands(src))
|
||||
msg = "Your Energy Katana teleports into your hand!"
|
||||
else if(user.equip_to_slot_if_possible(src, ITEM_SLOT_BELT, FALSE, TRUE))
|
||||
msg = "Your Energy Katana teleports back to you, sheathing itself as it does so!</span>"
|
||||
else
|
||||
loc = get_turf(user)
|
||||
msg = "Your Energy Katana teleports to your location!"
|
||||
|
||||
if(caught)
|
||||
if(loc == user)
|
||||
msg = "You catch your Energy Katana!"
|
||||
else
|
||||
msg = "Your Energy Katana lands at your feet!"
|
||||
|
||||
if(msg)
|
||||
to_chat(user, SPAN_NOTICE("[msg]"))
|
||||
|
||||
/obj/item/katana/energy/Initialize(mapload)
|
||||
. = ..()
|
||||
spark_system = new /datum/effect_system/spark_spread()
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
|
||||
/obj/item/katana/energy/Destroy()
|
||||
QDEL_NULL(spark_system)
|
||||
return ..()
|
||||
@@ -0,0 +1,101 @@
|
||||
/datum/action/cooldown/ninja
|
||||
background_icon_state = "bg_ninja"
|
||||
button_icon_state = "genetic_view"
|
||||
|
||||
/datum/action/cooldown/ninja/ninja_cloak
|
||||
name = "Ninja's Stealth"
|
||||
desc = "Toggles whether you are currently sneaking, reducing your visibility and movement speed. Enhanced effects in darkness."
|
||||
button_icon_state = "vampire_cloak"
|
||||
cooldown_time = 2 SECONDS
|
||||
var/sneaking = FALSE
|
||||
|
||||
/datum/action/cooldown/ninja/ninja_cloak/proc/update_action_name()
|
||||
name = "[initial(name)] ([sneaking ? "Deactivate" : "Activate"])"
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_NAME)
|
||||
build_all_button_icons()
|
||||
|
||||
/datum/action/cooldown/ninja/ninja_cloak/proc/stop_sneaking()
|
||||
if(!ishuman(owner))
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
sneaking = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
UnregisterSignal(H, COMSIG_ATTACK)
|
||||
UnregisterSignal(H, COMSIG_ATTACK_BY)
|
||||
H.set_alpha_tracking(ALPHA_VISIBLE, src)
|
||||
REMOVE_TRAIT(owner, TRAIT_GOTTAGOSLOW, src)
|
||||
|
||||
/datum/action/cooldown/ninja/ninja_cloak/process()
|
||||
. = ..()
|
||||
if(!ishuman(owner))
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(H.stat)
|
||||
stop_sneaking()
|
||||
return
|
||||
if(!sneaking)
|
||||
stop_sneaking()
|
||||
return
|
||||
var/turf/simulated/T = get_turf(H)
|
||||
var/light_available = T.get_lumcount() * 10
|
||||
|
||||
if(light_available <= 2)
|
||||
H.set_alpha_tracking(ALPHA_VISIBLE * 0.1, src)
|
||||
return
|
||||
H.set_alpha_tracking(ALPHA_VISIBLE * 0.5, src)
|
||||
|
||||
/datum/action/cooldown/ninja/ninja_cloak/Activate(atom/target)
|
||||
if(!ishuman(owner))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = owner
|
||||
|
||||
sneaking = !sneaking
|
||||
update_action_name()
|
||||
if(sneaking)
|
||||
to_chat(H, "<span class='notice'>You are now sneaking around. Stick to the darkness to conceal yourself better.</span>")
|
||||
START_PROCESSING(SSobj, src)
|
||||
RegisterSignal(owner, COMSIG_ATTACK, PROC_REF(stop_sneaking))
|
||||
RegisterSignal(owner, COMSIG_ATTACK_BY, PROC_REF(stop_sneaking))
|
||||
ADD_TRAIT(owner, TRAIT_GOTTAGOSLOW, src)
|
||||
else
|
||||
to_chat(H, "<span class='notice'>You are no longer sneaking around.</span>")
|
||||
stop_sneaking()
|
||||
StartCooldown()
|
||||
|
||||
/datum/action/cooldown/ninja/freedom_shoes
|
||||
name = "Ninja's Mobility"
|
||||
desc = "Breaks free of leg restraints. 2 Minute cooldown."
|
||||
button_icon = 'icons/obj/bio_chips.dmi'
|
||||
button_icon_state = "freedom"
|
||||
cooldown_time = 2 MINUTES
|
||||
|
||||
/datum/action/cooldown/ninja/freedom_shoes/Activate(atom/target)
|
||||
if(!ishuman(owner))
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.clear_legcuffs(TRUE)
|
||||
H.SetKnockDown(0)
|
||||
H.stand_up(TRUE)
|
||||
StartCooldown()
|
||||
|
||||
/datum/action/cooldown/ninja/stim_suit
|
||||
name = "Ninja's Tenacity"
|
||||
desc = "Activates an injector within your suit, pumping you with a small hit of stimulants. 2 Minute cooldown."
|
||||
button_icon = 'icons/obj/bio_chips.dmi'
|
||||
button_icon_state = "adrenal"
|
||||
cooldown_time = 2 MINUTES
|
||||
|
||||
/datum/action/cooldown/ninja/stim_suit/Activate(atom/target)
|
||||
if(!ishuman(owner))
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.SetStunned(0)
|
||||
H.SetWeakened(0)
|
||||
H.SetKnockDown(0)
|
||||
H.SetParalysis(0)
|
||||
H.adjustStaminaLoss(-75)
|
||||
H.stand_up(TRUE)
|
||||
SEND_SIGNAL(H, COMSIG_LIVING_CLEAR_STUNS)
|
||||
H.reagents.add_reagent("stimulative_agent", 1) // 10 Seconds.
|
||||
StartCooldown()
|
||||
@@ -0,0 +1,195 @@
|
||||
/obj/item/clothing/head/helmet/space_ninja
|
||||
desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear."
|
||||
name = "ninja fukumen"
|
||||
icon_state = "s-ninja"
|
||||
inhand_icon_state = "s-ninja_hood"
|
||||
flags = BLOCKHAIR
|
||||
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE
|
||||
armor = list(MELEE = 30, BULLET = 35, LASER = 25, ENERGY = 25, BOMB = 20, RAD = 100, FIRE = INFINITY, ACID = INFINITY)
|
||||
origin_tech = "combat=5;materials=5;syndicate=2"
|
||||
blockTracking = 1
|
||||
icon_monitor = 'icons/mob/clothing/species/machine/monitor/hood.dmi'
|
||||
sprite_sheets = list(
|
||||
"Unathi" = 'icons/mob/clothing/species/unathi/head.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/species/tajaran/head.dmi',
|
||||
"Skrell" = 'icons/mob/clothing/species/skrell/head.dmi',
|
||||
"Vox" = 'icons/mob/clothing/species/vox/head.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/head.dmi',
|
||||
"Drask" = 'icons/mob/clothing/species/drask/head.dmi',
|
||||
"Grey" = 'icons/mob/clothing/species/grey/head.dmi',
|
||||
"Nian" = 'icons/mob/clothing/species/nian/head.dmi',
|
||||
"Diona" = 'icons/mob/clothing/species/diona/head.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/species/kidan/head.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/vox/head.dmi',
|
||||
)
|
||||
/// Tracking the cloak action
|
||||
var/datum/action/cooldown/ninja/ninja_cloak/cloak_action
|
||||
|
||||
/obj/item/clothing/head/helmet/space_ninja/Initialize(mapload)
|
||||
. = ..()
|
||||
cloak_action = new(src)
|
||||
|
||||
/obj/item/clothing/head/helmet/space_ninja/equipped(mob/user, slot, initial)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot != ITEM_SLOT_HEAD)
|
||||
return
|
||||
cloak_action.Grant(user)
|
||||
|
||||
/obj/item/clothing/head/helmet/space_ninja/dropped(mob/user, silent)
|
||||
. = ..()
|
||||
cloak_action.stop_sneaking()
|
||||
cloak_action.Remove(user)
|
||||
|
||||
/obj/item/clothing/mask/gas/space_ninja
|
||||
name = "ninja mask"
|
||||
desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement."
|
||||
icon_state = "s-ninja"
|
||||
inhand_icon_state = "s-ninja_mask"
|
||||
flash_protect = FLASH_PROTECTION_FLASH
|
||||
origin_tech = "combat=4;materials=4;syndicate=1"
|
||||
icon_monitor = 'icons/mob/clothing/species/machine/monitor/mask.dmi'
|
||||
sprite_sheets = list(
|
||||
"Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/species/tajaran/mask.dmi',
|
||||
"Skrell" = 'icons/mob/clothing/species/skrell/mask.dmi',
|
||||
"Vox" = 'icons/mob/clothing/species/vox/mask.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi',
|
||||
"Drask" = 'icons/mob/clothing/species/drask/mask.dmi',
|
||||
"Grey" = 'icons/mob/clothing/species/grey/mask.dmi',
|
||||
"Nian" = 'icons/mob/clothing/species/nian/mask.dmi',
|
||||
"Diona" = 'icons/mob/clothing/species/diona/mask.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/species/kidan/mask.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/skkulakin/mask.dmi',
|
||||
)
|
||||
var/obj/item/voice_changer/voice_changer
|
||||
|
||||
/obj/item/clothing/mask/gas/space_ninja/Initialize(mapload)
|
||||
. = ..()
|
||||
voice_changer = new(src)
|
||||
|
||||
/obj/item/clothing/mask/gas/space_ninja/Destroy()
|
||||
QDEL_NULL(voice_changer)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/gloves/space_ninja
|
||||
desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
|
||||
name = "ninja tekko"
|
||||
icon_state = "s-ninja"
|
||||
siemens_coefficient = 0
|
||||
pickpocket = TRUE // Master of stealth, you can pick a pocket
|
||||
armor = list(MELEE = 30, BULLET = 35, LASER = 25, ENERGY = 25, BOMB = 20, RAD = 100, FIRE = INFINITY, ACID = INFINITY)
|
||||
cold_protection = HANDS
|
||||
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
|
||||
heat_protection = HANDS
|
||||
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
|
||||
origin_tech = "combat=5;materials=5;syndicate=2"
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/clothing/species/vox/gloves.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/vox/gloves.dmi',
|
||||
"Drask" = 'icons/mob/clothing/species/drask/gloves.dmi',
|
||||
"Diona" = 'icons/mob/clothing/species/diona/gloves.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/species/kidan/gloves.dmi',
|
||||
)
|
||||
|
||||
/obj/item/clothing/shoes/space_ninja
|
||||
name = "ninja jaka-tabi"
|
||||
desc = "A pair of split-toed rubber-soled shoes. Excellent for running and even better for smashing skulls."
|
||||
icon_state = "s-ninja"
|
||||
permeability_coefficient = 0.01
|
||||
no_slip = TRUE
|
||||
armor = list(MELEE = 30, BULLET = 35, LASER = 25, ENERGY = 25, BOMB = 20, RAD = 100, FIRE = INFINITY, ACID = INFINITY)
|
||||
cold_protection = FEET
|
||||
min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT
|
||||
heat_protection = FEET
|
||||
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
|
||||
origin_tech = "combat=5;materials=5;syndicate=2"
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/clothing/species/vox/shoes.dmi',
|
||||
"Drask" = 'icons/mob/clothing/species/drask/shoes.dmi',
|
||||
"Diona" = 'icons/mob/clothing/species/diona/shoes.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/species/kidan/shoes.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/vox/shoes.dmi',
|
||||
)
|
||||
/// Linked freedoms action
|
||||
var/datum/action/cooldown/ninja/freedom_shoes/freedoms_action
|
||||
|
||||
/obj/item/clothing/shoes/space_ninja/Initialize(mapload)
|
||||
. = ..()
|
||||
freedoms_action = new(src)
|
||||
|
||||
/obj/item/clothing/shoes/space_ninja/equipped(mob/user, slot, initial)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot != ITEM_SLOT_SHOES)
|
||||
return
|
||||
ADD_TRAIT(user, TRAIT_GOTTAGONOTSOFAST, src)
|
||||
freedoms_action.Grant(user)
|
||||
|
||||
/obj/item/clothing/shoes/space_ninja/dropped(mob/user, silent)
|
||||
. = ..()
|
||||
REMOVE_TRAIT(user, TRAIT_GOTTAGONOTSOFAST, src)
|
||||
freedoms_action.Remove(user)
|
||||
|
||||
/obj/item/clothing/suit/space_ninja
|
||||
name = "ninja uwagi"
|
||||
desc = "A unique suit of nano-enhanced armor designed specifically for Spider Clan assassins."
|
||||
icon_state = "s-ninja"
|
||||
inhand_icon_state = "s-ninja_suit"
|
||||
allowed = list(
|
||||
/obj/item/gun,
|
||||
/obj/item/ammo_box,
|
||||
/obj/item/melee/baton,
|
||||
/obj/item/tank/internals,
|
||||
/obj/item/katana/energy,
|
||||
/obj/item/restraints/handcuffs,
|
||||
/obj/item/ninja_scanner
|
||||
)
|
||||
flags_inv = HIDEJUMPSUIT
|
||||
armor = list(MELEE = 30, BULLET = 35, LASER = 25, ENERGY = 25, BOMB = 20, RAD = 100, FIRE = INFINITY, ACID = INFINITY)
|
||||
origin_tech = "combat=5;materials=5;syndicate=2"
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/clothing/species/vox/suit.dmi',
|
||||
"Drask" = 'icons/mob/clothing/species/drask/suit.dmi',
|
||||
"Grey" = 'icons/mob/clothing/species/grey/suit.dmi',
|
||||
"Nian" = 'icons/mob/clothing/species/nian/suit.dmi',
|
||||
"Diona" = 'icons/mob/clothing/species/diona/suit.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/species/kidan/suit.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/vox/suit.dmi',
|
||||
)
|
||||
/// Linked stims action
|
||||
var/datum/action/cooldown/ninja/stim_suit/antistun_action
|
||||
|
||||
/obj/item/clothing/suit/space_ninja/Initialize(mapload)
|
||||
. = ..()
|
||||
antistun_action = new(src)
|
||||
|
||||
/obj/item/clothing/suit/space_ninja/equipped(mob/user, slot, initial)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot != ITEM_SLOT_OUTER_SUIT)
|
||||
return
|
||||
antistun_action.Grant(user)
|
||||
|
||||
/obj/item/clothing/suit/space_ninja/dropped(mob/user, silent)
|
||||
. = ..()
|
||||
antistun_action.Remove(user)
|
||||
|
||||
/obj/item/storage/bag/garment/syndie/ninja_suit
|
||||
name = "ninja suit garment bag"
|
||||
|
||||
/obj/item/storage/bag/garment/syndie/ninja_suit/populate_contents()
|
||||
new /obj/item/clothing/under/syndicate(src)
|
||||
new /obj/item/clothing/shoes/space_ninja(src)
|
||||
new /obj/item/clothing/gloves/space_ninja(src)
|
||||
new /obj/item/clothing/head/helmet/space_ninja(src)
|
||||
new /obj/item/clothing/mask/gas/space_ninja(src)
|
||||
new /obj/item/clothing/suit/space_ninja(src)
|
||||
|
||||
/obj/item/card/id/syndicate/ninja
|
||||
name = "ninja card"
|
||||
initial_access = list(ACCESS_MAINT_TUNNELS)
|
||||
icon_state = "data"
|
||||
@@ -0,0 +1,181 @@
|
||||
/obj/machinery/syndicatebomb/ninja
|
||||
name = "spider clan bomb"
|
||||
payload = /obj/item/bombcore/ninja
|
||||
|
||||
/obj/machinery/syndicatebomb/ninja/emp
|
||||
name = "spider clan EMP bomb"
|
||||
payload = /obj/item/bombcore/emp/ninja
|
||||
|
||||
/obj/machinery/syndicatebomb/ninja/spiders
|
||||
name = "spider bomb"
|
||||
payload = /obj/item/bombcore/badmin/summon/ninja_spiders
|
||||
|
||||
/obj/item/bombcore/ninja
|
||||
desc = "A powerful secondary explosive of spider clan design and unknown composition, it should be stable under normal conditions..."
|
||||
range_heavy = 3
|
||||
range_medium = 8
|
||||
range_light = 15
|
||||
range_flame = 17
|
||||
|
||||
/obj/item/bombcore/emp/ninja
|
||||
light_emp = 24
|
||||
heavy_emp = 12
|
||||
|
||||
/obj/item/bombcore/badmin/summon/ninja_spiders
|
||||
summon_path = /mob/living/basic/giant_spider
|
||||
amt_summon = 12
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb
|
||||
name = "spider clan bomb deployment flare"
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
desc = "A single-use flare that will bring a high-yield payload to the location it was lit at."
|
||||
icon_state = "flare-contractor"
|
||||
inhand_icon_state = "flare"
|
||||
/// What area should be blow up?
|
||||
var/area/bomb_target
|
||||
/// What kind of bomb is it
|
||||
var/obj/machinery/syndicatebomb/bomb_type = /obj/machinery/syndicatebomb/ninja
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/Initialize(mapload)
|
||||
. = ..()
|
||||
var/list/possible_areas = list(
|
||||
// Rooms
|
||||
/area/station/hallway/primary/aft,
|
||||
/area/station/engineering/atmos,
|
||||
/area/station/public/arcade,
|
||||
/area/station/maintenance/assembly_line,
|
||||
/area/station/public/storage/tools/auxiliary,
|
||||
/area/station/command/office/blueshield,
|
||||
/area/station/supply/storage,
|
||||
/area/station/service/chapel,
|
||||
/area/station/service/chapel/office,
|
||||
/area/station/service/clown,
|
||||
/area/station/legal/courtroom,
|
||||
/area/station/public/toilet,
|
||||
/area/station/engineering/control,
|
||||
/area/station/engineering/controlroom,
|
||||
/area/station/hallway/secondary/exit,
|
||||
/area/holodeck/alphadeck,
|
||||
/area/station/service/hydroponics,
|
||||
/area/station/service/library,
|
||||
/area/station/service/mime,
|
||||
/area/station/supply/miningdock,
|
||||
/area/station/medical/morgue,
|
||||
/area/station/public/storage/office,
|
||||
/area/station/public/pet_store,
|
||||
/area/station/public/storage/tools,
|
||||
/area/station/public/mrchangs,
|
||||
/area/station/science/research,
|
||||
/area/station/security/checkpoint,
|
||||
/area/station/engineering/tech_storage,
|
||||
/area/station/command/teleporter,
|
||||
/area/station/science/storage,
|
||||
/area/station/science/misc_lab,
|
||||
/area/station/science/xenobiology,
|
||||
/area/station/turret_protected/aisat/interior,
|
||||
/area/station/aisat/atmos,
|
||||
/area/station/aisat/hall,
|
||||
/area/station/aisat/service,
|
||||
/area/station/service/bar,
|
||||
/area/station/supply/office,
|
||||
/area/station/medical/chemistry,
|
||||
/area/station/command/office/ce,
|
||||
/area/station/command/office/cmo,
|
||||
/area/station/medical/cloning,
|
||||
/area/station/medical/cryo,
|
||||
/area/station/public/dorms,
|
||||
/area/station/engineering/equipmentstorage,
|
||||
/area/station/engineering/break_room,
|
||||
/area/station/ai_monitored/storage/eva,
|
||||
/area/station/supply/expedition,
|
||||
/area/station/science/genetics,
|
||||
/area/station/engineering/gravitygenerator,
|
||||
/area/station/command/office/hop,
|
||||
/area/station/command/meeting_room,
|
||||
/area/station/service/kitchen,
|
||||
/area/station/science/robotics/chargebay,
|
||||
/area/station/medical/medbay,
|
||||
/area/station/medical/medbay2,
|
||||
/area/station/medical/medbay3,
|
||||
/area/station/medical/reception,
|
||||
/area/station/medical/storage,
|
||||
/area/station/medical/sleeper,
|
||||
/area/station/command/server,
|
||||
/area/station/command/office/ntrep,
|
||||
/area/station/medical/paramedic,
|
||||
/area/station/hallway/primary/port,
|
||||
/area/station/supply/qm,
|
||||
/area/station/command/office/rd,
|
||||
/area/station/science/rnd,
|
||||
/area/station/science/robotics,
|
||||
/area/station/medical/surgery/primary,
|
||||
/area/station/medical/surgery/secondary,
|
||||
/area/station/telecomms/chamber,
|
||||
/area/station/engineering/secure_storage
|
||||
)
|
||||
while(!bomb_target)
|
||||
var/area/selected_area = pick_n_take(possible_areas)
|
||||
for(var/area/potential in SSmapping.existing_station_areas)
|
||||
if(potential.type != selected_area)
|
||||
continue
|
||||
bomb_target = potential
|
||||
break
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/examine(mob/user)
|
||||
. = ..()
|
||||
if(isAntag(user))
|
||||
. += SPAN_WARNING("The target bomb location is: [bomb_target.name]")
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/activate(mob/user)
|
||||
if(!turf_check(user))
|
||||
return
|
||||
var/obj/effect/temp_visual/ninja_bomb/F = new /obj/effect/temp_visual/ninja_bomb(get_turf(src))
|
||||
user.drop_item()
|
||||
forceMove(F)
|
||||
log_and_message_admins("[user] activated a ninja bomb flare.")
|
||||
addtimer(CALLBACK(src, PROC_REF(spawn_bomb), user), 5 SECONDS)
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/proc/spawn_bomb(mob/user)
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
||||
var/obj/machinery/syndicatebomb/new_bomb = new bomb_type(get_turf(src))
|
||||
new_bomb.anchored = TRUE
|
||||
new_bomb.activate()
|
||||
var/objectives = user.mind.get_all_objectives()
|
||||
for(var/datum/objective/ninja/bomb_department/bomb_dep in objectives)
|
||||
if(!bomb_dep.completed)
|
||||
to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink."))
|
||||
bomb_dep.complete_objective()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/turf_check(mob/user)
|
||||
var/turf/device_turf = get_turf(user)
|
||||
if(!device_turf)
|
||||
to_chat(user, "<span class='notice'>You're having difficulties getting the [name] to work.</span>")
|
||||
return FALSE
|
||||
var/area/our_area = get_area(device_turf)
|
||||
if(!istype(our_area, bomb_target))
|
||||
to_chat(user, "<span class='notice'>You're having difficulties getting the [name] to work.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/emp
|
||||
bomb_type = /obj/machinery/syndicatebomb/ninja/emp
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/spiders
|
||||
bomb_type = /obj/machinery/syndicatebomb/ninja/spiders
|
||||
|
||||
/obj/effect/temp_visual/ninja_bomb
|
||||
name = "spider clan bomb deployment flare"
|
||||
layer = BELOW_MOB_LAYER
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "flare-contractor-on"
|
||||
duration = 5.1 SECONDS
|
||||
/// Sound that plays when activated
|
||||
var/activation_sound = 'sound/goonstation/misc/matchstick_light.ogg'
|
||||
/// Light emitted when activated
|
||||
var/emitted_color = "#1faf2b"
|
||||
|
||||
/obj/effect/temp_visual/ninja_bomb/Initialize(mapload)
|
||||
. = ..()
|
||||
playsound(loc, activation_sound, 50, TRUE)
|
||||
set_light(8, l_color = emitted_color)
|
||||
@@ -0,0 +1,54 @@
|
||||
/datum/outfit/space_ninja
|
||||
name = "Space Ninja"
|
||||
uniform = /obj/item/clothing/under/syndicate
|
||||
shoes = /obj/item/clothing/shoes/space_ninja
|
||||
gloves = /obj/item/clothing/gloves/space_ninja
|
||||
head = /obj/item/clothing/head/helmet/space_ninja
|
||||
mask = /obj/item/clothing/mask/gas/space_ninja
|
||||
glasses = /obj/item/clothing/glasses/night
|
||||
suit = /obj/item/clothing/suit/space_ninja
|
||||
belt = /obj/item/katana/energy
|
||||
id = /obj/item/card/id/syndicate/ninja
|
||||
back = /obj/item/storage/backpack/satchel
|
||||
l_ear = /obj/item/radio/headset
|
||||
box = /obj/item/storage/box/survival_syndie
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/syndie_kit/throwing_weapons,
|
||||
/obj/item/ninja_scanner,
|
||||
/obj/item/gun/energy/kinetic_accelerator/energy_net,
|
||||
/obj/item/wormhole_jaunter/extraction,
|
||||
/obj/item/teleportation_scroll/apprentice,
|
||||
)
|
||||
bio_chips = list(
|
||||
/obj/item/bio_chip/dust,
|
||||
/obj/item/bio_chip/uplink/ninja
|
||||
)
|
||||
|
||||
/datum/outfit/space_ninja/vox
|
||||
name = "Space Ninja - Vox"
|
||||
|
||||
/datum/outfit/space_ninja/vox/post_equip(mob/living/carbon/human/H, visualsOnly)
|
||||
. = ..()
|
||||
var/obj/item/tank/internal_tank = new /obj/item/tank/internals/emergency_oxygen/double/vox(H)
|
||||
if(!H.equip_to_appropriate_slot(internal_tank))
|
||||
if(!H.put_in_any_hand_if_possible(internal_tank))
|
||||
H.drop_item_to_ground(H.l_hand)
|
||||
H.equip_or_collect(internal_tank, ITEM_SLOT_LEFT_HAND)
|
||||
to_chat(H, "<span class='boldannounceooc'>Could not find an empty slot for internals! Please report this as a bug</span>")
|
||||
H.internal = internal_tank
|
||||
|
||||
/datum/outfit/admin/ghostbar_antag/space_ninja
|
||||
name = "Ghostbar Space Ninja"
|
||||
uniform = /obj/item/clothing/under/syndicate
|
||||
shoes = /obj/item/clothing/shoes/space_ninja
|
||||
gloves = /obj/item/clothing/gloves/space_ninja
|
||||
head = /obj/item/clothing/head/helmet/space_ninja
|
||||
mask = /obj/item/clothing/mask/gas/space_ninja
|
||||
suit = /obj/item/clothing/suit/space_ninja
|
||||
belt = /obj/item/toy/katana
|
||||
back = /obj/item/storage/backpack/satchel
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/engineer = 1,
|
||||
/obj/item/flashlight = 1,
|
||||
/obj/item/food/syndidonkpocket = 1,
|
||||
)
|
||||
@@ -0,0 +1,143 @@
|
||||
/obj/item/ninja_scanner
|
||||
name = "spider scanner"
|
||||
desc = "Advanced multi-use scanning device used by the spider clan to confirm bounty completion. Scan the corpses of dead or netted crew to redeem your bounties."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "ninja_scanner"
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
force = 9 // Can be used as a weapon in an emergency
|
||||
hitsound = 'sound/weapons/genhit1.ogg'
|
||||
new_attack_chain = TRUE
|
||||
|
||||
/obj/item/ninja_scanner/attack(mob/living/target, mob/living/user, params)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
if(!user.mind)
|
||||
return ..()
|
||||
var/list/obj_list = user.mind.get_all_objectives()
|
||||
if(!length(obj_list))
|
||||
to_chat(user, SPAN_WARNING("You have no objectives!"))
|
||||
return TRUE
|
||||
for(var/datum/objective/ninja/ninja_obj in obj_list)
|
||||
if(ninja_obj.completed)
|
||||
continue
|
||||
if(istype(ninja_obj, /datum/objective/ninja/kill))
|
||||
if(target.stat != DEAD)
|
||||
continue
|
||||
if(!ninja_obj.target.current || target != ninja_obj.target.current)
|
||||
continue
|
||||
user.visible_message(SPAN_DANGER("[user] begins to use [src] to scan [target]!"), \
|
||||
SPAN_NOTICE("You begin to scan [target]!"))
|
||||
if(!do_after_once(user, 8 SECONDS, target = target, allow_moving = FALSE, attempt_cancel_message = "You stop scanning [target] before completing the scan."))
|
||||
return TRUE
|
||||
ninja_obj.completed = TRUE
|
||||
to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink."))
|
||||
ninja_obj.complete_objective()
|
||||
return TRUE
|
||||
|
||||
if(istype(ninja_obj, /datum/objective/ninja/capture))
|
||||
var/datum/objective/ninja/capture/cap_obj = ninja_obj
|
||||
if(target != ninja_obj.target.current)
|
||||
continue
|
||||
if(target.stat == DEAD)
|
||||
if(!target.ghost_can_reenter()) // Target is DNR. Reroll.
|
||||
to_chat(user, SPAN_NOTICE("Target is unrecoverable. Finding a new target..."))
|
||||
ninja_obj.on_target_cryo()
|
||||
else
|
||||
to_chat(user, SPAN_NOTICE("Target is dead. Dead people don't talk. Esnure they are revived, then send them to us."))
|
||||
continue
|
||||
if(!target.buckled)
|
||||
continue
|
||||
var/obj/structure/bed/energy_net/trapped_net
|
||||
for(var/obj/structure/bed/energy_net/net in target.loc)
|
||||
trapped_net = net
|
||||
break
|
||||
if(!trapped_net)
|
||||
continue
|
||||
user.visible_message(SPAN_DANGER("[user] begins to use [src] to scan [target]!"), \
|
||||
SPAN_NOTICE("You begin to scan [target]!"))
|
||||
if(!do_after_once(user, 5 SECONDS, target = target, allow_moving = FALSE, attempt_cancel_message = "You stop scanning [target] before completing the scan."))
|
||||
return TRUE
|
||||
target.unbuckle(TRUE)
|
||||
trapped_net.Destroy()
|
||||
var/target_loc = target.loc
|
||||
do_teleport(target, pick(GLOB.ninjaprisonwarp), 0, TRUE, bypass_area_flag = TRUE)
|
||||
var/mob/living/carbon/c_target = target
|
||||
if(istype(c_target))
|
||||
var/obj/item/restraints/handcuffs/cuffs = target.get_item_by_slot(ITEM_SLOT_HANDCUFFED)
|
||||
qdel(cuffs)
|
||||
c_target.handcuffed = FALSE
|
||||
c_target.update_handcuffed()
|
||||
cap_obj.handle_capture(target, target_loc)
|
||||
ninja_obj.completed = TRUE
|
||||
to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink."))
|
||||
ninja_obj.complete_objective()
|
||||
return TRUE
|
||||
|
||||
if(istype(ninja_obj, /datum/objective/ninja/interrogate_ai))
|
||||
if(!is_ai(target))
|
||||
return TRUE
|
||||
var/mob/living/silicon/ai/AI = target
|
||||
user.visible_message(SPAN_DANGER("[user] begins to use [src] to upload [AI]!"), \
|
||||
SPAN_NOTICE("You begin to upload [AI]!"))
|
||||
if(!do_after_once(user, 8 SECONDS, target = AI, allow_moving = FALSE, attempt_cancel_message = "You stop uploading [AI] before completing the upload."))
|
||||
return TRUE
|
||||
var/obj/item/aicard/card = new()
|
||||
AI.take_overall_damage(50)
|
||||
AI.transfer_ai(AI_TRANS_TO_CARD, user, null, card)
|
||||
var/list/possible_spawns = GLOB.maints_loot_spawns
|
||||
while(length(possible_spawns))
|
||||
var/turf/current_turf = pick_n_take(possible_spawns)
|
||||
if(!is_station_level(current_turf))
|
||||
continue
|
||||
if(!current_turf.density)
|
||||
do_teleport(card, current_turf)
|
||||
break
|
||||
// Someone built a wall over it, check the surroundings
|
||||
var/list/open_turfs = current_turf.AdjacentTurfs(open_only = TRUE)
|
||||
if(length(open_turfs))
|
||||
do_teleport(card, pick(open_turfs))
|
||||
break
|
||||
ninja_obj.completed = TRUE
|
||||
to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink."))
|
||||
ninja_obj.complete_objective()
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/ninja_scanner/attack_obj(obj/attacked_obj, mob/living/user, params)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
if(!user.mind)
|
||||
return ..()
|
||||
var/list/obj_list = user.mind.get_all_objectives()
|
||||
if(!length(obj_list))
|
||||
to_chat(user, SPAN_WARNING("You have no objectives!"))
|
||||
return TRUE
|
||||
for(var/datum/objective/ninja/ninja_obj in obj_list)
|
||||
if(ninja_obj.completed)
|
||||
continue
|
||||
if(istype(ninja_obj, /datum/objective/ninja/hack_rnd) && istype(attacked_obj, /obj/machinery/computer/rnd_network_controller))
|
||||
if(!do_after_once(user, 12 SECONDS, target = attacked_obj, allow_moving = FALSE, attempt_cancel_message = "You stop hacking [attacked_obj] before completing the download."))
|
||||
return TRUE
|
||||
to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink."))
|
||||
var/obj/machinery/computer/rnd_network_controller/rnd = attacked_obj
|
||||
rnd.research_files.known_tech = list()
|
||||
ninja_obj.completed = TRUE
|
||||
ninja_obj.complete_objective()
|
||||
return TRUE
|
||||
if(istype(ninja_obj, /datum/objective/ninja/insert_spider_rod) && istype(attacked_obj, /obj/machinery/atmospherics/reactor_chamber))
|
||||
var/obj/machinery/atmospherics/reactor_chamber/r_chamber = attacked_obj
|
||||
if(!r_chamber.held_rod)
|
||||
to_chat(user, SPAN_NOTICE("There is no rod in [r_chamber]."))
|
||||
return TRUE
|
||||
if(!istype(r_chamber.held_rod, /obj/item/nuclear_rod/fuel/uranium_238/spiders))
|
||||
to_chat(user, SPAN_NOTICE("The rod in [r_chamber] is not one of ours."))
|
||||
return TRUE
|
||||
if(r_chamber.linked_reactor.offline)
|
||||
to_chat(user, SPAN_NOTICE("[r_chamber.linked_reactor] is not online."))
|
||||
return TRUE
|
||||
to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink."))
|
||||
ninja_obj.completed = TRUE
|
||||
ninja_obj.complete_objective()
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
@@ -0,0 +1,91 @@
|
||||
/obj/item/bio_chip/uplink/ninja
|
||||
name = "spider clan uplink bio-chip"
|
||||
desc = "Purchase things from the spider clan with earned currency."
|
||||
|
||||
/obj/item/bio_chip/uplink/ninja/Initialize(mapload)
|
||||
. = ..()
|
||||
if(hidden_uplink)
|
||||
hidden_uplink.update_uplink_type(UPLINK_TYPE_NINJA)
|
||||
hidden_uplink.uses = 0
|
||||
|
||||
/datum/uplink_item/ninja
|
||||
category = "Spider Clan Provisions"
|
||||
surplus = 0
|
||||
uplinktypes = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/ninja/shuriken_printer
|
||||
name = "Shuriken Printer"
|
||||
desc = "An advanced, tiny autofabricator that slowly creates and stores energy shurikens."
|
||||
reference = "SPR"
|
||||
item = /obj/item/shuriken_printer
|
||||
cost = 25
|
||||
|
||||
/datum/uplink_item/ninja/ninja_modsuit
|
||||
name = "'Shinobi' Stealth Modsuit"
|
||||
desc = "A specialized modsuit worn by the spider clan's elite ninja operatives."
|
||||
reference = "SNBMOD"
|
||||
item = /obj/item/mod/control/pre_equipped/ninja
|
||||
cost = 45
|
||||
|
||||
/datum/uplink_item/ninja/energy_katana
|
||||
name = "Energy Katana"
|
||||
desc = "A plastitanium katana with a reinforced emitter edge. A ninja's most reliable tool."
|
||||
reference = "EKAT"
|
||||
item = /obj/item/katana/energy
|
||||
cost = 20
|
||||
|
||||
/datum/uplink_item/ninja/energy_net
|
||||
name = "Energy Net Projector"
|
||||
desc = "A non-lethal weapon favored by the Spider Clan. Targets struck will find themselves trapped in an energy net."
|
||||
reference = "ENET"
|
||||
item = /obj/item/gun/energy/kinetic_accelerator/energy_net
|
||||
cost = 30
|
||||
|
||||
/datum/uplink_item/ninja/spider_bomb
|
||||
name = "Spider Bomb"
|
||||
desc = "An evil device fabricated by the Spider Clan. This bomb contains a large number of dehydrated spider-cubes that will all activate upon detonation. These spiders do not discern friend from foe - all non-spiders make for good food."
|
||||
reference = "SPBM"
|
||||
item = /obj/machinery/syndicatebomb/ninja/spiders
|
||||
cost = 65
|
||||
|
||||
/datum/uplink_item/ninja/hood
|
||||
name = "Ninja Scarf"
|
||||
desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear."
|
||||
reference = "NJSC"
|
||||
item = /obj/item/clothing/head/helmet/space_ninja
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/ninja/mask
|
||||
name = "Ninja Mask"
|
||||
desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement."
|
||||
reference = "NJMSK"
|
||||
item = /obj/item/clothing/mask/gas/space_ninja
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/ninja/gloves
|
||||
name = "Ninja Gloves"
|
||||
desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
|
||||
reference = "NJGL"
|
||||
item = /obj/item/clothing/gloves/space_ninja
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/ninja/shoes
|
||||
name = "Ninja Shoes"
|
||||
desc = "A pair of running shoes. Excellent for running and even better for smashing skulls."
|
||||
reference = "NJSH"
|
||||
item = /obj/item/clothing/shoes/space_ninja
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/ninja/suit
|
||||
name = "Ninja Kabuto"
|
||||
desc = "A unique suit of nano-enhanced armor designed specifically for Spider Clan assassins."
|
||||
reference = "NJKB"
|
||||
item = /obj/item/clothing/suit/space_ninja
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/ninja/suit_bundle
|
||||
name = "Full Ninja Outfit"
|
||||
desc = "A bulk purchase of a full ninja outfit. Good for if you somehow lost the other set of highly advanced Spider Clan equipment."
|
||||
reference = "NJST"
|
||||
item = /obj/item/clothing/suit/space_ninja
|
||||
cost = 40
|
||||
@@ -0,0 +1,227 @@
|
||||
/obj/item/katana/energy
|
||||
name = "energy katana"
|
||||
desc = "A plastitanium katana with a reinforced emitter edge. A ninja's most reliable tool."
|
||||
icon = 'icons/obj/weapons/energy_melee.dmi'
|
||||
icon_state = "energy_katana"
|
||||
force = 30
|
||||
embed_chance = 75
|
||||
throwforce = 20
|
||||
armor_penetration_percentage = 50
|
||||
armor_penetration_flat = 10
|
||||
origin_tech = "combat=6;syndicate=4"
|
||||
hitsound = 'sound/weapons/blade1.ogg'
|
||||
/// Is the weapon gripped or not?
|
||||
var/gripped = FALSE
|
||||
|
||||
/obj/item/katana/energy/activate_self(mob/living/carbon/human/user)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/is_proper_modsuit = FALSE
|
||||
if(istype(user.gloves, /obj/item/clothing/gloves/mod))
|
||||
var/obj/item/mod/control/modsuit = user.get_item_by_slot(ITEM_SLOT_BACK)
|
||||
if(istype(modsuit) && istype(modsuit.theme, /datum/mod_theme/ninja))
|
||||
is_proper_modsuit = TRUE
|
||||
if(!istype(user.gloves, /obj/item/clothing/gloves/space_ninja) && !is_proper_modsuit)
|
||||
return
|
||||
if(!gripped)
|
||||
gripped = TRUE
|
||||
to_chat(user, SPAN_NOTICE("You tighten your grip on [src], ensuring you won't drop it."))
|
||||
set_nodrop(TRUE, user)
|
||||
return
|
||||
gripped = FALSE
|
||||
to_chat(user, SPAN_NOTICE("You relax your grip on [src]."))
|
||||
set_nodrop(FALSE, user)
|
||||
|
||||
/obj/item/katana/energy/dropped(mob/user, silent)
|
||||
. = ..()
|
||||
gripped = FALSE
|
||||
to_chat(user, SPAN_WARNING("Your grip on [src] is loosened!"))
|
||||
set_nodrop(FALSE, user)
|
||||
|
||||
/obj/item/katana/energy/equipped(mob/user, slot, initial)
|
||||
. = ..()
|
||||
if(gripped)
|
||||
gripped = FALSE
|
||||
to_chat(user, SPAN_NOTICE("You relax your grip on [src]."))
|
||||
set_nodrop(FALSE, user)
|
||||
|
||||
/obj/item/katana/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
. = ..()
|
||||
if(!.) // they did not block the attack
|
||||
return
|
||||
if(isprojectile(hitby))
|
||||
var/obj/projectile/P = hitby
|
||||
if(P.reflectability == REFLECTABILITY_ENERGY)
|
||||
owner.visible_message(SPAN_DANGER("[owner] parries [attack_text] with [src]!"))
|
||||
add_attack_logs(P.firer, src, "hit by [P.type] but got parried by [src]")
|
||||
return -1
|
||||
owner.visible_message(SPAN_DANGER("[owner] blocks [attack_text] with [src]!"))
|
||||
playsound(src, 'sound/weapons/effects/ric3.ogg', 100, TRUE)
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
/obj/item/energy_shuriken
|
||||
name = "energy shuriken"
|
||||
desc = "An ancient weapon, redefined. The blade hums with an electric edge, using itself as fuel."
|
||||
icon = 'icons/obj/weapons/melee.dmi'
|
||||
icon_state = "energy-shuriken"
|
||||
inhand_icon_state = "eshield0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
|
||||
force = 5
|
||||
throwforce = 30 // This is never used on mobs since this has a 100% embed chance.
|
||||
throw_speed = 4
|
||||
embedded_pain_multiplier = 4
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
embed_chance = 100
|
||||
embedded_fall_chance = 0
|
||||
sharp = TRUE
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
/obj/item/energy_shuriken/Initialize(mapload)
|
||||
. = ..()
|
||||
// Only lasts so long. Delete self after some time.
|
||||
addtimer(CALLBACK(src, PROC_REF(qdel), src), 30 SECONDS)
|
||||
|
||||
/obj/item/energy_shuriken/throw_impact(atom/target)
|
||||
. = ..()
|
||||
if(!ishuman(target))
|
||||
return
|
||||
var/mob/living/carbon/human/H = target
|
||||
H.apply_damage(60, STAMINA)
|
||||
|
||||
/obj/item/shuriken_printer
|
||||
name = "shuriken printer"
|
||||
desc = "An advanced, tiny autofabricator that slowly creates and stores energy shurikens."
|
||||
icon = 'icons/obj/weapons/melee.dmi'
|
||||
icon_state = "shuriken-pouch"
|
||||
inhand_icon_state = "eshield0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
|
||||
origin_tech = "combat=6;syndicate=5"
|
||||
force = 5
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
new_attack_chain = TRUE
|
||||
/// What is the maximum number of energy shurikens the printer can hold?
|
||||
var/maximum_stars = 4
|
||||
/// What is the current number of energy shurikens the printer is holding?
|
||||
var/current_stars = 2
|
||||
/// How long the cooldown is to print more shurikens
|
||||
var/printing_time = 30 SECONDS
|
||||
/// Timer used to print stars
|
||||
var/fabrication_timer
|
||||
|
||||
/obj/item/shuriken_printer/Initialize(mapload)
|
||||
. = ..()
|
||||
fabrication_timer = addtimer(CALLBACK(src, PROC_REF(print_star)), 30 SECONDS, TIMER_LOOP | TIMER_STOPPABLE)
|
||||
|
||||
/obj/item/shuriken_printer/examine(mob/user)
|
||||
. = ..()
|
||||
. += SPAN_NOTICE("Alt-click to draw an energy shuriken!")
|
||||
. += SPAN_NOTICE("It has [current_stars] stored.")
|
||||
|
||||
/obj/item/shuriken_printer/AltClick(mob/living/carbon/user, modifiers)
|
||||
if(!iscarbon(user))
|
||||
return ..()
|
||||
if(current_stars < 1)
|
||||
return ..()
|
||||
current_stars--
|
||||
var/obj/item/energy_shuriken/star = new /obj/item/energy_shuriken(get_turf(src), src)
|
||||
user.put_in_hands(star)
|
||||
to_chat(user, SPAN_NOTICE("You draw [star] from [src]."))
|
||||
user.throw_mode_on()
|
||||
|
||||
/obj/item/shuriken_printer/proc/print_star()
|
||||
if(current_stars < maximum_stars)
|
||||
current_stars++
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/energy_net
|
||||
name = "energy net projector"
|
||||
desc = "A non-lethal weapon favored by the Spider Clan. Targets stunned by this weapon will be trapped in an energy net for extraction."
|
||||
icon_state = "energy-net-gun"
|
||||
inhand_icon_state = "energy-net-gun"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
materials = list(MAT_METAL=2000)
|
||||
origin_tech = "combat=6;magnets=4;syndicate=4"
|
||||
suppressed = TRUE
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/net)
|
||||
unique_rename = FALSE
|
||||
overheat_time = 3 SECONDS
|
||||
holds_charge = TRUE
|
||||
unique_frequency = TRUE
|
||||
can_flashlight = FALSE
|
||||
max_mod_capacity = 0
|
||||
empty_state = "energy-net-gun_empty"
|
||||
can_holster = TRUE
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/energy_net/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SILENT_INSERTION, ROUNDSTART_TRAIT)
|
||||
|
||||
/obj/item/ammo_casing/energy/net
|
||||
projectile_type = /obj/projectile/energy/net
|
||||
muzzle_flash_color = null
|
||||
muzzle_flash_effect = /obj/effect/temp_visual/target_angled/muzzle_flash
|
||||
select_name = "energy net"
|
||||
e_cost = 500
|
||||
fire_sound = 'sound/weapons/bolathrow.ogg'
|
||||
|
||||
/obj/projectile/energy/net
|
||||
name = "energy net"
|
||||
icon_state = "net-end"
|
||||
nodamage = 1
|
||||
stamina = 60
|
||||
knockdown = 4 SECONDS
|
||||
speed = 1.5
|
||||
|
||||
/obj/projectile/energy/net/fire(setAngle)
|
||||
if(firer)
|
||||
firer.Beam(src, icon_state = "net-beam", time = INFINITY, maxdistance = INFINITY, beam_type = /obj/effect/ebeam/floor)
|
||||
return ..()
|
||||
|
||||
/obj/projectile/energy/net/on_hit(atom/target, blocked, hit_zone)
|
||||
. = ..()
|
||||
if(!firer)
|
||||
return
|
||||
if(!ishuman(target))
|
||||
return
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!H.stam_paralyzed)
|
||||
return
|
||||
var/obj/item/restraints/handcuffs/cable/zipties/cuff = new()
|
||||
cuff.apply_cuffs(H, firer)
|
||||
var/obj/structure/bed/energy_net/net = new(H.loc)
|
||||
net.buckle_mob(H, TRUE)
|
||||
|
||||
/obj/structure/bed/energy_net
|
||||
name = "energy net"
|
||||
desc = "A pulsing array of green energy that can securely hold a victim in place."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "e-net"
|
||||
|
||||
/obj/structure/bed/energy_net/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
|
||||
if(!has_buckled_mobs())
|
||||
Destroy() // We don't exist if nothing is being held
|
||||
for(var/buck in buckled_mobs) // No net, no buckles
|
||||
var/mob/living/M = buck
|
||||
if(M != user)
|
||||
if(!do_after(user, 10 SECONDS, target = src))
|
||||
if(M && M.buckled)
|
||||
to_chat(user, SPAN_WARNING("You fail to release [M] from \the [src]!"))
|
||||
return
|
||||
M.visible_message(SPAN_NOTICE("[user.name] pulls [M.name] free from the energy net!"),\
|
||||
SPAN_NOTICE("[user.name] pulls you free from the energy net."),\
|
||||
SPAN_ITALICS("You hear a small zap..."))
|
||||
unbuckle_mob(M)
|
||||
Destroy()
|
||||
if(!M.buckled)
|
||||
return
|
||||
M.visible_message(SPAN_WARNING("[M.name] breaks free from the energy net!"),\
|
||||
SPAN_NOTICE("You break free from the energy net!"),\
|
||||
SPAN_ITALICS("You hear a small zap..."))
|
||||
unbuckle_mob(M)
|
||||
Destroy()
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
|
||||
/obj/item/clothing/gloves/space_ninja
|
||||
desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
|
||||
name = "ninja gloves"
|
||||
icon_state = "s-ninja"
|
||||
siemens_coefficient = 0
|
||||
pickpocket = 1
|
||||
cold_protection = HANDS
|
||||
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
|
||||
heat_protection = HANDS
|
||||
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
|
||||
/obj/item/clothing/head/helmet/space/space_ninja
|
||||
desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear."
|
||||
name = "ninja hood"
|
||||
icon_state = "s-ninja"
|
||||
inhand_icon_state = "s-ninja_hood"
|
||||
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE
|
||||
armor = list(MELEE = 75, BULLET = 50, LASER = 20, ENERGY = 10, BOMB = 20, RAD = 15, FIRE = INFINITY, ACID = INFINITY)
|
||||
blockTracking = 1
|
||||
@@ -1,28 +0,0 @@
|
||||
|
||||
/*
|
||||
|
||||
Contents:
|
||||
- The Ninja Space Mask
|
||||
|
||||
*/
|
||||
|
||||
/obj/item/clothing/mask/gas/space_ninja
|
||||
name = "ninja mask"
|
||||
desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement."
|
||||
icon_state = "s-ninja(norm)"
|
||||
inhand_icon_state = "s-ninja_mask"
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/clothing/species/vox/mask.dmi',
|
||||
"Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/species/tajaran/mask.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi'
|
||||
)
|
||||
var/obj/item/voice_changer/voice_changer
|
||||
|
||||
/obj/item/clothing/mask/gas/space_ninja/Initialize(mapload)
|
||||
. = ..()
|
||||
voice_changer = new(src)
|
||||
|
||||
/obj/item/clothing/mask/gas/space_ninja/Destroy()
|
||||
QDEL_NULL(voice_changer)
|
||||
return ..()
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
/obj/item/clothing/shoes/space_ninja
|
||||
name = "ninja shoes"
|
||||
desc = "A pair of running shoes. Excellent for running and even better for smashing skulls."
|
||||
icon_state = "s-ninja"
|
||||
permeability_coefficient = 0.01
|
||||
no_slip = TRUE
|
||||
armor = list(MELEE = 75, BULLET = 50, LASER = 20, ENERGY = 10, BOMB = 20, RAD = 15, FIRE = INFINITY, ACID = INFINITY)
|
||||
cold_protection = FEET
|
||||
min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT
|
||||
heat_protection = FEET
|
||||
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
|
||||
@@ -1,87 +0,0 @@
|
||||
|
||||
/*
|
||||
|
||||
Contents:
|
||||
- The Ninja Space Suit
|
||||
- Ninja Space Suit Procs
|
||||
|
||||
*/
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja
|
||||
name = "ninja suit"
|
||||
desc = "A unique, vacuum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
|
||||
icon_state = "s-ninja"
|
||||
inhand_icon_state = "s-ninja_suit"
|
||||
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/melee/baton, /obj/item/tank/internals, /obj/item/stock_parts/cell)
|
||||
slowdown = 0
|
||||
flags_inv = HIDEJUMPSUIT|HIDETAIL
|
||||
armor = list(MELEE = 75, BULLET = 50, LASER = 20, ENERGY = 10, BOMB = 20, RAD = 15, FIRE = INFINITY, ACID = INFINITY)
|
||||
|
||||
var/suitActive = 0
|
||||
var/suitBusy = 0
|
||||
|
||||
var/obj/item/stock_parts/cell/suitCell
|
||||
var/obj/item/clothing/head/helmet/space/space_ninja/suitHood
|
||||
var/obj/item/clothing/gloves/space_ninja/suitGloves
|
||||
var/obj/item/clothing/shoes/space_ninja/suitShoes
|
||||
var/obj/item/clothing/mask/gas/space_ninja/suitMask
|
||||
var/mob/living/carbon/human/suitOccupant
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/get_cell()
|
||||
return suitCell
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/toggle_suit_lock(mob/living/carbon/human/user)
|
||||
if(!suitActive)
|
||||
if(!istype(user.wear_suit, /obj/item/clothing/suit/space/space_ninja))
|
||||
to_chat(user, "<span style='color: #ff0000;'><b>ERROR:</b> Unable to locate user.\nABORTING...</span>")
|
||||
return 0
|
||||
if(!istype(user.head, /obj/item/clothing/head/helmet/space/space_ninja))
|
||||
to_chat(user, "<span style='color: #ff0000;'><b>ERROR:</b> Unable to locate hood.\nABORTING...</span>")
|
||||
return 0
|
||||
if(!istype(user.gloves, /obj/item/clothing/gloves/space_ninja))
|
||||
to_chat(user, "<span style='color: #ff0000;'><b>ERROR:</b> Unable to locate gloves.\nABORTING...</span>")
|
||||
return 0
|
||||
if(!istype(user.shoes, /obj/item/clothing/shoes/space_ninja))
|
||||
to_chat(user, "<span style='color: #ff0000;'><b>ERROR:</b> Unable to locate foot gear.\nABORTING...</span>")
|
||||
return 0
|
||||
if(!istype(user.wear_mask, /obj/item/clothing/mask/gas/space_ninja))
|
||||
to_chat(user, "<span style='color: #ff0000;'><b>ERROR:</b> Unable to locate mask.\nABORTING...</span>")
|
||||
return 0
|
||||
|
||||
suitHood = user.head
|
||||
suitMask = user.wear_mask
|
||||
suitGloves = user.gloves
|
||||
suitShoes = user.shoes
|
||||
suitOccupant = user
|
||||
|
||||
set_nodrop(TRUE)
|
||||
suitHood.set_nodrop(TRUE)
|
||||
suitMask.set_nodrop(TRUE)
|
||||
suitGloves.set_nodrop(TRUE)
|
||||
suitGloves.pickpocket = 1
|
||||
suitShoes.set_nodrop(TRUE)
|
||||
suitShoes.slowdown = -2
|
||||
|
||||
icon_state = (user.gender == MALE ? "s-ninjan" : "s-ninjanf")
|
||||
suitGloves.icon_state = "s-ninjan"
|
||||
|
||||
return 1
|
||||
|
||||
else
|
||||
set_nodrop(FALSE)
|
||||
suitHood.set_nodrop(FALSE)
|
||||
suitMask.set_nodrop(FALSE)
|
||||
suitGloves.set_nodrop(FALSE)
|
||||
suitGloves.pickpocket = 0
|
||||
suitShoes.set_nodrop(FALSE)
|
||||
suitShoes.slowdown = -1
|
||||
icon_state = "s-ninja"
|
||||
suitGloves.icon_state = "s-ninja"
|
||||
|
||||
suitHood = null
|
||||
suitMask = null
|
||||
suitGloves = null
|
||||
suitShoes = null
|
||||
suitOccupant = null
|
||||
|
||||
return 1
|
||||
@@ -1,92 +0,0 @@
|
||||
|
||||
//Verbs link to procs because verb-like procs have a bug which prevents their use if the arguments are not readily referenced.
|
||||
//^ Old coder words may be false these days, Not taking the risk for now.
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/verb/toggle_suit()
|
||||
set category = "Space Ninja - Equipment"
|
||||
set name = "Toggle Suit"
|
||||
|
||||
if(usr.mind.special_role == "Ninja")
|
||||
if(suitBusy)
|
||||
to_chat(usr, "<span style='color: #ff0000;'><b>ERROR: </b>Suit systems busy, cannot initiate [suitActive ? "de-activation" : "activation"] protocols at this time.</span>")
|
||||
return
|
||||
|
||||
suitBusy = 1
|
||||
|
||||
if(suitActive && (tgui_alert(usr, "Confirm suit systems shutdown? This cannot be halted once it has started.", "Confirm Shutdown", list("Yes", "No")) == "Yes"))
|
||||
to_chat(usr, SPAN_DARKMBLUE("Now de-initializing..."))
|
||||
|
||||
sleep(15)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Logging off, [usr.real_name]. Shutting down <b>SpiderOS</b>."))
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Primary system status: <B>OFFLINE</B>.\nBackup system status: <b>OFFLINE</b>."))
|
||||
|
||||
sleep(5)
|
||||
to_chat(usr, SPAN_DARKMBLUE("VOID-shift device status: <B>OFFLINE</B>.\nCLOAK-tech device status: <B>OFFLINE</B>."))
|
||||
//TODO: Shut down any active abilities
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Disconnecting neural-net interface...</span> <span style='color: #32CD32'><b>Success</b>."))
|
||||
|
||||
QDEL_NULL(usr.hud_used)
|
||||
usr.create_mob_hud()
|
||||
usr.regenerate_icons()
|
||||
|
||||
sleep(5)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Disengaging neural-net interface...</span> <span style='color: #32CD32'><b>Success</b>."))
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: <B>FINISHED</B>."))
|
||||
//TODO: Grant verbs
|
||||
toggle_suit_lock(usr)
|
||||
usr.regenerate_icons()
|
||||
suitBusy = 0
|
||||
suitActive = 0
|
||||
|
||||
else if(!suitActive) // Activate the suit.
|
||||
to_chat(usr, SPAN_DARKMBLUE("Now initializing..."))
|
||||
|
||||
sleep(15)
|
||||
to_chat(usr, "<span class='darkmblue'>Now establishing neural-net interface...")
|
||||
if(usr.mind.special_role != "Ninja")
|
||||
to_chat(usr, "<span style='color: #ff0000;'><b>FĆAL �Rr�R</b>: ŧer nt recgnized, c-cntr-r䣧-ç äcked.")
|
||||
return
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Neural-net established. Now monitoring brainwave pattern. \nBrainwave pattern</span> <span style='color: #32CD32;'><b>GREEN</b></span><span class='darkmblue'>, proceeding."))
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Securing external locking mechanism..."))
|
||||
if(!toggle_suit_lock(usr))
|
||||
return
|
||||
|
||||
sleep(5)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Suit secured, extending neural-net interface..."))
|
||||
|
||||
QDEL_NULL(usr.hud_used)
|
||||
usr.hud_used = new /datum/hud/human(usr, 'icons/mob/screen_ninja.dmi', "#ffffff", 255)
|
||||
if(usr.hud_used)
|
||||
usr.hud_used.show_hud(usr.hud_used.hud_version)
|
||||
usr.regenerate_icons()
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("VOID-shift device status: <b>ONLINE</b>.\nCLOAK-tech device status:<b>ONLINE</b>"))
|
||||
|
||||
sleep(5)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Primary system status: <b>ONLINE</b>.\nBackup system status: <b>ONLINE</b>."))
|
||||
if(suitCell)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Current energy capacity: <b>[suitCell.charge]/[suitCell.maxcharge]</b>."))
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("All systems operational. Welcome to <b>SpiderOS</b>, [usr.real_name]."))
|
||||
//TODO: Grant ninja verbs here.
|
||||
suitBusy = 0
|
||||
suitActive = 1
|
||||
|
||||
else
|
||||
suitBusy = 0
|
||||
to_chat(usr, SPAN_DARKMBLUE("<b>NOTICE: </b>Suit de-activation protocols aborted."))
|
||||
else
|
||||
to_chat(usr, "<span style='color: #ff0000;'><b>FĆAL �Rr�R</b>: ŧer nt recgnized, c-cntr-r䣧-ç äcked.")
|
||||
return
|
||||
@@ -105,6 +105,9 @@
|
||||
else if(!rad_component)
|
||||
start_rads()
|
||||
|
||||
/obj/item/nuclear_rod/proc/do_special_effect()
|
||||
return
|
||||
|
||||
/obj/item/nuclear_rod/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change)
|
||||
. = ..()
|
||||
check_rad_shield()
|
||||
@@ -164,6 +167,17 @@
|
||||
craftable = TRUE
|
||||
materials = list(MAT_METAL = 2000, MAT_URANIUM = 1000)
|
||||
|
||||
/obj/item/nuclear_rod/fuel/uranium_238/spiders
|
||||
name = "spider-clan uranium 238 fuel rod"
|
||||
desc = "A small fuel rod for most NGCR reactors. This one was green webs coating its surface, with tiny spiders skittering along them."
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
craftable = FALSE
|
||||
adjacent_requirements = list()
|
||||
|
||||
/obj/item/nuclear_rod/fuel/uranium_238/spiders/do_special_effect()
|
||||
if(prob(5))
|
||||
new /mob/living/basic/spiderling(get_turf(src))
|
||||
|
||||
/obj/item/nuclear_rod/fuel/weak_thorium
|
||||
name = "weak thorium fuel rod"
|
||||
desc = "A specialized fuel rod refined from uranium 238. This rod will last longer than normal, and won't generate as much heat."
|
||||
|
||||
@@ -605,6 +605,7 @@
|
||||
final_heat += heat_total
|
||||
final_power += power_total
|
||||
chamber.held_rod.durability -= durability_loss
|
||||
chamber.held_rod.do_special_effect()
|
||||
|
||||
if(final_heat)
|
||||
average_heatgen = final_heat / active_chambers
|
||||
|
||||
@@ -245,6 +245,9 @@
|
||||
/// How long has it been since we processed the crystal?
|
||||
var/tick_counter = 0
|
||||
|
||||
/// Are we being stolen?
|
||||
var/being_stolen = FALSE
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -697,12 +700,31 @@
|
||||
countdown()
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/update_overlays()
|
||||
. = ..()
|
||||
overlays.Cut()
|
||||
if(being_stolen)
|
||||
. += "causality_field"
|
||||
color = COLOR_GREEN
|
||||
else
|
||||
color = COLOR_WHITE
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/bullet_act(obj/projectile/proj)
|
||||
var/turf/L = loc
|
||||
if(!istype(L))
|
||||
return FALSE
|
||||
if(!istype(proj, /obj/projectile/beam/emitter/hitscan) && power_changes)
|
||||
investigate_log("has been hit by [proj] fired by [key_name(proj.firer)]", INVESTIGATE_SUPERMATTER)
|
||||
if(istype(proj, /obj/projectile/energy/net))
|
||||
var/mob/living/carbon/user = proj.firer
|
||||
var/list/obj_list = user.mind.get_all_objectives()
|
||||
for(var/datum/objective/ninja/ninja_obj in obj_list)
|
||||
if(ninja_obj.completed)
|
||||
continue
|
||||
if(!istype(ninja_obj, /datum/objective/ninja/steal_supermatter))
|
||||
continue
|
||||
begin_theft()
|
||||
return FALSE
|
||||
if(proj.flag != BULLET)
|
||||
if(power_changes) //This needs to be here I swear
|
||||
power += proj.damage * bullet_energy
|
||||
@@ -712,6 +734,32 @@
|
||||
damage += proj.damage * bullet_energy
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/proc/begin_theft(mob/living/carbon/thief)
|
||||
if(being_stolen)
|
||||
return
|
||||
message_admins("Ninja [thief] is beginning to steal the Supermatter Crystal.")
|
||||
addtimer(src, CALLBACK(PROC_REF(complete_theft), thief), 3 MINUTES)
|
||||
being_stolen = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/proc/complete_theft(mob/living/carbon/thief)
|
||||
if(!being_stolen)
|
||||
return
|
||||
if(!thief.mind)
|
||||
return
|
||||
var/list/obj_list = thief.mind.get_all_objectives()
|
||||
if(!length(obj_list))
|
||||
return
|
||||
for(var/datum/objective/ninja/ninja_obj in obj_list)
|
||||
if(ninja_obj.completed)
|
||||
continue
|
||||
if(!istype(ninja_obj, /datum/objective/ninja/steal_supermatter))
|
||||
continue
|
||||
ninja_obj.complete_objective()
|
||||
break
|
||||
message_admins("Ninja [thief] has stolen the Supermatter Crystal.")
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/singularity_act()
|
||||
var/gain = 100
|
||||
investigate_log("Supermatter shard consumed by singularity.", INVESTIGATE_SINGULO)
|
||||
@@ -796,6 +844,15 @@
|
||||
/obj/machinery/atmospherics/supermatter_crystal/item_interaction(mob/living/user, obj/item/used, list/modifiers)
|
||||
if(!istype(used) || (used.flags & ABSTRACT) || !istype(user))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(being_stolen)
|
||||
to_chat(user, SPAN_WARNING("You begin to very carefully unfasten the net tangled around [src]!"))
|
||||
if(!do_after_once(user, 5 SECONDS, TRUE, src))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
being_stolen = FALSE
|
||||
update_icon()
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(moveable && default_unfasten_wrench(user, used, time = 20))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 811 KiB After Width: | Height: | Size: 768 KiB |
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 263 KiB After Width: | Height: | Size: 254 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 109 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 632 B |
|
After Width: | Height: | Size: 547 B |
|
After Width: | Height: | Size: 506 B |
|
After Width: | Height: | Size: 546 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 508 B |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 440 B |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 674 B |
|
After Width: | Height: | Size: 1016 B |
|
Before Width: | Height: | Size: 875 B After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 594 B After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 22 KiB |