f
This commit is contained in:
@@ -266,8 +266,8 @@
|
||||
return TRUE
|
||||
|
||||
/datum/admins/proc/makeSpaceNinja()
|
||||
new /datum/round_event/ghost_role/ninja()
|
||||
return 1
|
||||
new /datum/round_event/ghost_role/space_ninja()
|
||||
return TRUE
|
||||
|
||||
// DEATH SQUADS
|
||||
/datum/admins/proc/makeDeathsquad()
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
/datum/antagonist/ninja
|
||||
name = "Ninja"
|
||||
antagpanel_category = "Ninja"
|
||||
job_rank = ROLE_NINJA
|
||||
show_name_in_check_antagonists = TRUE
|
||||
show_to_ghosts = TRUE
|
||||
antag_moodlet = /datum/mood_event/focused
|
||||
threat = 8
|
||||
var/helping_station = FALSE
|
||||
var/give_objectives = TRUE
|
||||
var/give_equipment = TRUE
|
||||
|
||||
/datum/antagonist/ninja/threat()
|
||||
return helping_station ? -(..()) : ..()
|
||||
|
||||
/datum/antagonist/ninja/apply_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_ninja_icons_added(M)
|
||||
|
||||
/datum/antagonist/ninja/remove_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/M = mob_override || owner.current
|
||||
update_ninja_icons_removed(M)
|
||||
|
||||
/datum/antagonist/ninja/proc/equip_space_ninja(mob/living/carbon/human/H = owner.current)
|
||||
return H.equipOutfit(/datum/outfit/ninja)
|
||||
|
||||
/datum/antagonist/ninja/proc/addMemories()
|
||||
antag_memory += "I am an elite mercenary assassin of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!<br>"
|
||||
antag_memory += "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by clicking the initialize UI button, to use abilities like stealth)!<br>"
|
||||
antag_memory += "Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.<br>"
|
||||
|
||||
/datum/antagonist/ninja/proc/addObjectives(quantity = 6)
|
||||
var/list/possible_targets = list()
|
||||
for(var/datum/mind/M in SSticker.minds)
|
||||
if(M.current && M.current.stat != DEAD)
|
||||
if(ishuman(M.current))
|
||||
if(M.special_role)
|
||||
possible_targets[M] = 0 //bad-guy
|
||||
else if(M.assigned_role in GLOB.command_positions)
|
||||
possible_targets[M] = 1 //good-guy
|
||||
|
||||
var/list/possible_objectives = list(1,2,3,4)
|
||||
|
||||
while(objectives.len < quantity)
|
||||
switch(pick_n_take(possible_objectives))
|
||||
if(1) //research
|
||||
var/datum/objective/download/O = new /datum/objective/download()
|
||||
O.owner = owner
|
||||
O.gen_amount_goal()
|
||||
objectives += O
|
||||
|
||||
if(2) //steal
|
||||
var/datum/objective/steal/special/O = new /datum/objective/steal/special()
|
||||
O.owner = owner
|
||||
O.find_target()
|
||||
objectives += O
|
||||
|
||||
if(3) //protect/kill
|
||||
if(!possible_targets.len) continue
|
||||
var/index = rand(1,possible_targets.len)
|
||||
var/datum/mind/M = possible_targets[index]
|
||||
var/is_bad_guy = possible_targets[M]
|
||||
possible_targets.Cut(index,index+1)
|
||||
|
||||
if(is_bad_guy ^ helping_station) //kill (good-ninja + bad-guy or bad-ninja + good-guy)
|
||||
var/datum/objective/assassinate/once/O = new /datum/objective/assassinate()
|
||||
O.owner = owner
|
||||
O.target = M
|
||||
O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]. You may let [M.p_they()] live, if they come back from death."
|
||||
objectives += O
|
||||
else //protect
|
||||
var/datum/objective/protect/O = new /datum/objective/protect()
|
||||
O.owner = owner
|
||||
O.target = M
|
||||
O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm."
|
||||
objectives += O
|
||||
if(4) //flavor
|
||||
var/datum/objective/flavor/O = helping_station ? new /datum/objective/flavor/ninja_helping : new /datum/objective/flavor/ninja_syndie
|
||||
O.owner = owner
|
||||
O.forge_objective()
|
||||
objectives += O
|
||||
else
|
||||
break
|
||||
var/datum/objective/O = new /datum/objective/survive()
|
||||
O.owner = owner
|
||||
objectives += O
|
||||
|
||||
/proc/remove_ninja(mob/living/L)
|
||||
if(!L || !L.mind)
|
||||
return FALSE
|
||||
var/datum/antagonist/datum = L.mind.has_antag_datum(/datum/antagonist/ninja)
|
||||
datum.on_removal()
|
||||
return TRUE
|
||||
|
||||
/proc/is_ninja(mob/living/M)
|
||||
return M && M.mind && M.mind.has_antag_datum(/datum/antagonist/ninja)
|
||||
|
||||
|
||||
/datum/antagonist/ninja/greet()
|
||||
SEND_SOUND(owner.current, sound('sound/effects/ninja_greeting.ogg'))
|
||||
to_chat(owner.current, "I am an elite mercenary assassin of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!")
|
||||
to_chat(owner.current, "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!")
|
||||
to_chat(owner.current, "Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.")
|
||||
owner.announce_objectives()
|
||||
return
|
||||
|
||||
/datum/antagonist/ninja/on_gain()
|
||||
if(give_objectives)
|
||||
addObjectives()
|
||||
addMemories()
|
||||
if(give_equipment)
|
||||
equip_space_ninja(owner.current)
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/ninja/admin_add(datum/mind/new_owner,mob/admin)
|
||||
var/adj
|
||||
switch(input("What kind of ninja?", "Ninja") as null|anything in list("Random","Syndicate","Nanotrasen","No objectives"))
|
||||
if("Random")
|
||||
helping_station = pick(TRUE,FALSE)
|
||||
adj = ""
|
||||
if("Syndicate")
|
||||
helping_station = FALSE
|
||||
adj = "syndie"
|
||||
if("Nanotrasen")
|
||||
helping_station = TRUE
|
||||
adj = "friendly"
|
||||
if("No objectives")
|
||||
give_objectives = FALSE
|
||||
adj = "objectiveless"
|
||||
else
|
||||
return
|
||||
new_owner.assigned_role = ROLE_NINJA
|
||||
new_owner.special_role = ROLE_NINJA
|
||||
new_owner.add_antag_datum(src)
|
||||
message_admins("[key_name_admin(admin)] has [adj] ninja'ed [new_owner.current].")
|
||||
log_admin("[key_name(admin)] has [adj] ninja'ed [new_owner.current].")
|
||||
|
||||
/datum/antagonist/ninja/proc/update_ninja_icons_added(var/mob/living/carbon/human/ninja)
|
||||
var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA]
|
||||
ninjahud.join_hud(ninja)
|
||||
set_antag_hud(ninja, "ninja")
|
||||
|
||||
/datum/antagonist/ninja/proc/update_ninja_icons_removed(var/mob/living/carbon/human/ninja)
|
||||
var/datum/atom_hud/antag/ninjahud = GLOB.huds[ANTAG_HUD_NINJA]
|
||||
ninjahud.leave_hud(ninja)
|
||||
set_antag_hud(ninja, null)
|
||||
@@ -0,0 +1,128 @@
|
||||
/datum/antagonist/ninja
|
||||
name = "Space Ninja"
|
||||
antagpanel_category = "Space Ninja"
|
||||
job_rank = ROLE_NINJA
|
||||
antag_hud_type = ANTAG_HUD_NINJA
|
||||
antag_hud_name = "space_ninja"
|
||||
show_name_in_check_antagonists = TRUE
|
||||
show_to_ghosts = TRUE
|
||||
antag_moodlet = /datum/mood_event/focused
|
||||
///Whether or not this ninja will obtain objectives
|
||||
var/give_objectives = TRUE
|
||||
///Whether or not this ninja receives the standard equipment
|
||||
var/give_equipment = TRUE
|
||||
|
||||
/datum/antagonist/ninja/apply_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/ninja = mob_override || owner.current
|
||||
add_antag_hud(antag_hud_type, antag_hud_name, ninja)
|
||||
|
||||
/datum/antagonist/ninja/remove_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/ninja = mob_override || owner.current
|
||||
remove_antag_hud(antag_hud_type, ninja)
|
||||
|
||||
/**
|
||||
* Proc that equips the space ninja outfit on a given individual. By default this is the owner of the antagonist datum.
|
||||
*
|
||||
* Proc that equips the space ninja outfit on a given individual. By default this is the owner of the antagonist datum.
|
||||
* Arguments:
|
||||
* * ninja - The human to receive the gear
|
||||
* * Returns a proc call on the given human which will equip them with all the gear.
|
||||
*/
|
||||
/datum/antagonist/ninja/proc/equip_space_ninja(mob/living/carbon/human/ninja = owner.current)
|
||||
return ninja.equipOutfit(/datum/outfit/ninja)
|
||||
|
||||
/**
|
||||
* Proc that adds the proper memories to the antag datum
|
||||
*
|
||||
* Proc that adds the ninja starting memories to the owner of the antagonist datum.
|
||||
*/
|
||||
/datum/antagonist/ninja/proc/addMemories()
|
||||
antag_memory += "I am an elite mercenary of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!<br>"
|
||||
antag_memory += "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by clicking the initialize UI button, to use abilities like stealth)!<br>"
|
||||
|
||||
/datum/objective/cyborg_hijack
|
||||
explanation_text = "Use your gloves to convert at least one cyborg to aide you in sabotaging the station."
|
||||
|
||||
/datum/objective/door_jack
|
||||
///How many doors that need to be opened using the gloves to pass the objective
|
||||
var/doors_required = 0
|
||||
|
||||
/datum/objective/plant_explosive
|
||||
var/area/detonation_location
|
||||
|
||||
/datum/objective/security_scramble
|
||||
explanation_text = "Use your gloves on a security console to set everyone to arrest at least once. Note that the AI will be alerted once you begin!"
|
||||
|
||||
/datum/objective/terror_message
|
||||
explanation_text = "Use your gloves on a communication console in order to bring another threat to the station. Note that the AI will be alerted once you begin!"
|
||||
|
||||
/**
|
||||
* Proc that adds all the ninja's objectives to the antag datum.
|
||||
*
|
||||
* Proc that adds all the ninja's objectives to the antag datum. Called when the datum is gained.
|
||||
*/
|
||||
/datum/antagonist/ninja/proc/addObjectives()
|
||||
//Cyborg Hijack: Flag set to complete in the DrainAct in ninjaDrainAct.dm
|
||||
var/datum/objective/hijack = new /datum/objective/cyborg_hijack()
|
||||
objectives += hijack
|
||||
|
||||
//Research stealing
|
||||
var/datum/objective/download/research = new /datum/objective/download()
|
||||
research.owner = owner
|
||||
research.gen_amount_goal()
|
||||
objectives += research
|
||||
|
||||
//Door jacks, flag will be set to complete on when the last door is hijacked
|
||||
var/datum/objective/door_jack/doorobjective = new /datum/objective/door_jack()
|
||||
doorobjective.doors_required = rand(15,40)
|
||||
doorobjective.explanation_text = "Use your gloves to doorjack [doorobjective.doors_required] airlocks on the station."
|
||||
objectives += doorobjective
|
||||
|
||||
//Explosive plant, the bomb will register its completion on priming
|
||||
var/datum/objective/plant_explosive/bombobjective = new /datum/objective/plant_explosive()
|
||||
for(var/sanity in 1 to 100) // 100 checks at most.
|
||||
var/area/selected_area = pick(GLOB.sortedAreas)
|
||||
if(!is_station_level(selected_area.z) || !(selected_area.area_flags & VALID_TERRITORY))
|
||||
continue
|
||||
bombobjective.detonation_location = selected_area
|
||||
break
|
||||
if(bombobjective.detonation_location)
|
||||
bombobjective.explanation_text = "Detonate your starter bomb in [bombobjective.detonation_location]. Note that the bomb will not work anywhere else!"
|
||||
objectives += bombobjective
|
||||
|
||||
//Security Scramble, set to complete upon using your gloves on a security console
|
||||
var/datum/objective/securityobjective = new /datum/objective/security_scramble()
|
||||
objectives += securityobjective
|
||||
|
||||
//Message of Terror, set to complete upon using your gloves a communication console
|
||||
var/datum/objective/communicationobjective = new /datum/objective/terror_message()
|
||||
objectives += communicationobjective
|
||||
|
||||
//Survival until end
|
||||
var/datum/objective/survival = new /datum/objective/survive()
|
||||
survival.owner = owner
|
||||
objectives += survival
|
||||
|
||||
/datum/antagonist/ninja/greet()
|
||||
SEND_SOUND(owner.current, sound('sound/effects/ninja_greeting.ogg'))
|
||||
to_chat(owner.current, "I am an elite mercenary of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!")
|
||||
to_chat(owner.current, "Surprise is my weapon. Shadows are my armor. Without them, I am nothing. (//initialize your suit by right clicking on it, to use abilities like stealth)!")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/ninja/on_gain()
|
||||
if(give_objectives)
|
||||
addObjectives()
|
||||
addMemories()
|
||||
if(give_equipment)
|
||||
equip_space_ninja(owner.current)
|
||||
|
||||
owner.current.mind.assigned_role = ROLE_NINJA
|
||||
owner.current.mind.special_role = ROLE_NINJA
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/ninja/admin_add(datum/mind/new_owner,mob/admin)
|
||||
new_owner.assigned_role = ROLE_NINJA
|
||||
new_owner.special_role = ROLE_NINJA
|
||||
new_owner.add_antag_datum(src)
|
||||
message_admins("[key_name_admin(admin)] has ninja'ed [key_name_admin(new_owner)].")
|
||||
log_admin("[key_name(admin)] has ninja'ed [key_name(new_owner)].")
|
||||
@@ -0,0 +1,51 @@
|
||||
/datum/round_event_control/space_ninja
|
||||
name = "Spawn Space Ninja"
|
||||
typepath = /datum/round_event/ghost_role/space_ninja
|
||||
max_occurrences = 1
|
||||
weight = 10
|
||||
earliest_start = 20 MINUTES
|
||||
min_players = 20
|
||||
|
||||
/datum/round_event/ghost_role/space_ninja
|
||||
minimum_required = 1
|
||||
role_name = "Space Ninja"
|
||||
|
||||
/datum/round_event/ghost_role/space_ninja/spawn_role()
|
||||
var/list/spawn_locs = list()
|
||||
for(var/obj/effect/landmark/carpspawn/carp_spawn in GLOB.landmarks_list)
|
||||
if(!isturf(carp_spawn.loc))
|
||||
stack_trace("Carp spawn found not on a turf: [carp_spawn.type] on [isnull(carp_spawn.loc) ? "null" : carp_spawn.loc.type]")
|
||||
continue
|
||||
spawn_locs += carp_spawn.loc
|
||||
if(!spawn_locs.len)
|
||||
message_admins("No valid spawn locations found, aborting...")
|
||||
return MAP_ERROR
|
||||
|
||||
//selecting a candidate player
|
||||
var/list/candidates = get_candidates(ROLE_NINJA, null, ROLE_NINJA)
|
||||
if(!candidates.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
var/mob/dead/selected_candidate = pick(candidates)
|
||||
var/key = selected_candidate.key
|
||||
|
||||
//spawn the ninja and assign the candidate
|
||||
var/mob/living/carbon/human/ninja = create_space_ninja(pick(spawn_locs))
|
||||
ninja.key = key
|
||||
ninja.mind.add_antag_datum(/datum/antagonist/ninja)
|
||||
spawned_mobs += ninja
|
||||
message_admins("[ADMIN_LOOKUPFLW(ninja)] has been made into a space ninja by an event.")
|
||||
log_game("[key_name(ninja)] was spawned as a ninja by an event.")
|
||||
|
||||
return SUCCESSFUL_SPAWN
|
||||
|
||||
|
||||
//=======//NINJA CREATION PROCS//=======//
|
||||
|
||||
/proc/create_space_ninja(spawn_loc)
|
||||
var/mob/living/carbon/human/new_ninja = new(spawn_loc)
|
||||
var/datum/preferences/random_human_options = new()//Randomize appearance for the ninja.
|
||||
random_human_options.real_name = "[pick(GLOB.ninja_titles)] [pick(GLOB.ninja_names)]"
|
||||
random_human_options.copy_to(new_ninja)
|
||||
new_ninja.dna.update_dna_identity()
|
||||
return new_ninja
|
||||
@@ -80,34 +80,6 @@
|
||||
. += ""
|
||||
. += "Chemical Storage: [changeling.chem_charges]/[changeling.chem_storage]"
|
||||
. += "Absorbed DNA: [changeling.absorbedcount]"
|
||||
//NINJACODE
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)) //Only display if actually a ninja.
|
||||
var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit
|
||||
. += "SpiderOS Status: [SN.s_initialized ? "Initialized" : "Disabled"]"
|
||||
. += "Current Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]"
|
||||
if(SN.s_initialized)
|
||||
//Suit gear
|
||||
. += "Energy Charge: [round(SN.cell.charge/100)]%"
|
||||
. += "Smoke Bombs: \Roman [SN.s_bombs]"
|
||||
//Ninja status
|
||||
. += "Fingerprints: [md5(dna.uni_identity)]"
|
||||
. += "Unique Identity: [dna.unique_enzymes]"
|
||||
. += "Overall Status: [stat > 1 ? "dead" : "[health]% healthy"]"
|
||||
. += "Nutrition Status: [nutrition]"
|
||||
. += "Oxygen Loss: [getOxyLoss()]"
|
||||
. += "Toxin Levels: [getToxLoss()]"
|
||||
. += "Burn Severity: [getFireLoss()]"
|
||||
. += "Brute Trauma: [getBruteLoss()]"
|
||||
. += "Radiation Levels: [radiation] rad"
|
||||
. += "Body Temperature: [bodytemperature-T0C] degrees C ([bodytemperature*1.8-459.67] degrees F)"
|
||||
|
||||
//Diseases
|
||||
if(length(diseases))
|
||||
. += "Viruses:"
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
. += "* [D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]"
|
||||
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
|
||||
/*
|
||||
|
||||
Contents:
|
||||
- Definitions, because the original Ninja code has so much magic.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//ninjacost() specificCheck defines
|
||||
#define N_STEALTH_CANCEL 1
|
||||
#define N_SMOKE_BOMB 2
|
||||
#define N_ADRENALINE 3
|
||||
#define N_ADRENALINE 2
|
||||
|
||||
//ninjaDrainAct() defines for non numerical returns
|
||||
//While not strictly needed, it's nicer than them just returning "twat"
|
||||
//Which was my original intention.
|
||||
|
||||
#define INVALID_DRAIN "INVALID" //This one is if the drain proc needs to cancel, eg missing variables, etc, it's important.
|
||||
|
||||
#define DRAIN_RD_HACK_FAILED "RDHACKFAIL"
|
||||
#define DRAIN_MOB_SHOCK "MOBSHOCK"
|
||||
#define DRAIN_MOB_SHOCK_FAILED "MOBSHOCKFAIL"
|
||||
|
||||
|
||||
//Tells whether or not someone is a space ninja
|
||||
#define IS_SPACE_NINJA(ninja) (ninja.mind && ninja.mind.has_antag_datum(/datum/antagonist/ninja))
|
||||
|
||||
//Defines for the suit's unique abilities
|
||||
#define IS_NINJA_SUIT_INITIALIZATION(action) (istype(action, /datum/action/item_action/initialize_ninja_suit))
|
||||
#define IS_NINJA_SUIT_STATUS(action) (istype(action, /datum/action/item_action/ninjastatus))
|
||||
#define IS_NINJA_SUIT_BOOST(action) (istype(action, /datum/action/item_action/ninjaboost))
|
||||
#define IS_NINJA_SUIT_EMP(action) (istype(action, /datum/action/item_action/ninjapulse))
|
||||
#define IS_NINJA_SUIT_STAR_CREATION(action) (istype(action, /datum/action/item_action/ninjastar))
|
||||
#define IS_NINJA_SUIT_NET_CREATION(action) (istype(action, /datum/action/item_action/ninjanet))
|
||||
#define IS_NINJA_SUIT_SWORD_RECALL(action) (istype(action, /datum/action/item_action/ninja_sword_recall))
|
||||
#define IS_NINJA_SUIT_STEALTH(action) (istype(action, /datum/action/item_action/ninja_stealth))
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
/**
|
||||
* # Energy Katana
|
||||
*
|
||||
* The space ninja's katana.
|
||||
*
|
||||
* The katana that only space ninja spawns with. Comes with 30 force and throwforce, along with a signature special jaunting system.
|
||||
* Upon clicking on a tile with the dash on, the user will teleport to that tile, assuming their target was not dense.
|
||||
* The katana has 3 dashes stored at maximum, and upon using the dash, it will return 20 seconds after it was used.
|
||||
* It also has a special feature where if it is tossed at a space ninja who owns it (determined by the ninja suit), the ninja will catch the katana instead of being hit by it.
|
||||
*
|
||||
*/
|
||||
/obj/item/energy_katana
|
||||
name = "energy katana"
|
||||
desc = "A katana infused with strong energy."
|
||||
@@ -5,8 +16,8 @@
|
||||
item_state = "energy_katana"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
force = 40
|
||||
throwforce = 20
|
||||
force = 30
|
||||
throwforce = 30
|
||||
block_chance = 50
|
||||
armour_penetration = 50
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
@@ -34,13 +45,8 @@
|
||||
|
||||
/obj/item/energy_katana/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
. = ..()
|
||||
if(dash_toggled)
|
||||
if(dash_toggled && !Adjacent(target) && !target.density)
|
||||
jaunt.Teleport(user, target)
|
||||
if(proximity_flag && (isobj(target) || issilicon(target)))
|
||||
spark_system.start()
|
||||
playsound(user, "sparks", 50, 1)
|
||||
playsound(user, 'sound/weapons/blade1.ogg', 50, 1)
|
||||
target.emag_act(user)
|
||||
|
||||
/obj/item/energy_katana/pickup(mob/living/user)
|
||||
. = ..()
|
||||
@@ -58,16 +64,30 @@
|
||||
//To throw it at the ninja
|
||||
/obj/item/energy_katana/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
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 == src)
|
||||
returnToOwner(H, 0, 1)
|
||||
var/mob/living/carbon/human/hit_human = hit_atom
|
||||
if(istype(hit_human.wear_suit, /obj/item/clothing/suit/space/space_ninja))
|
||||
var/obj/item/clothing/suit/space/space_ninja/ninja_suit = hit_human.wear_suit
|
||||
if(ninja_suit.energyKatana == src)
|
||||
returnToOwner(hit_human, 0, 1)
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/energy_katana/proc/returnToOwner(mob/living/carbon/human/user, doSpark = 1, caught = 0)
|
||||
/obj/item/energy_katana/Destroy()
|
||||
QDEL_NULL(spark_system)
|
||||
QDEL_NULL(jaunt)
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Proc called when the katana is recalled to its space ninja.
|
||||
*
|
||||
* Proc called when space ninja is hit with its suit's katana or the recall ability is used.
|
||||
* Arguments:
|
||||
* * user - To whom the katana is returning to.
|
||||
* * doSpark - whether or not the katana will spark when it returns.
|
||||
* * caught - boolean for whether or not the katana was caught or was teleported back.
|
||||
*/
|
||||
/obj/item/energy_katana/proc/returnToOwner(mob/living/carbon/human/user, doSpark = TRUE, caught = FALSE)
|
||||
if(!istype(user))
|
||||
return
|
||||
forceMove(get_turf(user))
|
||||
@@ -95,12 +115,9 @@
|
||||
to_chat(user, "<span class='notice'>[msg]</span>")
|
||||
|
||||
|
||||
/obj/item/energy_katana/Destroy()
|
||||
QDEL_NULL(spark_system)
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/dash/ninja
|
||||
current_charges = 3
|
||||
max_charges = 3
|
||||
charge_rate = 30
|
||||
charge_rate = 200
|
||||
recharge_sound = null
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
//Note to future generations: I didn't write this god-awful code I just ported it to the event system and tried to make it less moon-speaky.
|
||||
//Don't judge me D; ~Carn //Maximum judging occuring - Remie.
|
||||
// Tut tut Remie, let's keep our comments constructive. - coiax
|
||||
|
||||
/*
|
||||
|
||||
Contents:
|
||||
- The Ninja "Random" Event
|
||||
- Ninja creation code
|
||||
*/
|
||||
|
||||
/datum/round_event_control/ninja
|
||||
name = "Space Ninja"
|
||||
typepath = /datum/round_event/ghost_role/ninja
|
||||
max_occurrences = 1
|
||||
earliest_start = 40 MINUTES
|
||||
gamemode_blacklist = list("dynamic")
|
||||
min_players = 15
|
||||
|
||||
/datum/round_event/ghost_role/ninja
|
||||
var/success_spawn = 0
|
||||
role_name = "space ninja"
|
||||
minimum_required = 1
|
||||
|
||||
var/helping_station
|
||||
var/spawn_loc
|
||||
var/give_objectives = TRUE
|
||||
|
||||
/datum/round_event/ghost_role/ninja/setup()
|
||||
helping_station = rand(0,1)
|
||||
|
||||
/datum/round_event/ghost_role/ninja/kill()
|
||||
if(!success_spawn && control)
|
||||
control.occurrences--
|
||||
return ..()
|
||||
|
||||
/datum/round_event/ghost_role/ninja/spawn_role()
|
||||
//selecting a spawn_loc
|
||||
if(!spawn_loc)
|
||||
var/list/spawn_locs = list()
|
||||
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
|
||||
if(isturf(L.loc))
|
||||
spawn_locs += L.loc
|
||||
for(var/obj/effect/landmark/loneopspawn/L in GLOB.landmarks_list)
|
||||
if(isturf(L.loc))
|
||||
spawn_locs += L.loc
|
||||
if(!spawn_locs.len)
|
||||
return kill()
|
||||
spawn_loc = pick(spawn_locs)
|
||||
if(!spawn_loc)
|
||||
return MAP_ERROR
|
||||
|
||||
//selecting a candidate player
|
||||
var/list/candidates = get_candidates(ROLE_NINJA, null, ROLE_NINJA)
|
||||
if(!candidates.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
var/mob/dead/selected_candidate = pick_n_take(candidates)
|
||||
var/key = selected_candidate.key
|
||||
|
||||
//Prepare ninja player mind
|
||||
var/datum/mind/Mind = new /datum/mind(key)
|
||||
Mind.assigned_role = ROLE_NINJA
|
||||
Mind.special_role = ROLE_NINJA
|
||||
Mind.active = 1
|
||||
|
||||
//spawn the ninja and assign the candidate
|
||||
var/mob/living/carbon/human/Ninja = create_space_ninja(spawn_loc)
|
||||
Mind.transfer_to(Ninja)
|
||||
var/datum/antagonist/ninja/ninjadatum = new
|
||||
ninjadatum.helping_station = pick(TRUE,FALSE)
|
||||
Mind.add_antag_datum(ninjadatum)
|
||||
|
||||
if(Ninja.mind != Mind) //something has gone wrong!
|
||||
stack_trace("Ninja created with incorrect mind")
|
||||
|
||||
spawned_mobs += Ninja
|
||||
message_admins("[ADMIN_LOOKUPFLW(Ninja)] has been made into a ninja by an event.")
|
||||
log_game("[key_name(Ninja)] was spawned as a ninja by an event.")
|
||||
success_spawn = TRUE
|
||||
|
||||
return SUCCESSFUL_SPAWN
|
||||
|
||||
|
||||
//=======//NINJA CREATION PROCS//=======//
|
||||
|
||||
/proc/create_space_ninja(spawn_loc)
|
||||
var/mob/living/carbon/human/new_ninja = new(spawn_loc)
|
||||
var/datum/preferences/A = new()//Randomize appearance for the ninja.
|
||||
A.real_name = "[pick(GLOB.ninja_titles)] [pick(GLOB.ninja_names)]"
|
||||
A.copy_to(new_ninja)
|
||||
new_ninja.dna.update_dna_identity()
|
||||
return new_ninja
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* # Spider Charge
|
||||
*
|
||||
* A unique version of c4 possessed only by the space ninja. Has a stronger blast radius.
|
||||
* Can only be detonated by space ninjas with the bombing objective. Can only be set up where the objective says it can.
|
||||
* When it primes, the space ninja responsible will have their objective set to complete.
|
||||
*
|
||||
*/
|
||||
/obj/item/grenade/plastic/ninja
|
||||
name = "spider charge"
|
||||
desc = "A modified C-4 charge supplied to you by the Spider Clan. Its explosive power has been juiced up, but only works in one specific area."
|
||||
boom_sizes = list(4, 8, 12)
|
||||
var/mob/detonator = null
|
||||
|
||||
/obj/item/grenade/c4/ninja/afterattack(atom/movable/AM, mob/user, flag)
|
||||
var/datum/antagonist/ninja/ninja_antag = user.mind.has_antag_datum(/datum/antagonist/ninja)
|
||||
if(!ninja_antag)
|
||||
to_chat(user, "<span class='notice'>While it appears normal, you can't seem to detonate the charge.</span>")
|
||||
return
|
||||
var/datum/objective/plant_explosive/objective = locate() in ninja_antag.objectives
|
||||
if(!objective)
|
||||
to_chat(user, "<span class='notice'>You can't seem to activate the charge. It's location-locked, but you don't know where to detonate it.</span>")
|
||||
return
|
||||
if(objective.detonation_location != get_area(user))
|
||||
to_chat(user, "<span class='notice'>This isn't the location you're supposed to use this!</span>")
|
||||
return
|
||||
detonator = user
|
||||
return ..()
|
||||
|
||||
/obj/item/grenade/c4/ninja/prime(mob/living/lanced_by)
|
||||
. = ..()
|
||||
//Since we already did the checks in afterattack, the denonator must be a ninja with the bomb objective.
|
||||
if(!detonator)
|
||||
return
|
||||
var/datum/antagonist/ninja/ninja_antag = detonator.mind.has_antag_datum(/datum/antagonist/ninja)
|
||||
var/datum/objective/plant_explosive/objective = locate() in ninja_antag.objectives
|
||||
objective.completed = TRUE
|
||||
@@ -9,7 +9,7 @@
|
||||
shoes = /obj/item/clothing/shoes/space_ninja
|
||||
gloves = /obj/item/clothing/gloves/space_ninja
|
||||
back = /obj/item/tank/jetpack/carbondioxide
|
||||
l_pocket = /obj/item/grenade/plastic/x4
|
||||
l_pocket = /obj/item/grenade/plastic/ninja
|
||||
r_pocket = /obj/item/tank/internals/emergency_oxygen
|
||||
internals_slot = SLOT_R_STORE
|
||||
belt = /obj/item/energy_katana
|
||||
@@ -21,5 +21,3 @@
|
||||
var/obj/item/clothing/suit/space/space_ninja/S = H.wear_suit
|
||||
if(istype(H.belt, belt))
|
||||
S.energyKatana = H.belt
|
||||
S.randomize_param()
|
||||
|
||||
|
||||
@@ -1,30 +1,18 @@
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Dear ninja gloves
|
||||
|
||||
This isn't because I like you
|
||||
this is because your father is a bastard
|
||||
|
||||
...
|
||||
I guess you're a little cool.
|
||||
-Sayu
|
||||
|
||||
|
||||
see ninjaDrainAct.dm for ninjadrain_act()
|
||||
Touch() simply calls this on it's target now
|
||||
Ninja's electricuting people when?
|
||||
-Remie
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* # Ninja Gloves
|
||||
*
|
||||
* Space ninja's gloves. Gives access to a number of special interactions.
|
||||
*
|
||||
* Gloves only found from space ninjas. Allows the wearer to access special interactions with various objects.
|
||||
* These interactions are detailed in ninjaDrainAct.dm in the suit file.
|
||||
* These interactions are toggled by an action tied to the gloves. The interactions will not activate if the user is also not wearing a ninja suit.
|
||||
*
|
||||
*/
|
||||
/obj/item/clothing/gloves/space_ninja
|
||||
desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
|
||||
name = "ninja gloves"
|
||||
icon_state = "s-ninja"
|
||||
item_state = "s-ninja"
|
||||
icon_state = "black"
|
||||
item_state = "s-ninjan"
|
||||
siemens_coefficient = 0
|
||||
cold_protection = HANDS
|
||||
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
|
||||
@@ -32,11 +20,19 @@
|
||||
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
|
||||
strip_delay = 120
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/draining = 0
|
||||
var/candrain = 0
|
||||
actions_types = list(/datum/action/item_action/toggle_glove)
|
||||
///Whether or not we're currently draining something
|
||||
var/draining = FALSE
|
||||
///Whether or not we can currently drain something
|
||||
var/candrain = FALSE
|
||||
///Minimum amount of power we can drain in a single drain action
|
||||
var/mindrain = 200
|
||||
///Maximum amount of power we can drain in a single drain action
|
||||
var/maxdrain = 400
|
||||
|
||||
///Whether or not the communication console hack was used to summon another antagonist
|
||||
var/communication_console_hack_success = FALSE
|
||||
///How many times the gloves have been used to force open doors.
|
||||
var/door_hack_counter = 0
|
||||
var/stunforce = 100
|
||||
|
||||
/obj/item/clothing/gloves/space_ninja/Touch(atom/A,proximity)
|
||||
@@ -45,9 +41,9 @@
|
||||
if(!ishuman(loc))
|
||||
return FALSE //Only works while worn
|
||||
|
||||
var/mob/living/carbon/human/H = loc
|
||||
var/mob/living/carbon/human/wearer = loc
|
||||
|
||||
var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit
|
||||
var/obj/item/clothing/suit/space/space_ninja/suit = wearer.wear_suit
|
||||
if(!istype(suit))
|
||||
return FALSE
|
||||
if(isturf(A))
|
||||
@@ -56,17 +52,17 @@
|
||||
if(!proximity)
|
||||
return FALSE
|
||||
|
||||
A.add_fingerprint(H)
|
||||
A.add_fingerprint(wearer)
|
||||
|
||||
draining = TRUE
|
||||
. = A.ninjadrain_act(suit,H,src)
|
||||
. = A.ninjadrain_act(suit,wearer,src)
|
||||
draining = FALSE
|
||||
|
||||
if(isnum(.)) //Numerical values of drained handle their feedback here, Alpha values handle it themselves (Research hacking)
|
||||
if(.)
|
||||
to_chat(H, "<span class='notice'>Gained <B>[DisplayEnergy(.)]</B> of energy from [A].</span>")
|
||||
to_chat(wearer, "<span class='notice'>Gained <B>[DisplayEnergy(.)]</B> of energy from [A].</span>")
|
||||
else
|
||||
to_chat(H, "<span class='danger'>\The [A] has run dry of energy, you must find another source!</span>")
|
||||
to_chat(wearer, "<span class='danger'>\The [A] has run dry of energy, you must find another source!</span>")
|
||||
. = INTERRUPT_UNARMED_ATTACK
|
||||
else
|
||||
. = FALSE //as to not cancel attack_hand()
|
||||
@@ -75,12 +71,13 @@
|
||||
. = ..()
|
||||
REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT)
|
||||
|
||||
/obj/item/clothing/gloves/space_ninja/proc/toggledrain()
|
||||
var/mob/living/carbon/human/U = loc
|
||||
to_chat(U, "You <b>[candrain?"disable":"enable"]</b> special interaction.")
|
||||
candrain=!candrain
|
||||
|
||||
/obj/item/clothing/gloves/space_ninja/examine(mob/user)
|
||||
. = ..()
|
||||
if(HAS_TRAIT_FROM(src, TRAIT_NODROP, NINJA_SUIT_TRAIT))
|
||||
. += "The energy drain mechanism is <B>[candrain?"active":"inactive"]</B>."
|
||||
|
||||
/obj/item/clothing/gloves/space_ninja/ui_action_click(mob/user, action)
|
||||
if(istype(action, /datum/action/item_action/toggle_glove))
|
||||
toggledrain()
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
|
||||
|
||||
/**
|
||||
* # Ninja Hood
|
||||
*
|
||||
* Space ninja's hood. Provides armor and blocks AI tracking.
|
||||
*
|
||||
* A hood that only exists as a part of space ninja's starting kit. Provides armor equal of space ninja's suit and disallows an AI to track the wearer.
|
||||
*
|
||||
*/
|
||||
/obj/item/clothing/head/helmet/space/space_ninja
|
||||
desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear."
|
||||
name = "ninja hood"
|
||||
icon_state = "s-ninja"
|
||||
item_state = "s-ninja_mask"
|
||||
armor = list("melee" = 60, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 25, "fire" = 100, "acid" = 100)
|
||||
strip_delay = 12
|
||||
armor = list(MELEE = 40, BULLET = 30, LASER = 20,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 25, FIRE = 100, ACID = 100)
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
blockTracking = 1//Roughly the only unique thing about this helmet.
|
||||
blockTracking = TRUE//Roughly the only unique thing about this helmet.
|
||||
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
|
||||
|
||||
/obj/item/clothing/head/helmet/space/space_ninja/dropped(mob/user)
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
|
||||
/*
|
||||
|
||||
Contents:
|
||||
- The Ninja Space Mask
|
||||
- Ninja Space Mask speech modification
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* # Ninja Mask
|
||||
*
|
||||
* Space ninja's mask. Makes you sound like a real anime girl. Barely able to be considered a real upside.
|
||||
*
|
||||
* A mask which only spawns as a part of space ninja's starting kit. Functions as a gas 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."
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
It will teleport people to a holding facility after 30 seconds. (Check the process() proc to change where teleport goes)
|
||||
It is possible to destroy the net by the occupant or someone else.
|
||||
*/
|
||||
|
||||
/obj/structure/energy_net
|
||||
name = "energy net"
|
||||
desc = "It's a net made of green energy."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "energynet"
|
||||
|
||||
density = TRUE//Can't pass through.
|
||||
opacity = 0//Can see through.
|
||||
mouse_opacity = MOUSE_OPACITY_ICON//So you can hit it with stuff.
|
||||
anchored = TRUE//Can't drag/grab the net.
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
max_integrity = 50 //How much health it has.
|
||||
can_buckle = 1
|
||||
buckle_lying = 0
|
||||
buckle_prevents_pull = TRUE
|
||||
var/mob/living/carbon/affecting //Who it is currently affecting, if anyone.
|
||||
var/mob/living/carbon/master //Who shot web. Will let this person know if the net was successful or failed.
|
||||
var/check = 15//30 seconds before teleportation. Could be extended I guess.
|
||||
var/success = FALSE
|
||||
|
||||
|
||||
/obj/structure/energy_net/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0)
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
playsound(src, 'sound/weapons/slash.ogg', 80, 1)
|
||||
if(BURN)
|
||||
playsound(src, 'sound/weapons/slash.ogg', 80, 1)
|
||||
|
||||
/obj/structure/energy_net/Destroy()
|
||||
if(!success)
|
||||
if(!QDELETED(affecting))
|
||||
affecting.visible_message("[affecting.name] was recovered from the energy net!", "You were recovered from the energy net!", "<span class='italics'>You hear a grunt.</span>")
|
||||
if(!QDELETED(master))//As long as they still exist.
|
||||
to_chat(master, "<span class='userdanger'>ERROR</span>: unable to initiate transport protocol. Procedure terminated.")
|
||||
return ..()
|
||||
|
||||
/obj/structure/energy_net/process()
|
||||
if(QDELETED(affecting)||affecting.loc!=loc)
|
||||
qdel(src)//Get rid of the net.
|
||||
return
|
||||
|
||||
if(check>0)
|
||||
check--
|
||||
return
|
||||
|
||||
success = TRUE
|
||||
qdel(src)
|
||||
if(ishuman(affecting))
|
||||
var/mob/living/carbon/human/H = affecting
|
||||
for(var/obj/item/W in H)
|
||||
if(W == H.w_uniform || W == H.shoes)
|
||||
continue//So all they're left with are shoes and uniform.
|
||||
H.dropItemToGround(W)
|
||||
H.dna.species.give_important_for_life(H) // After we remove items, at least give them what they need to live.
|
||||
/*
|
||||
var/datum/antagonist/antag_datum
|
||||
for(var/datum/antagonist/ninja/AD in GLOB.antagonists) //Because only ninjas get capture objectives; They're not doable without the suit.
|
||||
if(AD.owner == master)
|
||||
antag_datum = AD
|
||||
break
|
||||
for(var/datum/objective/capture/capture in antag_datum)
|
||||
if(istype(affecting, /mob/living/carbon/human)) //Humans.
|
||||
if(affecting.stat == DEAD)//Dead folks are worth less.
|
||||
capture.captured_amount+=0.5
|
||||
continue
|
||||
capture.captured_amount+=1
|
||||
if(istype(affecting, /mob/living/carbon/monkey)) //Monkeys are almost worthless, you failure.
|
||||
capture.captured_amount+=0.1
|
||||
if(istype(affecting, /mob/living/carbon/alien/larva)) //Larva are important for research.
|
||||
if(affecting.stat == DEAD)
|
||||
capture.captured_amount+=0.5
|
||||
continue
|
||||
capture.captured_amount+=1
|
||||
if(istype(affecting, /mob/living/carbon/alien/humanoid)) //Aliens are worth twice as much as humans.
|
||||
if(istype(affecting, /mob/living/carbon/alien/humanoid/royal/queen)) //Queens are worth three times as much as humans.
|
||||
if(affecting.stat == DEAD)
|
||||
capture.captured_amount+=1.5
|
||||
else
|
||||
capture.captured_amount+=3
|
||||
continue
|
||||
if(affecting.stat == DEAD)
|
||||
capture.captured_amount+=1
|
||||
continue
|
||||
capture.captured_amount+=2
|
||||
*/
|
||||
|
||||
affecting.revive(1, 1) //Basically a revive and full heal, including limbs/organs
|
||||
//In case people who have been captured dead want to hang out at the holding area
|
||||
|
||||
playsound(affecting, 'sound/effects/sparks4.ogg', 50, 1)
|
||||
new /obj/effect/temp_visual/dir_setting/ninja/phase/out(affecting.drop_location(), affecting.dir)
|
||||
|
||||
visible_message("[affecting] suddenly vanishes!")
|
||||
affecting.forceMove(pick(GLOB.holdingfacility)) //Throw mob in to the holding facility.
|
||||
to_chat(affecting, "<span class='danger'>You appear in a strange place!</span>")
|
||||
|
||||
if(!QDELETED(master))//As long as they still exist.
|
||||
to_chat(master, "<span class='notice'><b>SUCCESS</b>: transport procedure of [affecting] complete.</span>")
|
||||
do_sparks(5, FALSE, affecting)
|
||||
playsound(affecting, 'sound/effects/phasein.ogg', 25, 1)
|
||||
playsound(affecting, 'sound/effects/sparks2.ogg', 50, 1)
|
||||
new /obj/effect/temp_visual/dir_setting/ninja/phase(affecting.drop_location(), affecting.dir)
|
||||
|
||||
/obj/structure/energy_net/attack_alien(mob/living/carbon/alien/humanoid/user)
|
||||
if(attack_generic(user, 15, BRUTE, "melee", 0)) //Aliens normally deal 60 damage to structures. They'd one-shot nets without this.
|
||||
playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
|
||||
|
||||
/obj/structure/energy_net/user_buckle_mob(mob/living/M, mob/living/user)
|
||||
return//We only want our target to be buckled
|
||||
|
||||
/obj/structure/energy_net/user_unbuckle_mob(mob/living/buckled_mob, mob/living/user)
|
||||
return//The net must be destroyed to free the target
|
||||
@@ -1,19 +0,0 @@
|
||||
//Wakes the user so they are able to do their thing. Also injects a decent dose of radium.
|
||||
//Movement impairing would indicate drugs and the like.
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost()
|
||||
|
||||
if(!ninjacost(0,N_ADRENALINE))
|
||||
var/mob/living/carbon/human/H = affecting
|
||||
H.do_adrenaline(150, TRUE, 0, 0, TRUE, list(/datum/reagent/medicine/inaprovaline = 3, /datum/reagent/medicine/synaptizine = 10, /datum/reagent/medicine/omnizine = 10), "<span class='boldnotice'>You feel a sudden surge of energy!</span>")
|
||||
|
||||
H.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!"), forced = "ninjaboost")
|
||||
|
||||
a_boost--
|
||||
to_chat(H, "<span class='notice'>There are <B>[a_boost]</B> adrenaline boosts remaining.</span>")
|
||||
s_coold = 3
|
||||
addtimer(CALLBACK(src, .proc/ninjaboost_after), 70)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost_after()
|
||||
var/mob/living/carbon/human/H = affecting
|
||||
H.reagents.add_reagent(/datum/reagent/radium, a_transfer)
|
||||
to_chat(H, "<span class='danger'>You are beginning to feel the after-effect of the injection.</span>")
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
|
||||
//Cost function for suit Procs/Verbs/Abilities
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjacost(cost = 0, specificCheck = 0)
|
||||
var/mob/living/carbon/human/H = affecting
|
||||
var/actualCost = cost*10
|
||||
if(cost && cell.charge < actualCost)
|
||||
to_chat(H, "<span class='danger'>Not enough energy.</span>")
|
||||
return 1
|
||||
else
|
||||
//This shit used to be handled individually on every proc.. why even bother with a universal check proc then?
|
||||
cell.charge-=(actualCost)
|
||||
|
||||
switch(specificCheck)
|
||||
if(N_STEALTH_CANCEL)
|
||||
cancel_stealth()//Get rid of it.
|
||||
if(N_SMOKE_BOMB)
|
||||
if(!s_bombs)
|
||||
to_chat(H, "<span class='danger'>There are no more smoke bombs remaining.</span>")
|
||||
return 1
|
||||
if(N_ADRENALINE)
|
||||
if(!a_boost)
|
||||
to_chat(H, "<span class='danger'>You do not have any more adrenaline boosters.</span>")
|
||||
return 1
|
||||
return (s_coold)//Returns the value of the variable which counts down to zero.
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
|
||||
//Disables nearby tech equipment.
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse()
|
||||
|
||||
if(!ninjacost(250,N_STEALTH_CANCEL))
|
||||
var/mob/living/carbon/human/H = affecting
|
||||
playsound(H.loc, 'sound/effects/empulse.ogg', 60, 2)
|
||||
empulse_using_range(H, 9) //Procs sure are nice. Slightly weaker than wizard's disable tch.
|
||||
s_coold = 2
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
//Allows the ninja to kidnap people
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjanet()
|
||||
var/mob/living/carbon/human/H = affecting
|
||||
var/mob/living/carbon/C
|
||||
|
||||
//If there's only one valid target, let's actually try to capture it, rather than forcing
|
||||
//the user to fiddle with the dialog displaying a list of one
|
||||
//Also, let's make this smarter and not list mobs you can't currently net.
|
||||
var/list/candidates
|
||||
for(var/mob/M in oview(H))
|
||||
if(!M.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame.
|
||||
continue
|
||||
for(var/obj/structure/energy_net/E in get_turf(M))//Check if they are already being affected by an energy net.
|
||||
if(E.affecting == M)
|
||||
continue
|
||||
LAZYADD(candidates, M)
|
||||
|
||||
if(!LAZYLEN(candidates))
|
||||
return FALSE
|
||||
|
||||
if(candidates.len == 1)
|
||||
C = candidates[1]
|
||||
else
|
||||
C = input("Select who to capture:","Capture who?",null) as null|mob in candidates
|
||||
|
||||
|
||||
if(QDELETED(C)||!(C in oview(H)))
|
||||
return FALSE
|
||||
|
||||
if(!ninjacost(200,N_STEALTH_CANCEL))
|
||||
H.Beam(C,"n_beam",time=15)
|
||||
H.say("Get over here!", forced = "ninja net")
|
||||
var/obj/structure/energy_net/E = new /obj/structure/energy_net(C.drop_location())
|
||||
E.affecting = C
|
||||
E.master = H
|
||||
H.visible_message("<span class='danger'>[H] caught [C] with an energy net!</span>","<span class='notice'>You caught [C] with an energy net!</span>")
|
||||
|
||||
if(C.buckled)
|
||||
C.buckled.unbuckle_mob(affecting,TRUE)
|
||||
E.buckle_mob(C, TRUE) //No moving for you!
|
||||
//The person can still try and attack the net when inside.
|
||||
|
||||
START_PROCESSING(SSobj, E)
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
|
||||
//Smoke bomb
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke()
|
||||
|
||||
if(!ninjacost(0,N_SMOKE_BOMB))
|
||||
var/mob/living/carbon/human/H = affecting
|
||||
var/datum/effect_system/smoke_spread/bad/smoke = new
|
||||
smoke.set_up(4, H.loc)
|
||||
smoke.start()
|
||||
playsound(H.loc, 'sound/effects/bamf.ogg', 50, 2)
|
||||
s_bombs--
|
||||
to_chat(H, "<span class='notice'>There are <B>[s_bombs]</B> smoke bombs remaining.</span>")
|
||||
s_coold = 1
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
|
||||
//Creates a throwing star
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjastar()
|
||||
if(!ninjacost(10))
|
||||
var/mob/living/carbon/human/H = affecting
|
||||
var/obj/item/throwing_star/ninja/N = new(H)
|
||||
if(H.put_in_hands(N))
|
||||
to_chat(H, "<span class='notice'>A throwing star has been created in your hand!</span>")
|
||||
else
|
||||
qdel(N)
|
||||
H.throw_mode_on() //So they can quickly throw it.
|
||||
|
||||
|
||||
/obj/item/throwing_star/ninja
|
||||
name = "ninja throwing star"
|
||||
throwforce = 20
|
||||
embedding = list("pain_mult" = 6, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15)
|
||||
@@ -1,54 +0,0 @@
|
||||
|
||||
/*
|
||||
|
||||
Contents:
|
||||
- Stealth Verbs
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/toggle_stealth()
|
||||
if(!affecting || stealth_cooldown > world.time)
|
||||
return
|
||||
if(stealth)
|
||||
cancel_stealth()
|
||||
else
|
||||
if(cell.charge <= 0)
|
||||
to_chat(affecting, "<span class='warning'>You don't have enough power to enable Stealth!</span>")
|
||||
return
|
||||
stealth = TRUE
|
||||
stealth_cooldown = world.time + 5 SECONDS
|
||||
animate(affecting, alpha = 15, time = 3 SECONDS)
|
||||
affecting.visible_message("<span class='warning'>[affecting.name] vanishes into thin air!</span>", \
|
||||
"<span class='notice'>You are now mostly invisible to normal detection.</span>")
|
||||
addtimer(CALLBACK(src, .proc/enable_signals), 3 SECONDS)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/enable_signals()
|
||||
if(!affecting)
|
||||
return
|
||||
RegisterSignal(affecting, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_PARENT_ATTACKBY, COMSIG_MOVABLE_TELEPORTED, COMSIG_LIVING_GUN_PROCESS_FIRE), .proc/reduce_stealth)
|
||||
RegisterSignal(affecting, COMSIG_MOVABLE_BUMP, .proc/bumping_stealth)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/reduce_stealth(datum/source)
|
||||
affecting.alpha = min(affecting.alpha + 40, 100)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/bumping_stealth(datum/source, atom/A)
|
||||
if(isliving(A))
|
||||
affecting.alpha = min(affecting.alpha + 20, 100)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/cancel_stealth()
|
||||
if(!affecting || !stealth)
|
||||
return FALSE
|
||||
stealth = !stealth
|
||||
stealth_cooldown = world.time + 5 SECONDS
|
||||
UnregisterSignal(affecting, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_PARENT_ATTACKBY, COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_TELEPORTED, COMSIG_LIVING_GUN_PROCESS_FIRE))
|
||||
animate(affecting, alpha = 255, time = 3 SECONDS)
|
||||
affecting.visible_message("<span class='warning'>[affecting.name] appears from thin air!</span>", \
|
||||
"<span class='notice'>You are now visible.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/stealth()
|
||||
if(!s_busy)
|
||||
toggle_stealth()
|
||||
else
|
||||
to_chat(affecting, "<span class='danger'>Stealth does not appear to work!</span>")
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninja_sword_recall()
|
||||
var/mob/living/carbon/human/H = affecting
|
||||
|
||||
var/cost = 0
|
||||
var/inview = 1
|
||||
|
||||
if(!energyKatana)
|
||||
to_chat(H, "<span class='warning'>Could not locate Energy Katana!</span>")
|
||||
return
|
||||
|
||||
if(energyKatana in H)
|
||||
return
|
||||
|
||||
var/distance = get_dist(H,energyKatana)
|
||||
|
||||
if(!(energyKatana in view(H)))
|
||||
cost = distance //Actual cost is cost x 10, so 5 turfs is 50 cost.
|
||||
inview = 0
|
||||
|
||||
if(!ninjacost(cost))
|
||||
if(iscarbon(energyKatana.loc))
|
||||
var/mob/living/carbon/C = energyKatana.loc
|
||||
C.transferItemToLoc(energyKatana, get_turf(energyKatana), TRUE)
|
||||
|
||||
//Somebody swollowed my sword, probably the clown doing a circus act.
|
||||
if(energyKatana in C.stomach_contents)
|
||||
C.stomach_contents -= energyKatana
|
||||
else
|
||||
energyKatana.forceMove(get_turf(energyKatana))
|
||||
|
||||
if(inview) //If we can see the katana, throw it towards ourselves, damaging people as we go.
|
||||
energyKatana.spark_system.start()
|
||||
playsound(H, "sparks", 50, 1)
|
||||
H.visible_message("<span class='danger'>\the [energyKatana] flies towards [H]!</span>","<span class='warning'>You hold out your hand and \the [energyKatana] flies towards you!</span>")
|
||||
energyKatana.throw_at(H, distance+1, energyKatana.throw_speed,H)
|
||||
|
||||
else //Else just TP it to us.
|
||||
energyKatana.returnToOwner(H,1)
|
||||
@@ -1,278 +1,288 @@
|
||||
|
||||
/*
|
||||
|
||||
Contents:
|
||||
- Assorted ninjadrain_act() procs
|
||||
- What is Object Oriented Programming
|
||||
|
||||
They *could* go in their appropriate files, but this is supposed to be modular
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//Needs to return the amount drained from the atom, if no drain on a power object, return FALSE, otherwise, return a define.
|
||||
/atom/proc/ninjadrain_act()
|
||||
/**
|
||||
* Atom level proc for space ninja's glove interactions.
|
||||
*
|
||||
* Proc which only occurs when space ninja uses his gloves on an atom.
|
||||
* Does nothing by default, but effects will vary.
|
||||
* Arguments:
|
||||
* * ninja_suit - The offending space ninja's suit.
|
||||
* * ninja - The human mob wearing the suit.
|
||||
* * ninja_gloves - The offending space ninja's gloves.
|
||||
*/
|
||||
/atom/proc/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
return INVALID_DRAIN
|
||||
|
||||
|
||||
|
||||
|
||||
//APC//
|
||||
/obj/machinery/power/apc/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
|
||||
if(!S || !H || !G)
|
||||
/obj/machinery/power/apc/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
if(!ninja_suit || !ninja || !ninja_gloves)
|
||||
return INVALID_DRAIN
|
||||
|
||||
var/maxcapacity = 0 //Safety check for batteries
|
||||
var/maxcapacity = FALSE //Safety check for batteries
|
||||
var/drain = 0 //Drain amount from batteries
|
||||
var/drain_total = 0
|
||||
|
||||
. = 0
|
||||
|
||||
if(cell && cell.charge)
|
||||
if(cell?.charge)
|
||||
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread()
|
||||
spark_system.set_up(5, 0, loc)
|
||||
|
||||
while(G.candrain && cell.charge> 0 && !maxcapacity)
|
||||
drain = rand(G.mindrain, G.maxdrain)
|
||||
while(ninja_gloves.candrain && cell.charge> 0 && !maxcapacity)
|
||||
drain = rand(ninja_gloves.mindrain, ninja_gloves.maxdrain)
|
||||
|
||||
if(cell.charge < drain)
|
||||
drain = cell.charge
|
||||
|
||||
if(S.cell.charge + drain > S.cell.maxcharge)
|
||||
drain = S.cell.maxcharge - S.cell.charge
|
||||
maxcapacity = 1//Reached maximum battery capacity.
|
||||
if(ninja_suit.cell.charge + drain > ninja_suit.cell.maxcharge)
|
||||
drain = ninja_suit.cell.maxcharge - ninja_suit.cell.charge
|
||||
maxcapacity = TRUE//Reached maximum battery capacity.
|
||||
|
||||
if (do_after(H,10, target = src))
|
||||
if (do_after(ninja ,10, target = src))
|
||||
spark_system.start()
|
||||
playsound(loc, "sparks", 50, 1)
|
||||
cell.charge -= drain
|
||||
S.cell.charge += drain
|
||||
. += drain
|
||||
playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
cell.use(drain)
|
||||
ninja_suit.cell.give(drain)
|
||||
drain_total += drain
|
||||
else
|
||||
break
|
||||
|
||||
if(!(obj_flags & EMAGGED))
|
||||
flick("apc-spark", G)
|
||||
playsound(loc, "sparks", 50, 1)
|
||||
flick("apc-spark", ninja_gloves)
|
||||
playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
obj_flags |= EMAGGED
|
||||
locked = FALSE
|
||||
update_icon()
|
||||
|
||||
|
||||
|
||||
|
||||
return drain_total
|
||||
|
||||
//SMES//
|
||||
/obj/machinery/power/smes/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
|
||||
if(!S || !H || !G)
|
||||
/obj/machinery/power/smes/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
if(!ninja_suit || !ninja || !ninja_gloves)
|
||||
return INVALID_DRAIN
|
||||
|
||||
var/maxcapacity = 0 //Safety check for batteries
|
||||
var/maxcapacity = FALSE //Safety check for batteries
|
||||
var/drain = 0 //Drain amount from batteries
|
||||
|
||||
. = 0
|
||||
var/drain_total = 0
|
||||
|
||||
if(charge)
|
||||
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread()
|
||||
spark_system.set_up(5, 0, loc)
|
||||
|
||||
while(G.candrain && charge > 0 && !maxcapacity)
|
||||
drain = rand(G.mindrain, G.maxdrain)
|
||||
while(ninja_gloves.candrain && charge > 0 && !maxcapacity)
|
||||
drain = rand(ninja_gloves.mindrain, ninja_gloves.maxdrain)
|
||||
|
||||
if(charge < drain)
|
||||
drain = charge
|
||||
|
||||
if(S.cell.charge + drain > S.cell.maxcharge)
|
||||
drain = S.cell.maxcharge - S.cell.charge
|
||||
maxcapacity = 1
|
||||
if(ninja_suit.cell.charge + drain > ninja_suit.cell.maxcharge)
|
||||
drain = ninja_suit.cell.maxcharge - ninja_suit.cell.charge
|
||||
maxcapacity = TRUE
|
||||
|
||||
if (do_after(H,10, target = src))
|
||||
if (do_after(ninja,10, target = src))
|
||||
spark_system.start()
|
||||
playsound(loc, "sparks", 50, 1)
|
||||
playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
charge -= drain
|
||||
S.cell.charge += drain
|
||||
. += drain
|
||||
ninja_suit.cell.give(drain)
|
||||
drain_total += drain
|
||||
|
||||
else
|
||||
break
|
||||
|
||||
return drain_total
|
||||
|
||||
//CELL//
|
||||
/obj/item/stock_parts/cell/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
|
||||
if(!S || !H || !G)
|
||||
/obj/item/stock_parts/cell/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
if(!ninja_suit || !ninja || !ninja_gloves)
|
||||
return INVALID_DRAIN
|
||||
|
||||
. = 0
|
||||
var/drain_total = 0
|
||||
|
||||
if(charge)
|
||||
if(G.candrain && do_after(H,30, target = src))
|
||||
. = charge
|
||||
if(S.cell.charge + charge > S.cell.maxcharge)
|
||||
S.cell.charge = S.cell.maxcharge
|
||||
if(ninja_gloves.candrain && do_after(ninja, 30, target = src))
|
||||
drain_total = charge
|
||||
if(ninja_suit.cell.charge + charge > ninja_suit.cell.maxcharge)
|
||||
ninja_suit.cell.charge = ninja_suit.cell.maxcharge
|
||||
else
|
||||
S.cell.charge += charge
|
||||
ninja_suit.cell.give(charge)
|
||||
charge = 0
|
||||
corrupt()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/proc/AI_notify_hack()
|
||||
var/turf/location = get_turf(src)
|
||||
var/alertstr = "<span class='userdanger'>Network Alert: Hacking attempt detected[location?" in [location]":". Unable to pinpoint location"]</span>."
|
||||
for(var/mob/living/silicon/ai/AI in GLOB.player_list)
|
||||
to_chat(AI, alertstr)
|
||||
return drain_total
|
||||
|
||||
//RDCONSOLE//
|
||||
/obj/machinery/computer/rdconsole/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
|
||||
if(!S || !H || !G)
|
||||
/obj/machinery/computer/rdconsole/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
if(!ninja_suit || !ninja || !ninja_gloves)
|
||||
return INVALID_DRAIN
|
||||
|
||||
. = DRAIN_RD_HACK_FAILED
|
||||
|
||||
to_chat(H, "<span class='notice'>Hacking \the [src]...</span>")
|
||||
to_chat(ninja, "<span class='notice'>Hacking \the [src]...</span>")
|
||||
AI_notify_hack()
|
||||
|
||||
if(stored_research)
|
||||
to_chat(H, "<span class='notice'>Copying files...</span>")
|
||||
if(do_after(H, S.s_delay, target = src) && G.candrain && src)
|
||||
stored_research.copy_research_to(S.stored_research)
|
||||
to_chat(H, "<span class='notice'>Data analyzed. Process finished.</span>")
|
||||
to_chat(ninja, "<span class='notice'>Copying files...</span>")
|
||||
if(do_after(ninja, ninja_suit.s_delay, target = src) && ninja_gloves.candrain && src)
|
||||
stored_research.copy_research_to(ninja_suit.stored_research)
|
||||
to_chat(ninja, "<span class='notice'>Data analyzed. Process finished.</span>")
|
||||
|
||||
//RD SERVER//
|
||||
//Shamelessly copypasted from above, since these two used to be the same proc, but with MANY colon operators
|
||||
/obj/machinery/rnd/server/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
|
||||
if(!S || !H || !G)
|
||||
/obj/machinery/rnd/server/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
if(!ninja_suit || !ninja || !ninja_gloves)
|
||||
return INVALID_DRAIN
|
||||
|
||||
. = DRAIN_RD_HACK_FAILED
|
||||
|
||||
to_chat(H, "<span class='notice'>Hacking \the [src]...</span>")
|
||||
to_chat(ninja, "<span class='notice'>Hacking \the [src]...</span>")
|
||||
AI_notify_hack()
|
||||
|
||||
if(stored_research)
|
||||
to_chat(H, "<span class='notice'>Copying files...</span>")
|
||||
if(do_after(H, S.s_delay, target = src) && G.candrain && src)
|
||||
stored_research.copy_research_to(S.stored_research)
|
||||
to_chat(H, "<span class='notice'>Data analyzed. Process finished.</span>")
|
||||
to_chat(ninja, "<span class='notice'>Copying files...</span>")
|
||||
if(do_after(ninja, ninja_suit.s_delay, target = src) && ninja_gloves.candrain && src)
|
||||
stored_research.copy_research_to(ninja_suit.stored_research)
|
||||
to_chat(ninja, "<span class='notice'>Data analyzed. Process finished.</span>")
|
||||
|
||||
//SECURITY CONSOLE//
|
||||
/obj/machinery/computer/secure_data/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
if(!ninja_suit || !ninja || !ninja_gloves)
|
||||
return INVALID_DRAIN
|
||||
AI_notify_hack()
|
||||
if(do_after(ninja, 200))
|
||||
for(var/datum/data/record/rec in sortRecord(GLOB.data_core.general, sortBy, order))
|
||||
for(var/datum/data/record/security_record in GLOB.data_core.security)
|
||||
security_record.fields["criminal"] = "*Arrest*"
|
||||
var/datum/antagonist/ninja/ninja_antag = ninja.mind.has_antag_datum(/datum/antagonist/ninja)
|
||||
if(!ninja_antag)
|
||||
return
|
||||
var/datum/objective/security_scramble/objective = locate() in ninja_antag.objectives
|
||||
if(objective)
|
||||
objective.completed = TRUE
|
||||
|
||||
//WIRE//
|
||||
/obj/structure/cable/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
|
||||
if(!S || !H || !G)
|
||||
//COMMUNICATIONS CONSOLE//
|
||||
/obj/machinery/computer/communications/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
if(!ninja_suit || !ninja || !ninja_gloves)
|
||||
return INVALID_DRAIN
|
||||
if(ninja_gloves.communication_console_hack_success)
|
||||
return
|
||||
AI_notify_hack()
|
||||
if(do_after(ninja, 300))
|
||||
var/announcement_pick = rand(0, 1)
|
||||
switch(announcement_pick)
|
||||
if(0)
|
||||
priority_announce("Attention crew, it appears that someone on your station has made unexpected communication with an alien device in nearby space.", "[command_name()] High-Priority Update")
|
||||
var/datum/round_event_control/spawn_swarmer/swarmer_event = new/datum/round_event_control/spawn_swarmer
|
||||
swarmer_event.runEvent()
|
||||
if(1)
|
||||
priority_announce("Attention crew, it appears that someone on your station has made unexpected communication with a syndicate ship in nearby space.", "[command_name()] High-Priority Update")
|
||||
var/datum/round_event_control/pirates/pirate_event = new/datum/round_event_control/pirates
|
||||
pirate_event.runEvent()
|
||||
ninja_gloves.communication_console_hack_success = TRUE
|
||||
var/datum/antagonist/ninja/ninja_antag = ninja.mind.has_antag_datum(/datum/antagonist/ninja)
|
||||
if(!ninja_antag)
|
||||
return
|
||||
var/datum/objective/terror_message/objective = locate() in ninja_antag.objectives
|
||||
if(objective)
|
||||
objective.completed = TRUE
|
||||
|
||||
//AIRLOCK//
|
||||
/obj/machinery/door/airlock/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
if(!ninja_suit || !ninja || !ninja_gloves)
|
||||
return INVALID_DRAIN
|
||||
|
||||
var/maxcapacity = 0 //Safety check
|
||||
if(!operating && density && hasPower() && !(obj_flags & EMAGGED))
|
||||
emag_act()
|
||||
ninja_gloves.door_hack_counter++
|
||||
var/datum/antagonist/ninja/ninja_antag = ninja.mind.has_antag_datum(/datum/antagonist/ninja)
|
||||
if(!ninja_antag)
|
||||
return
|
||||
var/datum/objective/door_jack/objective = locate() in ninja_antag.objectives
|
||||
if(objective && objective.doors_required <= ninja_gloves.door_hack_counter)
|
||||
objective.completed = TRUE
|
||||
|
||||
//WIRE//
|
||||
/obj/structure/cable/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
if(!ninja_suit || !ninja || !ninja_gloves)
|
||||
return INVALID_DRAIN
|
||||
|
||||
var/maxcapacity = FALSE //Safety check
|
||||
var/drain = 0 //Drain amount
|
||||
|
||||
. = 0
|
||||
var/drain_total = 0
|
||||
|
||||
var/datum/powernet/PN = powernet
|
||||
while(G.candrain && !maxcapacity && src)
|
||||
drain = (round((rand(G.mindrain, G.maxdrain))/2))
|
||||
var/datum/powernet/wire_powernet = powernet
|
||||
while(ninja_gloves.candrain && !maxcapacity && src)
|
||||
drain = (round((rand(ninja_gloves.mindrain, ninja_gloves.maxdrain))/2))
|
||||
var/drained = 0
|
||||
if(PN && do_after(H,10, target = src))
|
||||
if(wire_powernet && do_after(ninja ,10, target = src))
|
||||
drained = min(drain, delayed_surplus())
|
||||
add_delayedload(drained)
|
||||
if(drained < drain)//if no power on net, drain apcs
|
||||
for(var/obj/machinery/power/terminal/T in PN.nodes)
|
||||
if(istype(T.master, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/AP = T.master
|
||||
for(var/obj/machinery/power/terminal/affected_terminal in wire_powernet.nodes)
|
||||
if(istype(affected_terminal.master, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/AP = affected_terminal.master
|
||||
if(AP.operating && AP.cell && AP.cell.charge > 0)
|
||||
AP.cell.charge = max(0, AP.cell.charge - 5)
|
||||
drained += 5
|
||||
else
|
||||
break
|
||||
|
||||
S.cell.charge += drained
|
||||
if(S.cell.charge > S.cell.maxcharge)
|
||||
. += (drained-(S.cell.charge - S.cell.maxcharge))
|
||||
S.cell.charge = S.cell.maxcharge
|
||||
maxcapacity = 1
|
||||
ninja_suit.cell.give(drain)
|
||||
if(ninja_suit.cell.charge > ninja_suit.cell.maxcharge)
|
||||
drain_total += (drained-(ninja_suit.cell.charge - ninja_suit.cell.maxcharge))
|
||||
ninja_suit.cell.charge = ninja_suit.cell.maxcharge
|
||||
maxcapacity = TRUE
|
||||
else
|
||||
. += drained
|
||||
S.spark_system.start()
|
||||
drain_total += drained
|
||||
ninja_suit.spark_system.start()
|
||||
|
||||
return drain_total
|
||||
|
||||
//MECH//
|
||||
/obj/mecha/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
|
||||
if(!S || !H || !G)
|
||||
/obj/vehicle/sealed/mecha/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
if(!ninja_suit || !ninja || !ninja_gloves)
|
||||
return INVALID_DRAIN
|
||||
|
||||
var/maxcapacity = 0 //Safety check
|
||||
var/maxcapacity = FALSE //Safety check
|
||||
var/drain = 0 //Drain amount
|
||||
. = 0
|
||||
var/drain_total = 0
|
||||
|
||||
occupant_message("<span class='danger'>Warning: Unauthorized access through sub-route 4, block H, detected.</span>")
|
||||
to_chat(occupants, "[icon2html(src, occupants)]<span class='danger'>Warning: Unauthorized access through sub-route 4, block H, detected.</span>")
|
||||
if(get_charge())
|
||||
while(G.candrain && cell.charge > 0 && !maxcapacity)
|
||||
drain = rand(G.mindrain,G.maxdrain)
|
||||
while(ninja_gloves.candrain && cell.charge > 0 && !maxcapacity)
|
||||
drain = rand(ninja_gloves.mindrain, ninja_gloves.maxdrain)
|
||||
if(cell.charge < drain)
|
||||
drain = cell.charge
|
||||
if(S.cell.charge + drain > S.cell.maxcharge)
|
||||
drain = S.cell.maxcharge - S.cell.charge
|
||||
maxcapacity = 1
|
||||
if (do_after(H,10, target = src))
|
||||
if(ninja_suit.cell.charge + drain > ninja_suit.cell.maxcharge)
|
||||
drain = ninja_suit.cell.maxcharge - ninja_suit.cell.charge
|
||||
maxcapacity = TRUE
|
||||
if (do_after(ninja, 10, target = src))
|
||||
spark_system.start()
|
||||
playsound(loc, "sparks", 50, 1)
|
||||
playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
cell.use(drain)
|
||||
S.cell.charge += drain
|
||||
. += drain
|
||||
ninja_suit.cell.give(drain)
|
||||
drain_total += drain
|
||||
else
|
||||
break
|
||||
|
||||
return drain_total
|
||||
|
||||
//BORG//
|
||||
/mob/living/silicon/robot/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
|
||||
if(!S || !H || !G)
|
||||
/mob/living/silicon/robot/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves)
|
||||
if(!ninja_suit || !ninja || !ninja_gloves || (ROLE_NINJA in faction))
|
||||
return INVALID_DRAIN
|
||||
|
||||
var/maxcapacity = 0 //Safety check
|
||||
var/drain = 0 //Drain amount
|
||||
. = 0
|
||||
to_chat(src, "<span class='danger'>Warni-***BZZZZZZZZZRT*** UPLOADING SPYDERPATCHER VERSION 9.5.2...</span>")
|
||||
if (do_after(ninja, 60, target = src))
|
||||
spark_system.start()
|
||||
playsound(loc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
to_chat(src, "<span class='danger'>UPLOAD COMPLETE. NEW CYBORG MODEL DETECTED. INSTALLING...</span>")
|
||||
faction = list(ROLE_NINJA)
|
||||
bubble_icon = "syndibot"
|
||||
UnlinkSelf()
|
||||
ionpulse = TRUE
|
||||
laws = new /datum/ai_laws/ninja_override()
|
||||
model.transform_to(pick(/obj/item/robot_model/syndicate, /obj/item/robot_model/syndicate_medical, /obj/item/robot_model/saboteur))
|
||||
|
||||
to_chat(src, "<span class='danger'>Warning: Unauthorized access through sub-route 12, block C, detected.</span>")
|
||||
|
||||
if(cell && cell.charge)
|
||||
while(G.candrain && cell.charge > 0 && !maxcapacity)
|
||||
drain = rand(G.mindrain,G.maxdrain)
|
||||
if(cell.charge < drain)
|
||||
drain = cell.charge
|
||||
if(S.cell.charge+drain > S.cell.maxcharge)
|
||||
drain = S.cell.maxcharge - S.cell.charge
|
||||
maxcapacity = 1
|
||||
if (do_after(H,10))
|
||||
spark_system.start()
|
||||
playsound(loc, "sparks", 50, 1)
|
||||
cell.charge -= drain
|
||||
S.cell.charge += drain
|
||||
. += drain
|
||||
else
|
||||
break
|
||||
|
||||
|
||||
//CARBON MOBS//
|
||||
/mob/living/carbon/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G)
|
||||
if(!S || !H || !G)
|
||||
return INVALID_DRAIN
|
||||
|
||||
. = DRAIN_MOB_SHOCK_FAILED
|
||||
|
||||
//Default cell = 10,000 charge, 10,000/1000 = 10 uses without charging/upgrading
|
||||
if(S.cell && S.cell.charge && S.cell.use(500))
|
||||
. = DRAIN_MOB_SHOCK
|
||||
//Got that electric touch
|
||||
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread()
|
||||
spark_system.set_up(5, 0, loc)
|
||||
playsound(src, "sparks", 50, 1)
|
||||
visible_message("<span class='danger'>[H] electrocutes [src] with [H.p_their()] touch!</span>", "<span class='userdanger'>[H] electrocutes you with [H.p_their()] touch!</span>")
|
||||
electrocute_act(15, H, flags = SHOCK_NOSTUN)
|
||||
|
||||
DefaultCombatKnockdown(G.stunforce, override_hardstun = 0)
|
||||
apply_effect(EFFECT_STUTTER, G.stunforce)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_MINOR_SHOCK)
|
||||
|
||||
lastattacker = H.real_name
|
||||
lastattackerckey = H.ckey
|
||||
log_combat(H, src, "stunned")
|
||||
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/Hsrc = src
|
||||
Hsrc.forcesay(GLOB.hit_appends)
|
||||
var/datum/antagonist/ninja/ninja_antag = ninja.mind.has_antag_datum(/datum/antagonist/ninja)
|
||||
if(!ninja_antag)
|
||||
return
|
||||
var/datum/objective/cyborg_hijack/objective = locate() in ninja_antag.objectives
|
||||
if(objective)
|
||||
objective.completed = TRUE
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* # Energy Net
|
||||
*
|
||||
* Energy net which ensnares prey until it is destroyed. Used by space ninjas.
|
||||
*
|
||||
* Energy net which keeps its target from moving until it is destroyed. Used to send
|
||||
* players to a holding area in which they could never leave, but such feature has since
|
||||
* been removed.
|
||||
*/
|
||||
/obj/structure/energy_net
|
||||
name = "energy net"
|
||||
desc = "It's a net made of green energy."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "energynet"
|
||||
|
||||
density = TRUE//Can't pass through.
|
||||
opacity = FALSE //Can see through.
|
||||
mouse_opacity = MOUSE_OPACITY_ICON//So you can hit it with stuff.
|
||||
anchored = TRUE//Can't drag/grab the net.
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
max_integrity = 60 //How much health it has.
|
||||
can_buckle = 1
|
||||
buckle_lying = 0
|
||||
buckle_prevents_pull = TRUE
|
||||
///The creature currently caught in the net
|
||||
var/mob/living/affecting
|
||||
|
||||
/obj/structure/energy_net/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0)
|
||||
if(damage_type == BRUTE || damage_type == BURN)
|
||||
playsound(src, 'sound/weapons/slash.ogg', 80, TRUE)
|
||||
|
||||
/obj/structure/energy_net/Destroy()
|
||||
if(!QDELETED(affecting))
|
||||
affecting.visible_message("<span class='notice'>[affecting.name] is recovered from the energy net!</span>", "<span class='notice'>You are recovered from the energy net!</span>", "<span class='hear'>You hear a grunt.</span>")
|
||||
affecting = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/energy_net/attack_paw(mob/user)
|
||||
return attack_hand()
|
||||
|
||||
/obj/structure/energy_net/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE)
|
||||
return//We only want our target to be buckled
|
||||
|
||||
/obj/structure/energy_net/user_unbuckle_mob(mob/living/buckled_mob, mob/living/user)
|
||||
return//The net must be destroyed to free the target
|
||||
@@ -0,0 +1,45 @@
|
||||
//Wakes the user so they are able to do their thing. Also injects a decent dose of radium.
|
||||
//Movement impairing would indicate drugs and the like.
|
||||
|
||||
/datum/action/item_action/ninjaboost
|
||||
check_flags = NONE
|
||||
name = "Adrenaline Boost"
|
||||
desc = "Inject a secret chemical that will counteract all movement-impairing effect."
|
||||
button_icon_state = "repulse"
|
||||
icon_icon = 'icons/mob/actions/actions_spells.dmi'
|
||||
|
||||
/**
|
||||
* Proc called to activate space ninja's adrenaline.
|
||||
*
|
||||
* Proc called to use space ninja's adrenaline. Gets the ninja out of almost any stun.
|
||||
* Also makes them shout MGS references when used. After a bit, it injects the user with
|
||||
* radium by calling a different proc.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost()
|
||||
if(ninjacost(0,N_ADRENALINE))
|
||||
return
|
||||
var/mob/living/carbon/human/ninja = affecting
|
||||
ninja.SetUnconscious(0)
|
||||
ninja.SetStun(0)
|
||||
ninja.SetKnockdown(0)
|
||||
ninja.SetImmobilized(0)
|
||||
ninja.SetParalyzed(0)
|
||||
ninja.adjustStaminaLoss(-200)
|
||||
ninja.stuttering = 0
|
||||
ninja.reagents.add_reagent(/datum/reagent/medicine/stimulants, 5)
|
||||
ninja.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!"), forced = "ninjaboost")
|
||||
a_boost = FALSE
|
||||
to_chat(ninja, "<span class='notice'>You have used the adrenaline boost.</span>")
|
||||
s_coold = 6
|
||||
addtimer(CALLBACK(src, .proc/ninjaboost_after), 70)
|
||||
|
||||
/**
|
||||
* Proc called to inject the ninja with radium.
|
||||
*
|
||||
* Used after 7 seconds of using the ninja's adrenaline.
|
||||
* Injects the user with how much radium the suit needs to refill an adrenaline boost.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost_after()
|
||||
var/mob/living/carbon/human/ninja = affecting
|
||||
ninja.reagents.add_reagent(/datum/reagent/uranium/radium, a_transfer * 0.25)
|
||||
to_chat(ninja, "<span class='danger'>You are beginning to feel the after-effect of the injection.</span>")
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Proc called to check if the ninja can afford an ability's cost.
|
||||
*
|
||||
* Proc which determine whether or not a space ninja can afford to use a specific ability.
|
||||
* It can also cancel stealth if the ability requested it.
|
||||
* Arguments:
|
||||
* * cost - the energy cost of the ability
|
||||
* * specificCheck - Determines if the check is a normal one, an adrenaline one, or a stealth cancel check.
|
||||
* * Returns TRUE or the current cooldown timer if we can't perform the ability, and FALSE if we can.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjacost(cost = 0, specificCheck = 0)
|
||||
var/mob/living/carbon/human/ninja = affecting
|
||||
var/actualCost = cost*10
|
||||
if(cost && cell.charge < actualCost)
|
||||
to_chat(ninja, "<span class='warning'>Not enough energy!</span>")
|
||||
return TRUE
|
||||
else
|
||||
//This shit used to be handled individually on every proc.. why even bother with a universal check proc then?
|
||||
cell.charge-=(actualCost)
|
||||
|
||||
switch(specificCheck)
|
||||
if(N_STEALTH_CANCEL)
|
||||
cancel_stealth()//Get rid of it.
|
||||
if(N_ADRENALINE)
|
||||
if(!a_boost)
|
||||
to_chat(ninja, "<span class='warning'>You do not have any more adrenaline boosters!</span>")
|
||||
return TRUE
|
||||
return (s_coold)//Returns the value of the variable which counts down to zero.
|
||||
@@ -0,0 +1,21 @@
|
||||
//Disables nearby tech equipment.
|
||||
|
||||
/datum/action/item_action/ninjapulse
|
||||
name = "EM Burst (50E)"
|
||||
desc = "Disable any nearby technology with an electro-magnetic pulse."
|
||||
button_icon_state = "emp"
|
||||
icon_icon = 'icons/mob/actions/actions_spells.dmi'
|
||||
|
||||
/**
|
||||
* Proc called to allow the ninja to EMP the nearby area.
|
||||
*
|
||||
* Proc called to allow the ninja to EMP the nearby area. By default, costs 500E, which is half of the default battery's max charge.
|
||||
* Also affects the ninja as well.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse()
|
||||
if(ninjacost(500,N_STEALTH_CANCEL))
|
||||
return
|
||||
var/mob/living/carbon/human/H = affecting
|
||||
playsound(H.loc, 'sound/effects/empulse.ogg', 60, 2)
|
||||
empulse(H, 4, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch.
|
||||
s_coold = 4
|
||||
@@ -0,0 +1,15 @@
|
||||
/datum/action/item_action/toggle_glove
|
||||
name = "Toggle interaction"
|
||||
desc = "Switch between normal interaction and drain mode."
|
||||
button_icon_state = "s-ninjan"
|
||||
icon_icon = 'icons/obj/clothing/gloves.dmi'
|
||||
|
||||
/**
|
||||
* Proc called to toggle the ninja glove's special abilities.
|
||||
*
|
||||
* Used to toggle whether or not the ninja glove's abilities will activate on touch.
|
||||
*/
|
||||
/obj/item/clothing/gloves/space_ninja/proc/toggledrain()
|
||||
var/mob/living/carbon/human/ninja = loc
|
||||
to_chat(ninja, "<span class='notice'>You [candrain?"disable":"enable"] special interaction.</span>")
|
||||
candrain=!candrain
|
||||
@@ -0,0 +1,36 @@
|
||||
/datum/action/item_action/ninjanet
|
||||
name = "Energy Net (40E)"
|
||||
desc = "Captures a fallen opponent in a net of energy."
|
||||
button_icon_state = "energynet"
|
||||
icon_icon = 'icons/effects/effects.dmi'
|
||||
|
||||
/**
|
||||
* Proc called to ensnare a person in a energy net.
|
||||
*
|
||||
* Used to ensnare a target in an energy net, preventing them from moving until the net is broken.
|
||||
* Costs 40E, which is 40% of the default battery's max charge. Intended as a means of reliably locking down an opponent when ninja stars won't suffice.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjanet()
|
||||
var/mob/living/carbon/human/ninja = affecting
|
||||
var/mob/living/net_target = input("Select who to capture:","Capture who?",null) as null|mob in sortNames(oview(ninja))
|
||||
|
||||
if(QDELETED(net_target)||!(net_target in oview(ninja)))
|
||||
return
|
||||
|
||||
if(locate(/obj/structure/energy_net) in get_turf(net_target))//Check if they are already being affected by an energy net.
|
||||
to_chat(ninja, "<span class='warning'>[net_target.p_they(TRUE)] are already trapped inside an energy net!</span>")
|
||||
return
|
||||
for(var/turf/between_turf in getline(get_turf(ninja), get_turf(net_target)))
|
||||
if(between_turf.density)//Don't want them shooting nets through walls. It's kind of cheesy.
|
||||
to_chat(ninja, "<span class='warning'>You may not use an energy net through solid obstacles!</span>")
|
||||
return
|
||||
if(!ninjacost(400,N_STEALTH_CANCEL))
|
||||
ninja.Beam(net_target, "n_beam", time = 15)
|
||||
ninja.say("Get over here!", forced = "ninja net")
|
||||
var/obj/structure/energy_net/net = new /obj/structure/energy_net(net_target.drop_location())
|
||||
net.affecting = net_target
|
||||
ninja.visible_message("<span class='danger'>[ninja] caught [net_target] with an energy net!</span>","<span class='notice'>You caught [net_target] with an energy net!</span>")
|
||||
|
||||
if(net_target.buckled)
|
||||
net_target.buckled.unbuckle_mob(affecting,TRUE)
|
||||
net.buckle_mob(net_target, TRUE) //No moving for you!
|
||||
@@ -0,0 +1,43 @@
|
||||
/datum/action/item_action/ninjastar
|
||||
name = "Create Throwing Stars (1E)"
|
||||
desc = "Creates a throwing star in your hand, if possible."
|
||||
button_icon_state = "throwingstar"
|
||||
icon_icon = 'icons/obj/items_and_weapons.dmi'
|
||||
|
||||
/**
|
||||
* Proc called to create a ninja star in the ninja's hands.
|
||||
*
|
||||
* Called to create a ninja star in the wearer's hand. The ninja
|
||||
* star doesn't do much up-front damage, but deals stamina damage
|
||||
* as the target moves around, forcing a finish or flee scenario.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjastar()
|
||||
if(ninjacost(10))
|
||||
return
|
||||
var/mob/living/carbon/human/ninja = affecting
|
||||
var/obj/item/throwing_star/stamina/ninja/ninja_star = new(ninja)
|
||||
if(ninja.put_in_hands(ninja_star))
|
||||
to_chat(ninja, "<span class='notice'>A throwing star has been created in your hand!</span>")
|
||||
else
|
||||
qdel(ninja_star)
|
||||
to_chat(ninja, "<span class='notice'>You can't create a throwing star, your hands are full!</span>")
|
||||
ninja.throw_mode_on() //So they can quickly throw it.
|
||||
|
||||
/**
|
||||
* # Ninja Throwing Star
|
||||
*
|
||||
* a throwing star which specifically makes sure you know it came from a real ninja.
|
||||
*
|
||||
* The most important item in the entire codebase, as without it we would all cease to exist.
|
||||
* Inherits everything that makes it interesting the stamina throwing star, but the most
|
||||
* important change made is that its name specifically has the prefix, 'ninja' in it.
|
||||
* This provides the detective role with information to play off of by ensuring that his
|
||||
* assumption that a space ninja is aboard the ship to be true when he find 20 of these in
|
||||
* the captain's back. Along with this, its throwforce is 10 instead of the 5 of the stamina
|
||||
* throwing star, meaning it'll do a little more damage than the stamina throwing star does as well.
|
||||
* Changes to this item need to be approved by all maintainers, so if you do change it, make sure
|
||||
* you go through the proper channels, lest you get permabanned. Do I make myself clear?
|
||||
*/
|
||||
/obj/item/throwing_star/stamina/ninja
|
||||
name = "ninja throwing star"
|
||||
throwforce = 10
|
||||
@@ -0,0 +1,39 @@
|
||||
/datum/action/item_action/ninjastatus
|
||||
check_flags = NONE
|
||||
name = "Status Readout"
|
||||
desc = "Gives a detailed readout about your current status."
|
||||
button_icon_state = "health"
|
||||
icon_icon = 'icons/obj/device.dmi'
|
||||
|
||||
/**
|
||||
* Proc called to put a status readout to the ninja in chat.
|
||||
*
|
||||
* Called put some information about the ninja's current status into chat.
|
||||
* This information used to be displayed constantly on the status tab screen
|
||||
* when the suit was on, but was turned into this as to remove the code from
|
||||
* human.dm
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjastatus()
|
||||
var/mob/living/carbon/human/ninja = affecting
|
||||
var/list/info_list = list()
|
||||
info_list += "<span class='info'>SpiderOS Status: [s_initialized ? "Initialized" : "Disabled"]</span>\n"
|
||||
info_list += "<span class='info'>Current Time: [station_time_timestamp()]</span>\n"
|
||||
//Ninja status
|
||||
info_list += "<span class='info'>Fingerprints: [md5(ninja.dna.uni_identity)]</span>\n"
|
||||
info_list += "<span class='info'>Unique Identity: [ninja.dna.unique_enzymes]</span>\n"
|
||||
info_list += "<span class='info'>Overall Status: [ninja.stat > 1 ? "dead" : "[ninja.health]% healthy"]</span>\n"
|
||||
info_list += "<span class='info'>Nutrition Status: [ninja.nutrition]</span>\n"
|
||||
info_list += "<span class='info'>Oxygen Loss: [ninja.getOxyLoss()]</span>\n"
|
||||
info_list += "<span class='info'>Toxin Levels: [ninja.getToxLoss()]</span>\n"
|
||||
info_list += "<span class='info'>Burn Severity: [ninja.getFireLoss()]</span>\n"
|
||||
info_list += "<span class='info'>Brute Trauma: [ninja.getBruteLoss()]</span>\n"
|
||||
info_list += "<span class='info'>Radiation Levels: [ninja.radiation] rad</span>\n"
|
||||
info_list += "<span class='info'>Body Temperature: [ninja.bodytemperature-T0C] degrees C ([ninja.bodytemperature*1.8-459.67] degrees F)</span>\n"
|
||||
|
||||
//Diseases
|
||||
if(length(ninja.diseases))
|
||||
info_list += "Viruses:"
|
||||
for(var/datum/disease/ninja_disease in ninja.diseases)
|
||||
info_list += "<span class='info'>* [ninja_disease.name], Type: [ninja_disease.spread_text], Stage: [ninja_disease.stage]/[ninja_disease.max_stages], Possible Cure: [ninja_disease.cure_text]</span>\n"
|
||||
|
||||
to_chat(ninja, "[info_list.Join()]")
|
||||
@@ -0,0 +1,46 @@
|
||||
/datum/action/item_action/ninja_stealth
|
||||
name = "Toggle Stealth"
|
||||
desc = "Toggles stealth mode on and off."
|
||||
button_icon_state = "ninja_cloak"
|
||||
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
|
||||
|
||||
/**
|
||||
* Proc called to toggle ninja stealth.
|
||||
*
|
||||
* Proc called to toggle whether or not the ninja is in stealth mode.
|
||||
* If cancelling, calls a separate proc in case something else needs to quickly cancel stealth.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/toggle_stealth()
|
||||
var/mob/living/carbon/human/ninja = affecting
|
||||
if(!ninja)
|
||||
return
|
||||
if(stealth)
|
||||
cancel_stealth()
|
||||
else
|
||||
if(cell.charge <= 0)
|
||||
to_chat(ninja, "<span class='warning'>You don't have enough power to enable Stealth!</span>")
|
||||
return
|
||||
stealth = !stealth
|
||||
animate(ninja, alpha = 20,time = 12)
|
||||
ninja.visible_message("<span class='warning'>[ninja.name] vanishes into thin air!</span>", \
|
||||
"<span class='notice'>You are now mostly invisible to normal detection.</span>")
|
||||
|
||||
/**
|
||||
* Proc called to cancel stealth.
|
||||
*
|
||||
* Called to cancel the stealth effect if it is ongoing.
|
||||
* Does nothing otherwise.
|
||||
* Arguments:
|
||||
* * Returns false if either the ninja no longer exists or is already visible, returns true if we successfully made the ninja visible.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/cancel_stealth()
|
||||
var/mob/living/carbon/human/ninja = affecting
|
||||
if(!ninja)
|
||||
return FALSE
|
||||
if(stealth)
|
||||
stealth = !stealth
|
||||
animate(ninja, alpha = 255, time = 12)
|
||||
ninja.visible_message("<span class='warning'>[ninja.name] appears from thin air!</span>", \
|
||||
"<span class='notice'>You are now visible.</span>")
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -0,0 +1,125 @@
|
||||
#define NINJA_LOCK_PHASE 1
|
||||
#define NINJA_ICON_GENERATE_PHASE 3
|
||||
#define NINJA_COMPLETE_PHASE 6
|
||||
#define NINJA_DEINIT_LOGOFF_PHASE 1
|
||||
#define NINJA_DEINIT_STEALTH_PHASE 5
|
||||
|
||||
GLOBAL_LIST_INIT(ninja_initialize_messages, list(
|
||||
"Now initializing...",
|
||||
"Securing external locking mechanism...\nNeural-net established.",
|
||||
"Extending neural-net interface...\nNow monitoring brain wave pattern...",
|
||||
"Linking neural-net interface...\nPattern <b class='nicegreen'>GREEN</b>, continuing operation.",
|
||||
"VOID-shift device status: <B>ONLINE</B>.\nCLOAK-tech device status: <B>ONLINE</B>.",
|
||||
"Primary system status: <B>ONLINE</B>.\nBackup system status: <B>ONLINE</B>.\nCurrent energy capacity: ",
|
||||
"All systems operational. Welcome to <B>SpiderOS</B>, "
|
||||
))
|
||||
|
||||
GLOBAL_LIST_INIT(ninja_deinitialize_messages, list(
|
||||
"Now de-initializing...",
|
||||
"Shutting down <B>SpiderOS</B>.",
|
||||
"Primary system status: <B>OFFLINE</B>.\nBackup system status: <B>OFFLINE</B>.",
|
||||
"VOID-shift device status: <B>OFFLINE</B>.\nCLOAK-tech device status: <B>OFFLINE</B>.",
|
||||
"Disconnecting neural-net interface...<b class='nicegreen'>Success</b>.",
|
||||
"Disengaging neural-net interface... <b class='nicegreen'>Success</b>.",
|
||||
"Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: <B>FINISHED</B>."
|
||||
))
|
||||
|
||||
/datum/action/item_action/initialize_ninja_suit
|
||||
name = "Toggle Ninja Suit"
|
||||
|
||||
/**
|
||||
* Toggles the ninja suit on/off
|
||||
*
|
||||
* Attempts to initialize or deinitialize the ninja suit
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/toggle_on_off()
|
||||
. = TRUE
|
||||
if(s_busy)
|
||||
to_chat(loc, "<span class='warning'>ERROR</span>: You cannot use this function at this time.")
|
||||
return FALSE
|
||||
s_busy = TRUE
|
||||
if(s_initialized)
|
||||
deinitialize()
|
||||
else
|
||||
ninitialize()
|
||||
|
||||
/**
|
||||
* Initializes the ninja suit
|
||||
*
|
||||
* Initializes the ninja suit through seven phases, each of which calls this proc with an incremented phase
|
||||
* Arguments:
|
||||
* * delay - The delay between each phase of initialization
|
||||
* * ninja - The human who is being affected by the suit
|
||||
* * phase - The phase of initialization
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize(delay = s_delay, mob/living/carbon/human/ninja = loc, phase = 0)
|
||||
if(!ninja || !ninja.mind)
|
||||
s_busy = FALSE
|
||||
return
|
||||
if (phase > NINJA_LOCK_PHASE && (ninja.stat == DEAD || ninja.health <= 0))
|
||||
to_chat(ninja, "<span class='danger'><B>FÄAL �Rr�R</B>: 344--93#�&&21 BR��N |/|/aV� PATT$RN <B>RED</B>\nA-A-aB�rT�NG...</span>")
|
||||
unlock_suit(ninja)
|
||||
s_busy = FALSE
|
||||
return
|
||||
|
||||
var/message = GLOB.ninja_initialize_messages[phase + 1]
|
||||
switch(phase)
|
||||
if (NINJA_LOCK_PHASE)
|
||||
if(!lock_suit(ninja))//To lock the suit onto wearer.
|
||||
s_busy = FALSE
|
||||
return
|
||||
if (NINJA_ICON_GENERATE_PHASE)
|
||||
lockIcons(ninja)//Check for icons.
|
||||
ninja.regenerate_icons()
|
||||
if (NINJA_COMPLETE_PHASE - 1)
|
||||
message += "<B>[DisplayEnergy(cell.charge)]</B>."
|
||||
if (NINJA_COMPLETE_PHASE)
|
||||
message += "[ninja.real_name]."
|
||||
s_initialized = TRUE
|
||||
s_busy = FALSE
|
||||
|
||||
to_chat(ninja, "<span class='notice'>[message]</span>")
|
||||
playsound(ninja, 'sound/effects/sparks1.ogg', 10, TRUE)
|
||||
|
||||
if (phase < NINJA_COMPLETE_PHASE)
|
||||
addtimer(CALLBACK(src, .proc/ninitialize, delay, ninja, phase + 1), delay)
|
||||
|
||||
/**
|
||||
* Deinitializes the ninja suit
|
||||
*
|
||||
* Deinitializes the ninja suit through eight phases, each of which calls this proc with an incremented phase
|
||||
* Arguments:
|
||||
* * delay - The delay between each phase of deinitialization
|
||||
* * ninja - The human who is being affected by the suit
|
||||
* * phase - The phase of deinitialization
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/deinitialize(delay = s_delay, mob/living/carbon/human/ninja = affecting == loc ? affecting : null, phase = 0)
|
||||
if (!ninja || !ninja.mind)
|
||||
s_busy = FALSE
|
||||
return
|
||||
if (phase == 0 && alert("Are you certain you wish to remove the suit? This will take time and remove all abilities.",,"Yes","No") == "No")
|
||||
s_busy = FALSE
|
||||
return
|
||||
|
||||
var/message = GLOB.ninja_deinitialize_messages[phase + 1]
|
||||
switch(phase)
|
||||
if(NINJA_DEINIT_LOGOFF_PHASE)
|
||||
message = "Logging off, [ninja.real_name]. " + message
|
||||
if(NINJA_DEINIT_STEALTH_PHASE)
|
||||
cancel_stealth()
|
||||
to_chat(ninja, "<span class='notice'>[message]</span>")
|
||||
playsound(ninja, 'sound/items/deconstruct.ogg', 10, TRUE)
|
||||
|
||||
if (phase < NINJA_COMPLETE_PHASE)
|
||||
addtimer(CALLBACK(src, .proc/deinitialize, delay, ninja, phase + 1), delay)
|
||||
else
|
||||
unlock_suit(ninja)
|
||||
ninja.regenerate_icons()
|
||||
s_initialized = FALSE
|
||||
s_busy = FALSE
|
||||
|
||||
#undef NINJA_LOCK_PHASE
|
||||
#undef NINJA_ICON_GENERATE_PHASE
|
||||
#undef NINJA_COMPLETE_PHASE
|
||||
#undef NINJA_DEINIT_LOGOFF_PHASE
|
||||
#undef NINJA_DEINIT_STEALTH_PHASE
|
||||
@@ -0,0 +1,47 @@
|
||||
/datum/action/item_action/ninja_sword_recall
|
||||
name = "Recall Energy Katana (Variable Cost)"
|
||||
desc = "Teleports the Energy Katana linked to this suit to its wearer, cost based on distance."
|
||||
button_icon_state = "energy_katana"
|
||||
icon_icon = 'icons/obj/items_and_weapons.dmi'
|
||||
|
||||
/**
|
||||
* Proc called to recall the ninja's sword.
|
||||
*
|
||||
* Called to summon the ninja's katana back to them
|
||||
* If the katana can see the ninja, it will throw itself towards them.
|
||||
* If not, the katana will teleport itself to the ninja.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninja_sword_recall()
|
||||
var/mob/living/carbon/human/ninja = affecting
|
||||
var/cost = 0
|
||||
var/inview = TRUE
|
||||
|
||||
if(!energyKatana)
|
||||
to_chat(ninja, "<span class='warning'>Could not locate Energy Katana!</span>")
|
||||
return
|
||||
|
||||
if(energyKatana in ninja)
|
||||
return
|
||||
|
||||
var/distance = get_dist(ninja,energyKatana)
|
||||
|
||||
if(!(energyKatana in view(ninja)))
|
||||
cost = distance //Actual cost is cost x 10, so 5 turfs is 50 cost.
|
||||
inview = FALSE
|
||||
|
||||
if(!ninjacost(cost))
|
||||
if(iscarbon(energyKatana.loc))
|
||||
var/mob/living/carbon/sword_holder = energyKatana.loc
|
||||
sword_holder.transferItemToLoc(energyKatana, get_turf(energyKatana), TRUE)
|
||||
|
||||
else
|
||||
energyKatana.forceMove(get_turf(energyKatana))
|
||||
|
||||
if(inview) //If we can see the katana, throw it towards ourselves, damaging people as we go.
|
||||
energyKatana.spark_system.start()
|
||||
playsound(ninja, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
ninja.visible_message("<span class='danger'>\the [energyKatana] flies towards [ninja]!</span>","<span class='warning'>You hold out your hand and \the [energyKatana] flies towards you!</span>")
|
||||
energyKatana.throw_at(ninja, distance+1, energyKatana.throw_speed, ninja)
|
||||
|
||||
else //Else just TP it to us.
|
||||
energyKatana.returnToOwner(ninja, 1)
|
||||
@@ -1,3 +1,12 @@
|
||||
/**
|
||||
* # Ninja Shoes
|
||||
*
|
||||
* Space ninja's shoes. Gives him armor on his feet.
|
||||
*
|
||||
* Space ninja's ninja shoes. How mousey. Gives him slip protection and protection against attacks.
|
||||
* Also are temperature resistant.
|
||||
*
|
||||
*/
|
||||
/obj/item/clothing/shoes/space_ninja
|
||||
name = "ninja shoes"
|
||||
desc = "A pair of running shoes. Excellent for running and even better for smashing skulls."
|
||||
@@ -5,8 +14,7 @@
|
||||
permeability_coefficient = 0.01
|
||||
clothing_flags = NOSLIP
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
armor = list("melee" = 60, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 100, "acid" = 100)
|
||||
strip_delay = 120
|
||||
armor = list(MELEE = 40, BULLET = 30, LASER = 20,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 100, ACID = 100)
|
||||
cold_protection = FEET
|
||||
min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT
|
||||
heat_protection = FEET
|
||||
|
||||
+156
-111
@@ -1,16 +1,13 @@
|
||||
|
||||
/*
|
||||
|
||||
Contents:
|
||||
- The Ninja Space Suit
|
||||
- Ninja Space Suit Procs
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// /obj/item/clothing/suit/space/space_ninja
|
||||
|
||||
|
||||
/**
|
||||
* # Ninja Suit
|
||||
*
|
||||
* Space ninja's suit. Provides him with most of his powers.
|
||||
*
|
||||
* Space ninja's suit. Gives space ninja all his iconic powers, which are mostly kept in
|
||||
* the folder ninja_equipment_actions. Has a lot of unique stuff going on, so make sure to check
|
||||
* the variables. Check suit_attackby to see radium interaction, disk copying, and cell replacement.
|
||||
*
|
||||
*/
|
||||
/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."
|
||||
@@ -19,12 +16,11 @@ Contents:
|
||||
allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/stock_parts/cell)
|
||||
slowdown = 1
|
||||
resistance_flags = LAVA_PROOF | ACID_PROOF
|
||||
armor = list("melee" = 60, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 100, "acid" = 100)
|
||||
strip_delay = 12
|
||||
armor = list(MELEE = 40, BULLET = 30, LASER = 20,ENERGY = 30, BOMB = 30, BIO = 30, RAD = 30, FIRE = 100, ACID = 100)
|
||||
|
||||
actions_types = list(/datum/action/item_action/initialize_ninja_suit, /datum/action/item_action/ninjasmoke, /datum/action/item_action/ninjaboost, /datum/action/item_action/ninjapulse, /datum/action/item_action/ninjastar, /datum/action/item_action/ninja_sword_recall, /datum/action/item_action/ninja_stealth, /datum/action/item_action/toggle_glove)
|
||||
actions_types = list(/datum/action/item_action/initialize_ninja_suit, /datum/action/item_action/ninjastatus, /datum/action/item_action/ninjaboost, /datum/action/item_action/ninjapulse, /datum/action/item_action/ninjastar, /datum/action/item_action/ninjanet, /datum/action/item_action/ninja_sword_recall, /datum/action/item_action/ninja_stealth)
|
||||
|
||||
//Important parts of the suit.
|
||||
///The person wearing the suit
|
||||
var/mob/living/carbon/human/affecting = null
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/datum/effect_system/spark_spread/spark_system
|
||||
@@ -37,28 +33,36 @@ Contents:
|
||||
var/obj/item/clothing/shoes/space_ninja/n_shoes
|
||||
var/obj/item/clothing/gloves/space_ninja/n_gloves
|
||||
|
||||
//Main function variables.
|
||||
var/s_initialized = 0//Suit starts off.
|
||||
var/s_coold = 0//If the suit is on cooldown. Can be used to attach different cooldowns to abilities. Ticks down every second based on suit ntick().
|
||||
var/s_cost = 5//Base energy cost each ntick.
|
||||
var/s_acost = 25//Additional cost for additional powers active.
|
||||
var/s_delay = 40//How fast the suit does certain things, lower is faster. Can be overridden in specific procs. Also determines adverse probability.
|
||||
var/a_transfer = 20//How much radium is used per adrenaline boost.
|
||||
var/a_maxamount = 7//Maximum number of adrenaline boosts.
|
||||
var/s_maxamount = 20//Maximum number of smoke bombs.
|
||||
///The space ninja's mask.
|
||||
var/obj/item/clothing/mask/gas/space_ninja/n_mask
|
||||
|
||||
//Support function variables.
|
||||
///Whether or not the suit is currently booted up. Starts off.
|
||||
var/s_initialized = FALSE//Suit starts off.
|
||||
///The suit's current cooldown. If not 0, blocks usage of most abilities, and decrements its value by 1 every process
|
||||
var/s_coold = 0
|
||||
///How much energy the suit expends in a single process
|
||||
var/s_cost = 1
|
||||
///Additional energy cost for cloaking per process
|
||||
var/s_acost = 4
|
||||
///How fast the suit is at certain actions, like draining power from things
|
||||
var/s_delay = 40
|
||||
///Units of radium required to refill the adrenaline boost
|
||||
var/a_transfer = 20//How much radium is required to refill the adrenaline boost.
|
||||
///Whether or not the suit is currently in stealth mode.
|
||||
var/stealth = FALSE//Stealth off.
|
||||
var/stealth_cooldown = 0
|
||||
var/s_busy = FALSE//Is the suit busy with a process? Like AI hacking. Used for safety functions.
|
||||
|
||||
//Ability function variables.
|
||||
var/s_bombs = 10//Number of smoke bombs.
|
||||
var/a_boost = 3//Number of adrenaline boosters.
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/get_cell()
|
||||
return cell
|
||||
///Whether or not the wearer is in the middle of an action, like hacking.
|
||||
var/s_busy = FALSE
|
||||
///Whether or not the adrenaline boost ability is available
|
||||
var/a_boost = TRUE
|
||||
/obj/item/clothing/suit/space/space_ninja/examine(mob/user)
|
||||
. = ..()
|
||||
if(!s_initialized)
|
||||
return
|
||||
if(!user == affecting)
|
||||
return
|
||||
. += "All systems operational. Current energy capacity: <B>[DisplayEnergy(cell.charge)]</B>.\n"+\
|
||||
"The CLOAK-tech device is <B>[stealth?"active":"inactive"]</B>.\n"+\
|
||||
"[a_boost?"An adrenaline boost is available to use.":"There is no adrenaline boost available. Try refilling the suit with 20 units of radium."]"
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/Initialize()
|
||||
. = ..()
|
||||
@@ -82,106 +86,147 @@ Contents:
|
||||
qdel(n_hood)
|
||||
qdel(n_gloves)
|
||||
qdel(n_shoes)
|
||||
qdel(src)
|
||||
/obj/item/clothing/suit/space/space_ninja/ui_action_click(mob/user, action)
|
||||
if(IS_NINJA_SUIT_INITIALIZATION(action))
|
||||
toggle_on_off()
|
||||
return TRUE
|
||||
if(!s_initialized)
|
||||
to_chat(user, "<span class='warning'><b>ERROR</b>: suit offline. Please activate suit.</span>")
|
||||
return FALSE
|
||||
if(s_coold != 0)
|
||||
to_chat(user, "<span class='warning'><b>ERROR</b>: suit is on cooldown.</span>")
|
||||
return FALSE
|
||||
if(IS_NINJA_SUIT_STATUS(action))
|
||||
ninjastatus()
|
||||
return TRUE
|
||||
if(IS_NINJA_SUIT_BOOST(action))
|
||||
ninjaboost()
|
||||
return TRUE
|
||||
if(IS_NINJA_SUIT_EMP(action))
|
||||
ninjapulse()
|
||||
return TRUE
|
||||
if(IS_NINJA_SUIT_STAR_CREATION(action))
|
||||
ninjastar()
|
||||
return TRUE
|
||||
if(IS_NINJA_SUIT_NET_CREATION(action))
|
||||
ninjanet()
|
||||
return TRUE
|
||||
if(IS_NINJA_SUIT_SWORD_RECALL(action))
|
||||
ninja_sword_recall()
|
||||
return TRUE
|
||||
if(IS_NINJA_SUIT_STEALTH(action))
|
||||
toggle_stealth()
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/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(stealth)
|
||||
cancel_stealth()
|
||||
s_coold = 5
|
||||
|
||||
/**
|
||||
* Proc for changing the suit's appearance upon locking.
|
||||
*
|
||||
* Proc for when space ninja's suit locks. If the user selects Original, gives it glowing lights, along with having an alternate sprite for female body types.
|
||||
* Yes, we do have nipLEDs, how could you tell?
|
||||
* If the user selects New Age, it applies new sprites to all the gear.
|
||||
* Arguments:
|
||||
* * ninja - The person wearing the suit.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/lockIcons(mob/living/carbon/human/ninja)
|
||||
var/design_choice = alert(ninja, "Please choose your desired suit design.",,"Original","New Age")
|
||||
switch(design_choice)
|
||||
if("Original")
|
||||
icon_state = ninja.body_type == "female" ? "s-ninjanf" : "s-ninjan"
|
||||
ninja.gloves.icon_state = "s-ninjan"
|
||||
ninja.gloves.inhand_icon_state = "s-ninjan"
|
||||
if("New Age")
|
||||
icon_state ="ninja_new"
|
||||
n_hood.icon_state = "ninja_newcowl"
|
||||
n_gloves.icon_state = "ninja_new"
|
||||
if(n_mask)
|
||||
n_mask.icon_state = "ninja_new"
|
||||
|
||||
|
||||
//Randomizes suit parameters.
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/randomize_param()
|
||||
s_cost = rand(1,20)
|
||||
s_acost = rand(20,100)
|
||||
s_delay = rand(10,100)
|
||||
s_bombs = rand(5,20)
|
||||
a_boost = rand(1,7)
|
||||
|
||||
|
||||
//This proc prevents the suit from being taken off.
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/human/H)
|
||||
if(!istype(H))
|
||||
/**
|
||||
* Proc called to lock the important gear pieces onto space ninja's body.
|
||||
*
|
||||
* Called during the suit startup to lock all gear pieces onto space ninja.
|
||||
* Terminates if a gear piece is not being worn. Also gives the ninja the inability to use firearms.
|
||||
* If the person in the suit isn't a ninja when this is called, this proc just gibs them instead.
|
||||
* Arguments:
|
||||
* * ninja - The person wearing the suit.
|
||||
* * Returns false if the locking fails due to lack of all suit parts, and true if it succeeds.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/human/ninja)
|
||||
if(!istype(ninja))
|
||||
return FALSE
|
||||
if(!is_ninja(H))
|
||||
to_chat(H, "<span class='danger'><B>fÄTaL ÈÈRRoR</B>: 382200-*#00CÖDE <B>RED</B>\nUNAUHORIZED USÈ DETÈCeD\nCoMMÈNCING SUB-R0UIN3 13...\nTÈRMInATING U-U-USÈR...</span>")
|
||||
H.gib()
|
||||
if(!IS_SPACE_NINJA(ninja))
|
||||
to_chat(ninja, "<span class='danger'><B>fÄTaL ÈÈRRoR</B>: 382200-*#00CÖDE <B>RED</B>\nUNAUHORIZED USÈ DETÈCeD\nCoMMÈNCING SUB-R0UIN3 13...\nTÈRMInATING U-U-USÈR...</span>")
|
||||
ninja.gib()
|
||||
return FALSE
|
||||
if(!istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja))
|
||||
to_chat(H, "<span class='userdanger'>ERROR</span>: 100113 UNABLE TO LOCATE HEAD GEAR\nABORTING...")
|
||||
if(!istype(ninja.head, /obj/item/clothing/head/helmet/space/space_ninja))
|
||||
to_chat(ninja, "<span class='userdanger'>ERROR</span>: 100113 UNABLE TO LOCATE HEAD GEAR\nABORTING...")
|
||||
return FALSE
|
||||
if(!istype(H.shoes, /obj/item/clothing/shoes/space_ninja))
|
||||
to_chat(H, "<span class='userdanger'>ERROR</span>: 122011 UNABLE TO LOCATE FOOT GEAR\nABORTING...")
|
||||
if(!istype(ninja.shoes, /obj/item/clothing/shoes/space_ninja))
|
||||
to_chat(ninja, "<span class='userdanger'>ERROR</span>: 122011 UNABLE TO LOCATE FOOT GEAR\nABORTING...")
|
||||
return FALSE
|
||||
if(!istype(H.gloves, /obj/item/clothing/gloves/space_ninja))
|
||||
to_chat(H, "<span class='userdanger'>ERROR</span>: 110223 UNABLE TO LOCATE HAND GEAR\nABORTING...")
|
||||
if(!istype(ninja.gloves, /obj/item/clothing/gloves/space_ninja))
|
||||
to_chat(ninja, "<span class='userdanger'>ERROR</span>: 110223 UNABLE TO LOCATE HAND GEAR\nABORTING...")
|
||||
return FALSE
|
||||
affecting = H
|
||||
affecting = ninja
|
||||
ADD_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT) //colons make me go all |=
|
||||
slowdown = 0
|
||||
n_hood = H.head
|
||||
n_hood = ninja.head
|
||||
ADD_TRAIT(n_hood, TRAIT_NODROP, NINJA_SUIT_TRAIT)
|
||||
n_shoes = H.shoes
|
||||
n_shoes = ninja.shoes
|
||||
ADD_TRAIT(n_shoes, TRAIT_NODROP, NINJA_SUIT_TRAIT)
|
||||
n_shoes.slowdown--
|
||||
n_gloves = H.gloves
|
||||
n_gloves = ninja.gloves
|
||||
ADD_TRAIT(n_gloves, TRAIT_NODROP, NINJA_SUIT_TRAIT)
|
||||
n_mask = ninja.wear_mask
|
||||
|
||||
ADD_TRAIT(ninja, TRAIT_NOGUNS, NINJA_SUIT_TRAIT)
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/lockIcons(mob/living/carbon/human/H)
|
||||
icon_state = H.dna.features["body_model"] == FEMALE ? "s-ninjanf" : "s-ninjan"
|
||||
H.gloves.icon_state = "s-ninjan"
|
||||
H.gloves.item_state = "s-ninjan"
|
||||
|
||||
|
||||
//This proc allows the suit to be taken off.
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/unlock_suit()
|
||||
/**
|
||||
* Proc called to unlock all the gear off space ninja's body.
|
||||
*
|
||||
* Proc which is essentially the opposite of lock_suit. Lets you take off all the suit parts.
|
||||
* Also gets rid of the objection to using firearms from the wearer.
|
||||
* Arguments:
|
||||
* * ninja - The person wearing the suit.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/unlock_suit(mob/living/carbon/human/ninja)
|
||||
affecting = null
|
||||
REMOVE_TRAIT(src, TRAIT_NODROP, NINJA_SUIT_TRAIT)
|
||||
slowdown = 1
|
||||
icon_state = "s-ninja"
|
||||
if(n_hood)//Should be attached, might not be attached.
|
||||
REMOVE_TRAIT(n_hood, TRAIT_NODROP, NINJA_SUIT_TRAIT)
|
||||
n_hood.icon_state = "s-ninja"
|
||||
if(n_shoes)
|
||||
REMOVE_TRAIT(n_shoes, TRAIT_NODROP, NINJA_SUIT_TRAIT)
|
||||
n_shoes.slowdown++
|
||||
if(n_gloves)
|
||||
n_gloves.icon_state = "s-ninja"
|
||||
n_gloves.item_state = "s-ninja"
|
||||
n_gloves.icon_state = "black"
|
||||
REMOVE_TRAIT(n_gloves, TRAIT_NODROP, NINJA_SUIT_TRAIT)
|
||||
n_gloves.candrain=0
|
||||
n_gloves.draining=0
|
||||
n_gloves.candrain = FALSE
|
||||
n_gloves.draining = FALSE
|
||||
|
||||
REMOVE_TRAIT(ninja, TRAIT_NOGUNS, NINJA_SUIT_TRAIT)
|
||||
if(n_mask)
|
||||
n_mask.icon_state = "s-ninja"
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/examine(mob/user)
|
||||
. = ..()
|
||||
if(s_initialized && user == affecting)
|
||||
. += "All systems operational. Current energy capacity: <B>[DisplayEnergy(cell.charge)]</B>.\n\
|
||||
The CLOAK-tech device is <B>[stealth?"active":"inactive"]</B>.\n\
|
||||
There are <B>[s_bombs]</B> smoke bomb\s remaining.\n\
|
||||
There are <B>[a_boost]</B> adrenaline booster\s remaining."
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/ui_action_click(mob/user, action)
|
||||
if(istype(action, /datum/action/item_action/initialize_ninja_suit))
|
||||
toggle_on_off()
|
||||
return TRUE
|
||||
if(!s_initialized)
|
||||
to_chat(user, "<span class='warning'><b>ERROR</b>: suit offline. Please activate suit.</span>")
|
||||
return FALSE
|
||||
if(istype(action, /datum/action/item_action/ninjasmoke))
|
||||
ninjasmoke()
|
||||
return TRUE
|
||||
if(istype(action, /datum/action/item_action/ninjaboost))
|
||||
ninjaboost()
|
||||
return TRUE
|
||||
if(istype(action, /datum/action/item_action/ninjapulse))
|
||||
ninjapulse()
|
||||
return TRUE
|
||||
if(istype(action, /datum/action/item_action/ninjastar))
|
||||
ninjastar()
|
||||
return TRUE
|
||||
if(istype(action, /datum/action/item_action/ninja_sword_recall))
|
||||
ninja_sword_recall()
|
||||
return TRUE
|
||||
if(istype(action, /datum/action/item_action/ninja_stealth))
|
||||
stealth()
|
||||
return TRUE
|
||||
if(istype(action, /datum/action/item_action/toggle_glove))
|
||||
n_gloves.toggledrain()
|
||||
return TRUE
|
||||
return FALSE
|
||||
/**
|
||||
* Proc used to delete all the attachments and itself.
|
||||
*
|
||||
* Can be called to entire rid of the suit pieces and the suit itself.
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/terminate()
|
||||
QDEL_NULL(n_hood)
|
||||
QDEL_NULL(n_gloves)
|
||||
QDEL_NULL(n_shoes)
|
||||
QDEL_NULL(src)
|
||||
|
||||
@@ -1,51 +1,43 @@
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/U, params)
|
||||
if(U!=affecting)//Safety, in case you try doing this without wearing the suit/being the person with the suit.
|
||||
/obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/ninja, params)
|
||||
if(ninja!=affecting)//Safety, in case you try doing this without wearing the suit/being the person with the suit.
|
||||
return ..()
|
||||
|
||||
if(istype(I, /obj/item/reagent_containers/glass))//If it's a glass beaker.
|
||||
if(I.reagents.has_reagent(/datum/reagent/radium, a_transfer) && a_boost < a_maxamount)
|
||||
I.reagents.remove_reagent(/datum/reagent/radium, a_transfer)
|
||||
a_boost++;
|
||||
to_chat(U, "<span class='notice'>There are now [a_boost] adrenaline boosts remaining.</span>")
|
||||
return
|
||||
if(I.reagents.has_reagent(/datum/reagent/smoke_powder, a_transfer) && s_bombs < s_maxamount)
|
||||
I.reagents.remove_reagent(/datum/reagent/smoke_powder, a_transfer)
|
||||
s_bombs++;
|
||||
to_chat(U, "<span class='notice'>There are now [s_bombs] smoke bombs remaining.</span>")
|
||||
return
|
||||
if(istype(I, /obj/item/reagent_containers/glass) && I.reagents.has_reagent(/datum/reagent/uranium/radium, a_transfer) && a_boost != TRUE)//If it's a glass beaker, and what we're transferring is radium.
|
||||
I.reagents.remove_reagent(/datum/reagent/uranium/radium, a_transfer)
|
||||
a_boost = TRUE;
|
||||
to_chat(ninja, "<span class='notice'>The suit's adrenaline boost is now reloaded.</span>")
|
||||
return
|
||||
|
||||
|
||||
else if(istype(I, /obj/item/stock_parts/cell))
|
||||
var/obj/item/stock_parts/cell/CELL = I
|
||||
if(CELL.maxcharge > cell.maxcharge && n_gloves && n_gloves.candrain)
|
||||
to_chat(U, "<span class='notice'>Higher maximum capacity detected.\nUpgrading...</span>")
|
||||
if (n_gloves && n_gloves.candrain && do_after(U,s_delay, target = src))
|
||||
U.transferItemToLoc(CELL, src)
|
||||
to_chat(ninja, "<span class='notice'>Higher maximum capacity detected.\nUpgrading...</span>")
|
||||
if (n_gloves?.candrain && do_after(ninja,s_delay, target = src))
|
||||
ninja.transferItemToLoc(CELL, src)
|
||||
CELL.charge = min(CELL.charge+cell.charge, CELL.maxcharge)
|
||||
var/obj/item/stock_parts/cell/old_cell = cell
|
||||
old_cell.charge = 0
|
||||
U.put_in_hands(old_cell)
|
||||
old_cell.add_fingerprint(U)
|
||||
ninja.put_in_hands(old_cell)
|
||||
old_cell.add_fingerprint(ninja)
|
||||
old_cell.corrupt()
|
||||
old_cell.update_icon()
|
||||
cell = CELL
|
||||
to_chat(U, "<span class='notice'>Upgrade complete. Maximum capacity: <b>[round(cell.maxcharge/100)]</b>%</span>")
|
||||
to_chat(ninja, "<span class='notice'>Upgrade complete. Maximum capacity: <b>[round(cell.maxcharge/100)]</b>%</span>")
|
||||
else
|
||||
to_chat(U, "<span class='danger'>Procedure interrupted. Protocol terminated.</span>")
|
||||
to_chat(ninja, "<span class='danger'>Procedure interrupted. Protocol terminated.</span>")
|
||||
return
|
||||
|
||||
else if(istype(I, /obj/item/disk/tech_disk))//If it's a data disk, we want to copy the research on to the suit.
|
||||
var/obj/item/disk/tech_disk/TD = I
|
||||
var/has_research = 0
|
||||
if(has_research)//If it has something on it.
|
||||
to_chat(U, "Research information detected, processing...")
|
||||
if(do_after(U,s_delay, target = src))
|
||||
to_chat(ninja, "Research information detected, processing...")
|
||||
if(do_after(ninja,s_delay, target = src))
|
||||
TD.stored_research.copy_research_to(stored_research)
|
||||
to_chat(U, "<span class='notice'>Data analyzed and updated. Disk erased.</span>")
|
||||
to_chat(ninja, "<span class='notice'>Data analyzed and updated. Disk erased.</span>")
|
||||
else
|
||||
to_chat(U, "<span class='userdanger'>ERROR</span>: Procedure interrupted. Process terminated.")
|
||||
to_chat(ninja, "<span class='userdanger'>ERROR</span>: Procedure interrupted. Process terminated.")
|
||||
else
|
||||
to_chat(U, "<span class='notice'>No research information detected.</span>")
|
||||
return
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/toggle_on_off()
|
||||
if(s_busy)
|
||||
to_chat(loc, "<span class='userdanger'>ERROR</span>: You cannot use this function at this time.")
|
||||
return FALSE
|
||||
if(s_initialized)
|
||||
deinitialize()
|
||||
else
|
||||
ninitialize()
|
||||
. = TRUE
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize(delay = s_delay, mob/living/carbon/human/U = loc)
|
||||
if(!U.mind)
|
||||
return //Not sure how this could happen.
|
||||
s_busy = TRUE
|
||||
to_chat(U, "<span class='notice'>Now initializing...</span>")
|
||||
addtimer(CALLBACK(src, .proc/ninitialize_two, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_two(delay, mob/living/carbon/human/U)
|
||||
if(!lock_suit(U))//To lock the suit onto wearer.
|
||||
s_busy = FALSE
|
||||
return
|
||||
to_chat(U, "<span class='notice'>Securing external locking mechanism...\nNeural-net established.</span>")
|
||||
addtimer(CALLBACK(src, .proc/ninitialize_three, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_three(delay, mob/living/carbon/human/U)
|
||||
to_chat(U, "<span class='notice'>Extending neural-net interface...\nNow monitoring brain wave pattern...</span>")
|
||||
addtimer(CALLBACK(src, .proc/ninitialize_four, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_four(delay, mob/living/carbon/human/U)
|
||||
if(U.stat == DEAD|| U.health <= 0)
|
||||
to_chat(U, "<span class='danger'><B>FÄAL �Rr�R</B>: 344--93#�&&21 BR��N |/|/aV� PATT$RN <B>RED</B>\nA-A-aB�rT�NG...</span>")
|
||||
unlock_suit()
|
||||
s_busy = FALSE
|
||||
return
|
||||
lockIcons(U)//Check for icons.
|
||||
U.regenerate_icons()
|
||||
to_chat(U, "<span class='notice'>Linking neural-net interface...\nPattern</span>\green <B>GREEN</B><span class='notice'>, continuing operation.</span>")
|
||||
addtimer(CALLBACK(src, .proc/ninitialize_five, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_five(delay, mob/living/carbon/human/U)
|
||||
to_chat(U, "<span class='notice'>VOID-shift device status: <B>ONLINE</B>.\nCLOAK-tech device status: <B>ONLINE</B>.</span>")
|
||||
addtimer(CALLBACK(src, .proc/ninitialize_six, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_six(delay, mob/living/carbon/human/U)
|
||||
to_chat(U, "<span class='notice'>Primary system status: <B>ONLINE</B>.\nBackup system status: <B>ONLINE</B>.\nCurrent energy capacity: <B>[DisplayEnergy(cell.charge)]</B>.</span>")
|
||||
addtimer(CALLBACK(src, .proc/ninitialize_seven, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_seven(delay, mob/living/carbon/human/U)
|
||||
to_chat(U, "<span class='notice'>All systems operational. Welcome to <B>SpiderOS</B>, [U.real_name].</span>")
|
||||
s_initialized = TRUE
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
s_busy = FALSE
|
||||
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/deinitialize(delay = s_delay)
|
||||
if(affecting==loc)
|
||||
var/mob/living/carbon/human/U = affecting
|
||||
if(alert("Are you certain you wish to remove the suit? This will take time and remove all abilities.",,"Yes","No")=="No")
|
||||
return
|
||||
s_busy = TRUE
|
||||
addtimer(CALLBACK(src, .proc/deinitialize_two, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_two(delay, mob/living/carbon/human/U)
|
||||
to_chat(U, "<span class='notice'>Now de-initializing...</span>")
|
||||
addtimer(CALLBACK(src, .proc/deinitialize_three, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_three(delay, mob/living/carbon/human/U)
|
||||
to_chat(U, "<span class='notice'>Logging off, [U.real_name]. Shutting down <B>SpiderOS</B>.</span>")
|
||||
addtimer(CALLBACK(src, .proc/deinitialize_four, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_four(delay, mob/living/carbon/human/U)
|
||||
to_chat(U, "<span class='notice'>Primary system status: <B>OFFLINE</B>.\nBackup system status: <B>OFFLINE</B>.</span>")
|
||||
addtimer(CALLBACK(src, .proc/deinitialize_five, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_five(delay, mob/living/carbon/human/U)
|
||||
to_chat(U, "<span class='notice'>VOID-shift device status: <B>OFFLINE</B>.\nCLOAK-tech device status: <B>OFFLINE</B>.</span>")
|
||||
cancel_stealth()//Shutdowns stealth.
|
||||
addtimer(CALLBACK(src, .proc/deinitialize_six, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_six(delay, mob/living/carbon/human/U)
|
||||
to_chat(U, "<span class='notice'>Disconnecting neural-net interface...</span>\green<B>Success</B><span class='notice'>.</span>")
|
||||
addtimer(CALLBACK(src, .proc/deinitialize_seven, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_seven(delay, mob/living/carbon/human/U)
|
||||
to_chat(U, "<span class='notice'>Disengaging neural-net interface...</span>\green<B>Success</B><span class='notice'>.</span>")
|
||||
addtimer(CALLBACK(src, .proc/deinitialize_eight, delay, U), delay)
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/deinitialize_eight(delay, mob/living/carbon/human/U)
|
||||
to_chat(U, "<span class='notice'>Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: <B>FINISHED</B>.</span>")
|
||||
unlock_suit()
|
||||
U.regenerate_icons()
|
||||
s_initialized = FALSE
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
s_busy = FALSE
|
||||
@@ -1,17 +0,0 @@
|
||||
/obj/item/clothing/suit/space/space_ninja/process()
|
||||
if(!affecting || !s_initialized)
|
||||
return PROCESS_KILL
|
||||
|
||||
if(cell.charge > 0)
|
||||
if(s_coold)
|
||||
s_coold--//Checks for ability s_cooldown first.
|
||||
|
||||
cell.charge -= s_cost//s_cost is the default energy cost each tick, usually 5.
|
||||
if(stealth && stealth_cooldown <= world.time)//If stealth is active.
|
||||
cell.charge -= s_acost
|
||||
affecting.alpha = max(affecting.alpha - 10, 15)
|
||||
|
||||
else
|
||||
cell.charge = 0
|
||||
if(stealth)
|
||||
cancel_stealth()
|
||||
Reference in New Issue
Block a user