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
This commit is contained in:
PollardTheDragon
2026-03-25 19:11:10 -04:00
committed by GitHub
parent 3e8f140498
commit 394c3b0108
120 changed files with 2616 additions and 1184 deletions
File diff suppressed because it is too large Load Diff
+1
View File
@@ -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.
+2
View File
@@ -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,
+1
View File
@@ -14,6 +14,7 @@ GLOBAL_LIST_INIT(antag_roles, list(
ROLE_GUARDIAN,
ROLE_MORPH,
ROLE_TSPIDER,
ROLE_NINJA,
))
// Bannable other roles
+1
View File
@@ -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"
+1 -1
View File
@@ -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)
+32
View File
@@ -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)
+39 -2
View File
@@ -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"
+7 -7
View File
@@ -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."
+1 -1
View File
@@ -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"
+25 -25
View File
@@ -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)
+2
View File
@@ -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
+352
View File
@@ -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
+11
View File
@@ -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
+5 -1
View File
@@ -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 ..()
+10 -10
View File
@@ -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 RrR")]: ŧ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."
+2 -2
View File
@@ -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',
+1 -1
View File
@@ -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)
+86
View File
@@ -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()
+20 -2
View File
@@ -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',
+55
View File
@@ -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)
+19
View File
@@ -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
+74
View File
@@ -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)
-76
View File
@@ -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 ..()
+101
View File
@@ -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()
+195
View File
@@ -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"
+181
View File
@@ -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)
+54
View File
@@ -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,
)
+143
View File
@@ -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 ..()
+91
View File
@@ -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
+227
View File
@@ -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()
-12
View File
@@ -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
-10
View File
@@ -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
-28
View File
@@ -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 ..()
-12
View File
@@ -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
-87
View File
@@ -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 RrR</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 RrR</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
Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 811 KiB

After

Width:  |  Height:  |  Size: 768 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 KiB

After

Width:  |  Height:  |  Size: 254 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1016 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 875 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 594 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Some files were not shown because too many files have changed in this diff Show More