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:
@@ -74,6 +74,8 @@
|
||||
var/list/datum/mind/wizards = list()
|
||||
/// A list of all minds that are wizard apprentices
|
||||
var/list/datum/mind/apprentices = list()
|
||||
/// A list of all minds that are ninjas
|
||||
var/list/datum/mind/ninjas = list()
|
||||
|
||||
/// The cult team datum
|
||||
var/datum/team/cult/cult_team
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
#define NINJA_OBJECTIVE_EASY 10
|
||||
#define NINJA_OBJECTIVE_NORMAL 20
|
||||
#define NINJA_OBJECTIVE_HARD 40
|
||||
|
||||
/datum/objective/ninja
|
||||
/// Can you only roll this objective once?
|
||||
var/onlyone = FALSE
|
||||
/// Does this objective come with special gear
|
||||
var/special_equipment_path
|
||||
/// Rewarded currency for objective completion
|
||||
var/reward_tc = NINJA_OBJECTIVE_EASY
|
||||
|
||||
/datum/objective/ninja/New(text, datum/team/team_to_join, datum/mind/_owner)
|
||||
. = ..()
|
||||
if(special_equipment_path)
|
||||
addtimer(CALLBACK(src, PROC_REF(hand_out_equipment)), 3 SECONDS, TIMER_DELETE_ME)
|
||||
|
||||
/datum/objective/ninja/proc/hand_out_equipment()
|
||||
give_kit(special_equipment_path)
|
||||
|
||||
/datum/objective/ninja/is_invalid_target(datum/mind/possible_target)
|
||||
. = ..()
|
||||
if(possible_target.current)
|
||||
var/turf/current_location = get_turf(possible_target.current)
|
||||
if(current_location && !is_station_level(current_location.z))
|
||||
return TARGET_INVALID_UNREACHABLE
|
||||
|
||||
/datum/objective/ninja/proc/complete_objective()
|
||||
for(var/datum/mind/M in get_owners())
|
||||
var/mob/living/carbon/human/H = M.current
|
||||
if(!ishuman(H))
|
||||
continue
|
||||
var/obj/item/bio_chip/uplink/ninja/nuplink = locate(/obj/item/bio_chip/uplink/ninja) in H
|
||||
if(!nuplink)
|
||||
continue
|
||||
nuplink.hidden_uplink.uses += reward_tc
|
||||
completed = TRUE
|
||||
|
||||
/datum/objective/ninja/proc/check_objective_conditions()
|
||||
return TRUE
|
||||
|
||||
/datum/objective/ninja/kill
|
||||
name = "Kill a Target"
|
||||
reward_tc = NINJA_OBJECTIVE_NORMAL
|
||||
|
||||
/datum/objective/ninja/kill/update_explanation_text()
|
||||
if(target?.current)
|
||||
explanation_text = "Kill [target.current.real_name], the [target.assigned_role]. Scan the corpse with your scanner to verify that the deed is done."
|
||||
var/datum/job/target_job = SSjobs.GetJob(target.assigned_role)
|
||||
if(target_job.job_department_flags & DEP_FLAG_COMMAND || target_job.job_department_flags & DEP_FLAG_SECURITY)
|
||||
reward_tc = NINJA_OBJECTIVE_HARD
|
||||
|
||||
/datum/objective/ninja/capture
|
||||
name = "Capture a Target"
|
||||
reward_tc = NINJA_OBJECTIVE_NORMAL
|
||||
/// The kidnapee's belongings. Set upon capture.
|
||||
var/list/obj/item/victim_belongings = null
|
||||
/// Temporary objects that are available to the kidnapee during their time in jail. These are deleted when the victim is returned.
|
||||
var/list/obj/temp_objs = null
|
||||
/// Prisoner jail timer handle. On completion, returns the prisoner back to station.
|
||||
var/prisoner_timer_handle = null
|
||||
|
||||
/datum/objective/ninja/capture/update_explanation_text()
|
||||
if(target?.current)
|
||||
explanation_text = "Capture [target.current.real_name], the [target.assigned_role]. Use your energy net to capture them so that we can interrogate them at one of our many secret dojos."
|
||||
var/datum/job/target_job = SSjobs.GetJob(target.assigned_role)
|
||||
if(target_job.job_department_flags & DEP_FLAG_COMMAND || target_job.job_department_flags & DEP_FLAG_SECURITY)
|
||||
reward_tc = NINJA_OBJECTIVE_HARD
|
||||
if(target_job.job_department_flags & DEP_FLAG_SERVICE)
|
||||
reward_tc = NINJA_OBJECTIVE_EASY
|
||||
|
||||
/datum/objective/ninja/capture/proc/handle_capture(mob/living/sucker, turf/T)
|
||||
var/mob/living/carbon/human/H = sucker
|
||||
|
||||
// Prepare their return
|
||||
prisoner_timer_handle = addtimer(CALLBACK(src, PROC_REF(handle_target_return), sucker, T), rand(3 MINUTES, 5 MINUTES), TIMER_STOPPABLE)
|
||||
|
||||
LAZYSET(GLOB.prisoner_belongings.prisoners, sucker, src)
|
||||
|
||||
// Shove all of the victim's items in the secure locker.
|
||||
victim_belongings = list()
|
||||
var/list/obj/item/stuff_to_transfer = list()
|
||||
|
||||
// Cybernetic implants get removed first (to deal with NODROP stuff)
|
||||
for(var/obj/item/organ/internal/cyberimp/I in H.internal_organs)
|
||||
// Greys get to keep their implant
|
||||
if(isgrey(H) && istype(I, /obj/item/organ/internal/cyberimp/brain/speech_translator))
|
||||
continue
|
||||
// IPCs keep this implant, free of charge!
|
||||
if(ismachineperson(H) && istype(I, /obj/item/organ/internal/cyberimp/arm/power_cord))
|
||||
continue
|
||||
// Try removing it
|
||||
I = I.remove(H)
|
||||
if(I)
|
||||
stuff_to_transfer += I
|
||||
|
||||
// Skrell headpocket. They already have a check in place to limit what's placed in them.
|
||||
var/obj/item/organ/internal/headpocket/C = H.get_int_organ(/obj/item/organ/internal/headpocket)
|
||||
if(C?.held_item)
|
||||
GLOB.prisoner_belongings.give_item(C.held_item)
|
||||
victim_belongings += C.held_item
|
||||
C.held_item = null
|
||||
|
||||
if(sucker.back) // Lets not bork modsuits in funny ways.
|
||||
var/obj/modsuit_safety = sucker.back
|
||||
sucker.drop_item_to_ground(modsuit_safety)
|
||||
stuff_to_transfer += modsuit_safety
|
||||
// Regular items get removed in second
|
||||
for(var/obj/item/I in sucker)
|
||||
// Keep their uniform and shoes
|
||||
if(I == H.w_uniform || I == H.shoes)
|
||||
continue
|
||||
// Plasmamen are no use if they're crispy
|
||||
if(isplasmaman(H) && I == H.head)
|
||||
continue
|
||||
|
||||
// Any kind of implant gets potentially removed (mindshield, freedoms, etc)
|
||||
if(istype(I, /obj/item/bio_chip))
|
||||
if(istype(I, /obj/item/bio_chip/storage)) // Storage items are removed and placed in the confiscation locker before the implant is taken.
|
||||
var/obj/item/bio_chip/storage/storage_chip = I
|
||||
for(var/it in storage_chip.storage)
|
||||
storage_chip.storage.remove_from_storage(it)
|
||||
stuff_to_transfer += it
|
||||
qdel(I)
|
||||
continue
|
||||
|
||||
if(sucker.drop_item_to_ground(I))
|
||||
stuff_to_transfer += I
|
||||
|
||||
// Remove accessories from the suit if present
|
||||
if(length(H.w_uniform?.accessories))
|
||||
for(var/obj/item/clothing/accessory/A in H.w_uniform.accessories)
|
||||
H.w_uniform.detach_accessory(A, null)
|
||||
H.drop_item_to_ground(A)
|
||||
stuff_to_transfer += A
|
||||
|
||||
// Transfer it all (or drop it if not possible)
|
||||
for(var/obj/item/i as anything in stuff_to_transfer)
|
||||
if(GLOB.prisoner_belongings.give_item(i))
|
||||
victim_belongings += i
|
||||
else if(!((ABSTRACT|NODROP) in i.flags)) // Anything that can't be put on hold, just drop it on the ground
|
||||
i.forceMove(T)
|
||||
|
||||
// Give some species the necessary to survive. Courtesy of the Syndicate.
|
||||
if(istype(H))
|
||||
var/obj/item/tank/internals/emergency_oxygen/tank
|
||||
var/obj/item/clothing/mask/breath/mask
|
||||
if(isvox(H))
|
||||
tank = new /obj/item/tank/internals/emergency_oxygen/nitrogen(H)
|
||||
mask = new /obj/item/clothing/mask/breath/vox(H)
|
||||
else if(isplasmaman(H))
|
||||
tank = new /obj/item/tank/internals/emergency_oxygen/plasma(H)
|
||||
mask = new /obj/item/clothing/mask/breath(H)
|
||||
|
||||
if(tank)
|
||||
H.equip_to_appropriate_slot(tank)
|
||||
H.equip_to_appropriate_slot(mask)
|
||||
tank.toggle_internals(H, TRUE)
|
||||
|
||||
sucker.reagents.add_reagent("mutadone", 1) // 1u of mutadone for the Hulk:tm: experience
|
||||
sucker.update_icons()
|
||||
|
||||
// Supply them with some chow. How generous is the Syndicate?
|
||||
var/obj/item/food/sliced/bread/food = new(get_turf(sucker))
|
||||
food.name = "stale bread"
|
||||
food.desc = "Looks like your captors care for their prisoners as much as their bread."
|
||||
food.trash = null
|
||||
if(prob(10))
|
||||
// Mold adds a bit of spice to it
|
||||
food.name = "moldy bread"
|
||||
food.reagents.add_reagent("fungus", 1)
|
||||
|
||||
var/obj/item/reagent_containers/drinks/drinkingglass/drink = new(get_turf(sucker))
|
||||
drink.reagents.add_reagent("tea", 25) // British coders beware, tea in glasses
|
||||
|
||||
var/obj/item/coin/antagtoken/passingtime = new(get_turf(sucker))
|
||||
|
||||
temp_objs = list(food, drink, passingtime)
|
||||
|
||||
// Narrate their kidnapping and torturing experience.
|
||||
if(sucker.stat != DEAD)
|
||||
// Heal them up - gets them out of crit/soft crit.
|
||||
sucker.reagents.add_reagent("omnizine", 10)
|
||||
|
||||
to_chat(sucker, SPAN_WARNING("You feel strange..."))
|
||||
sucker.Paralyse(30 SECONDS)
|
||||
sucker.EyeBlind(35 SECONDS)
|
||||
sucker.EyeBlurry(35 SECONDS)
|
||||
sucker.AdjustConfused(35 SECONDS)
|
||||
|
||||
for(var/mob/living/simple_animal/hostile/guardian/G in GLOB.alive_mob_list)
|
||||
if(G.summoner == sucker)
|
||||
sucker.remove_guardian_actions()
|
||||
to_chat(G, SPAN_DANGER("You feel your body ripped to shreds as you're forcibly removed from your summoner!"))
|
||||
to_chat(sucker, SPAN_WARNING("You feel some part of you missing, you're not who you used to be..."))
|
||||
G.ghostize()
|
||||
qdel(G)
|
||||
|
||||
sleep(6 SECONDS)
|
||||
to_chat(sucker, SPAN_WARNING("That portal did something to you..."))
|
||||
|
||||
sleep(6.5 SECONDS)
|
||||
to_chat(sucker, SPAN_WARNING("Your head pounds... It feels like it's going to burst out your skull!"))
|
||||
|
||||
sleep(3 SECONDS)
|
||||
to_chat(sucker, SPAN_WARNING("Your head pounds..."))
|
||||
|
||||
sleep(10 SECONDS)
|
||||
to_chat(sucker, "<span class='specialnotice'>A million voices echo in your head... <i>\"Your mind held many valuable secrets - \
|
||||
we thank you for providing them. Your value is expended, and you will be ransomed back to your station. We always get paid, \
|
||||
so it's only a matter of time before we send you back...\"</i></span>")
|
||||
|
||||
to_chat(sucker, SPAN_DANGER("<font size=3>You have been kidnapped and interrogated for valuable information! You will be sent back to the station in a few minutes...</font>"))
|
||||
|
||||
/datum/objective/ninja/capture/proc/handle_target_return(mob/living/M, turf/T)
|
||||
// Make a closet to return the target and their items neatly
|
||||
var/obj/structure/closet/closet = new(T)
|
||||
|
||||
// Return their items
|
||||
for(var/i in victim_belongings)
|
||||
var/obj/item/I = GLOB.prisoner_belongings.remove_item(i)
|
||||
if(!I)
|
||||
continue
|
||||
I.forceMove(closet)
|
||||
|
||||
victim_belongings = list()
|
||||
|
||||
// Clean up
|
||||
var/obj/item/bio_chip/uplink/uplink_implant = locate() in M
|
||||
uplink_implant?.hidden_uplink?.is_jammed = FALSE
|
||||
|
||||
QDEL_LIST_CONTENTS(temp_objs)
|
||||
|
||||
// Injuries due to questioning
|
||||
injure_target(M)
|
||||
|
||||
// Return them a bit confused.
|
||||
M.visible_message(SPAN_NOTICE("[M] vanishes..."))
|
||||
M.forceMove(closet)
|
||||
M.Paralyse(3 SECONDS)
|
||||
M.EyeBlurry(5 SECONDS)
|
||||
M.AdjustConfused(5 SECONDS)
|
||||
M.Dizzy(70 SECONDS)
|
||||
do_sparks(4, FALSE, T)
|
||||
|
||||
prisoner_timer_handle = null
|
||||
GLOB.prisoner_belongings.prisoners[M] = null
|
||||
|
||||
/datum/objective/ninja/capture/proc/injure_target(mob/living/M)
|
||||
var/obj/item/organ/external/injury_target
|
||||
if(prob(20)) // See if they're !!!lucky!!! enough to just chop a hand or foot off first, or even !!LUCKIER!! that it chose an already amputated limb
|
||||
injury_target = M.get_organ(pick(BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT))
|
||||
if(!injury_target)
|
||||
return
|
||||
default_damage(M)
|
||||
injury_target.droplimb()
|
||||
to_chat(M, SPAN_WARNING("You were interrogated by your captors before being sent back! Oh god, something's missing!"))
|
||||
return
|
||||
// Species specific punishments first
|
||||
if(ismachineperson(M))
|
||||
M.emp_act(EMP_HEAVY)
|
||||
M.adjustBrainLoss(30)
|
||||
to_chat(M, SPAN_WARNING("You were interrogated by your captors before being sent back! You feel like some of your components are loose!"))
|
||||
return
|
||||
default_damage(M) // Now that we won't accidentally kill an IPC we can make everyone take damage
|
||||
if(isslimeperson(M))
|
||||
injury_target = M.get_organ(pick(BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT))
|
||||
if(!injury_target)
|
||||
return
|
||||
injury_target.cause_internal_bleeding()
|
||||
injury_target = M.get_organ(BODY_ZONE_CHEST)
|
||||
injury_target.cause_internal_bleeding()
|
||||
to_chat(M, SPAN_WARNING("You were interrogated by your captors before being sent back! You feel like your inner membrane has been punctured!"))
|
||||
return
|
||||
if(prob(25)) // You either get broken ribs, or a broken limb and IB if you made it this far
|
||||
injury_target = M.get_organ(BODY_ZONE_CHEST)
|
||||
injury_target.fracture()
|
||||
else
|
||||
injury_target = M.get_organ(pick(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_R_LEG))
|
||||
if(!injury_target)
|
||||
return
|
||||
injury_target.fracture()
|
||||
injury_target.cause_internal_bleeding()
|
||||
|
||||
/datum/objective/ninja/capture/proc/default_damage(mob/living/M)
|
||||
M.adjustBruteLoss(40)
|
||||
M.adjustBrainLoss(25)
|
||||
|
||||
/datum/objective/ninja/hack_rnd
|
||||
name = "Hack RnD"
|
||||
explanation_text = "A client wants access to Nanotrasen's research databank. Use your scanner on their servers to give them a way inside."
|
||||
needs_target = FALSE
|
||||
onlyone = TRUE
|
||||
|
||||
/datum/objective/ninja/interrogate_ai
|
||||
name = "Interrogate AI"
|
||||
explanation_text = "We wish to expunge some data from their AI system. Use your scanner on an active AI core to wirelessly transfer it to us for interrogation."
|
||||
needs_target = FALSE
|
||||
onlyone = TRUE
|
||||
reward_tc = NINJA_OBJECTIVE_HARD
|
||||
|
||||
/datum/objective/ninja/interrogate_ai/check_objective_conditions() // If there is no AI, you don't get the objective.
|
||||
if(!length(GLOB.ai_list))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/objective/ninja/steal_supermatter
|
||||
name = "Steal Supermatter"
|
||||
explanation_text = "Steal the supermatter crystal, using the net gun we have modified for you. The crystal will sell well to the highest bidder."
|
||||
needs_target = FALSE
|
||||
onlyone = TRUE
|
||||
reward_tc = NINJA_OBJECTIVE_HARD
|
||||
|
||||
/datum/objective/ninja/steal_supermatter/check_objective_conditions() // If there is no supermatter, you don't get the objective.
|
||||
return !isnull(GLOB.main_supermatter_engine)
|
||||
|
||||
/datum/objective/ninja/insert_spider_rod
|
||||
name = "Sabotage Fission Reactor"
|
||||
explanation_text = "Insert a spider-clan uranium 238 fuel rod into the station's fission reactor, then scan the reactor chamber while it is active."
|
||||
needs_target = FALSE
|
||||
onlyone = TRUE
|
||||
reward_tc = NINJA_OBJECTIVE_HARD
|
||||
special_equipment_path = /obj/item/beacon/ninja_rod_spawner
|
||||
|
||||
/datum/objective/ninja/insert_spider_rod/check_objective_conditions() // If there is no reactor, you don't get the objective.
|
||||
return !isnull(GLOB.main_fission_reactor)
|
||||
|
||||
/datum/objective/ninja/bomb_department
|
||||
name = "Bomb Department"
|
||||
needs_target = FALSE
|
||||
special_equipment_path = /obj/item/wormhole_jaunter/ninja_bomb
|
||||
explanation_text = "Use the special flare provided to call down and arm a spider bomb. The target department is inscribed on the flare."
|
||||
reward_tc = NINJA_OBJECTIVE_NORMAL
|
||||
|
||||
/datum/objective/ninja/bomb_department/emp
|
||||
name = "EMP Department"
|
||||
explanation_text = "Use the special flare provided to call down and arm an EMP bomb. The target department is inscribed on the flare."
|
||||
special_equipment_path = /obj/item/wormhole_jaunter/ninja_bomb/emp
|
||||
|
||||
/datum/objective/ninja/bomb_department/spiders
|
||||
name = "Spider Bomb Department"
|
||||
explanation_text = "Use the special flare provided to call down and arm a Spider bomb. The target department is inscribed on the flare."
|
||||
special_equipment_path = /obj/item/wormhole_jaunter/ninja_bomb/spiders
|
||||
|
||||
/datum/objective/ninja_exfiltrate
|
||||
name = "Exfiltrate"
|
||||
explanation_text = "Use your exfiltration flare to escape the station when your work is done."
|
||||
needs_target = FALSE
|
||||
|
||||
#undef NINJA_OBJECTIVE_EASY
|
||||
#undef NINJA_OBJECTIVE_NORMAL
|
||||
#undef NINJA_OBJECTIVE_HARD
|
||||
@@ -1014,6 +1014,17 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
|
||||
add_fingerprint(user)
|
||||
if(!headbutt_shock_check(user))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(istype(used, /obj/item/katana/energy) && user.a_intent == INTENT_HELP)
|
||||
if(locked)
|
||||
if(!do_after_once(user, 5 SECONDS, TRUE, src, allow_moving = FALSE, must_be_held = FALSE))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
unlock()
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
else
|
||||
if(!do_after_once(user, 2.5 SECONDS, TRUE, src, allow_moving = FALSE, must_be_held = FALSE))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
open()
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(panel_open)
|
||||
if(istype(used, /obj/item/kitchen/utensil/fork))
|
||||
return NONE
|
||||
|
||||
@@ -317,7 +317,11 @@
|
||||
//If it's in the process of opening/closing, ignore the click
|
||||
if(operating)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(istype(used, /obj/item/katana/energy) && user.a_intent == INTENT_HELP)
|
||||
if(!do_after_once(user, 2.5 SECONDS, TRUE, src, allow_moving = FALSE, must_be_held = FALSE))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
open()
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
add_fingerprint(user)
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -104,6 +104,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp
|
||||
name = "revenantspawn"
|
||||
icon_state = "Rev"
|
||||
|
||||
/obj/effect/landmark/spawner/ninja
|
||||
name = "ninjaspawn"
|
||||
|
||||
/obj/effect/landmark/spawner/bubblegum_arena
|
||||
name = "bubblegum_arena_human"
|
||||
icon_state = "Explorer"
|
||||
@@ -142,13 +145,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp
|
||||
spawner_list = GLOB.ertdirector
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/spawner/ninjastart
|
||||
name = "ninjastart"
|
||||
|
||||
/obj/effect/landmark/spawner/ninjastart/Initialize(mapload)
|
||||
spawner_list = GLOB.ninjastart
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/spawner/aroomwarp
|
||||
name = "aroomwarp"
|
||||
|
||||
@@ -198,6 +194,13 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp
|
||||
spawner_list = GLOB.syndieprisonwarp
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/spawner/ninja_prison_warp
|
||||
name = "ninja prison warp"
|
||||
|
||||
/obj/effect/landmark/spawner/ninja_prison_warp/Initialize(mapload)
|
||||
spawner_list = GLOB.ninjaprisonwarp
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/spawner/antag_extract_warp
|
||||
name = "antagextractwarp"
|
||||
|
||||
@@ -230,9 +233,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp
|
||||
/obj/effect/landmark/spawner/commando_manual
|
||||
name = "Deathsquad Commando Manual"
|
||||
|
||||
/obj/effect/landmark/spawner/holding_facility
|
||||
name = "Holding Facility"
|
||||
|
||||
/obj/effect/landmark/spawner/holocarp
|
||||
name = "Holocarp Spawn"
|
||||
|
||||
|
||||
@@ -44,6 +44,19 @@
|
||||
syndicate = TRUE
|
||||
emagged = TRUE
|
||||
|
||||
// Spawns a spider fuel rod for ninja objectives
|
||||
/obj/item/beacon/ninja_rod_spawner
|
||||
name = "spider clan beacon"
|
||||
desc = "A label on it reads: <i>Activate to have a spider clan brand fuel rod teleported to your location</i>."
|
||||
origin_tech = "bluespace=6;syndicate=3"
|
||||
|
||||
/obj/item/beacon/ninja_rod_spawner/attack_self__legacy__attackchain(mob/user)
|
||||
if(!user)
|
||||
return
|
||||
var/obj/item/nuclear_rod/fuel/uranium_238/spiders/new_rod = new(user.loc)
|
||||
qdel(src)
|
||||
user.put_in_hands(new_rod)
|
||||
|
||||
// SINGULO BEACON SPAWNER
|
||||
/obj/item/beacon/syndicate
|
||||
name = "suspicious beacon"
|
||||
|
||||
@@ -594,3 +594,34 @@
|
||||
playsound(src, pick('sound/weapons/bulletflyby.ogg','sound/weapons/bulletflyby2.ogg','sound/weapons/bulletflyby3.ogg'), 75, 1)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// MARK: KATANA
|
||||
/obj/item/katana
|
||||
name = "katana"
|
||||
desc = "Woefully underpowered in D20."
|
||||
icon = 'icons/obj/weapons/melee.dmi'
|
||||
icon_state = "katana"
|
||||
lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
|
||||
flags = CONDUCT
|
||||
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK
|
||||
flags_2 = ALLOW_BELT_NO_JUMPSUIT_2 // Look, you can strap it to your back. You can strap it to your waist too.
|
||||
force = 40
|
||||
throwforce = 10
|
||||
sharp = TRUE
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 50)
|
||||
resistance_flags = FIRE_PROOF
|
||||
needs_permit = TRUE
|
||||
|
||||
new_attack_chain = TRUE
|
||||
|
||||
/obj/item/katana/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES)
|
||||
|
||||
/obj/item/katana/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!</span>")
|
||||
return BRUTELOSS
|
||||
|
||||
@@ -78,34 +78,6 @@
|
||||
desc = "An engraved and fancy version of the claymore. It appears to be less sharp than it's more functional cousin."
|
||||
force = 20
|
||||
|
||||
/obj/item/katana
|
||||
name = "katana"
|
||||
desc = "Woefully underpowered in D20."
|
||||
icon = 'icons/obj/weapons/melee.dmi'
|
||||
icon_state = "katana"
|
||||
lefthand_file = 'icons/mob/inhands/weapons_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons_righthand.dmi'
|
||||
flags = CONDUCT
|
||||
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK
|
||||
flags_2 = ALLOW_BELT_NO_JUMPSUIT_2 //Look, you can strap it to your back. You can strap it to your waist too.
|
||||
force = 40
|
||||
throwforce = 10
|
||||
sharp = TRUE
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 100, ACID = 50)
|
||||
resistance_flags = FIRE_PROOF
|
||||
needs_permit = TRUE
|
||||
|
||||
/obj/item/katana/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES)
|
||||
|
||||
/obj/item/katana/suicide_act(mob/user)
|
||||
user.visible_message(SPAN_SUICIDE("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!"))
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/harpoon
|
||||
name = "harpoon"
|
||||
desc = "Tharr she blows!"
|
||||
|
||||
@@ -76,35 +76,6 @@
|
||||
else
|
||||
icon_state = "signpost_wood"
|
||||
|
||||
/obj/structure/ninjatele
|
||||
name = "Long-Distance Teleportation Console"
|
||||
desc = "A console used to send a Spider Clan operative long distances rapidly."
|
||||
icon = 'icons/obj/ninjaobjects.dmi'
|
||||
icon_state = "teleconsole"
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/ninjatele/attack_hand(mob/user as mob)
|
||||
if(user.mind.special_role=="Ninja")
|
||||
switch(tgui_alert(user, "Phase Jaunt relay primed, target locked as [station_name()], initiate VOID-shift translocation? (Warning! Internals required!)", "Void Shift", list("Yes", "No")))
|
||||
if("Yes")
|
||||
if(user.z != src.z)
|
||||
return
|
||||
|
||||
user.loc.loc.Exited(user)
|
||||
user.loc = pick(GLOB.carplist) // In the future, possibly make specific NinjaTele landmarks, and give him an option to teleport to North/South/East/West of SS13 instead of just hijacking a carpspawn.
|
||||
|
||||
playsound(user.loc, 'sound/effects/phasein.ogg', 25, 1)
|
||||
playsound(user.loc, 'sound/effects/sparks2.ogg', 50, 1)
|
||||
new /obj/effect/temp_visual/dir_setting/ninja/phase(get_turf(user), user.dir)
|
||||
to_chat(user, "[SPAN_BOLDNOTICE("VOID-Shift")] translocation successful")
|
||||
|
||||
if("No")
|
||||
to_chat(user, SPAN_DANGER("Process aborted!"))
|
||||
return
|
||||
|
||||
else
|
||||
to_chat(user, "[SPAN_DANGER("FĆAL �Rr�R")]: ŧer nt recgnized, c-cntr-r䣧-ç äcked.")
|
||||
|
||||
/obj/structure/respawner
|
||||
name = "\improper Long-Distance Cloning Machine"
|
||||
desc = "Top-of-the-line Nanotrasen technology allows for cloning of crew members from off-station upon bluespace request."
|
||||
|
||||
Reference in New Issue
Block a user