diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index 5eb6c3b54fc..b0e8290ffee 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -13,7 +13,7 @@
/obj/structure/ninjatele
name = "Long-Distance Teleportation Console"
- desc = "A console used to send a Spider Clan agent long distances rapidly."
+ desc = "A console used to send a Spider Clan operative long distances rapidly."
icon = 'icons/obj/ninjaobjects.dmi'
icon_state = "teleconsole"
anchored = 1
diff --git a/code/game/objects/items/weapons/power_cells.dm b/code/game/objects/items/weapons/power_cells.dm
index 7424f685ef8..1756935eacb 100644
--- a/code/game/objects/items/weapons/power_cells.dm
+++ b/code/game/objects/items/weapons/power_cells.dm
@@ -128,6 +128,13 @@
name = "pulse pistol power cell"
maxcharge = 1600
+/obj/item/weapon/stock_parts/cell/ninja
+ name = "spider-clan power cell"
+ desc = "A standard ninja-suit power cell."
+ maxcharge = 10000
+ rating = 3
+ g_amt = 60
+
/obj/item/weapon/stock_parts/cell/emproof
name = "\improper EMP-proof cell"
desc = "An EMP-proof cell."
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 61dbe8e5e5c..38a08c66b45 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -416,6 +416,7 @@
for(var/mob/O in viewers(user, 4))
O.show_message("\blue The [src] was sliced apart by [user]!", 1, "\red You hear [src] coming apart.", 2)
destroy()
+ return
if(!(W.flags & ABSTRACT))
if(user.drop_item())
@@ -427,7 +428,7 @@
//Clamp it so that the icon never moves more than 16 pixels in either direction (thus leaving the table turf)
W.pixel_x = Clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2)
W.pixel_y = Clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2)
-
+
return
/obj/structure/table/proc/straight_table_check(var/direction)
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index 7f592a2405b..77e31587c41 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -8,6 +8,7 @@
//var/darkness_view = 0//Base human is 2
//var/invisa_view = 0
var/prescription = 0
+ var/see_darkness = 1
/obj/item/clothing/glasses/meson
name = "Optical Meson Scanner"
@@ -20,13 +21,14 @@
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi'
)
-
+
/obj/item/clothing/glasses/meson/night
name = "Night Vision Optical Meson Scanner"
desc = "An Optical Meson Scanner fitted with an amplified visible light spectrum overlay, providing greater visual clarity in darkness."
icon_state = "nvgmeson"
item_state = "glasses"
darkness_view = 8
+ see_darkness = 0
/obj/item/clothing/glasses/meson/prescription
name = "prescription mesons"
@@ -49,7 +51,7 @@
desc = "nothing"
icon_state = "purple"
item_state = "glasses"
-
+
/obj/item/clothing/glasses/janitor
name = "Janitorial Goggles"
desc = "These'll keep the soap out of your eyes."
@@ -63,6 +65,7 @@
item_state = "glasses"
origin_tech = "magnets=2"
darkness_view = 8
+ see_darkness = 0
species_fit = list("Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi'
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index 47d9875c2a9..9a52deadebc 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -26,6 +26,7 @@
icon_state = "healthhudnight"
item_state = "glasses"
darkness_view = 8
+ see_darkness = 0
/obj/item/clothing/glasses/hud/health/process_hud(var/mob/M)
process_med_hud(M,1)
@@ -53,6 +54,7 @@
desc = "An advanced heads-up display which provides id data and vision in complete darkness."
icon_state = "securityhudnight"
darkness_view = 8
+ see_darkness = 0
/obj/item/clothing/glasses/hud/security/process_hud(var/mob/M)
diff --git a/code/modules/clothing/spacesuits/space_ninja.dm b/code/modules/clothing/spacesuits/space_ninja.dm
new file mode 100644
index 00000000000..acc53c3dc40
--- /dev/null
+++ b/code/modules/clothing/spacesuits/space_ninja.dm
@@ -0,0 +1,350 @@
+// ** BEGIN NINJA CLOTHING DEFINES **
+
+/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"
+ item_state = "s-ninja_hood"
+ armor = list(melee = 60, bullet = 60, laser = 45, energy = 15, bomb = 30, bio = 30, rad = 25)
+ unacidable = 1
+ siemens_coefficient = 0.2
+
+
+/obj/item/clothing/mask/gas/voice/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)"
+ item_state = "s-ninja_mask"
+ unacidable = 1
+ siemens_coefficient = 0.2
+
+/obj/item/clothing/glasses/hud/space_ninja
+ name = "vision enhancement implant"
+ desc = "A high-tech ocular implant designed for Spider Clan operatives."
+ icon_state = "cybereye-off"
+ item_state = "eyepatch"
+ flags = NODROP
+
+ var/enabled = 0
+ var/energyConsumption = 0
+ var/antagHUDEnabled = 0
+ var/mesonEnabled = 0
+ var/materialEnabled = 0
+ var/thermalEnabled = 0
+
+/obj/item/clothing/suit/space/space_ninja
+ name = "ninja suit"
+ desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
+ icon_state = "s-ninja"
+ item_state = "s-ninja_suit"
+ allowed = list(/obj/item/weapon/gun, /obj/item/ammo_box, /obj/item/weapon/melee/baton, /obj/item/weapon/tank, /obj/item/weapon/stock_parts/cell)
+ slowdown = 0
+ unacidable = 1
+ armor = list(melee = 60, bullet = 60, laser = 45,energy = 15, bomb = 30, bio = 30, rad = 30)
+ siemens_coefficient = 0.2
+
+ var/suitActive = 0
+ var/suitBusy = 0
+
+ var/obj/item/weapon/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/voice/space_ninja/suitMask
+ var/obj/item/clothing/glasses/hud/space_ninja/suitGlasses
+ var/mob/living/carbon/human/suitOccupant
+
+/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"
+ item_state = "s-ninja"
+ siemens_coefficient = 0
+ cold_protection = HANDS
+ min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE
+ heat_protection = HANDS
+ max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE
+ transfer_prints = FALSE
+
+
+/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
+ flags = NOSLIP
+ armor = list(melee = 60, bullet = 60, laser = 45,energy = 15, bomb = 30, bio = 30, rad = 30)
+ siemens_coefficient = 0.2
+ cold_protection = FEET
+ min_cold_protection_temperature = SHOE_MIN_COLD_PROTECTION_TEMPERATURE
+ heat_protection = FEET
+ max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE
+
+// ** END NINJA CLOTHING DEFINES **
+
+// ** BEGIN NINJA SUIT PROCS **
+
+/obj/item/clothing/suit/space/space_ninja/New()
+ suitCell = new/obj/item/weapon/stock_parts/cell/ninja // The Ninja starts out with a 10,000 energy cell.
+ if(suitCell.charge != suitCell.maxcharge)
+ suitCell.charge = suitCell.maxcharge
+
+/obj/item/clothing/suit/space/space_ninja/verb/toggle_suit()
+ set category = "Space Ninja - Equiptment"
+ set name = "Toggle Suit"
+
+ if(usr.mind.special_role == "Ninja")
+ if(suitBusy)
+ usr << "ERROR: Suit systems busy, cannot initiate [suitActive ? "de-activation" : "activation"] protocals at this time."
+ return
+
+ suitBusy = 1
+
+ if(suitActive && (alert("Confirm suit systems shutdown? This cannot be halted once it has started.", "Confirm Shutdown", "Yes", "No") == "Yes"))
+ usr << "Now de-initializing..."
+
+ sleep(15)
+ usr << "Logging off, [usr.real_name]. Shutting down SpiderOS."
+
+ sleep(10)
+ usr<< "Primary system status: OFFLINE.\nBackup system status: OFFLINE."
+
+ sleep(5)
+ usr<< "VOID-shift device status: OFFLINE.\nCLOAK-tech device status: OFFLINE."
+ //TODO: Shut down any active abilities
+
+ sleep(10)
+ usr<< "Disconnecting neural-net interface... Success."
+ usr.hud_used.instantiate()
+ usr.regenerate_icons()
+
+ sleep(5)
+ usr<< "Disengaging neural-net interface... Success."
+
+ sleep(10)
+ usr<< "Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: FINISHED."
+ //TODO: Grant verbs
+ toggle_suit_lock(usr)
+ usr.regenerate_icons()
+ suitBusy = 0
+ suitActive = 0
+
+ else if(!suitActive) // Activate the suit.
+ usr << "Now initializing..."
+
+ sleep(15)
+ usr<< "Now establishing neural-net interface..."
+ if(usr.mind.special_role != "Ninja")
+ usr << "FĆAL �Rr�R: µ§er n¤t rec¤gnized, c-c¤ntr-r¤£§-£§ £¤cked."
+ return
+
+ sleep(10)
+ usr<< "Neural-net established. Now monitoring brainwave pattern. \nBrainwave pattern GREEN, proceeding."
+
+ sleep(10)
+ usr<< "Securing external locking mechanism..."
+ if(!toggle_suit_lock(usr))
+ return
+
+ sleep(5)
+ usr<< "Suit secured, extending neural-net interface..."
+ usr.hud_used.human_hud('icons/mob/screen1_NinjaHUD.dmi',"#ffffff",255)
+ usr.regenerate_icons()
+
+ sleep(10)
+ usr<< "VOID-shift device status: ONLINE.\nCLOAK-tech device status:ONLINE"
+
+ sleep(5)
+ usr<< "Primary system status: ONLINE.\nBackup system status: ONLINE.\nCurrent energy capacity: [suitCell.charge]/[suitCell.maxcharge]."
+
+ sleep(10)
+ usr<< "All systems operational. Welcome to SpiderOS, [usr.real_name]."
+ //TODO: Grant ninja verbs here.
+ suitBusy = 0
+ suitActive = 1
+
+ else
+ suitBusy = 0
+ usr << "NOTICE: Suit de-activation protocals aborted."
+ else
+ usr << "FĆAL �Rr�R: µ§er n¤t rec¤gnized, c-c¤ntr-r¤£§-£§ £¤cked."
+ return
+
+/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))
+ user<< "ERROR: Unable to locate user.\nABORTING..."
+ return 0
+ if(!istype(user.head, /obj/item/clothing/head/helmet/space/space_ninja))
+ user<< "ERROR: Unable to locate hood.\nABORTING..."
+ return 0
+ if(!istype(user.gloves, /obj/item/clothing/gloves/space_ninja))
+ user<< "ERROR: Unable to locate gloves.\nABORTING..."
+ return 0
+ if(!istype(user.shoes, /obj/item/clothing/shoes/space_ninja))
+ user<< "ERROR: Unable to locate foot gear.\nABORTING..."
+ return 0
+ if(!istype(user.wear_mask, /obj/item/clothing/mask/gas/voice/space_ninja))
+ user<< "ERROR: Unable to locate mask.\nABORTING..."
+ return 0
+ if(!istype(user.glasses, /obj/item/clothing/glasses/hud/space_ninja))
+ user<< "WARNING: Unable to locate eye gear, vision enhancement unavailable.\nProceeding..."
+ else
+ suitGlasses = user.glasses
+ suitGlasses.enabled = 1
+ suitGlasses.icon_state = "cybereye-green"
+
+ suitHood = user.head
+ suitMask = user.wear_mask
+ suitGloves = user.gloves
+ suitShoes = user.shoes
+ suitOccupant = user
+
+ flags |= NODROP
+ suitHood.flags |= NODROP
+ suitMask.flags |= NODROP
+ suitGloves.flags |= NODROP
+ suitGloves.pickpocket = 1
+ suitShoes.flags |= NODROP
+ suitShoes.slowdown = -2
+
+ icon_state = (user.gender == MALE ? "s-ninjan" : "s-ninjanf")
+ suitGloves.icon_state = "s-ninjan"
+ suitGloves.item_state = "s-ninjan"
+
+ return 1
+
+ else
+ flags &= ~NODROP
+ suitHood.flags &= ~NODROP
+ suitMask.flags &= ~NODROP
+ if(suitGlasses)
+ suitGlasses.enabled = 0
+ suitGlasses.icon_state = "cybereye-off"
+ suitGloves.flags &= ~NODROP
+ suitGloves.pickpocket = 0
+ suitShoes.flags &= ~NODROP
+ suitShoes.slowdown = -1
+ icon_state = "s-ninja"
+ suitGloves.icon_state = "s-ninja"
+ suitGloves.item_state = "s-ninja"
+
+ suitHood = null
+ suitMask = null
+ suitGlasses = null
+ suitGloves = null
+ suitShoes = null
+ suitOccupant = null
+
+ return 1
+
+// ** END NINJA SUIT PROCS **
+
+// **BEGIN NINJA GLASSES PROCS**
+
+/obj/item/clothing/glasses/hud/space_ninja/process_hud(var/mob/M) // Antag HUD processing.
+
+ if(antagHUDEnabled) // We only process if the antag-vision mode is enabled.
+ if(!M) return
+ if(!M.client) return
+ var/client/C = M.client
+ for(var/mob/living/carbon/human/target in view(get_turf(M)))
+ if(M.see_invisible < target.invisibility)
+ continue
+ if(!C) continue
+ C.images += target.hud_list[SPECIALROLE_HUD]
+
+/obj/item/clothing/glasses/hud/space_ninja/verb/modifyHUD(mob/user as mob)
+ set category = "Space Ninja - Equiptment"
+ set name = "Modify Vision"
+
+ if(usr.mind.special_role != "Ninja")
+ usr << "FĆAL �Rr�R: µ§er n¤t rec¤gnized, c-c¤ntr-r¤£§-£§ £¤cked."
+ return
+
+ if(!enabled) // If the Ninja's suit is on and connected.
+ usr << "ERROR: No power supply detected, cannot activate optical implant."
+ return
+
+ if(!user) // The user var is, so far as I can tell, required to refresh the window after each click.
+ user = usr
+
+ /*
+ * Each vision type the Ninja enables will drain more from his suit's battery per tick.
+ * For instance, if the Ninja were to rn around with thermals and AntagHUD on he would be losing an additional 10 energy per tick.
+ * Current vision modes are:
+ * - Night
+ * - Meson (Turfs)
+ * - Material (Objects)
+ * - Thermal (Mobs)
+ * - Antag HUD
+ *
+ * -Dave
+ */
+ var/dat = {"
+ Night Vision (2E) - [darkness_view ? "ENABLED" : "DISABLED"]
+ Meson Scanner (2E) - [mesonEnabled ? "ENABLED" : "DISABLED"]
+ Material Scanner (4E) - [materialEnabled ? "ENABLED" : "DISABLED"]
+ Thermal Scanner (4E) - [thermalEnabled ? "ENABLED" : "DISABLED"]
+ Threat Identification HUD (6E) - [antagHUDEnabled ? "ENABLED" : "DISABLED"]
+ "}
+
+ var/datum/browser/popup = new(user, "SpiderOS", "SpiderOS Optical Interface", 310, 150)
+ popup.set_content(dat)
+ popup.open()
+
+
+/obj/item/clothing/glasses/hud/space_ninja/Topic(href, href_list)
+ if(usr.stat != 0 || !enabled)
+ return 1
+
+ if(href_list["night"])
+ darkness_view = (darkness_view ? 0 : 8)
+ see_darkness = (darkness_view ? 0 : 1)
+ energyConsumption += (darkness_view ? 2 : -2)
+ usr << "Light amplification [(darkness_view ? "ENABLED" : "DISABLED")]."
+
+ else if(href_list["meson"])
+ mesonEnabled = (mesonEnabled ? 0 : 1)
+
+ if(mesonEnabled)
+ vision_flags |= SEE_TURFS
+ else
+ vision_flags &= ~SEE_TURFS
+
+ energyConsumption += (mesonEnabled ? 2 : -2)
+ usr << "Meson scanning [(mesonEnabled ? "ENABLED" : "DISABLED")]."
+
+ else if(href_list["material"])
+ materialEnabled = (materialEnabled ? 0 : 1)
+
+ if(materialEnabled)
+ vision_flags |= SEE_OBJS
+ else
+ vision_flags &= ~SEE_OBJS
+
+ energyConsumption += (materialEnabled ? 4 : -4)
+ usr << "Material scanning [(materialEnabled ? "ENABLED" : "DISABLED")]."
+
+ else if(href_list["thermal"])
+ thermalEnabled = (thermalEnabled ? 0 : 1)
+
+ if(thermalEnabled)
+ vision_flags |= SEE_MOBS
+ invisa_view = 2
+ else
+ vision_flags &= ~SEE_MOBS
+ invisa_view = 0
+
+ energyConsumption += (thermalEnabled ? 4 : -4)
+ usr << "Thermal scanning [(thermalEnabled ? "ENABLED" : "DISABLED")]."
+
+ else if(href_list["antagHUD"])
+ antagHUDEnabled = (antagHUDEnabled ? 0 : 1)
+ energyConsumption += (antagHUDEnabled ? 6 : -6)
+ usr << "Threat identification HUD [(antagHUDEnabled ? "ENABLED" : "DISABLED")]."
+
+ modifyHUD(usr) // Re-call the verb to get a fresh version of the window.
+ return
+
+// **END NINJA GLASSES PROCS**
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 5ef569596cf..440252a136c 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -1230,12 +1230,12 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(glasses)
var/obj/item/clothing/glasses/G = glasses
if(istype(G))
- see_in_dark += G.darkness_view
+ see_in_dark = (G.darkness_view ? see_in_dark + G.darkness_view : species.darksight) // Otherwise we keep our darkness view with togglable nightvision.
if(G.vision_flags) // MESONS
sight |= G.vision_flags
if(!druggy)
see_invisible = SEE_INVISIBLE_MINIMUM
- if(istype(G,/obj/item/clothing/glasses/night))
+ if(!G.see_darkness)
see_invisible = SEE_INVISIBLE_MINIMUM
/* HUD shit goes here, as long as it doesn't modify sight flags */
// The purpose of this is to stop xray and w/e from preventing you from using huds -- Love, Doohl
@@ -1245,15 +1245,13 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(istype(glasses, /obj/item/clothing/glasses/sunglasses/sechud))
var/obj/item/clothing/glasses/sunglasses/sechud/O = glasses
if(O.hud) O.hud.process_hud(src)
- if(!druggy) see_invisible = SEE_INVISIBLE_LIVING
+ if(!druggy) see_invisible = (!O.see_darkness || O.vision_flags ? SEE_INVISIBLE_MINIMUM : SEE_INVISIBLE_LIVING) // So we can have meson/thermal/material sunglasses
if(istype(glasses, /obj/item/clothing/glasses/hud))
var/obj/item/clothing/glasses/hud/O = glasses
O.process_hud(src)
if(!druggy)
- see_invisible = SEE_INVISIBLE_LIVING
- if(istype(O,/obj/item/clothing/glasses/hud/security/night) || istype(O,/obj/item/clothing/glasses/hud/health/night))
- see_invisible = SEE_INVISIBLE_MINIMUM
+ see_invisible = (!O.see_darkness || O.vision_flags ? SEE_INVISIBLE_MINIMUM : SEE_INVISIBLE_LIVING)
else if(!seer)
see_in_dark = species.darksight
see_invisible = SEE_INVISIBLE_LIVING
diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi
index 9a066c9eb3f..1a34c2836cb 100644
Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ
diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi
index 6652a1f6acd..2a425ddf251 100644
Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ
diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi
index 9dcc7b4735c..efcefe0cad9 100644
Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ
diff --git a/icons/obj/ninjaobjects.dmi b/icons/obj/ninjaobjects.dmi
index d57727cdc73..9e2288d786c 100644
Binary files a/icons/obj/ninjaobjects.dmi and b/icons/obj/ninjaobjects.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 27274de9efa..9dd76ebc48c 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -993,6 +993,7 @@
#include "code\modules\clothing\spacesuits\miscellaneous.dm"
#include "code\modules\clothing\spacesuits\plasmamen.dm"
#include "code\modules\clothing\spacesuits\rig.dm"
+#include "code\modules\clothing\spacesuits\space_ninja.dm"
#include "code\modules\clothing\spacesuits\syndi.dm"
#include "code\modules\clothing\spacesuits\void.dm"
#include "code\modules\clothing\suits\alien.dm"