diff --git a/code/__defines/radio.dm b/code/__defines/radio.dm index 9224603bbc7..d634b6b23b1 100644 --- a/code/__defines/radio.dm +++ b/code/__defines/radio.dm @@ -9,6 +9,7 @@ #define AI_FREQ 1343 #define DTH_FREQ 1341 #define SYND_FREQ 1213 +#define NINJ_FREQ 1255 #define RAID_FREQ 1277 #define ENT_FREQ 1461 //entertainment frequency. This is not a diona exclusive frequency. @@ -35,6 +36,7 @@ var/list/radiochannels = list( "Response Team" = ERT_FREQ, "Special Ops" = DTH_FREQ, "Mercenary" = SYND_FREQ, + "Ninja" = NINJ_FREQ, "Raider" = RAID_FREQ, "Supply" = SUP_FREQ, "Service" = SRV_FREQ, @@ -60,12 +62,14 @@ var/list/CENT_FREQS_ASSOC = list( // Antag channels, i.e. Syndicate var/list/ANTAG_FREQS = list( SYND_FREQ, - RAID_FREQ + RAID_FREQ, + NINJ_FREQ ) var/list/ANTAG_FREQS_ASSOC = list( "[SYND_FREQ]" = TRUE, - "[RAID_FREQ]" = TRUE + "[RAID_FREQ]" = TRUE, + "[NINJ_FREQ]" = TRUE ) //Department channels, arranged lexically diff --git a/code/controllers/subsystems/statistics.dm b/code/controllers/subsystems/statistics.dm index 23c228dc05f..f37ee3cfb7e 100644 --- a/code/controllers/subsystems/statistics.dm +++ b/code/controllers/subsystems/statistics.dm @@ -18,6 +18,7 @@ var/list/msg_deathsquad = list() var/list/msg_syndicate = list() var/list/msg_raider = list() + var/list/msg_ninja = list() var/list/msg_cargo = list() var/list/msg_service = list() diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm index 653207b7e14..f86939bacef 100644 --- a/code/datums/outfits/outfit_admin.dm +++ b/code/datums/outfits/outfit_admin.dm @@ -224,6 +224,32 @@ /obj/item/weapon/implant/explosive ) +/datum/outfit/admin/syndicate/ninja + name = "Infiltrator" + + uniform = /obj/item/clothing/under/syndicate/ninja + back = /obj/item/weapon/rig/light/ninja + belt = /obj/item/weapon/storage/belt/ninja + shoes = /obj/item/clothing/shoes/swat/ert + gloves = /obj/item/clothing/ring/ninja + mask = /obj/item/clothing/mask/balaclava + l_ear = /obj/item/device/radio/headset/ninja + glasses = /obj/item/clothing/glasses/sunglasses/sechud/tactical + id = /obj/item/weapon/card/id/syndicate + l_pocket = /obj/item/device/ninja_uplink + r_pocket = null + accessory = /obj/item/clothing/accessory/storage/black_pouches + + backpack_contents = list() + + belt_contents = list( + /obj/item/device/flashlight/maglight = 1, + /obj/item/weapon/crowbar = 1, + /obj/item/weapon/screwdriver = 1, + /obj/item/device/paicard = 1 + ) + + id_access = "Syndicate Agent" /datum/outfit/admin/nt name = "NanoTrasen Representative" @@ -607,4 +633,4 @@ return "Visitor" /datum/outfit/admin/random/visitor/get_id_rank() - return "Visitor" \ No newline at end of file + return "Visitor" diff --git a/code/game/antagonist/antagonist_create.dm b/code/game/antagonist/antagonist_create.dm index f1890cb1503..6babfe5bb68 100644 --- a/code/game/antagonist/antagonist_create.dm +++ b/code/game/antagonist/antagonist_create.dm @@ -45,6 +45,8 @@ var/obj/item/device/radio/R switch(freq) + if(NINJ_FREQ) + R = new/obj/item/device/radio/headset/ninja(player) if(SYND_FREQ) R = new/obj/item/device/radio/headset/syndicate(player) if(RAID_FREQ) diff --git a/code/game/antagonist/outsider/ninja.dm b/code/game/antagonist/outsider/ninja.dm index 03c981b3987..13ce0b96805 100644 --- a/code/game/antagonist/outsider/ninja.dm +++ b/code/game/antagonist/outsider/ninja.dm @@ -11,9 +11,9 @@ var/datum/antagonist/ninja/ninjas flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE antaghud_indicator = "hudninja" - initial_spawn_req = 1 - initial_spawn_target = 1 - hard_cap = 1 + initial_spawn_req = 2 + initial_spawn_target = 2 + hard_cap = 2 hard_cap_round = 3 id_type = /obj/item/weapon/card/id/syndicate @@ -99,35 +99,20 @@ var/datum/antagonist/ninja/ninjas player.name = H.name /datum/antagonist/ninja/equip(var/mob/living/carbon/human/player) - if(!..()) return 0 - var/obj/item/device/radio/R = new /obj/item/device/radio/headset(player) - player.equip_to_slot_or_del(R, slot_l_ear) - player.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(player), slot_w_uniform) - player.equip_to_slot_or_del(new /obj/item/device/flashlight(player), slot_belt) - player.equip_to_slot_or_del(new /obj/item/device/ninja_uplink(player, player.mind), slot_l_store) - create_id("Infiltrator", player) - - var/obj/item/weapon/rig/light/ninja/ninjasuit = new(get_turf(player)) - ninjasuit.seal_delay = 0 - player.put_in_hands(ninjasuit) - player.equip_to_slot_or_del(ninjasuit,slot_back) - if(ninjasuit) - ninjasuit.toggle_seals(src,1) - ninjasuit.seal_delay = initial(ninjasuit.seal_delay) - - if(istype(player.back,/obj/item/weapon/rig)) - var/obj/item/weapon/rig/rig = player.back - if(rig.air_supply) - player.internal = rig.air_supply - - spawn(10) - if(player.internal) - player.internals.icon_state = "internal1" - else - to_chat(player, "You forgot to turn on your internals! Quickly, toggle the valve!") + for (var/obj/item/I in player) + if (istype(I, /obj/item/weapon/implant)) + continue + player.drop_from_inventory(I) + if(I.loc != player) + qdel(I) + player.preEquipOutfit(/datum/outfit/admin/syndicate/ninja, FALSE) + player.equipOutfit(/datum/outfit/admin/syndicate/ninja, FALSE) + player.force_update_limbs() + player.update_eyes() + player.regenerate_icons() /datum/antagonist/ninja/proc/generate_ninja_directive(side) var/directive = "[side=="face"?"[current_map.company_name]":"A criminal syndicate"] is your employer. "//Let them know which side they're on. diff --git a/code/game/gamemodes/ninja/ninja.dm b/code/game/gamemodes/ninja/ninja.dm index a3b37d657d2..0de04faab83 100644 --- a/code/game/gamemodes/ninja/ninja.dm +++ b/code/game/gamemodes/ninja/ninja.dm @@ -1,16 +1,16 @@ /datum/game_mode/ninja - name = "ninja" + name = "ninjas" round_description = "An agent of the Spider Clan is onboard the station!" extended_round_description = "What was that?! Was that a person or did your eyes just play tricks on you? \ - You have no idea. That slim-suited, cryptic individual is an enigma to you and all of your knowledge. \ + You have no idea. Those slim-suited, cryptic individuals are an enigma to you and all of your knowledge. \ Their purpose is unknown. Their mission is unknown. How they arrived to this secure and isolated \ - section of the galaxy, you don't know. What you do know is that there is a silent shadow-stalker piercing \ + section of the galaxy, you don't know. What you do know is that there are silent shadow-stalkers piercing \ through the defenses of the station with technological capabilities eons ahead of your time. They can avoid \ the omniscience of the AI and rival the most hardened weapons your station is capable of. Tread lightly and \ - only hope this unknown assassin isn't here for you." + only hope these unknown assassins aren't here for you." config_tag = "ninja" - required_players = 2 - max_players = 15 - required_enemies = 1 - end_on_antag_death = 1 + required_players = 10 + max_players = 30 + required_enemies = 2 + end_on_antag_death = 0 antag_tags = list(MODE_NINJA) diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index 59afb9b58f8..7a610ec7c97 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -380,6 +380,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept SSfeedback.msg_syndicate += blackbox_msg if(RAID_FREQ) SSfeedback.msg_raider += blackbox_msg + if(NINJ_FREQ) + SSfeedback.msg_ninja += blackbox_msg if(SUP_FREQ) SSfeedback.msg_cargo += blackbox_msg if(SRV_FREQ) @@ -566,6 +568,8 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept SSfeedback.msg_syndicate += blackbox_msg if(RAID_FREQ) SSfeedback.msg_raider += blackbox_msg + if(NINJ_FREQ) + SSfeedback.msg_ninja += blackbox_msg if(SUP_FREQ) SSfeedback.msg_cargo += blackbox_msg if(SRV_FREQ) diff --git a/code/game/objects/items/devices/hacktool.dm b/code/game/objects/items/devices/hacktool.dm index 6b12c556ee6..2379c9a94f6 100644 --- a/code/game/objects/items/devices/hacktool.dm +++ b/code/game/objects/items/devices/hacktool.dm @@ -1,16 +1,22 @@ /obj/item/device/multitool/hacktool var/is_hacking = 0 - var/max_known_targets var/in_hack_mode = 0 + var/list/current_hacks var/list/known_targets var/list/supported_types var/datum/topic_state/default/must_hack/hack_state + var/hack_time = 30 SECONDS + var/max_known_targets = 7 + var/silent = FALSE + var/multihack = FALSE + var/allow_movement = FALSE + /obj/item/device/multitool/hacktool/New() ..() known_targets = list() - max_known_targets = 5 + rand(1,3) + current_hacks = list() supported_types = list(/obj/machinery/door/airlock) hack_state = new(src) @@ -26,7 +32,7 @@ /obj/item/device/multitool/hacktool/attackby(var/obj/item/W, var/mob/user) if(W.isscrewdriver()) in_hack_mode = !in_hack_mode - playsound(src.loc, W.usesound, 50, 1) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) else ..() @@ -39,13 +45,17 @@ if(!attempt_hack(user, A)) return 0 - A.ui_interact(user, state = hack_state) + if(A.Adjacent(user)) + A.ui_interact(user, state = hack_state) return 1 /obj/item/device/multitool/hacktool/proc/attempt_hack(var/mob/user, var/atom/target) - if(is_hacking) + if(is_hacking && !multihack) to_chat(user, "You are already hacking!") return 0 + if(target in current_hacks) + to_chat(user, span("warning", "You are already hacking this door!")) + return 0 if(!is_type_in_list(target, supported_types)) to_chat(user, "\icon[src] Unable to hack this target!") return 0 @@ -56,13 +66,17 @@ to_chat(user, "You begin hacking \the [target]...") is_hacking = 1 + current_hacks += target + // On average hackin takes ~30 seconds. Fairly small random span to avoid people simply aborting and trying again - var/hack_result = do_after(user, (20 SECONDS + rand(0, 10 SECONDS) + rand(0, 10 SECONDS))) + var/hack_result = do_after(user, hack_time + rand(-5,5), use_user_turf = (allow_movement ? -1 : FALSE)) is_hacking = 0 + current_hacks -= target if(hack_result && in_hack_mode) to_chat(user, "Your hacking attempt was succesful!") - playsound(src.loc, 'sound/piano/A#6.ogg', 75) + if(!silent) + playsound(src.loc, 'sound/piano/A#6.ogg', 75) else to_chat(user, "Your hacking attempt failed!") return 0 @@ -83,6 +97,39 @@ /obj/item/device/multitool/hacktool/proc/on_target_destroy(var/target) known_targets -= target +/obj/item/device/multitool/hacktool/rig //For ninjas; Credits to BurgerBB + hack_time = 50 + max_known_targets = 10 + in_hack_mode = TRUE + silent = TRUE + multihack = TRUE + allow_movement = TRUE + reach = 8 + var/mob/living/creator + +/obj/item/device/multitool/hacktool/rig/Initialize() + . = ..() + START_PROCESSING(SSprocessing, src) + +/obj/item/device/multitool/hacktool/rig/Destroy() + STOP_PROCESSING(SSprocessing, src) + return ..() + +/obj/item/device/multitool/hacktool/rig/process() + if(!creator || loc != creator || (creator.l_hand != src && creator.r_hand != src)) + // Tidy up a bit. + if(istype(loc,/mob/living)) + var/mob/living/carbon/human/host = loc + if(istype(host)) + for(var/obj/item/organ/external/organ in host.organs) + for(var/obj/item/O in organ.implants) + if(O == src) + organ.implants -= src + host.pinned -= src + host.embedded -= src + host.drop_from_inventory(src) + QDEL_IN(src, 1) + /datum/topic_state/default/must_hack var/obj/item/device/multitool/hacktool/hacktool @@ -97,4 +144,4 @@ /datum/topic_state/default/must_hack/can_use_topic(var/src_object, var/mob/user) if(!hacktool || !hacktool.in_hack_mode || !(src_object in hacktool.known_targets)) return STATUS_CLOSE - return ..() + return ..() \ No newline at end of file diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index 4d0bf11e699..e0e885e7c27 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -27,6 +27,12 @@ origin_tech = list(TECH_ILLEGAL = 2) syndie = 1 +/obj/item/device/encryptionkey/ninja + icon_state = "cypherkey" + channels = list("Ninja" = 1) + origin_tech = list(TECH_ILLEGAL = 3) + syndie = 1 + /obj/item/device/encryptionkey/binary icon_state = "cypherkey" translate_binary = 1 diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 8548a89656e..f73f16dd8a2 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -83,6 +83,11 @@ syndie = 1 ks1type = /obj/item/device/encryptionkey/raider +/obj/item/device/radio/headset/ninja + origin_tech = list(TECH_ILLEGAL = 3) + syndie = 1 + ks1type = /obj/item/device/encryptionkey/ninja + /obj/item/device/radio/headset/binary origin_tech = list(TECH_ILLEGAL = 3) ks1type = /obj/item/device/encryptionkey/binary diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 2697459f84a..2337ca52d47 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -347,6 +347,45 @@ /obj/item/clothing/gloves/botanic_leather, ) +/obj/item/weapon/storage/belt/ninja //credits to BurgerBB + name = "advanced combat belt" + desc = "A very robust belt that can hold various specialized gear such as swords, grenades, shurikens, and food rations." + icon_state = "securitybelt" + item_state = "security" + storage_slots = 9 + max_w_class = 4 + max_storage_space = 28 + + can_hold = list( + /obj/item/weapon/grenade, + /obj/item/weapon/handcuffs, + /obj/item/device/flash, + /obj/item/device/paicard, + /obj/item/clothing/glasses, + /obj/item/ammo_casing/shotgun, + /obj/item/ammo_magazine, + /obj/item/weapon/melee/baton, + /obj/item/device/flashlight, + /obj/item/device/pda, + /obj/item/device/radio/headset, + /obj/item/weapon/melee, + /obj/item/weapon/crowbar, + /obj/item/weapon/screwdriver, + /obj/item/weapon/shield/energy, + /obj/item/weapon/pinpointer, + /obj/item/weapon/plastique, + /obj/item/weapon/gun/projectile/pistol, + /obj/item/weapon/gun/energy/crossbow, + /obj/item/ammo_casing/a145, + /obj/item/device/radio/uplink, + /obj/item/weapon/card/emag, + /obj/item/device/multitool/hacktool, + /obj/item/weapon/reagent_containers, + /obj/item/stack/telecrystal, + /obj/item/weapon/material/sword, + /obj/item/weapon/material/star + ) + /obj/item/weapon/storage/belt/fannypack name = "leather fannypack" desc = "A dorky fannypack for keeping small items in." diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 2263f9f7c6f..df97f7af736 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -41,6 +41,19 @@ heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE +/obj/item/clothing/ring/ninja + desc = "A pair of plain black infiltration gloves. Too thin to protect anything, but can fit underneath a hardsuit gauntlet." + name = "black slipgloves" + icon = 'icons/obj/clothing/gloves.dmi' + icon_state = "s-ninja" + item_state = "s-ninja" + siemens_coefficient = 0 + permeability_coefficient = 0.05 + undergloves = 1 + cold_protection = HANDS + min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE + heat_protection = HANDS + max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE /obj/item/clothing/gloves/latex name = "latex gloves" diff --git a/code/modules/clothing/spacesuits/rig/modules/ninja.dm b/code/modules/clothing/spacesuits/rig/modules/ninja.dm index 45c3e263897..680c3fc330e 100644 --- a/code/modules/clothing/spacesuits/rig/modules/ninja.dm +++ b/code/modules/clothing/spacesuits/rig/modules/ninja.dm @@ -78,6 +78,7 @@ redundant = 1 usable = 1 selectable = 1 + var/lastteleport engage_string = "Emergency Leap" @@ -106,13 +107,17 @@ /obj/item/rig_module/teleporter/engage(var/atom/target, var/notify_ai) - if(!..()) return 0 + if(!..()) return FALSE var/mob/living/carbon/human/H = holder.wearer + if(lastteleport + (5 SECONDS) > world.time) + to_chat(H, span("warning", "The teleporter needs time to cool down!")) + return FALSE + if(!istype(H.loc, /turf)) to_chat(H, "You cannot teleport out of your current location.") - return 0 + return FALSE var/turf/T if(target) @@ -122,19 +127,19 @@ if(!T || T.density) to_chat(H, "You cannot teleport into solid walls.") - return 0 + return FALSE if(T.z in current_map.admin_levels) to_chat(H, "You cannot use your teleporter on this Z-level.") - return 0 + return FALSE if(T.contains_dense_objects()) to_chat(H, "You cannot teleport to a location with solid objects.") - return 0 + return FALSE if((T.z != H.z || get_dist(T, get_turf(H)) > world.view) && target) to_chat(H, "You cannot teleport to such a distant object.") - return 0 + return FALSE phase_out(H,get_turf(H)) do_teleport(H,T) @@ -149,7 +154,8 @@ do_teleport(G.affecting,locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)) phase_in(G.affecting,get_turf(G.affecting)) - return 1 + lastteleport = world.time + return TRUE /obj/item/rig_module/fabricator/energy_net @@ -264,7 +270,7 @@ interface_name = "emergency power generator" interface_desc = "A high yield power generating device that takes a long time to recharge." - var/generation_ammount = 1500 + var/generation_ammount = 2500 category = MODULE_SPECIAL @@ -280,7 +286,7 @@ playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1) holder.cell.give(generation_ammount) cooldown = 1 - addtimer(CALLBACK(src, /obj/item/rig_module/emergency_powergenerator/proc/reset_cooldown), 240) + addtimer(CALLBACK(src, /obj/item/rig_module/emergency_powergenerator/proc/reset_cooldown), 5 MINUTES) /obj/item/rig_module/emergency_powergenerator/proc/reset_cooldown() cooldown = 0 @@ -297,3 +303,64 @@ device_type = /obj/item/weapon/robot_emag category = MODULE_SPECIAL + +/obj/item/rig_module/stealth_field/advanced //credits to Burger BB + name = "advanced active camouflage module" + desc = "A robust hardsuit-integrated stealth module. This model sports a significantly lower cooldown between uses as well as a reduced charge cost." + use_power_cost = 10 + active_power_cost = 2 + passive_power_cost = 0 + module_cooldown = 10 + + category = MODULE_SPECIAL + +/obj/item/rig_module/device/door_hack //credits to BurgerBB + name = "advanced door hacking tool" + desc = "An advanced door hacking tool that sports a low power cost and incredibly quick door hacking time. The device also supports hacking several signals at once remotely, and the last 10 doors hacked can be instantly accessed." + use_power_cost = 10 + module_cooldown = 5 + + usable = 0 + selectable = 0 + toggleable = 1 + + interface_name = "advanced door hacking tool" + interface_desc = "An advanced door hacking tool that sports a low power cost and incredibly quick door hacking time. The device also supports hacking several signals at once remotely, and the last 10 doors hacked can be instantly accessed." + + category = MODULE_SPECIAL + +/obj/item/rig_module/device/door_hack/process() + + if(holder && holder.wearer) + if(!(locate(/obj/item/device/multitool/hacktool/rig) in holder.wearer)) + deactivate() + return 0 + + return ..() + +/obj/item/rig_module/device/door_hack/activate() + + ..() + + var/mob/living/M = holder.wearer + + if(M.l_hand && M.r_hand) + to_chat(M, "Your hands are full.") + deactivate() + return + + var/obj/item/device/multitool/hacktool/rig/hacktool = new(M) + hacktool.creator = M + M.put_in_hands(hacktool) + +/obj/item/rig_module/device/door_hack/deactivate() + + ..() + + var/mob/living/M = holder.wearer + + if(!M) + return + + for(var/obj/item/device/multitool/hacktool/rig/hacktool in M.contents) + qdel(hacktool) \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/rig/suits/light.dm b/code/modules/clothing/spacesuits/rig/suits/light.dm index 2a7d3a8f813..a767a9d1219 100644 --- a/code/modules/clothing/spacesuits/rig/suits/light.dm +++ b/code/modules/clothing/spacesuits/rig/suits/light.dm @@ -76,31 +76,40 @@ /obj/item/weapon/rig/light/ninja name = "stealth suit control module" suit_type = "stealth suit" - desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for stealth operations." + desc = "A unique, vacuum-proof suit of nano-enhanced armor designed specifically for stealth operations." icon_state = "ninja_rig" - armor = list(melee = 50, bullet = 35, laser = 35, energy = 30, bomb = 25, bio = 100, rad = 30) + armor = list(melee = 50, bullet = 45, laser = 45, energy = 30, bomb = 35, bio = 100, rad = 100) emp_protection = 40 slowdown = 0 species_restricted = list("Human","Tajara","Unathi", "Skrell", "Machine", "Vaurca") + helm_type = /obj/item/clothing/head/helmet/space/rig/light/ninja chest_type = /obj/item/clothing/suit/space/rig/light/ninja glove_type = /obj/item/clothing/gloves/rig/light/ninja - boot_type = /obj/item/clothing/shoes/rig/light/ninja + boot_type = /obj/item/clothing/shoes/magboots/rig/light/ninja req_access = list(access_syndicate) initial_modules = list( - /obj/item/rig_module/teleporter, /obj/item/rig_module/vision, /obj/item/rig_module/voice, + /obj/item/rig_module/teleporter, + /obj/item/rig_module/stealth_field, + /obj/item/rig_module/electrowarfare_suite, /obj/item/rig_module/ai_container, + /obj/item/rig_module/device/door_hack, /obj/item/rig_module/datajack, + /obj/item/rig_module/chem_dispenser/ninja, /obj/item/rig_module/self_destruct, - /obj/item/rig_module/actuators + /obj/item/rig_module/actuators/combat ) allowed_module_types = MODULE_GENERAL | MODULE_LIGHT_COMBAT | MODULE_HEAVY_COMBAT | MODULE_SPECIAL | MODULE_MEDICAL | MODULE_UTILITY | MODULE_VAURCA +/obj/item/clothing/head/helmet/space/rig/light/ninja + light_overlay = "helmet_light_dual_green" + light_color = "#3e7c3e" + /obj/item/weapon/rig/light/ninja/equipped initial_modules = list( /obj/item/rig_module/teleporter, @@ -122,7 +131,7 @@ name = "insulated gloves" siemens_coefficient = 0 -/obj/item/clothing/shoes/rig/light/ninja +/obj/item/clothing/shoes/magboots/rig/light/ninja silent = 1 /obj/item/clothing/suit/space/rig/light/ninja @@ -223,4 +232,4 @@ /obj/item/rig_module/fabricator/energy_net, /obj/item/rig_module/chem_dispenser/combat, /obj/item/rig_module/mounted/xray - ) \ No newline at end of file + ) diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index 782c5e0f0e1..b20dad820ba 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -28,3 +28,10 @@ icon_state = "fulltracksuit" item_state = "fulltracksuit" contained_sprite = 1 + +/obj/item/clothing/under/syndicate/ninja + name = "slipsuit" + desc = "A sleek, form-fitting undersuit designed to retain the wearer's mobility. It almost feels like you're wearing nothing at all." + icon_state = "ninja" + item_state = "ninja" + worn_state = "ninja" \ No newline at end of file diff --git a/html/changelogs/geeves_duoNinja.yml b/html/changelogs/geeves_duoNinja.yml new file mode 100644 index 00000000000..848a16f79de --- /dev/null +++ b/html/changelogs/geeves_duoNinja.yml @@ -0,0 +1,52 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# balance +# admin +# backend +# security +# refactor +################################# + +# Your name. +author: Geeves, with some code by BurgerBB + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Added a ninja frequency to radios which ninjas spawn with to collaborate." + - tweak: "Two ninjas now spawn instead of just one." + - rscadd: "Gave the ninja better spawning gear, a syndicate uniform, a belt with some tools and a pAI card." + - tweak: "The ninja suit now has new lights, and its shoes are now magboots." + - rscadd: "Added a doorhack RIG module. Functions the same as the normal doorhack, but the user can move around after initiating the hack, as well as hack multiple airlocks at once." + - tweak: "Gave the ninja teleporter a 5 second cooldown between uses." + - rscadd: "Added new advanced combat belt, can hold various gear that a ninja would usually come across." + - tweak : "Buffed the ninja's RIG armour values slightly. Still requires feedback, if ninjas die too quickly, it will be buffed more." + - rscadd: "Added an additional toolbox, chair, suitcooling unit and ninja spawn point to the ninja shuttle on the centcomm level." + - rscadd: Gave the ninja a new uniform + gloves. + - tweak: "EMERGENCY power generator now generates 2500 units of power, with a cooldown of five minutes." + - wip: "Gnomes still evading capture. Report any occurences of gnomes and gnome activity to Aurora authorities." diff --git a/icons/mob/hands.dmi b/icons/mob/hands.dmi index d559cbf534d..ceb37c9d97d 100644 Binary files a/icons/mob/hands.dmi and b/icons/mob/hands.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 75a85365757..0b03cf93899 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 2da123493e5..b7cb92b551b 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/maps/aurora/aurora-1_centcomm.dmm b/maps/aurora/aurora-1_centcomm.dmm index 3d170428f7b..0ce207de579 100644 --- a/maps/aurora/aurora-1_centcomm.dmm +++ b/maps/aurora/aurora-1_centcomm.dmm @@ -3788,6 +3788,7 @@ "aki" = ( /obj/structure/table/rack, /obj/item/device/suit_cooling_unit/improved, +/obj/item/device/suit_cooling_unit/improved, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -22216,6 +22217,7 @@ /obj/item/weapon/storage/toolbox/syndicate, /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle, /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle, +/obj/item/weapon/storage/toolbox/syndicate, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -25376,6 +25378,19 @@ icon_state = "green" }, /area/centcom/living) +"wQa" = ( +/obj/effect/landmark{ + name = "ninjastart" + }, +/obj/structure/bed/chair{ + dir = 1 + }, +/turf/simulated/shuttle/floor{ + icon_state = "floor4" + }, +/area/syndicate_mothership{ + name = "\improper Ninja Base" + }) "xhq" = ( /obj/machinery/computer/cryopod{ pixel_y = 32 @@ -65562,7 +65577,7 @@ ahn ajU aXO akh -akh +wQa akF akh akN