mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 03:27:05 +01:00
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:
@@ -433,8 +433,8 @@
|
||||
if(length(SSticker.mode.apprentices))
|
||||
dat += check_role_table("Apprentices", SSticker.mode.apprentices)
|
||||
|
||||
/*if(length(ticker.mode.ninjas))
|
||||
dat += check_role_table("Ninjas", ticker.mode.ninjas)*/
|
||||
if(length(SSticker.mode.ninjas))
|
||||
dat += check_role_table("Ninjas", SSticker.mode.ninjas)
|
||||
|
||||
if(SSticker.mode.cult_team)
|
||||
dat += check_role_table("Cultists", SSticker.mode.cult_team.members)
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
RESTRICT_TYPE(/datum/antagonist/space_ninja)
|
||||
|
||||
// Spider Clan Space Ninja
|
||||
/datum/antagonist/space_ninja
|
||||
name = "Space Ninja"
|
||||
roundend_category = "ninjas"
|
||||
job_rank = ROLE_NINJA
|
||||
special_role = SPECIAL_ROLE_NINJA
|
||||
antag_hud_name = "hud_ninja"
|
||||
antag_hud_type = ANTAG_HUD_NINJA
|
||||
clown_gain_text = "Your spider clan training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself."
|
||||
clown_removal_text = "You lose your spider clan training and return to your own clumsy, clownish self."
|
||||
wiki_page_name = "Space Ninja"
|
||||
var/give_uplink = TRUE
|
||||
blurb_r = 200
|
||||
blurb_a = 0.75
|
||||
boss_title = "Spider Clan Daimyo"
|
||||
/// Number of missions needed to complete
|
||||
var/mission_goal = 4
|
||||
|
||||
/datum/antagonist/space_ninja/on_gain()
|
||||
..()
|
||||
mission_goal = 4 + (length(GLOB.crew_list) / 10)
|
||||
SEND_SOUND(owner.current, sound('sound/ambience/antag/ninjaalert.ogg'))
|
||||
|
||||
/datum/antagonist/space_ninja/give_objectives()
|
||||
forge_objectives()
|
||||
|
||||
/datum/antagonist/space_ninja/exfiltrate(mob/living/carbon/human/extractor, obj/item/radio/radio)
|
||||
extractor.equipOutfit(/datum/outfit/admin/ghostbar_antag/space_ninja)
|
||||
radio.autosay("<b>--ZZZT!- Domo Ar!g@to, [extractor.real_name]. Your training paid -^%&!-ZZT!-</b>", "Spider Clan HQ", "Security")
|
||||
SSblackbox.record_feedback("tally", "successful_extraction", 1, "Space Ninja")
|
||||
|
||||
/datum/antagonist/space_ninja/finalize_antag()
|
||||
. = ..()
|
||||
equip_ninja()
|
||||
|
||||
/datum/antagonist/space_ninja/add_owner_to_gamemode()
|
||||
SSticker.mode.ninjas |= owner
|
||||
|
||||
/datum/antagonist/space_ninja/remove_owner_from_gamemode()
|
||||
SSticker.mode.ninjas -= owner
|
||||
|
||||
/datum/antagonist/space_ninja/proc/equip_ninja()
|
||||
if(!ishuman(owner.current))
|
||||
return
|
||||
var/mob/living/carbon/human/new_ninja = owner.current
|
||||
new_ninja.delete_equipment()
|
||||
if(isvox(new_ninja))
|
||||
new_ninja.equipOutfit(/datum/outfit/space_ninja/vox)
|
||||
else
|
||||
new_ninja.equipOutfit(/datum/outfit/space_ninja)
|
||||
|
||||
/datum/antagonist/space_ninja/proc/forge_objectives()
|
||||
var/list/moderate_objectives = list(
|
||||
/datum/objective/ninja/capture = 8,
|
||||
/datum/objective/ninja/kill = 8,
|
||||
/datum/objective/ninja/hack_rnd = 5,
|
||||
/datum/objective/ninja/bomb_department/emp = 3,
|
||||
/datum/objective/ninja/bomb_department/spiders = 3,
|
||||
)
|
||||
var/list/all_ninja_objectives = list(
|
||||
/datum/objective/ninja/capture = 8,
|
||||
/datum/objective/ninja/kill = 8,
|
||||
/datum/objective/ninja/hack_rnd = 4,
|
||||
/datum/objective/ninja/bomb_department = 3,
|
||||
/datum/objective/ninja/bomb_department/emp = 3,
|
||||
/datum/objective/ninja/bomb_department/spiders = 3,
|
||||
/datum/objective/ninja/steal_supermatter = 3,
|
||||
/datum/objective/ninja/insert_spider_rod = 3,
|
||||
/datum/objective/ninja/interrogate_ai = 3,
|
||||
)
|
||||
for(var/i in 1 to mission_goal)
|
||||
if(i <= mission_goal / 2) // This ensures some easier objectives are rolled to allow ninjas to work up to harder ones.
|
||||
forge_objective(moderate_objectives)
|
||||
continue
|
||||
forge_objective(all_ninja_objectives)
|
||||
add_antag_objective(/datum/objective/ninja_exfiltrate)
|
||||
|
||||
/datum/antagonist/space_ninja/proc/forge_objective(list/objective_list)
|
||||
|
||||
var/datum/objective/ninja/new_objective = pickweight(objective_list)
|
||||
var/datum/objective/ninja/obj_item = new new_objective() // Needed to do to check validity and reroll
|
||||
if(!obj_item.check_objective_conditions())
|
||||
forge_objective(objective_list)
|
||||
qdel(obj_item)
|
||||
return
|
||||
qdel(obj_item)
|
||||
if(new_objective.onlyone)
|
||||
var/list/current_objectives = get_antag_objectives()
|
||||
for(var/datum/objective/ninja/c_objective in current_objectives)
|
||||
if(istype(c_objective, new_objective))
|
||||
forge_objective(objective_list)
|
||||
return
|
||||
add_antag_objective(new_objective)
|
||||
@@ -7,6 +7,7 @@ GLOBAL_LIST_INIT(special_role_times, list(
|
||||
ROLE_TRAITOR = 7,
|
||||
ROLE_CHANGELING = 14,
|
||||
ROLE_WIZARD = 14,
|
||||
ROLE_NINJA = 14,
|
||||
ROLE_REV = 14,
|
||||
ROLE_VAMPIRE = 14,
|
||||
ROLE_BLOB = 14,
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
var/can_be_cut = 1
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/clothing/species/vox/gloves.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/skkulakin/gloves.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/vox/gloves.dmi',
|
||||
"Drask" = 'icons/mob/clothing/species/drask/gloves.dmi',
|
||||
"Grey" = 'icons/mob/clothing/species/grey/gloves.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/species/kidan/gloves.dmi',
|
||||
|
||||
@@ -177,7 +177,6 @@ GLOBAL_LIST_EMPTY(event_last_fired)
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/radiation_storm, 10, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/spider_infestation, 10, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/ion_storm, 10),
|
||||
//new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 15), TRUE),
|
||||
// NON-BAY EVENTS
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/mass_hallucination, 10),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, /datum/event/brand_intelligence, 5, TRUE),
|
||||
@@ -216,6 +215,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/demon_incursion, 10, TRUE, _first_run_time = 35 MINUTES),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/disease_outbreak, 8, TRUE),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/revenant, 9),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/space_ninja, 9),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_morph, 16, is_one_shot = TRUE),
|
||||
//new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_floor_cluwne, 15, is_one_shot = TRUE)
|
||||
//new /datum/event_meta(EVENT_LEVEL_MAJOR, /datum/event/spawn_pulsedemon, 20, is_one_shot = TRUE)
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/datum/event/space_ninja
|
||||
name = "Space Ninja"
|
||||
role_weights = list(ASSIGNMENT_SECURITY = 2)
|
||||
role_requirements = list(ASSIGNMENT_CREW = 20, ASSIGNMENT_SECURITY = 2)
|
||||
nominal_severity = EVENT_LEVEL_MAJOR
|
||||
|
||||
/datum/event/space_ninja/start()
|
||||
INVOKE_ASYNC(src, PROC_REF(poll_ninja))
|
||||
|
||||
/datum/event/space_ninja/proc/poll_ninja(list/potential_ninjas)
|
||||
var/list/candidates = list()
|
||||
if(!potential_ninjas)
|
||||
candidates = SSghost_spawns.poll_candidates("Do you want to play as a space ninja?", ROLE_NINJA, TRUE)
|
||||
else
|
||||
candidates = potential_ninjas
|
||||
if(!length(candidates))
|
||||
kill()
|
||||
return
|
||||
var/mob/new_ninja
|
||||
while(length(candidates))
|
||||
new_ninja = pick_n_take(candidates)
|
||||
if(jobban_isbanned(new_ninja, ROLE_TRAITOR))
|
||||
continue
|
||||
break
|
||||
if(!new_ninja)
|
||||
kill()
|
||||
return
|
||||
|
||||
var/gender_pref = input_async(new_ninja, "Please select a gender (10 seconds):", list("Male", "Female"))
|
||||
addtimer(CALLBACK(src, PROC_REF(get_species), candidates, new_ninja, gender_pref), 10 SECONDS)
|
||||
|
||||
/datum/event/space_ninja/proc/get_species(list/potential_ninjas, mob/new_ninja, datum/async_input/gender_pref)
|
||||
gender_pref.close()
|
||||
var/sel_gender = gender_pref.result
|
||||
if(!sel_gender) // Player was AFK and did not select a gender
|
||||
poll_ninja(potential_ninjas)
|
||||
return
|
||||
var/species_pref = input_async(new_ninja, "Please select a species (10 seconds):", list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin", "Nian", "Drask", "Kidan", "Grey", "Skkulakin", "Vox", "Slime", "Machine", "Random"))
|
||||
addtimer(CALLBACK(src, PROC_REF(create_ninja), potential_ninjas, new_ninja, sel_gender, species_pref), 10 SECONDS)
|
||||
|
||||
/datum/event/space_ninja/proc/create_ninja(list/potential_ninjas, mob/new_ninja, sel_gender, datum/async_input/species_pref)
|
||||
species_pref.close()
|
||||
var/sel_species = species_pref.result
|
||||
if(!sel_species) // Player was AFK and did not select a species
|
||||
poll_ninja(potential_ninjas)
|
||||
return
|
||||
if(!new_ninja || !new_ninja.client)
|
||||
poll_ninja(potential_ninjas)
|
||||
return
|
||||
|
||||
var/list/spawn_locs = list()
|
||||
for(var/obj/effect/landmark/spawner/ninja/N in GLOB.landmarks_list)
|
||||
spawn_locs += get_turf(N)
|
||||
if(!length(spawn_locs))
|
||||
message_admins("Unable to spawn ninja - no valid spawn locations.")
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/M = new(pick(spawn_locs))
|
||||
|
||||
M.ckey = new_ninja.ckey
|
||||
dust_if_respawnable(new_ninja)
|
||||
|
||||
if(sel_gender == "Male")
|
||||
M.change_gender(MALE)
|
||||
M.change_body_type(MALE)
|
||||
else
|
||||
M.change_gender(FEMALE)
|
||||
M.change_body_type(FEMALE)
|
||||
|
||||
if(sel_species == "Random")
|
||||
sel_species = pick("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin", "Nian", "Drask", "Kidan", "Grey", "Skkulakin", "Vox", "Slime", "Machine")
|
||||
if(sel_species == "Slime")
|
||||
sel_species = "Slime People"
|
||||
var/datum/species/S = GLOB.all_species[sel_species]
|
||||
var/species = S.type
|
||||
M.set_species(species, TRUE)
|
||||
M.dna.ready_dna(M)
|
||||
M.cleanSE()
|
||||
M.overeatduration = 0
|
||||
M.age = rand(23, 35)
|
||||
M.regenerate_icons()
|
||||
|
||||
M.mind = new
|
||||
M.mind.bind_to(M)
|
||||
M.mind.set_original_mob(M)
|
||||
M.mind.make_space_ninja()
|
||||
@@ -11,6 +11,11 @@
|
||||
permeability_coefficient = 0.01
|
||||
sprite_sheets = list(
|
||||
"Grey" = 'icons/mob/clothing/modsuit/species/grey_helmets.dmi',
|
||||
"Skrell" = 'icons/mob/clothing/modsuit/species/skrell_modsuits.dmi',
|
||||
"Nian" = 'icons/mob/clothing/modsuit/species/nian_modsuits.dmi',
|
||||
"Diona" = 'icons/mob/clothing/modsuit/species/diona_modsuits.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/modsuit/species/kidan_modsuits.dmi',
|
||||
"Drask" = 'icons/mob/clothing/modsuit/species/drask_modsuits.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/modsuit/species/vulp_modsuits.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/modsuit/species/taj_modsuits.dmi',
|
||||
"Unathi" = 'icons/mob/clothing/modsuit/species/unathi_modsuits.dmi',
|
||||
@@ -37,13 +42,17 @@
|
||||
insert_max = 0
|
||||
hide_tail_by_species = list("modsuit")
|
||||
sprite_sheets = list(
|
||||
"Skrell" = 'icons/mob/clothing/modsuit/species/skrell_modsuits.dmi',
|
||||
"Nian" = 'icons/mob/clothing/modsuit/species/nian_modsuits.dmi',
|
||||
"Diona" = 'icons/mob/clothing/modsuit/species/diona_modsuits.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/modsuit/species/kidan_modsuits.dmi',
|
||||
"Drask" = 'icons/mob/clothing/modsuit/species/drask_modsuits.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/modsuit/species/vulp_modsuits.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/modsuit/species/taj_modsuits.dmi',
|
||||
"Unathi" = 'icons/mob/clothing/modsuit/species/unathi_modsuits.dmi',
|
||||
"Vox" = 'icons/mob/clothing/modsuit/species/vox_modsuits.dmi'
|
||||
)
|
||||
|
||||
|
||||
/obj/item/clothing/gloves/mod
|
||||
name = "MOD gauntlets"
|
||||
desc = "A pair of gauntlets for a MODsuit."
|
||||
@@ -56,13 +65,17 @@
|
||||
cold_protection = HANDS|ARMS
|
||||
permeability_coefficient = 0.01
|
||||
sprite_sheets = list(
|
||||
"Skrell" = 'icons/mob/clothing/modsuit/species/skrell_modsuits.dmi',
|
||||
"Nian" = 'icons/mob/clothing/modsuit/species/nian_modsuits.dmi',
|
||||
"Diona" = 'icons/mob/clothing/modsuit/species/diona_modsuits.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/modsuit/species/kidan_modsuits.dmi',
|
||||
"Drask" = 'icons/mob/clothing/modsuit/species/drask_modsuits.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/modsuit/species/vulp_modsuits.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/modsuit/species/taj_modsuits.dmi',
|
||||
"Unathi" = 'icons/mob/clothing/modsuit/species/unathi_modsuits.dmi',
|
||||
"Vox" = 'icons/mob/clothing/modsuit/species/vox_modsuits.dmi'
|
||||
)
|
||||
|
||||
|
||||
/obj/item/clothing/shoes/mod
|
||||
name = "MOD boots"
|
||||
desc = "A pair of boots for a MODsuit."
|
||||
@@ -75,6 +88,11 @@
|
||||
cold_protection = FEET|LEGS
|
||||
permeability_coefficient = 0.01
|
||||
sprite_sheets = list(
|
||||
"Skrell" = 'icons/mob/clothing/modsuit/species/skrell_modsuits.dmi',
|
||||
"Nian" = 'icons/mob/clothing/modsuit/species/nian_modsuits.dmi',
|
||||
"Diona" = 'icons/mob/clothing/modsuit/species/diona_modsuits.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/modsuit/species/kidan_modsuits.dmi',
|
||||
"Drask" = 'icons/mob/clothing/modsuit/species/drask_modsuits.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/modsuit/species/vulp_modsuits.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/modsuit/species/taj_modsuits.dmi',
|
||||
"Unathi" = 'icons/mob/clothing/modsuit/species/unathi_modsuits.dmi',
|
||||
|
||||
@@ -1384,3 +1384,58 @@
|
||||
/// considering this should not be used, it's getting just DS armor, not infinity in everything.
|
||||
/obj/item/mod/armor/mod_theme_administrative
|
||||
armor = list(MELEE = 200, BULLET = 200, LASER = 50, ENERGY = 50, BOMB = INFINITY, RAD = INFINITY, FIRE = INFINITY, ACID = INFINITY)
|
||||
|
||||
/datum/mod_theme/ninja
|
||||
name = "'Shinobi' stealthsuit"
|
||||
desc = "A specialized modsuit worn by the spider clan's elite ninja operatives."
|
||||
default_skin = "ninja"
|
||||
armor_type_1 = /obj/item/mod/armor/mod_theme_ninja
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
flag_2_flags = RAD_PROTECT_CONTENTS_2
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
siemens_coefficient = 0
|
||||
slowdown_inactive = 1
|
||||
slowdown_active = 0.3
|
||||
ui_theme = "syndicate"
|
||||
allowed_suit_storage = list(
|
||||
/obj/item/katana/energy,
|
||||
/obj/item/wormhole_jaunter/ninja_bomb,
|
||||
/obj/item/throwing_star,
|
||||
/obj/item/restraints/legcuffs/bola,
|
||||
/obj/item/gun,
|
||||
/obj/item/ninja_scanner,
|
||||
)
|
||||
skins = list(
|
||||
"ninja" = list(
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_LAYER = null,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDMAGE | BLOCKHAIR,
|
||||
UNSEALED_INVISIBILITY = HIDEFACE,
|
||||
SEALED_INVISIBILITY = HIDEMASK | HIDEEYES | HIDEEARS | HIDEFACE,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH,
|
||||
SEALED_COVER = HEADCOVERSEYES,
|
||||
CAN_OVERSLOT = TRUE,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT | HIDETAIL,
|
||||
CAN_OVERSLOT = TRUE,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDMAGE,
|
||||
CAN_OVERSLOT = TRUE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDMAGE,
|
||||
CAN_OVERSLOT = TRUE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/obj/item/mod/armor/mod_theme_ninja
|
||||
|
||||
armor = list(MELEE = 50, BULLET = 35, LASER = 35, ENERGY = 30, BOMB = 25, RAD = 200, FIRE = INFINITY, ACID = INFINITY)
|
||||
|
||||
@@ -569,6 +569,25 @@
|
||||
/obj/item/mod/module/jetpack/advanced,
|
||||
)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/ninja
|
||||
icon_state = "ninja-control"
|
||||
theme = /datum/mod_theme/ninja
|
||||
starting_frequency = MODLINK_FREQ_SYNDICATE
|
||||
applied_cell = /obj/item/stock_parts/cell/bluespace
|
||||
applied_modules = list(
|
||||
/obj/item/mod/module/storage/syndicate,
|
||||
/obj/item/mod/module/jetpack/advanced,
|
||||
/obj/item/mod/module/dispenser/smoke,
|
||||
/obj/item/mod/module/shinobi_stealth,
|
||||
/obj/item/mod/module/shinobi_freedom,
|
||||
/obj/item/mod/module/shinobi_stims,
|
||||
/obj/item/mod/module/noslip,
|
||||
)
|
||||
default_pins = list(
|
||||
/obj/item/mod/module/jetpack/advanced,
|
||||
/obj/item/mod/module/dispenser/smoke,
|
||||
)
|
||||
|
||||
//these exist for the prefs menu
|
||||
/obj/item/mod/control/pre_equipped/empty
|
||||
starting_frequency = null
|
||||
|
||||
@@ -641,3 +641,77 @@
|
||||
/obj/item/mod/module/anomaly_locked/teslawall/prebuilt
|
||||
prebuilt = TRUE
|
||||
removable = FALSE // No switching it into another suit / no free anomaly core
|
||||
|
||||
/obj/item/mod/module/shinobi_stealth
|
||||
name = "MOD shinobi stealth module"
|
||||
desc = "An advanced module, designed by the Spider Clan, that replicates the advanced stealth technology in the classic ninja scarf."
|
||||
icon_state = "armor_booster"
|
||||
origin_tech = "combat=5;bluespace=6;syndicate=4"
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
|
||||
removable = FALSE
|
||||
/// Linked sneaking action
|
||||
var/datum/action/cooldown/ninja/ninja_cloak/cloak_action
|
||||
|
||||
/obj/item/mod/module/shinobi_stealth/Initialize(mapload)
|
||||
. = ..()
|
||||
cloak_action = new(src)
|
||||
|
||||
/obj/item/mod/module/shinobi_stealth/on_suit_activation()
|
||||
. = ..()
|
||||
cloak_action.Grant(mod.wearer)
|
||||
|
||||
/obj/item/mod/module/shinobi_stealth/on_suit_deactivation(deleting = FALSE)
|
||||
if(deleting)
|
||||
return
|
||||
cloak_action.stop_sneaking()
|
||||
cloak_action.Remove(mod.wearer)
|
||||
|
||||
/obj/item/mod/module/shinobi_freedom
|
||||
name = "MOD shinobi escape module"
|
||||
desc = "An advanced module, designed by the Spider Clan, that replicates the advanced escaping technology in the classic ninja boots."
|
||||
icon_state = "armor_booster"
|
||||
origin_tech = "combat=5;bluespace=6;syndicate=4"
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
|
||||
removable = FALSE
|
||||
/// Linked freedom action
|
||||
var/datum/action/cooldown/ninja/freedom_shoes/freedoms_action
|
||||
|
||||
/obj/item/mod/module/shinobi_freedom/Initialize(mapload)
|
||||
. = ..()
|
||||
freedoms_action = new(src)
|
||||
|
||||
/obj/item/mod/module/shinobi_freedom/on_suit_activation()
|
||||
. = ..()
|
||||
ADD_TRAIT(mod.wearer, TRAIT_GOTTAGONOTSOFAST, src)
|
||||
freedoms_action.Grant(mod.wearer)
|
||||
|
||||
/obj/item/mod/module/shinobi_freedom/on_suit_deactivation(deleting = FALSE)
|
||||
if(deleting)
|
||||
return
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_GOTTAGONOTSOFAST, src)
|
||||
freedoms_action.Remove(mod.wearer)
|
||||
|
||||
/obj/item/mod/module/shinobi_stims
|
||||
name = "MOD shinobi stimulant module"
|
||||
desc = "An advanced module, designed by the Spider Clan, that replicates the advanced stimulants technology in the classic ninja kabuto."
|
||||
icon_state = "armor_booster"
|
||||
origin_tech = "combat=5;bluespace=6;syndicate=4"
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
|
||||
removable = FALSE
|
||||
/// Linked stims action
|
||||
var/datum/action/cooldown/ninja/stim_suit/antistun_action
|
||||
|
||||
/obj/item/mod/module/shinobi_stims/Initialize(mapload)
|
||||
. = ..()
|
||||
antistun_action = new(src)
|
||||
|
||||
/obj/item/mod/module/shinobi_stims/on_suit_activation()
|
||||
. = ..()
|
||||
ADD_TRAIT(mod.wearer, TRAIT_GOTTAGONOTSOFAST, src)
|
||||
antistun_action.Grant(mod.wearer)
|
||||
|
||||
/obj/item/mod/module/shinobi_stims/on_suit_deactivation(deleting = FALSE)
|
||||
if(deleting)
|
||||
return
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_GOTTAGONOTSOFAST, src)
|
||||
antistun_action.Remove(mod.wearer)
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/obj/item/katana/energy
|
||||
name = "energy katana"
|
||||
desc = "A katana infused with a strong energy."
|
||||
icon = 'icons/obj/weapons/energy_melee.dmi'
|
||||
icon_state = "energy_katana"
|
||||
throwforce = 20
|
||||
armor_penetration_percentage = 50
|
||||
armor_penetration_flat = 10
|
||||
var/cooldown = 0 // Because spam aint cool, yo.
|
||||
var/datum/effect_system/spark_spread/spark_system
|
||||
|
||||
/obj/item/katana/energy/attack__legacy__attackchain(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
playsound(user, 'sound/weapons/blade1.ogg', 50, TRUE, -1)
|
||||
return ..()
|
||||
|
||||
/obj/item/katana/energy/afterattack__legacy__attackchain(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
if(!user || !target)
|
||||
return
|
||||
|
||||
if(proximity_flag && user.mind.special_role == "Ninja" && !cooldown && isobj(target))
|
||||
cooldown = 1
|
||||
spark_system.start()
|
||||
playsound(user, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
playsound(user, 'sound/weapons/blade1.ogg', 50, 1)
|
||||
user.visible_message(SPAN_DANGER("[user] masterfully slices [target]!"), SPAN_NOTICE("You masterfully slice [target]!"))
|
||||
target.emag_act(user)
|
||||
sleep(15)
|
||||
cooldown = 0
|
||||
|
||||
/*/obj/item/katana/energy/throw_impact(atom/hit_atom)
|
||||
if(ishuman(hit_atom))
|
||||
var/mob/living/carbon/human/H = hit_atom
|
||||
if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
|
||||
var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit
|
||||
if(SN.energyKatana && SN.energyKatana == src)
|
||||
returnToOwner(H, 0, 1)
|
||||
return
|
||||
..()*/
|
||||
|
||||
/obj/item/katana/energy/proc/returnToOwner(mob/living/carbon/human/user, doSpark = 1, caught = 0)
|
||||
if(!istype(user))
|
||||
return
|
||||
loc = get_turf(src)
|
||||
|
||||
if(doSpark)
|
||||
spark_system.start()
|
||||
playsound(get_turf(src), "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
|
||||
var/msg = ""
|
||||
|
||||
if(user.put_in_hands(src))
|
||||
msg = "Your Energy Katana teleports into your hand!"
|
||||
else if(user.equip_to_slot_if_possible(src, ITEM_SLOT_BELT, FALSE, TRUE))
|
||||
msg = "Your Energy Katana teleports back to you, sheathing itself as it does so!</span>"
|
||||
else
|
||||
loc = get_turf(user)
|
||||
msg = "Your Energy Katana teleports to your location!"
|
||||
|
||||
if(caught)
|
||||
if(loc == user)
|
||||
msg = "You catch your Energy Katana!"
|
||||
else
|
||||
msg = "Your Energy Katana lands at your feet!"
|
||||
|
||||
if(msg)
|
||||
to_chat(user, SPAN_NOTICE("[msg]"))
|
||||
|
||||
/obj/item/katana/energy/Initialize(mapload)
|
||||
. = ..()
|
||||
spark_system = new /datum/effect_system/spark_spread()
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
|
||||
/obj/item/katana/energy/Destroy()
|
||||
QDEL_NULL(spark_system)
|
||||
return ..()
|
||||
@@ -0,0 +1,101 @@
|
||||
/datum/action/cooldown/ninja
|
||||
background_icon_state = "bg_ninja"
|
||||
button_icon_state = "genetic_view"
|
||||
|
||||
/datum/action/cooldown/ninja/ninja_cloak
|
||||
name = "Ninja's Stealth"
|
||||
desc = "Toggles whether you are currently sneaking, reducing your visibility and movement speed. Enhanced effects in darkness."
|
||||
button_icon_state = "vampire_cloak"
|
||||
cooldown_time = 2 SECONDS
|
||||
var/sneaking = FALSE
|
||||
|
||||
/datum/action/cooldown/ninja/ninja_cloak/proc/update_action_name()
|
||||
name = "[initial(name)] ([sneaking ? "Deactivate" : "Activate"])"
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_NAME)
|
||||
build_all_button_icons()
|
||||
|
||||
/datum/action/cooldown/ninja/ninja_cloak/proc/stop_sneaking()
|
||||
if(!ishuman(owner))
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
sneaking = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
UnregisterSignal(H, COMSIG_ATTACK)
|
||||
UnregisterSignal(H, COMSIG_ATTACK_BY)
|
||||
H.set_alpha_tracking(ALPHA_VISIBLE, src)
|
||||
REMOVE_TRAIT(owner, TRAIT_GOTTAGOSLOW, src)
|
||||
|
||||
/datum/action/cooldown/ninja/ninja_cloak/process()
|
||||
. = ..()
|
||||
if(!ishuman(owner))
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(H.stat)
|
||||
stop_sneaking()
|
||||
return
|
||||
if(!sneaking)
|
||||
stop_sneaking()
|
||||
return
|
||||
var/turf/simulated/T = get_turf(H)
|
||||
var/light_available = T.get_lumcount() * 10
|
||||
|
||||
if(light_available <= 2)
|
||||
H.set_alpha_tracking(ALPHA_VISIBLE * 0.1, src)
|
||||
return
|
||||
H.set_alpha_tracking(ALPHA_VISIBLE * 0.5, src)
|
||||
|
||||
/datum/action/cooldown/ninja/ninja_cloak/Activate(atom/target)
|
||||
if(!ishuman(owner))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = owner
|
||||
|
||||
sneaking = !sneaking
|
||||
update_action_name()
|
||||
if(sneaking)
|
||||
to_chat(H, "<span class='notice'>You are now sneaking around. Stick to the darkness to conceal yourself better.</span>")
|
||||
START_PROCESSING(SSobj, src)
|
||||
RegisterSignal(owner, COMSIG_ATTACK, PROC_REF(stop_sneaking))
|
||||
RegisterSignal(owner, COMSIG_ATTACK_BY, PROC_REF(stop_sneaking))
|
||||
ADD_TRAIT(owner, TRAIT_GOTTAGOSLOW, src)
|
||||
else
|
||||
to_chat(H, "<span class='notice'>You are no longer sneaking around.</span>")
|
||||
stop_sneaking()
|
||||
StartCooldown()
|
||||
|
||||
/datum/action/cooldown/ninja/freedom_shoes
|
||||
name = "Ninja's Mobility"
|
||||
desc = "Breaks free of leg restraints. 2 Minute cooldown."
|
||||
button_icon = 'icons/obj/bio_chips.dmi'
|
||||
button_icon_state = "freedom"
|
||||
cooldown_time = 2 MINUTES
|
||||
|
||||
/datum/action/cooldown/ninja/freedom_shoes/Activate(atom/target)
|
||||
if(!ishuman(owner))
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.clear_legcuffs(TRUE)
|
||||
H.SetKnockDown(0)
|
||||
H.stand_up(TRUE)
|
||||
StartCooldown()
|
||||
|
||||
/datum/action/cooldown/ninja/stim_suit
|
||||
name = "Ninja's Tenacity"
|
||||
desc = "Activates an injector within your suit, pumping you with a small hit of stimulants. 2 Minute cooldown."
|
||||
button_icon = 'icons/obj/bio_chips.dmi'
|
||||
button_icon_state = "adrenal"
|
||||
cooldown_time = 2 MINUTES
|
||||
|
||||
/datum/action/cooldown/ninja/stim_suit/Activate(atom/target)
|
||||
if(!ishuman(owner))
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.SetStunned(0)
|
||||
H.SetWeakened(0)
|
||||
H.SetKnockDown(0)
|
||||
H.SetParalysis(0)
|
||||
H.adjustStaminaLoss(-75)
|
||||
H.stand_up(TRUE)
|
||||
SEND_SIGNAL(H, COMSIG_LIVING_CLEAR_STUNS)
|
||||
H.reagents.add_reagent("stimulative_agent", 1) // 10 Seconds.
|
||||
StartCooldown()
|
||||
@@ -0,0 +1,195 @@
|
||||
/obj/item/clothing/head/helmet/space_ninja
|
||||
desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear."
|
||||
name = "ninja fukumen"
|
||||
icon_state = "s-ninja"
|
||||
inhand_icon_state = "s-ninja_hood"
|
||||
flags = BLOCKHAIR
|
||||
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE
|
||||
armor = list(MELEE = 30, BULLET = 35, LASER = 25, ENERGY = 25, BOMB = 20, RAD = 100, FIRE = INFINITY, ACID = INFINITY)
|
||||
origin_tech = "combat=5;materials=5;syndicate=2"
|
||||
blockTracking = 1
|
||||
icon_monitor = 'icons/mob/clothing/species/machine/monitor/hood.dmi'
|
||||
sprite_sheets = list(
|
||||
"Unathi" = 'icons/mob/clothing/species/unathi/head.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/species/tajaran/head.dmi',
|
||||
"Skrell" = 'icons/mob/clothing/species/skrell/head.dmi',
|
||||
"Vox" = 'icons/mob/clothing/species/vox/head.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/head.dmi',
|
||||
"Drask" = 'icons/mob/clothing/species/drask/head.dmi',
|
||||
"Grey" = 'icons/mob/clothing/species/grey/head.dmi',
|
||||
"Nian" = 'icons/mob/clothing/species/nian/head.dmi',
|
||||
"Diona" = 'icons/mob/clothing/species/diona/head.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/species/kidan/head.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/vox/head.dmi',
|
||||
)
|
||||
/// Tracking the cloak action
|
||||
var/datum/action/cooldown/ninja/ninja_cloak/cloak_action
|
||||
|
||||
/obj/item/clothing/head/helmet/space_ninja/Initialize(mapload)
|
||||
. = ..()
|
||||
cloak_action = new(src)
|
||||
|
||||
/obj/item/clothing/head/helmet/space_ninja/equipped(mob/user, slot, initial)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot != ITEM_SLOT_HEAD)
|
||||
return
|
||||
cloak_action.Grant(user)
|
||||
|
||||
/obj/item/clothing/head/helmet/space_ninja/dropped(mob/user, silent)
|
||||
. = ..()
|
||||
cloak_action.stop_sneaking()
|
||||
cloak_action.Remove(user)
|
||||
|
||||
/obj/item/clothing/mask/gas/space_ninja
|
||||
name = "ninja mask"
|
||||
desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement."
|
||||
icon_state = "s-ninja"
|
||||
inhand_icon_state = "s-ninja_mask"
|
||||
flash_protect = FLASH_PROTECTION_FLASH
|
||||
origin_tech = "combat=4;materials=4;syndicate=1"
|
||||
icon_monitor = 'icons/mob/clothing/species/machine/monitor/mask.dmi'
|
||||
sprite_sheets = list(
|
||||
"Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/species/tajaran/mask.dmi',
|
||||
"Skrell" = 'icons/mob/clothing/species/skrell/mask.dmi',
|
||||
"Vox" = 'icons/mob/clothing/species/vox/mask.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi',
|
||||
"Drask" = 'icons/mob/clothing/species/drask/mask.dmi',
|
||||
"Grey" = 'icons/mob/clothing/species/grey/mask.dmi',
|
||||
"Nian" = 'icons/mob/clothing/species/nian/mask.dmi',
|
||||
"Diona" = 'icons/mob/clothing/species/diona/mask.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/species/kidan/mask.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/skkulakin/mask.dmi',
|
||||
)
|
||||
var/obj/item/voice_changer/voice_changer
|
||||
|
||||
/obj/item/clothing/mask/gas/space_ninja/Initialize(mapload)
|
||||
. = ..()
|
||||
voice_changer = new(src)
|
||||
|
||||
/obj/item/clothing/mask/gas/space_ninja/Destroy()
|
||||
QDEL_NULL(voice_changer)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/gloves/space_ninja
|
||||
desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
|
||||
name = "ninja tekko"
|
||||
icon_state = "s-ninja"
|
||||
siemens_coefficient = 0
|
||||
pickpocket = TRUE // Master of stealth, you can pick a pocket
|
||||
armor = list(MELEE = 30, BULLET = 35, LASER = 25, ENERGY = 25, BOMB = 20, RAD = 100, FIRE = INFINITY, ACID = INFINITY)
|
||||
cold_protection = HANDS
|
||||
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
|
||||
heat_protection = HANDS
|
||||
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
|
||||
origin_tech = "combat=5;materials=5;syndicate=2"
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/clothing/species/vox/gloves.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/vox/gloves.dmi',
|
||||
"Drask" = 'icons/mob/clothing/species/drask/gloves.dmi',
|
||||
"Diona" = 'icons/mob/clothing/species/diona/gloves.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/species/kidan/gloves.dmi',
|
||||
)
|
||||
|
||||
/obj/item/clothing/shoes/space_ninja
|
||||
name = "ninja jaka-tabi"
|
||||
desc = "A pair of split-toed rubber-soled shoes. Excellent for running and even better for smashing skulls."
|
||||
icon_state = "s-ninja"
|
||||
permeability_coefficient = 0.01
|
||||
no_slip = TRUE
|
||||
armor = list(MELEE = 30, BULLET = 35, LASER = 25, ENERGY = 25, BOMB = 20, RAD = 100, FIRE = INFINITY, ACID = INFINITY)
|
||||
cold_protection = FEET
|
||||
min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT
|
||||
heat_protection = FEET
|
||||
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
|
||||
origin_tech = "combat=5;materials=5;syndicate=2"
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/clothing/species/vox/shoes.dmi',
|
||||
"Drask" = 'icons/mob/clothing/species/drask/shoes.dmi',
|
||||
"Diona" = 'icons/mob/clothing/species/diona/shoes.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/species/kidan/shoes.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/vox/shoes.dmi',
|
||||
)
|
||||
/// Linked freedoms action
|
||||
var/datum/action/cooldown/ninja/freedom_shoes/freedoms_action
|
||||
|
||||
/obj/item/clothing/shoes/space_ninja/Initialize(mapload)
|
||||
. = ..()
|
||||
freedoms_action = new(src)
|
||||
|
||||
/obj/item/clothing/shoes/space_ninja/equipped(mob/user, slot, initial)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot != ITEM_SLOT_SHOES)
|
||||
return
|
||||
ADD_TRAIT(user, TRAIT_GOTTAGONOTSOFAST, src)
|
||||
freedoms_action.Grant(user)
|
||||
|
||||
/obj/item/clothing/shoes/space_ninja/dropped(mob/user, silent)
|
||||
. = ..()
|
||||
REMOVE_TRAIT(user, TRAIT_GOTTAGONOTSOFAST, src)
|
||||
freedoms_action.Remove(user)
|
||||
|
||||
/obj/item/clothing/suit/space_ninja
|
||||
name = "ninja uwagi"
|
||||
desc = "A unique suit of nano-enhanced armor designed specifically for Spider Clan assassins."
|
||||
icon_state = "s-ninja"
|
||||
inhand_icon_state = "s-ninja_suit"
|
||||
allowed = list(
|
||||
/obj/item/gun,
|
||||
/obj/item/ammo_box,
|
||||
/obj/item/melee/baton,
|
||||
/obj/item/tank/internals,
|
||||
/obj/item/katana/energy,
|
||||
/obj/item/restraints/handcuffs,
|
||||
/obj/item/ninja_scanner
|
||||
)
|
||||
flags_inv = HIDEJUMPSUIT
|
||||
armor = list(MELEE = 30, BULLET = 35, LASER = 25, ENERGY = 25, BOMB = 20, RAD = 100, FIRE = INFINITY, ACID = INFINITY)
|
||||
origin_tech = "combat=5;materials=5;syndicate=2"
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/clothing/species/vox/suit.dmi',
|
||||
"Drask" = 'icons/mob/clothing/species/drask/suit.dmi',
|
||||
"Grey" = 'icons/mob/clothing/species/grey/suit.dmi',
|
||||
"Nian" = 'icons/mob/clothing/species/nian/suit.dmi',
|
||||
"Diona" = 'icons/mob/clothing/species/diona/suit.dmi',
|
||||
"Kidan" = 'icons/mob/clothing/species/kidan/suit.dmi',
|
||||
"Skkulakin" = 'icons/mob/clothing/species/vox/suit.dmi',
|
||||
)
|
||||
/// Linked stims action
|
||||
var/datum/action/cooldown/ninja/stim_suit/antistun_action
|
||||
|
||||
/obj/item/clothing/suit/space_ninja/Initialize(mapload)
|
||||
. = ..()
|
||||
antistun_action = new(src)
|
||||
|
||||
/obj/item/clothing/suit/space_ninja/equipped(mob/user, slot, initial)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot != ITEM_SLOT_OUTER_SUIT)
|
||||
return
|
||||
antistun_action.Grant(user)
|
||||
|
||||
/obj/item/clothing/suit/space_ninja/dropped(mob/user, silent)
|
||||
. = ..()
|
||||
antistun_action.Remove(user)
|
||||
|
||||
/obj/item/storage/bag/garment/syndie/ninja_suit
|
||||
name = "ninja suit garment bag"
|
||||
|
||||
/obj/item/storage/bag/garment/syndie/ninja_suit/populate_contents()
|
||||
new /obj/item/clothing/under/syndicate(src)
|
||||
new /obj/item/clothing/shoes/space_ninja(src)
|
||||
new /obj/item/clothing/gloves/space_ninja(src)
|
||||
new /obj/item/clothing/head/helmet/space_ninja(src)
|
||||
new /obj/item/clothing/mask/gas/space_ninja(src)
|
||||
new /obj/item/clothing/suit/space_ninja(src)
|
||||
|
||||
/obj/item/card/id/syndicate/ninja
|
||||
name = "ninja card"
|
||||
initial_access = list(ACCESS_MAINT_TUNNELS)
|
||||
icon_state = "data"
|
||||
@@ -0,0 +1,181 @@
|
||||
/obj/machinery/syndicatebomb/ninja
|
||||
name = "spider clan bomb"
|
||||
payload = /obj/item/bombcore/ninja
|
||||
|
||||
/obj/machinery/syndicatebomb/ninja/emp
|
||||
name = "spider clan EMP bomb"
|
||||
payload = /obj/item/bombcore/emp/ninja
|
||||
|
||||
/obj/machinery/syndicatebomb/ninja/spiders
|
||||
name = "spider bomb"
|
||||
payload = /obj/item/bombcore/badmin/summon/ninja_spiders
|
||||
|
||||
/obj/item/bombcore/ninja
|
||||
desc = "A powerful secondary explosive of spider clan design and unknown composition, it should be stable under normal conditions..."
|
||||
range_heavy = 3
|
||||
range_medium = 8
|
||||
range_light = 15
|
||||
range_flame = 17
|
||||
|
||||
/obj/item/bombcore/emp/ninja
|
||||
light_emp = 24
|
||||
heavy_emp = 12
|
||||
|
||||
/obj/item/bombcore/badmin/summon/ninja_spiders
|
||||
summon_path = /mob/living/basic/giant_spider
|
||||
amt_summon = 12
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb
|
||||
name = "spider clan bomb deployment flare"
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
desc = "A single-use flare that will bring a high-yield payload to the location it was lit at."
|
||||
icon_state = "flare-contractor"
|
||||
inhand_icon_state = "flare"
|
||||
/// What area should be blow up?
|
||||
var/area/bomb_target
|
||||
/// What kind of bomb is it
|
||||
var/obj/machinery/syndicatebomb/bomb_type = /obj/machinery/syndicatebomb/ninja
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/Initialize(mapload)
|
||||
. = ..()
|
||||
var/list/possible_areas = list(
|
||||
// Rooms
|
||||
/area/station/hallway/primary/aft,
|
||||
/area/station/engineering/atmos,
|
||||
/area/station/public/arcade,
|
||||
/area/station/maintenance/assembly_line,
|
||||
/area/station/public/storage/tools/auxiliary,
|
||||
/area/station/command/office/blueshield,
|
||||
/area/station/supply/storage,
|
||||
/area/station/service/chapel,
|
||||
/area/station/service/chapel/office,
|
||||
/area/station/service/clown,
|
||||
/area/station/legal/courtroom,
|
||||
/area/station/public/toilet,
|
||||
/area/station/engineering/control,
|
||||
/area/station/engineering/controlroom,
|
||||
/area/station/hallway/secondary/exit,
|
||||
/area/holodeck/alphadeck,
|
||||
/area/station/service/hydroponics,
|
||||
/area/station/service/library,
|
||||
/area/station/service/mime,
|
||||
/area/station/supply/miningdock,
|
||||
/area/station/medical/morgue,
|
||||
/area/station/public/storage/office,
|
||||
/area/station/public/pet_store,
|
||||
/area/station/public/storage/tools,
|
||||
/area/station/public/mrchangs,
|
||||
/area/station/science/research,
|
||||
/area/station/security/checkpoint,
|
||||
/area/station/engineering/tech_storage,
|
||||
/area/station/command/teleporter,
|
||||
/area/station/science/storage,
|
||||
/area/station/science/misc_lab,
|
||||
/area/station/science/xenobiology,
|
||||
/area/station/turret_protected/aisat/interior,
|
||||
/area/station/aisat/atmos,
|
||||
/area/station/aisat/hall,
|
||||
/area/station/aisat/service,
|
||||
/area/station/service/bar,
|
||||
/area/station/supply/office,
|
||||
/area/station/medical/chemistry,
|
||||
/area/station/command/office/ce,
|
||||
/area/station/command/office/cmo,
|
||||
/area/station/medical/cloning,
|
||||
/area/station/medical/cryo,
|
||||
/area/station/public/dorms,
|
||||
/area/station/engineering/equipmentstorage,
|
||||
/area/station/engineering/break_room,
|
||||
/area/station/ai_monitored/storage/eva,
|
||||
/area/station/supply/expedition,
|
||||
/area/station/science/genetics,
|
||||
/area/station/engineering/gravitygenerator,
|
||||
/area/station/command/office/hop,
|
||||
/area/station/command/meeting_room,
|
||||
/area/station/service/kitchen,
|
||||
/area/station/science/robotics/chargebay,
|
||||
/area/station/medical/medbay,
|
||||
/area/station/medical/medbay2,
|
||||
/area/station/medical/medbay3,
|
||||
/area/station/medical/reception,
|
||||
/area/station/medical/storage,
|
||||
/area/station/medical/sleeper,
|
||||
/area/station/command/server,
|
||||
/area/station/command/office/ntrep,
|
||||
/area/station/medical/paramedic,
|
||||
/area/station/hallway/primary/port,
|
||||
/area/station/supply/qm,
|
||||
/area/station/command/office/rd,
|
||||
/area/station/science/rnd,
|
||||
/area/station/science/robotics,
|
||||
/area/station/medical/surgery/primary,
|
||||
/area/station/medical/surgery/secondary,
|
||||
/area/station/telecomms/chamber,
|
||||
/area/station/engineering/secure_storage
|
||||
)
|
||||
while(!bomb_target)
|
||||
var/area/selected_area = pick_n_take(possible_areas)
|
||||
for(var/area/potential in SSmapping.existing_station_areas)
|
||||
if(potential.type != selected_area)
|
||||
continue
|
||||
bomb_target = potential
|
||||
break
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/examine(mob/user)
|
||||
. = ..()
|
||||
if(isAntag(user))
|
||||
. += SPAN_WARNING("The target bomb location is: [bomb_target.name]")
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/activate(mob/user)
|
||||
if(!turf_check(user))
|
||||
return
|
||||
var/obj/effect/temp_visual/ninja_bomb/F = new /obj/effect/temp_visual/ninja_bomb(get_turf(src))
|
||||
user.drop_item()
|
||||
forceMove(F)
|
||||
log_and_message_admins("[user] activated a ninja bomb flare.")
|
||||
addtimer(CALLBACK(src, PROC_REF(spawn_bomb), user), 5 SECONDS)
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/proc/spawn_bomb(mob/user)
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
||||
var/obj/machinery/syndicatebomb/new_bomb = new bomb_type(get_turf(src))
|
||||
new_bomb.anchored = TRUE
|
||||
new_bomb.activate()
|
||||
var/objectives = user.mind.get_all_objectives()
|
||||
for(var/datum/objective/ninja/bomb_department/bomb_dep in objectives)
|
||||
if(!bomb_dep.completed)
|
||||
to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink."))
|
||||
bomb_dep.complete_objective()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/turf_check(mob/user)
|
||||
var/turf/device_turf = get_turf(user)
|
||||
if(!device_turf)
|
||||
to_chat(user, "<span class='notice'>You're having difficulties getting the [name] to work.</span>")
|
||||
return FALSE
|
||||
var/area/our_area = get_area(device_turf)
|
||||
if(!istype(our_area, bomb_target))
|
||||
to_chat(user, "<span class='notice'>You're having difficulties getting the [name] to work.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/emp
|
||||
bomb_type = /obj/machinery/syndicatebomb/ninja/emp
|
||||
|
||||
/obj/item/wormhole_jaunter/ninja_bomb/spiders
|
||||
bomb_type = /obj/machinery/syndicatebomb/ninja/spiders
|
||||
|
||||
/obj/effect/temp_visual/ninja_bomb
|
||||
name = "spider clan bomb deployment flare"
|
||||
layer = BELOW_MOB_LAYER
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "flare-contractor-on"
|
||||
duration = 5.1 SECONDS
|
||||
/// Sound that plays when activated
|
||||
var/activation_sound = 'sound/goonstation/misc/matchstick_light.ogg'
|
||||
/// Light emitted when activated
|
||||
var/emitted_color = "#1faf2b"
|
||||
|
||||
/obj/effect/temp_visual/ninja_bomb/Initialize(mapload)
|
||||
. = ..()
|
||||
playsound(loc, activation_sound, 50, TRUE)
|
||||
set_light(8, l_color = emitted_color)
|
||||
@@ -0,0 +1,54 @@
|
||||
/datum/outfit/space_ninja
|
||||
name = "Space Ninja"
|
||||
uniform = /obj/item/clothing/under/syndicate
|
||||
shoes = /obj/item/clothing/shoes/space_ninja
|
||||
gloves = /obj/item/clothing/gloves/space_ninja
|
||||
head = /obj/item/clothing/head/helmet/space_ninja
|
||||
mask = /obj/item/clothing/mask/gas/space_ninja
|
||||
glasses = /obj/item/clothing/glasses/night
|
||||
suit = /obj/item/clothing/suit/space_ninja
|
||||
belt = /obj/item/katana/energy
|
||||
id = /obj/item/card/id/syndicate/ninja
|
||||
back = /obj/item/storage/backpack/satchel
|
||||
l_ear = /obj/item/radio/headset
|
||||
box = /obj/item/storage/box/survival_syndie
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/syndie_kit/throwing_weapons,
|
||||
/obj/item/ninja_scanner,
|
||||
/obj/item/gun/energy/kinetic_accelerator/energy_net,
|
||||
/obj/item/wormhole_jaunter/extraction,
|
||||
/obj/item/teleportation_scroll/apprentice,
|
||||
)
|
||||
bio_chips = list(
|
||||
/obj/item/bio_chip/dust,
|
||||
/obj/item/bio_chip/uplink/ninja
|
||||
)
|
||||
|
||||
/datum/outfit/space_ninja/vox
|
||||
name = "Space Ninja - Vox"
|
||||
|
||||
/datum/outfit/space_ninja/vox/post_equip(mob/living/carbon/human/H, visualsOnly)
|
||||
. = ..()
|
||||
var/obj/item/tank/internal_tank = new /obj/item/tank/internals/emergency_oxygen/double/vox(H)
|
||||
if(!H.equip_to_appropriate_slot(internal_tank))
|
||||
if(!H.put_in_any_hand_if_possible(internal_tank))
|
||||
H.drop_item_to_ground(H.l_hand)
|
||||
H.equip_or_collect(internal_tank, ITEM_SLOT_LEFT_HAND)
|
||||
to_chat(H, "<span class='boldannounceooc'>Could not find an empty slot for internals! Please report this as a bug</span>")
|
||||
H.internal = internal_tank
|
||||
|
||||
/datum/outfit/admin/ghostbar_antag/space_ninja
|
||||
name = "Ghostbar Space Ninja"
|
||||
uniform = /obj/item/clothing/under/syndicate
|
||||
shoes = /obj/item/clothing/shoes/space_ninja
|
||||
gloves = /obj/item/clothing/gloves/space_ninja
|
||||
head = /obj/item/clothing/head/helmet/space_ninja
|
||||
mask = /obj/item/clothing/mask/gas/space_ninja
|
||||
suit = /obj/item/clothing/suit/space_ninja
|
||||
belt = /obj/item/toy/katana
|
||||
back = /obj/item/storage/backpack/satchel
|
||||
backpack_contents = list(
|
||||
/obj/item/storage/box/engineer = 1,
|
||||
/obj/item/flashlight = 1,
|
||||
/obj/item/food/syndidonkpocket = 1,
|
||||
)
|
||||
@@ -0,0 +1,143 @@
|
||||
/obj/item/ninja_scanner
|
||||
name = "spider scanner"
|
||||
desc = "Advanced multi-use scanning device used by the spider clan to confirm bounty completion. Scan the corpses of dead or netted crew to redeem your bounties."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "ninja_scanner"
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
force = 9 // Can be used as a weapon in an emergency
|
||||
hitsound = 'sound/weapons/genhit1.ogg'
|
||||
new_attack_chain = TRUE
|
||||
|
||||
/obj/item/ninja_scanner/attack(mob/living/target, mob/living/user, params)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
if(!user.mind)
|
||||
return ..()
|
||||
var/list/obj_list = user.mind.get_all_objectives()
|
||||
if(!length(obj_list))
|
||||
to_chat(user, SPAN_WARNING("You have no objectives!"))
|
||||
return TRUE
|
||||
for(var/datum/objective/ninja/ninja_obj in obj_list)
|
||||
if(ninja_obj.completed)
|
||||
continue
|
||||
if(istype(ninja_obj, /datum/objective/ninja/kill))
|
||||
if(target.stat != DEAD)
|
||||
continue
|
||||
if(!ninja_obj.target.current || target != ninja_obj.target.current)
|
||||
continue
|
||||
user.visible_message(SPAN_DANGER("[user] begins to use [src] to scan [target]!"), \
|
||||
SPAN_NOTICE("You begin to scan [target]!"))
|
||||
if(!do_after_once(user, 8 SECONDS, target = target, allow_moving = FALSE, attempt_cancel_message = "You stop scanning [target] before completing the scan."))
|
||||
return TRUE
|
||||
ninja_obj.completed = TRUE
|
||||
to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink."))
|
||||
ninja_obj.complete_objective()
|
||||
return TRUE
|
||||
|
||||
if(istype(ninja_obj, /datum/objective/ninja/capture))
|
||||
var/datum/objective/ninja/capture/cap_obj = ninja_obj
|
||||
if(target != ninja_obj.target.current)
|
||||
continue
|
||||
if(target.stat == DEAD)
|
||||
if(!target.ghost_can_reenter()) // Target is DNR. Reroll.
|
||||
to_chat(user, SPAN_NOTICE("Target is unrecoverable. Finding a new target..."))
|
||||
ninja_obj.on_target_cryo()
|
||||
else
|
||||
to_chat(user, SPAN_NOTICE("Target is dead. Dead people don't talk. Esnure they are revived, then send them to us."))
|
||||
continue
|
||||
if(!target.buckled)
|
||||
continue
|
||||
var/obj/structure/bed/energy_net/trapped_net
|
||||
for(var/obj/structure/bed/energy_net/net in target.loc)
|
||||
trapped_net = net
|
||||
break
|
||||
if(!trapped_net)
|
||||
continue
|
||||
user.visible_message(SPAN_DANGER("[user] begins to use [src] to scan [target]!"), \
|
||||
SPAN_NOTICE("You begin to scan [target]!"))
|
||||
if(!do_after_once(user, 5 SECONDS, target = target, allow_moving = FALSE, attempt_cancel_message = "You stop scanning [target] before completing the scan."))
|
||||
return TRUE
|
||||
target.unbuckle(TRUE)
|
||||
trapped_net.Destroy()
|
||||
var/target_loc = target.loc
|
||||
do_teleport(target, pick(GLOB.ninjaprisonwarp), 0, TRUE, bypass_area_flag = TRUE)
|
||||
var/mob/living/carbon/c_target = target
|
||||
if(istype(c_target))
|
||||
var/obj/item/restraints/handcuffs/cuffs = target.get_item_by_slot(ITEM_SLOT_HANDCUFFED)
|
||||
qdel(cuffs)
|
||||
c_target.handcuffed = FALSE
|
||||
c_target.update_handcuffed()
|
||||
cap_obj.handle_capture(target, target_loc)
|
||||
ninja_obj.completed = TRUE
|
||||
to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink."))
|
||||
ninja_obj.complete_objective()
|
||||
return TRUE
|
||||
|
||||
if(istype(ninja_obj, /datum/objective/ninja/interrogate_ai))
|
||||
if(!is_ai(target))
|
||||
return TRUE
|
||||
var/mob/living/silicon/ai/AI = target
|
||||
user.visible_message(SPAN_DANGER("[user] begins to use [src] to upload [AI]!"), \
|
||||
SPAN_NOTICE("You begin to upload [AI]!"))
|
||||
if(!do_after_once(user, 8 SECONDS, target = AI, allow_moving = FALSE, attempt_cancel_message = "You stop uploading [AI] before completing the upload."))
|
||||
return TRUE
|
||||
var/obj/item/aicard/card = new()
|
||||
AI.take_overall_damage(50)
|
||||
AI.transfer_ai(AI_TRANS_TO_CARD, user, null, card)
|
||||
var/list/possible_spawns = GLOB.maints_loot_spawns
|
||||
while(length(possible_spawns))
|
||||
var/turf/current_turf = pick_n_take(possible_spawns)
|
||||
if(!is_station_level(current_turf))
|
||||
continue
|
||||
if(!current_turf.density)
|
||||
do_teleport(card, current_turf)
|
||||
break
|
||||
// Someone built a wall over it, check the surroundings
|
||||
var/list/open_turfs = current_turf.AdjacentTurfs(open_only = TRUE)
|
||||
if(length(open_turfs))
|
||||
do_teleport(card, pick(open_turfs))
|
||||
break
|
||||
ninja_obj.completed = TRUE
|
||||
to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink."))
|
||||
ninja_obj.complete_objective()
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/ninja_scanner/attack_obj(obj/attacked_obj, mob/living/user, params)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
if(!user.mind)
|
||||
return ..()
|
||||
var/list/obj_list = user.mind.get_all_objectives()
|
||||
if(!length(obj_list))
|
||||
to_chat(user, SPAN_WARNING("You have no objectives!"))
|
||||
return TRUE
|
||||
for(var/datum/objective/ninja/ninja_obj in obj_list)
|
||||
if(ninja_obj.completed)
|
||||
continue
|
||||
if(istype(ninja_obj, /datum/objective/ninja/hack_rnd) && istype(attacked_obj, /obj/machinery/computer/rnd_network_controller))
|
||||
if(!do_after_once(user, 12 SECONDS, target = attacked_obj, allow_moving = FALSE, attempt_cancel_message = "You stop hacking [attacked_obj] before completing the download."))
|
||||
return TRUE
|
||||
to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink."))
|
||||
var/obj/machinery/computer/rnd_network_controller/rnd = attacked_obj
|
||||
rnd.research_files.known_tech = list()
|
||||
ninja_obj.completed = TRUE
|
||||
ninja_obj.complete_objective()
|
||||
return TRUE
|
||||
if(istype(ninja_obj, /datum/objective/ninja/insert_spider_rod) && istype(attacked_obj, /obj/machinery/atmospherics/reactor_chamber))
|
||||
var/obj/machinery/atmospherics/reactor_chamber/r_chamber = attacked_obj
|
||||
if(!r_chamber.held_rod)
|
||||
to_chat(user, SPAN_NOTICE("There is no rod in [r_chamber]."))
|
||||
return TRUE
|
||||
if(!istype(r_chamber.held_rod, /obj/item/nuclear_rod/fuel/uranium_238/spiders))
|
||||
to_chat(user, SPAN_NOTICE("The rod in [r_chamber] is not one of ours."))
|
||||
return TRUE
|
||||
if(r_chamber.linked_reactor.offline)
|
||||
to_chat(user, SPAN_NOTICE("[r_chamber.linked_reactor] is not online."))
|
||||
return TRUE
|
||||
to_chat(user, SPAN_NOTICE("Contract complete. Good work - your cut of the pay has been forwarded to your uplink."))
|
||||
ninja_obj.completed = TRUE
|
||||
ninja_obj.complete_objective()
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
@@ -0,0 +1,91 @@
|
||||
/obj/item/bio_chip/uplink/ninja
|
||||
name = "spider clan uplink bio-chip"
|
||||
desc = "Purchase things from the spider clan with earned currency."
|
||||
|
||||
/obj/item/bio_chip/uplink/ninja/Initialize(mapload)
|
||||
. = ..()
|
||||
if(hidden_uplink)
|
||||
hidden_uplink.update_uplink_type(UPLINK_TYPE_NINJA)
|
||||
hidden_uplink.uses = 0
|
||||
|
||||
/datum/uplink_item/ninja
|
||||
category = "Spider Clan Provisions"
|
||||
surplus = 0
|
||||
uplinktypes = list(UPLINK_TYPE_NINJA)
|
||||
|
||||
/datum/uplink_item/ninja/shuriken_printer
|
||||
name = "Shuriken Printer"
|
||||
desc = "An advanced, tiny autofabricator that slowly creates and stores energy shurikens."
|
||||
reference = "SPR"
|
||||
item = /obj/item/shuriken_printer
|
||||
cost = 25
|
||||
|
||||
/datum/uplink_item/ninja/ninja_modsuit
|
||||
name = "'Shinobi' Stealth Modsuit"
|
||||
desc = "A specialized modsuit worn by the spider clan's elite ninja operatives."
|
||||
reference = "SNBMOD"
|
||||
item = /obj/item/mod/control/pre_equipped/ninja
|
||||
cost = 45
|
||||
|
||||
/datum/uplink_item/ninja/energy_katana
|
||||
name = "Energy Katana"
|
||||
desc = "A plastitanium katana with a reinforced emitter edge. A ninja's most reliable tool."
|
||||
reference = "EKAT"
|
||||
item = /obj/item/katana/energy
|
||||
cost = 20
|
||||
|
||||
/datum/uplink_item/ninja/energy_net
|
||||
name = "Energy Net Projector"
|
||||
desc = "A non-lethal weapon favored by the Spider Clan. Targets struck will find themselves trapped in an energy net."
|
||||
reference = "ENET"
|
||||
item = /obj/item/gun/energy/kinetic_accelerator/energy_net
|
||||
cost = 30
|
||||
|
||||
/datum/uplink_item/ninja/spider_bomb
|
||||
name = "Spider Bomb"
|
||||
desc = "An evil device fabricated by the Spider Clan. This bomb contains a large number of dehydrated spider-cubes that will all activate upon detonation. These spiders do not discern friend from foe - all non-spiders make for good food."
|
||||
reference = "SPBM"
|
||||
item = /obj/machinery/syndicatebomb/ninja/spiders
|
||||
cost = 65
|
||||
|
||||
/datum/uplink_item/ninja/hood
|
||||
name = "Ninja Scarf"
|
||||
desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear."
|
||||
reference = "NJSC"
|
||||
item = /obj/item/clothing/head/helmet/space_ninja
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/ninja/mask
|
||||
name = "Ninja Mask"
|
||||
desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement."
|
||||
reference = "NJMSK"
|
||||
item = /obj/item/clothing/mask/gas/space_ninja
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/ninja/gloves
|
||||
name = "Ninja Gloves"
|
||||
desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
|
||||
reference = "NJGL"
|
||||
item = /obj/item/clothing/gloves/space_ninja
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/ninja/shoes
|
||||
name = "Ninja Shoes"
|
||||
desc = "A pair of running shoes. Excellent for running and even better for smashing skulls."
|
||||
reference = "NJSH"
|
||||
item = /obj/item/clothing/shoes/space_ninja
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/ninja/suit
|
||||
name = "Ninja Kabuto"
|
||||
desc = "A unique suit of nano-enhanced armor designed specifically for Spider Clan assassins."
|
||||
reference = "NJKB"
|
||||
item = /obj/item/clothing/suit/space_ninja
|
||||
cost = 10
|
||||
|
||||
/datum/uplink_item/ninja/suit_bundle
|
||||
name = "Full Ninja Outfit"
|
||||
desc = "A bulk purchase of a full ninja outfit. Good for if you somehow lost the other set of highly advanced Spider Clan equipment."
|
||||
reference = "NJST"
|
||||
item = /obj/item/clothing/suit/space_ninja
|
||||
cost = 40
|
||||
@@ -0,0 +1,227 @@
|
||||
/obj/item/katana/energy
|
||||
name = "energy katana"
|
||||
desc = "A plastitanium katana with a reinforced emitter edge. A ninja's most reliable tool."
|
||||
icon = 'icons/obj/weapons/energy_melee.dmi'
|
||||
icon_state = "energy_katana"
|
||||
force = 30
|
||||
embed_chance = 75
|
||||
throwforce = 20
|
||||
armor_penetration_percentage = 50
|
||||
armor_penetration_flat = 10
|
||||
origin_tech = "combat=6;syndicate=4"
|
||||
hitsound = 'sound/weapons/blade1.ogg'
|
||||
/// Is the weapon gripped or not?
|
||||
var/gripped = FALSE
|
||||
|
||||
/obj/item/katana/energy/activate_self(mob/living/carbon/human/user)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/is_proper_modsuit = FALSE
|
||||
if(istype(user.gloves, /obj/item/clothing/gloves/mod))
|
||||
var/obj/item/mod/control/modsuit = user.get_item_by_slot(ITEM_SLOT_BACK)
|
||||
if(istype(modsuit) && istype(modsuit.theme, /datum/mod_theme/ninja))
|
||||
is_proper_modsuit = TRUE
|
||||
if(!istype(user.gloves, /obj/item/clothing/gloves/space_ninja) && !is_proper_modsuit)
|
||||
return
|
||||
if(!gripped)
|
||||
gripped = TRUE
|
||||
to_chat(user, SPAN_NOTICE("You tighten your grip on [src], ensuring you won't drop it."))
|
||||
set_nodrop(TRUE, user)
|
||||
return
|
||||
gripped = FALSE
|
||||
to_chat(user, SPAN_NOTICE("You relax your grip on [src]."))
|
||||
set_nodrop(FALSE, user)
|
||||
|
||||
/obj/item/katana/energy/dropped(mob/user, silent)
|
||||
. = ..()
|
||||
gripped = FALSE
|
||||
to_chat(user, SPAN_WARNING("Your grip on [src] is loosened!"))
|
||||
set_nodrop(FALSE, user)
|
||||
|
||||
/obj/item/katana/energy/equipped(mob/user, slot, initial)
|
||||
. = ..()
|
||||
if(gripped)
|
||||
gripped = FALSE
|
||||
to_chat(user, SPAN_NOTICE("You relax your grip on [src]."))
|
||||
set_nodrop(FALSE, user)
|
||||
|
||||
/obj/item/katana/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
. = ..()
|
||||
if(!.) // they did not block the attack
|
||||
return
|
||||
if(isprojectile(hitby))
|
||||
var/obj/projectile/P = hitby
|
||||
if(P.reflectability == REFLECTABILITY_ENERGY)
|
||||
owner.visible_message(SPAN_DANGER("[owner] parries [attack_text] with [src]!"))
|
||||
add_attack_logs(P.firer, src, "hit by [P.type] but got parried by [src]")
|
||||
return -1
|
||||
owner.visible_message(SPAN_DANGER("[owner] blocks [attack_text] with [src]!"))
|
||||
playsound(src, 'sound/weapons/effects/ric3.ogg', 100, TRUE)
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
/obj/item/energy_shuriken
|
||||
name = "energy shuriken"
|
||||
desc = "An ancient weapon, redefined. The blade hums with an electric edge, using itself as fuel."
|
||||
icon = 'icons/obj/weapons/melee.dmi'
|
||||
icon_state = "energy-shuriken"
|
||||
inhand_icon_state = "eshield0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
|
||||
force = 5
|
||||
throwforce = 30 // This is never used on mobs since this has a 100% embed chance.
|
||||
throw_speed = 4
|
||||
embedded_pain_multiplier = 4
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
embed_chance = 100
|
||||
embedded_fall_chance = 0
|
||||
sharp = TRUE
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
/obj/item/energy_shuriken/Initialize(mapload)
|
||||
. = ..()
|
||||
// Only lasts so long. Delete self after some time.
|
||||
addtimer(CALLBACK(src, PROC_REF(qdel), src), 30 SECONDS)
|
||||
|
||||
/obj/item/energy_shuriken/throw_impact(atom/target)
|
||||
. = ..()
|
||||
if(!ishuman(target))
|
||||
return
|
||||
var/mob/living/carbon/human/H = target
|
||||
H.apply_damage(60, STAMINA)
|
||||
|
||||
/obj/item/shuriken_printer
|
||||
name = "shuriken printer"
|
||||
desc = "An advanced, tiny autofabricator that slowly creates and stores energy shurikens."
|
||||
icon = 'icons/obj/weapons/melee.dmi'
|
||||
icon_state = "shuriken-pouch"
|
||||
inhand_icon_state = "eshield0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
|
||||
origin_tech = "combat=6;syndicate=5"
|
||||
force = 5
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
new_attack_chain = TRUE
|
||||
/// What is the maximum number of energy shurikens the printer can hold?
|
||||
var/maximum_stars = 4
|
||||
/// What is the current number of energy shurikens the printer is holding?
|
||||
var/current_stars = 2
|
||||
/// How long the cooldown is to print more shurikens
|
||||
var/printing_time = 30 SECONDS
|
||||
/// Timer used to print stars
|
||||
var/fabrication_timer
|
||||
|
||||
/obj/item/shuriken_printer/Initialize(mapload)
|
||||
. = ..()
|
||||
fabrication_timer = addtimer(CALLBACK(src, PROC_REF(print_star)), 30 SECONDS, TIMER_LOOP | TIMER_STOPPABLE)
|
||||
|
||||
/obj/item/shuriken_printer/examine(mob/user)
|
||||
. = ..()
|
||||
. += SPAN_NOTICE("Alt-click to draw an energy shuriken!")
|
||||
. += SPAN_NOTICE("It has [current_stars] stored.")
|
||||
|
||||
/obj/item/shuriken_printer/AltClick(mob/living/carbon/user, modifiers)
|
||||
if(!iscarbon(user))
|
||||
return ..()
|
||||
if(current_stars < 1)
|
||||
return ..()
|
||||
current_stars--
|
||||
var/obj/item/energy_shuriken/star = new /obj/item/energy_shuriken(get_turf(src), src)
|
||||
user.put_in_hands(star)
|
||||
to_chat(user, SPAN_NOTICE("You draw [star] from [src]."))
|
||||
user.throw_mode_on()
|
||||
|
||||
/obj/item/shuriken_printer/proc/print_star()
|
||||
if(current_stars < maximum_stars)
|
||||
current_stars++
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/energy_net
|
||||
name = "energy net projector"
|
||||
desc = "A non-lethal weapon favored by the Spider Clan. Targets stunned by this weapon will be trapped in an energy net for extraction."
|
||||
icon_state = "energy-net-gun"
|
||||
inhand_icon_state = "energy-net-gun"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
materials = list(MAT_METAL=2000)
|
||||
origin_tech = "combat=6;magnets=4;syndicate=4"
|
||||
suppressed = TRUE
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/net)
|
||||
unique_rename = FALSE
|
||||
overheat_time = 3 SECONDS
|
||||
holds_charge = TRUE
|
||||
unique_frequency = TRUE
|
||||
can_flashlight = FALSE
|
||||
max_mod_capacity = 0
|
||||
empty_state = "energy-net-gun_empty"
|
||||
can_holster = TRUE
|
||||
|
||||
/obj/item/gun/energy/kinetic_accelerator/energy_net/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SILENT_INSERTION, ROUNDSTART_TRAIT)
|
||||
|
||||
/obj/item/ammo_casing/energy/net
|
||||
projectile_type = /obj/projectile/energy/net
|
||||
muzzle_flash_color = null
|
||||
muzzle_flash_effect = /obj/effect/temp_visual/target_angled/muzzle_flash
|
||||
select_name = "energy net"
|
||||
e_cost = 500
|
||||
fire_sound = 'sound/weapons/bolathrow.ogg'
|
||||
|
||||
/obj/projectile/energy/net
|
||||
name = "energy net"
|
||||
icon_state = "net-end"
|
||||
nodamage = 1
|
||||
stamina = 60
|
||||
knockdown = 4 SECONDS
|
||||
speed = 1.5
|
||||
|
||||
/obj/projectile/energy/net/fire(setAngle)
|
||||
if(firer)
|
||||
firer.Beam(src, icon_state = "net-beam", time = INFINITY, maxdistance = INFINITY, beam_type = /obj/effect/ebeam/floor)
|
||||
return ..()
|
||||
|
||||
/obj/projectile/energy/net/on_hit(atom/target, blocked, hit_zone)
|
||||
. = ..()
|
||||
if(!firer)
|
||||
return
|
||||
if(!ishuman(target))
|
||||
return
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!H.stam_paralyzed)
|
||||
return
|
||||
var/obj/item/restraints/handcuffs/cable/zipties/cuff = new()
|
||||
cuff.apply_cuffs(H, firer)
|
||||
var/obj/structure/bed/energy_net/net = new(H.loc)
|
||||
net.buckle_mob(H, TRUE)
|
||||
|
||||
/obj/structure/bed/energy_net
|
||||
name = "energy net"
|
||||
desc = "A pulsing array of green energy that can securely hold a victim in place."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "e-net"
|
||||
|
||||
/obj/structure/bed/energy_net/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
|
||||
if(!has_buckled_mobs())
|
||||
Destroy() // We don't exist if nothing is being held
|
||||
for(var/buck in buckled_mobs) // No net, no buckles
|
||||
var/mob/living/M = buck
|
||||
if(M != user)
|
||||
if(!do_after(user, 10 SECONDS, target = src))
|
||||
if(M && M.buckled)
|
||||
to_chat(user, SPAN_WARNING("You fail to release [M] from \the [src]!"))
|
||||
return
|
||||
M.visible_message(SPAN_NOTICE("[user.name] pulls [M.name] free from the energy net!"),\
|
||||
SPAN_NOTICE("[user.name] pulls you free from the energy net."),\
|
||||
SPAN_ITALICS("You hear a small zap..."))
|
||||
unbuckle_mob(M)
|
||||
Destroy()
|
||||
if(!M.buckled)
|
||||
return
|
||||
M.visible_message(SPAN_WARNING("[M.name] breaks free from the energy net!"),\
|
||||
SPAN_NOTICE("You break free from the energy net!"),\
|
||||
SPAN_ITALICS("You hear a small zap..."))
|
||||
unbuckle_mob(M)
|
||||
Destroy()
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
|
||||
/obj/item/clothing/gloves/space_ninja
|
||||
desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
|
||||
name = "ninja gloves"
|
||||
icon_state = "s-ninja"
|
||||
siemens_coefficient = 0
|
||||
pickpocket = 1
|
||||
cold_protection = HANDS
|
||||
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
|
||||
heat_protection = HANDS
|
||||
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
|
||||
/obj/item/clothing/head/helmet/space/space_ninja
|
||||
desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear."
|
||||
name = "ninja hood"
|
||||
icon_state = "s-ninja"
|
||||
inhand_icon_state = "s-ninja_hood"
|
||||
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE
|
||||
armor = list(MELEE = 75, BULLET = 50, LASER = 20, ENERGY = 10, BOMB = 20, RAD = 15, FIRE = INFINITY, ACID = INFINITY)
|
||||
blockTracking = 1
|
||||
@@ -1,28 +0,0 @@
|
||||
|
||||
/*
|
||||
|
||||
Contents:
|
||||
- The Ninja Space Mask
|
||||
|
||||
*/
|
||||
|
||||
/obj/item/clothing/mask/gas/space_ninja
|
||||
name = "ninja mask"
|
||||
desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement."
|
||||
icon_state = "s-ninja(norm)"
|
||||
inhand_icon_state = "s-ninja_mask"
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/clothing/species/vox/mask.dmi',
|
||||
"Unathi" = 'icons/mob/clothing/species/unathi/mask.dmi',
|
||||
"Tajaran" = 'icons/mob/clothing/species/tajaran/mask.dmi',
|
||||
"Vulpkanin" = 'icons/mob/clothing/species/vulpkanin/mask.dmi'
|
||||
)
|
||||
var/obj/item/voice_changer/voice_changer
|
||||
|
||||
/obj/item/clothing/mask/gas/space_ninja/Initialize(mapload)
|
||||
. = ..()
|
||||
voice_changer = new(src)
|
||||
|
||||
/obj/item/clothing/mask/gas/space_ninja/Destroy()
|
||||
QDEL_NULL(voice_changer)
|
||||
return ..()
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
/obj/item/clothing/shoes/space_ninja
|
||||
name = "ninja shoes"
|
||||
desc = "A pair of running shoes. Excellent for running and even better for smashing skulls."
|
||||
icon_state = "s-ninja"
|
||||
permeability_coefficient = 0.01
|
||||
no_slip = TRUE
|
||||
armor = list(MELEE = 75, BULLET = 50, LASER = 20, ENERGY = 10, BOMB = 20, RAD = 15, FIRE = INFINITY, ACID = INFINITY)
|
||||
cold_protection = FEET
|
||||
min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT
|
||||
heat_protection = FEET
|
||||
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
|
||||
@@ -1,87 +0,0 @@
|
||||
|
||||
/*
|
||||
|
||||
Contents:
|
||||
- The Ninja Space Suit
|
||||
- Ninja Space Suit Procs
|
||||
|
||||
*/
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja
|
||||
name = "ninja suit"
|
||||
desc = "A unique, vacuum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
|
||||
icon_state = "s-ninja"
|
||||
inhand_icon_state = "s-ninja_suit"
|
||||
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/melee/baton, /obj/item/tank/internals, /obj/item/stock_parts/cell)
|
||||
slowdown = 0
|
||||
flags_inv = HIDEJUMPSUIT|HIDETAIL
|
||||
armor = list(MELEE = 75, BULLET = 50, LASER = 20, ENERGY = 10, BOMB = 20, RAD = 15, FIRE = INFINITY, ACID = INFINITY)
|
||||
|
||||
var/suitActive = 0
|
||||
var/suitBusy = 0
|
||||
|
||||
var/obj/item/stock_parts/cell/suitCell
|
||||
var/obj/item/clothing/head/helmet/space/space_ninja/suitHood
|
||||
var/obj/item/clothing/gloves/space_ninja/suitGloves
|
||||
var/obj/item/clothing/shoes/space_ninja/suitShoes
|
||||
var/obj/item/clothing/mask/gas/space_ninja/suitMask
|
||||
var/mob/living/carbon/human/suitOccupant
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/get_cell()
|
||||
return suitCell
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/toggle_suit_lock(mob/living/carbon/human/user)
|
||||
if(!suitActive)
|
||||
if(!istype(user.wear_suit, /obj/item/clothing/suit/space/space_ninja))
|
||||
to_chat(user, "<span style='color: #ff0000;'><b>ERROR:</b> Unable to locate user.\nABORTING...</span>")
|
||||
return 0
|
||||
if(!istype(user.head, /obj/item/clothing/head/helmet/space/space_ninja))
|
||||
to_chat(user, "<span style='color: #ff0000;'><b>ERROR:</b> Unable to locate hood.\nABORTING...</span>")
|
||||
return 0
|
||||
if(!istype(user.gloves, /obj/item/clothing/gloves/space_ninja))
|
||||
to_chat(user, "<span style='color: #ff0000;'><b>ERROR:</b> Unable to locate gloves.\nABORTING...</span>")
|
||||
return 0
|
||||
if(!istype(user.shoes, /obj/item/clothing/shoes/space_ninja))
|
||||
to_chat(user, "<span style='color: #ff0000;'><b>ERROR:</b> Unable to locate foot gear.\nABORTING...</span>")
|
||||
return 0
|
||||
if(!istype(user.wear_mask, /obj/item/clothing/mask/gas/space_ninja))
|
||||
to_chat(user, "<span style='color: #ff0000;'><b>ERROR:</b> Unable to locate mask.\nABORTING...</span>")
|
||||
return 0
|
||||
|
||||
suitHood = user.head
|
||||
suitMask = user.wear_mask
|
||||
suitGloves = user.gloves
|
||||
suitShoes = user.shoes
|
||||
suitOccupant = user
|
||||
|
||||
set_nodrop(TRUE)
|
||||
suitHood.set_nodrop(TRUE)
|
||||
suitMask.set_nodrop(TRUE)
|
||||
suitGloves.set_nodrop(TRUE)
|
||||
suitGloves.pickpocket = 1
|
||||
suitShoes.set_nodrop(TRUE)
|
||||
suitShoes.slowdown = -2
|
||||
|
||||
icon_state = (user.gender == MALE ? "s-ninjan" : "s-ninjanf")
|
||||
suitGloves.icon_state = "s-ninjan"
|
||||
|
||||
return 1
|
||||
|
||||
else
|
||||
set_nodrop(FALSE)
|
||||
suitHood.set_nodrop(FALSE)
|
||||
suitMask.set_nodrop(FALSE)
|
||||
suitGloves.set_nodrop(FALSE)
|
||||
suitGloves.pickpocket = 0
|
||||
suitShoes.set_nodrop(FALSE)
|
||||
suitShoes.slowdown = -1
|
||||
icon_state = "s-ninja"
|
||||
suitGloves.icon_state = "s-ninja"
|
||||
|
||||
suitHood = null
|
||||
suitMask = null
|
||||
suitGloves = null
|
||||
suitShoes = null
|
||||
suitOccupant = null
|
||||
|
||||
return 1
|
||||
@@ -1,92 +0,0 @@
|
||||
|
||||
//Verbs link to procs because verb-like procs have a bug which prevents their use if the arguments are not readily referenced.
|
||||
//^ Old coder words may be false these days, Not taking the risk for now.
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/verb/toggle_suit()
|
||||
set category = "Space Ninja - Equipment"
|
||||
set name = "Toggle Suit"
|
||||
|
||||
if(usr.mind.special_role == "Ninja")
|
||||
if(suitBusy)
|
||||
to_chat(usr, "<span style='color: #ff0000;'><b>ERROR: </b>Suit systems busy, cannot initiate [suitActive ? "de-activation" : "activation"] protocols at this time.</span>")
|
||||
return
|
||||
|
||||
suitBusy = 1
|
||||
|
||||
if(suitActive && (tgui_alert(usr, "Confirm suit systems shutdown? This cannot be halted once it has started.", "Confirm Shutdown", list("Yes", "No")) == "Yes"))
|
||||
to_chat(usr, SPAN_DARKMBLUE("Now de-initializing..."))
|
||||
|
||||
sleep(15)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Logging off, [usr.real_name]. Shutting down <b>SpiderOS</b>."))
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Primary system status: <B>OFFLINE</B>.\nBackup system status: <b>OFFLINE</b>."))
|
||||
|
||||
sleep(5)
|
||||
to_chat(usr, SPAN_DARKMBLUE("VOID-shift device status: <B>OFFLINE</B>.\nCLOAK-tech device status: <B>OFFLINE</B>."))
|
||||
//TODO: Shut down any active abilities
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Disconnecting neural-net interface...</span> <span style='color: #32CD32'><b>Success</b>."))
|
||||
|
||||
QDEL_NULL(usr.hud_used)
|
||||
usr.create_mob_hud()
|
||||
usr.regenerate_icons()
|
||||
|
||||
sleep(5)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Disengaging neural-net interface...</span> <span style='color: #32CD32'><b>Success</b>."))
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: <B>FINISHED</B>."))
|
||||
//TODO: Grant verbs
|
||||
toggle_suit_lock(usr)
|
||||
usr.regenerate_icons()
|
||||
suitBusy = 0
|
||||
suitActive = 0
|
||||
|
||||
else if(!suitActive) // Activate the suit.
|
||||
to_chat(usr, SPAN_DARKMBLUE("Now initializing..."))
|
||||
|
||||
sleep(15)
|
||||
to_chat(usr, "<span class='darkmblue'>Now establishing neural-net interface...")
|
||||
if(usr.mind.special_role != "Ninja")
|
||||
to_chat(usr, "<span style='color: #ff0000;'><b>FĆAL �Rr�R</b>: ŧer nt recgnized, c-cntr-r䣧-ç äcked.")
|
||||
return
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Neural-net established. Now monitoring brainwave pattern. \nBrainwave pattern</span> <span style='color: #32CD32;'><b>GREEN</b></span><span class='darkmblue'>, proceeding."))
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Securing external locking mechanism..."))
|
||||
if(!toggle_suit_lock(usr))
|
||||
return
|
||||
|
||||
sleep(5)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Suit secured, extending neural-net interface..."))
|
||||
|
||||
QDEL_NULL(usr.hud_used)
|
||||
usr.hud_used = new /datum/hud/human(usr, 'icons/mob/screen_ninja.dmi', "#ffffff", 255)
|
||||
if(usr.hud_used)
|
||||
usr.hud_used.show_hud(usr.hud_used.hud_version)
|
||||
usr.regenerate_icons()
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("VOID-shift device status: <b>ONLINE</b>.\nCLOAK-tech device status:<b>ONLINE</b>"))
|
||||
|
||||
sleep(5)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Primary system status: <b>ONLINE</b>.\nBackup system status: <b>ONLINE</b>."))
|
||||
if(suitCell)
|
||||
to_chat(usr, SPAN_DARKMBLUE("Current energy capacity: <b>[suitCell.charge]/[suitCell.maxcharge]</b>."))
|
||||
|
||||
sleep(10)
|
||||
to_chat(usr, SPAN_DARKMBLUE("All systems operational. Welcome to <b>SpiderOS</b>, [usr.real_name]."))
|
||||
//TODO: Grant ninja verbs here.
|
||||
suitBusy = 0
|
||||
suitActive = 1
|
||||
|
||||
else
|
||||
suitBusy = 0
|
||||
to_chat(usr, SPAN_DARKMBLUE("<b>NOTICE: </b>Suit de-activation protocols aborted."))
|
||||
else
|
||||
to_chat(usr, "<span style='color: #ff0000;'><b>FĆAL �Rr�R</b>: ŧer nt recgnized, c-cntr-r䣧-ç äcked.")
|
||||
return
|
||||
@@ -105,6 +105,9 @@
|
||||
else if(!rad_component)
|
||||
start_rads()
|
||||
|
||||
/obj/item/nuclear_rod/proc/do_special_effect()
|
||||
return
|
||||
|
||||
/obj/item/nuclear_rod/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change)
|
||||
. = ..()
|
||||
check_rad_shield()
|
||||
@@ -164,6 +167,17 @@
|
||||
craftable = TRUE
|
||||
materials = list(MAT_METAL = 2000, MAT_URANIUM = 1000)
|
||||
|
||||
/obj/item/nuclear_rod/fuel/uranium_238/spiders
|
||||
name = "spider-clan uranium 238 fuel rod"
|
||||
desc = "A small fuel rod for most NGCR reactors. This one was green webs coating its surface, with tiny spiders skittering along them."
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
craftable = FALSE
|
||||
adjacent_requirements = list()
|
||||
|
||||
/obj/item/nuclear_rod/fuel/uranium_238/spiders/do_special_effect()
|
||||
if(prob(5))
|
||||
new /mob/living/basic/spiderling(get_turf(src))
|
||||
|
||||
/obj/item/nuclear_rod/fuel/weak_thorium
|
||||
name = "weak thorium fuel rod"
|
||||
desc = "A specialized fuel rod refined from uranium 238. This rod will last longer than normal, and won't generate as much heat."
|
||||
|
||||
@@ -605,6 +605,7 @@
|
||||
final_heat += heat_total
|
||||
final_power += power_total
|
||||
chamber.held_rod.durability -= durability_loss
|
||||
chamber.held_rod.do_special_effect()
|
||||
|
||||
if(final_heat)
|
||||
average_heatgen = final_heat / active_chambers
|
||||
|
||||
@@ -245,6 +245,9 @@
|
||||
/// How long has it been since we processed the crystal?
|
||||
var/tick_counter = 0
|
||||
|
||||
/// Are we being stolen?
|
||||
var/being_stolen = FALSE
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -697,12 +700,31 @@
|
||||
countdown()
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/update_overlays()
|
||||
. = ..()
|
||||
overlays.Cut()
|
||||
if(being_stolen)
|
||||
. += "causality_field"
|
||||
color = COLOR_GREEN
|
||||
else
|
||||
color = COLOR_WHITE
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/bullet_act(obj/projectile/proj)
|
||||
var/turf/L = loc
|
||||
if(!istype(L))
|
||||
return FALSE
|
||||
if(!istype(proj, /obj/projectile/beam/emitter/hitscan) && power_changes)
|
||||
investigate_log("has been hit by [proj] fired by [key_name(proj.firer)]", INVESTIGATE_SUPERMATTER)
|
||||
if(istype(proj, /obj/projectile/energy/net))
|
||||
var/mob/living/carbon/user = proj.firer
|
||||
var/list/obj_list = user.mind.get_all_objectives()
|
||||
for(var/datum/objective/ninja/ninja_obj in obj_list)
|
||||
if(ninja_obj.completed)
|
||||
continue
|
||||
if(!istype(ninja_obj, /datum/objective/ninja/steal_supermatter))
|
||||
continue
|
||||
begin_theft()
|
||||
return FALSE
|
||||
if(proj.flag != BULLET)
|
||||
if(power_changes) //This needs to be here I swear
|
||||
power += proj.damage * bullet_energy
|
||||
@@ -712,6 +734,32 @@
|
||||
damage += proj.damage * bullet_energy
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/proc/begin_theft(mob/living/carbon/thief)
|
||||
if(being_stolen)
|
||||
return
|
||||
message_admins("Ninja [thief] is beginning to steal the Supermatter Crystal.")
|
||||
addtimer(src, CALLBACK(PROC_REF(complete_theft), thief), 3 MINUTES)
|
||||
being_stolen = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/proc/complete_theft(mob/living/carbon/thief)
|
||||
if(!being_stolen)
|
||||
return
|
||||
if(!thief.mind)
|
||||
return
|
||||
var/list/obj_list = thief.mind.get_all_objectives()
|
||||
if(!length(obj_list))
|
||||
return
|
||||
for(var/datum/objective/ninja/ninja_obj in obj_list)
|
||||
if(ninja_obj.completed)
|
||||
continue
|
||||
if(!istype(ninja_obj, /datum/objective/ninja/steal_supermatter))
|
||||
continue
|
||||
ninja_obj.complete_objective()
|
||||
break
|
||||
message_admins("Ninja [thief] has stolen the Supermatter Crystal.")
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/atmospherics/supermatter_crystal/singularity_act()
|
||||
var/gain = 100
|
||||
investigate_log("Supermatter shard consumed by singularity.", INVESTIGATE_SINGULO)
|
||||
@@ -796,6 +844,15 @@
|
||||
/obj/machinery/atmospherics/supermatter_crystal/item_interaction(mob/living/user, obj/item/used, list/modifiers)
|
||||
if(!istype(used) || (used.flags & ABSTRACT) || !istype(user))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(being_stolen)
|
||||
to_chat(user, SPAN_WARNING("You begin to very carefully unfasten the net tangled around [src]!"))
|
||||
if(!do_after_once(user, 5 SECONDS, TRUE, src))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
being_stolen = FALSE
|
||||
update_icon()
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(moveable && default_unfasten_wrench(user, used, time = 20))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user