A restructure/removal/cleanup of Ninja Code

This commit is contained in:
Remie Richards
2015-03-09 20:43:56 +00:00
parent d525fd6a87
commit f6e4c1518d
42 changed files with 2048 additions and 2681 deletions

View File

@@ -426,21 +426,30 @@ datum/objective/download/proc/gen_amount_goal()
explanation_text = "Download [target_amount] research level\s."
return target_amount
datum/objective/download/check_completion()
datum/objective/download/check_completion()//NINJACODE
if(!ishuman(owner.current))
return 0
if(!owner.current || owner.current.stat == 2)
var/mob/living/carbon/human/H = owner.current
if(!H || H.stat == DEAD)
return 0
if(!(istype(owner.current:wear_suit, /obj/item/clothing/suit/space/space_ninja)&&owner.current:wear_suit:s_initialized))
if(!istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
return 0
var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit
if(!SN.s_initialized)
return 0
var/current_amount
var/obj/item/clothing/suit/space/space_ninja/S = owner.current:wear_suit
if(!S.stored_research.len)
if(!SN.stored_research.len)
return 0
else
for(var/datum/tech/current_data in S.stored_research)
if(current_data.level>1) current_amount+=(current_data.level-1)
if(current_amount<target_amount) return 0
for(var/datum/tech/current_data in SN.stored_research)
if(current_data.level)
current_amount += (current_data.level-1)
if(current_amount<target_amount)
return 0
return 1

View File

@@ -73,8 +73,11 @@
//Cameras can't track people wearing an agent card or a ninja hood.
if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
continue
if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && (H.head.flags & NODROP))
continue
//Generic variable who's existance is to blame on shitty old ninja code
if(istype(H.head, /obj/item/clothing/head))
var/obj/item/clothing/head/hat = H.head
if(hat.blockTracking)
continue
// Now, are they viewable by a camera? (This is last because it's the most intensive check)
if(!near_camera(M))
@@ -127,10 +130,12 @@
U << "Follow camera mode terminated."
U.cameraFollow = null
return
if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja) && (H.head.flags & NODROP))
U << "Follow camera mode terminated."
U.cameraFollow = null
return
if(istype(H.head, /obj/item/clothing/head))
var/obj/item/clothing/head/hat = H.head
if(hat.blockTracking)
U << "Follow camera mode terminated."
U.cameraFollow = null
return
if(H.digitalcamo)
U << "Follow camera mode terminated."
U.cameraFollow = null

View File

@@ -262,22 +262,6 @@
add_fingerprint(user)
//ninja sword garbage
if (src.density && istype(I, /obj/item/weapon/melee/energy/blade))
src.operating = -1
flick("[src.base_state]spark", src)
sleep(6)
desc += "<BR><span class='warning'>Its access panel is smoking slightly.</span>"
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src.loc)
spark_system.start()
playsound(src.loc, "sparks", 50, 1)
playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
visible_message("<span class='warning'> The glass door was sliced open by [user]!</span>")
open(2)
emagged = 1
return 1
if(istype(I, /obj/item/weapon/screwdriver))
if(src.density || src.operating)
user << "<span class='warning'>You need to open the door to access the maintenance panel.</span>"

View File

@@ -193,7 +193,7 @@
src.cancable = 1//so cables can be laid
new /obj/structure/lattice/catwalk(locate(src.x, src.y, src.z) )
/turf/proc/phase_damage_creatures(damage,mob/U = null)//>Ninja Code. Hurts and knocks out creatures on this turf
/turf/proc/phase_damage_creatures(damage,mob/U = null)//>Ninja Code. Hurts and knocks out creatures on this turf //NINJACODE
for(var/mob/living/M in src)
if(M==U)
continue//Will not harm U. Since null != M, can be excluded to kill everyone.

View File

@@ -327,7 +327,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
new_character.loc = get_turf(synd_spawn)
call(/datum/game_mode/proc/equip_syndicate)(new_character)
if("Space Ninja")
var/ninja_spawn[] = list()
var/list/ninja_spawn = list()
for(var/obj/effect/landmark/L in landmarks_list)
if(L.name=="carpspawn")
ninja_spawn += L

View File

@@ -76,6 +76,7 @@ BLIND // can't see anything
icon = 'icons/obj/clothing/hats.dmi'
body_parts_covered = HEAD
slot_flags = SLOT_HEAD
var/blockTracking = 0 //For AI tracking
//Mask
/obj/item/clothing/mask

View File

@@ -1,104 +0,0 @@
/*
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
*/
/obj/item/clothing/gloves/space_ninja
desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
name = "ninja gloves"
icon_state = "s-ninja"
item_state = "s-ninja"
siemens_coefficient = 0
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
strip_delay = 120
var/draining = 0
var/candrain = 0
var/mindrain = 200
var/maxdrain = 400
/*
This runs the gamut of what ninja gloves can do
The other option would be a dedicated ninja touch bullshit proc on everything
which would probably more efficient, but ninjas are pretty rare.
This was mostly introduced to keep ninja code from contaminating other code;
with this in place it would be easier to untangle the rest of it.
For the drain proc, see events/ninja.dm
*/
/obj/item/clothing/gloves/space_ninja/Touch(var/atom/A,var/proximity)
if(!candrain || draining) return 0
var/mob/living/carbon/human/H = loc
if(!istype(H)) return 0 // what
var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit
if(!istype(suit)) return 0
if(isturf(A)) return 0
if(!proximity) // todo: you could add ninja stars or computer hacking here
return 0
A.add_fingerprint(H)
// steal energy from powered things
if(istype(A,/mob/living/silicon/robot))
drain("CYBORG",A,suit)
return 1
if(istype(A,/obj/machinery/power/apc))
drain("APC",A,suit)
return 1
if(istype(A,/obj/structure/cable))
drain("WIRE",A,suit)
return 1
if(istype(A,/obj/structure/grille))
var/obj/structure/cable/C = locate() in A.loc
if(C)
drain("WIRE",C,suit)
return 1
if(istype(A,/obj/machinery/power/smes))
drain("SMES",A,suit)
return 1
if(istype(A,/obj/mecha))
drain("MECHA",A,suit)
return 1
if(istype(A,/obj/machinery/computer/rdconsole)) // download research
drain("RESEARCH",A,suit)
return 1
if(istype(A,/obj/machinery/r_n_d/server))
A.add_fingerprint(H)
var/obj/machinery/r_n_d/server/S = A
if(S.disabled)
return 1
if(S.shocked)
S.shock(H,50)
return 1
drain("RESEARCH",A,suit)
return 1
//do AI transfers
if(istype(A,/mob/living/silicon/ai))
suit.NAI.transfer_ai("AICORE", "AICARD", A, H)
return 1
if(istype(A,/obj/structure/AIcore/deactivated))
suit.NAI.transfer_ai("INACTIVE","AICARD",A, H)
return 1
if(istype(A,/obj/machinery/computer/aifixer))
suit.NAI.transfer_ai("AIFIXER","AICARD",A, H)
return 1

View File

@@ -219,35 +219,6 @@
vchange = !vchange
user << "<span class='notice'>The voice changer is now [vchange ? "on" : "off"]!</span>"
/obj/item/clothing/mask/gas/voice/space_ninja
name = "ninja mask"
desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement."
icon_state = "s-ninja"
item_state = "s-ninja_mask"
vchange = 1
strip_delay = 120
/obj/item/clothing/mask/gas/voice/space_ninja/speechModification(message)
if(voice == "Unknown")
if(copytext(message, 1, 2) != "*")
var/list/temp_message = text2list(message, " ")
var/list/pick_list = list()
for(var/i = 1, i <= temp_message.len, i++)
pick_list += i
for(var/i=1, i <= abs(temp_message.len/3), i++)
var/H = pick(pick_list)
if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
temp_message[H] = ninjaspeak(temp_message[H])
pick_list -= H
message = list2text(temp_message, " ")
message = replacetext(message, "o", "?")
message = replacetext(message, "p", "?")
message = replacetext(message, "l", "?")
message = replacetext(message, "s", "?")
message = replacetext(message, "u", "?")
message = replacetext(message, "b", "?")
return message
/obj/item/clothing/mask/gas/clown_hat
name = "clown wig and mask"

View File

@@ -1,65 +0,0 @@
/obj/item/clothing/head/helmet/space/space_ninja
desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear."
name = "ninja hood"
icon_state = "s-ninja"
item_state = "s-ninja_mask"
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 25)
strip_delay = 12
unacidable = 1
/obj/item/clothing/suit/space/space_ninja
name = "ninja suit"
desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
icon_state = "s-ninja"
item_state = "s-ninja_suit"
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/internals,/obj/item/weapon/stock_parts/cell)
slowdown = 0
unacidable = 1
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
strip_delay = 12
//Important parts of the suit.
var/mob/living/carbon/affecting = null//The wearer.
var/obj/item/weapon/stock_parts/cell/cell//Starts out with a high-capacity cell using New().
var/datum/effect/effect/system/spark_spread/spark_system//To create sparks.
var/reagent_list[] = list("omnizine","salbutamol","spaceacillin","charcoal","nutriment","radium","potass_iodide")//The reagents ids which are added to the suit at New().
var/stored_research[]//For stealing station research.
var/obj/item/weapon/disk/tech_disk/t_disk//To copy design onto disk.
//Other articles of ninja gear worn together, used to easily reference them after initializing.
var/obj/item/clothing/head/helmet/space/space_ninja/n_hood
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.0//Base energy cost each ntick.
var/s_acost = 25.0//Additional cost for additional powers active.
var/k_cost = 200.0//Kamikaze energy cost each ntick.
var/k_damage = 1.0//Brute damage potentially done by Kamikaze each ntick.
var/s_delay = 40.0//How fast the suit does certain things, lower is faster. Can be overridden in specific procs. Also determines adverse probability.
var/a_transfer = 20.0//How much reagent is transferred when injecting.
var/r_maxamount = 80.0//How much reagent in total there is.
//Support function variables.
var/spideros = 0//Mode of SpiderOS. This can change so I won't bother listing the modes here (0 is hub). Check ninja_equipment.dm for how it all works.
var/s_active = 0//Stealth off.
var/s_busy = 0//Is the suit busy with a process? Like AI hacking. Used for safety functions.
var/kamikaze = 0//Kamikaze on or off.
var/k_unlock = 0//To unlock Kamikaze.
//Ability function variables.
var/s_bombs = 10.0//Number of starting ninja smoke bombs.
var/a_boost = 3.0//Number of adrenaline boosters.
//Onboard AI related variables.
var/obj/item/device/aicard/NAI //Integrated intellicard.
var/obj/item/device/paicard/pai//A slot for a pAI device
var/obj/effect/overlay/hologram//Is the AI hologram on or off? Visible only to the wearer of the suit. This works by attaching an image to a blank overlay.
var/s_control = 1//If user in control of the suit.

File diff suppressed because it is too large Load Diff

View File

@@ -73,8 +73,12 @@
if(mind.changeling)
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
stat("Absorbed DNA", mind.changeling.absorbedcount)
if (istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)&&wear_suit:s_initialized)
stat("Energy Charge", round(wear_suit:cell:charge/100))
//NINJACODE
if(istype(wear_suit, /obj/item/clothing/suit/space/space_ninja))
var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit
if(SN.s_initialized)
stat("Energy Charge", round(SN.cell.charge/100))
/mob/living/carbon/human/ex_act(severity, ex_target)

View File

@@ -286,7 +286,7 @@ proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 fo
return returntext
/proc/ninjaspeak(n)
/proc/ninjaspeak(n) //NINJACODE
/*
The difference with stutter is that this proc can stutter more than 1 letter
The issue here is that anything that does not have a space is treated as one word (in many instances). For instance, "LOOKING," is a word, including the comma.

View File

@@ -0,0 +1,10 @@
/*
Removing Snowflake:
- Search for NINJACODE (one word, all caps) to find Space Ninja Code outside of the /modules/ninja folder.
Ninja Folder:
- This folder contains 90% of Ninja code and will eventually contain it all, once snowflake is cleaned out
*/

View File

@@ -0,0 +1,13 @@
/*
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

View File

@@ -0,0 +1,61 @@
/*
Contents:
- Admin procs that make ninjas
*/
//ADMIN CREATE NINJA (From Player)
/client/proc/cmd_admin_ninjafy(var/mob/living/carbon/human/H in player_list)
set category = null
set name = "Make Space Ninja"
if(!ticker)
alert("Wait until the game starts")
return
if(!istype(H))
return
if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes")
return
log_admin("[key_name(src)] turned [H.key] into a Space Ninja.")
H.mind = create_ninja_mind(H.key)
H.mind_initialize()
H.equip_space_ninja(1)
if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
H.wear_suit:randomize_param()
spawn(0)
H.wear_suit:ninitialize(10,H)
//ADMIN CREATE NINJA (From Ghost)
/client/proc/send_space_ninja()
set category = "Fun"
set name = "Spawn Space Ninja"
set desc = "Spawns a space ninja for when you need a teenager with attitude."
set popup_menu = 0
if(!holder)
src << "Only administrators may use this command."
return
if(!ticker.mode)
alert("The game hasn't started yet!")
return
if(alert("Are you sure you want to send in a space ninja?",,"Yes","No")=="No")
return
var/client/C = input("Pick character to spawn as the Space Ninja", "Key", "") as null|anything in clients
if(!C)
return
var/datum/round_event/ninja/E = new /datum/round_event/ninja()
E.key=C.key
message_admins("<span class='notice'>[key_name_admin(key)] has spawned [key_name_admin(C.key)] as a Space Ninja.</span>")
log_admin("[key] used Spawn Space Ninja.")
return

View File

@@ -0,0 +1,10 @@
/obj/item/weapon/katana/energy
name = "energy katana"
desc = "a katana infused with a strong energy"
icon_state = "energy_katana"
item_state = "energy_katana"
force = 40
throwforce = 20
slot_flags = SLOT_BELT

View File

@@ -0,0 +1,214 @@
//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.
/*
Contents:
- The Ninja "Random" Event
- Ninja creation code
*/
/datum/round_event_control/ninja
name = "Space Ninja"
typepath = /datum/round_event/ninja
max_occurrences = 1
earliest_start = 30000 // 1 hour
/datum/round_event/ninja
var/success_spawn = 0
var/helping_station
var/key
var/spawn_loc
var/mob/living/carbon/human/Ninja
/datum/round_event/ninja/setup()
helping_station = rand(0,1)
/datum/round_event/ninja/kill()
if(!success_spawn && control)
control.occurrences--
return ..()
/datum/round_event/ninja/start()
//selecting a spawn_loc
if(!spawn_loc)
var/list/spawn_locs = list()
for(var/obj/effect/landmark/L in landmarks_list)
if(isturf(L.loc))
switch(L.name)
if("ninjaspawn","carpspawn")
spawn_locs += L.loc
if(!spawn_locs.len)
return kill()
spawn_loc = pick(spawn_locs)
if(!spawn_loc)
return kill()
//selecting a candidate player
if(!key)
var/list/candidates = get_candidates(BE_NINJA)
if(!candidates.len)
return kill()
var/client/C = pick(candidates)
key = C.key
if(!key)
return kill()
//Prepare ninja player mind
var/datum/mind/Mind = create_ninja_mind(key)
Mind.active = 1
//generate objectives - You'll generally get 6 objectives (Ninja is meant to be hardmode!)
var/list/possible_targets = list()
for(var/datum/mind/M in ticker.minds)
if(M.current && M.current.stat != DEAD)
if(istype(M.current,/mob/living/carbon/human))
if(M.special_role)
possible_targets[M] = 0 //bad-guy
else if(M.assigned_role in command_positions)
possible_targets[M] = 1 //good-guy
var/list/objectives = list(1,2,3,4)
while(Mind.objectives.len < 6) //still not enough objectives!
switch(pick_n_take(objectives))
if(1) //research
var/datum/objective/download/O = new /datum/objective/download()
O.owner = Mind
O.gen_amount_goal()
Mind.objectives += O
if(2) //steal
var/datum/objective/steal/special/O = new /datum/objective/steal/special()
O.owner = Mind
Mind.objectives += O
if(3) //protect/kill
if(!possible_targets.len) continue
var/selected = rand(1,possible_targets.len)
var/datum/mind/M = possible_targets[selected]
var/is_bad_guy = possible_targets[M]
possible_targets.Cut(selected,selected+1)
if(is_bad_guy ^ helping_station) //kill (good-ninja + bad-guy or bad-ninja + good-guy)
var/datum/objective/assassinate/O = new /datum/objective/assassinate()
O.owner = Mind
O.target = M
O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]."
Mind.objectives += O
else //protect
var/datum/objective/protect/O = new /datum/objective/protect()
O.owner = Mind
O.target = M
O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm."
Mind.objectives += O
if(4) //debrain/capture
if(!possible_targets.len) continue
var/selected = rand(1,possible_targets.len)
var/datum/mind/M = possible_targets[selected]
var/is_bad_guy = possible_targets[M]
possible_targets.Cut(selected,selected+1)
if(is_bad_guy ^ helping_station) //debrain (good-ninja + bad-guy or bad-ninja + good-guy)
var/datum/objective/debrain/O = new /datum/objective/debrain()
O.owner = Mind
O.target = M
O.explanation_text = "Steal the brain of [M.current.real_name]."
Mind.objectives += O
else //capture
var/datum/objective/capture/O = new /datum/objective/capture()
O.owner = Mind
O.gen_amount_goal()
Mind.objectives += O
else
break
//Add a survival objective since it's usually broad enough for any round type.
var/datum/objective/O = new /datum/objective/survive()
O.owner = Mind
Mind.objectives += O
//add some RP-fluff
Mind.store_memory("I am an elite mercenary assassin of the mighty Spider Clan. A <font color='red'><B>SPACE NINJA</B></font>!")
Mind.store_memory("Suprise 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)!")
Mind.store_memory("Officially, [helping_station?"Nanotrasen":"The Syndicate"] are my employer.")
//spawn the ninja and assign the candidate
Ninja = create_space_ninja(spawn_loc)
Mind.transfer_to(Ninja)
//initialise equipment
if(istype(Ninja.wear_suit,/obj/item/clothing/suit/space/space_ninja))
//Should be true but we have to check these things.
var/obj/item/clothing/suit/space/space_ninja/N = Ninja.wear_suit
N.randomize_param()
Ninja.internal = Ninja.s_store
if(Ninja.internals)
Ninja.internals.icon_state = "internal1"
if(Ninja.mind != Mind) //something has gone wrong!
ERROR("The ninja wasn't assigned the right mind. ;ç;")
Ninja << sound('sound/effects/ninja_greeting.ogg') //so ninja you probably wouldn't even know if you were made one
success_spawn = 1
//=======//NINJA CREATION PROCS//=======//
/proc/create_space_ninja(spawn_loc)
var/mob/living/carbon/human/new_ninja = new(spawn_loc)
if(prob(50)) new_ninja.gender = "female"
var/datum/preferences/A = new()//Randomize appearance for the ninja.
A.real_name = "[pick(ninja_titles)] [pick(ninja_names)]"
A.copy_to(new_ninja)
ready_dna(new_ninja)
new_ninja.equip_space_ninja()
return new_ninja
proc/create_ninja_mind(key)
var/datum/mind/Mind = new /datum/mind(key)
Mind.assigned_role = "MODE"
Mind.special_role = "Space Ninja"
ticker.mode.traitors |= Mind //Adds them to current traitor list. Which is really the extra antagonist list.
return Mind
/mob/living/carbon/human/proc/equip_space_ninja(safety=0)//Safety in case you need to unequip stuff for existing characters.
if(safety)
qdel(w_uniform)
qdel(wear_suit)
qdel(wear_mask)
qdel(head)
qdel(shoes)
qdel(gloves)
var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src)
equip_to_slot_or_del(R, slot_ears)
equip_to_slot_or_del(new /obj/item/clothing/under/color/black(src), slot_w_uniform)
equip_to_slot_or_del(new /obj/item/clothing/shoes/space_ninja(src), slot_shoes)
equip_to_slot_or_del(new /obj/item/clothing/suit/space/space_ninja(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/gloves/space_ninja(src), slot_gloves)
equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/space_ninja(src), slot_head)
equip_to_slot_or_del(new /obj/item/clothing/mask/gas/voice/space_ninja(src), slot_wear_mask)
equip_to_slot_or_del(new /obj/item/clothing/glasses/night(src), slot_glasses)
equip_to_slot_or_del(new /obj/item/weapon/katana/energy(src), slot_belt)
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_r_store)
equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/weapon/tank/internals/emergency_oxygen(src), slot_s_store)
equip_to_slot_or_del(new /obj/item/weapon/tank/jetpack/carbondioxide(src), slot_back)
var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(src)
E.imp_in = src
E.implanted = 1
E.implanted(src)
return 1

View File

@@ -0,0 +1,277 @@
//HERE BE A VERY LARGE DRAGON
/obj/item/clothing/suit/space/space_ninja/proc/spideros()
set name = "Display SpiderOS"
set desc = "Utilize built-in computer system."
set category = "Ninja Equip"
if(!s_busy)
display_spideros()
else
affecting << "<span class='danger'>The interface is locked!</span>"
/obj/item/clothing/suit/space/space_ninja/proc/display_spideros()
if(!affecting) return//If no mob is wearing the suit. I almost forgot about this variable.
var/mob/living/carbon/human/U = affecting
var/display_to = U//Who do we want to display certain messages to?
var/dat = "<html><head><title>SpiderOS</title></head><body bgcolor=\"#3D5B43\" text=\"#DB2929\"><style>a, a:link, a:visited, a:active, a:hover { color: #DB2929; }img {border-style:none;}</style>"
dat += "<a href='byond://?src=\ref[src];choice=Refresh'><img src=sos_7.png> Refresh</a>"
if(spideros)
dat += " | <a href='byond://?src=\ref[src];choice=Return'><img src=sos_1.png> Return</a>"
dat += " | <a href='byond://?src=\ref[src];choice=Close'><img src=sos_8.png> Close</a>"
dat += "<br>"
dat += "<h2 ALIGN=CENTER>SpiderOS v.1.337</h2>"
dat += "Welcome, <b>[U.real_name]</b>.<br>"
dat += "<br>"
dat += "<img src=sos_10.png> Current Time: [worldtime2text()]<br>"
dat += "<img src=sos_9.png> Battery Life: [round(cell.charge/100)]%<br>"
dat += "<img src=sos_11.png> Smoke Bombs: \Roman [s_bombs]<br>"
dat += "<br><br>"
switch(spideros)
if(0)
dat += "<h4><img src=sos_1.png> Available Functions:</h4>"
dat += "<ul>"
dat += "<li><a href='byond://?src=\ref[src];choice=7'><img src=sos_4.png> Research Stored</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=3'><img src=sos_3.png> Medical Screen</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=1'><img src=sos_5.png> Atmos Scan</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=2'><img src=sos_12.png> Messenger</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=4'><img src=sos_6.png> Other</a></li>"
dat += "</ul>"
if(3)
dat += "<h4><img src=sos_3.png> Medical Report:</h4>"
if(U.dna)
dat += "<b>Fingerprints</b>: <i>[md5(U.dna.uni_identity)]</i><br>"
dat += "<b>Unique identity</b>: <i>[U.dna.unique_enzymes]</i><br>"
dat += "<h4>Overall Status: [U.stat > 1 ? "dead" : "[U.health]% healthy"]</h4>"
dat += "<h4>Nutrition Status: [U.nutrition]</h4>"
dat += "Oxygen loss: [U.getOxyLoss()]"
dat += " | Toxin levels: [U.getToxLoss()]<br>"
dat += "Burn severity: [U.getFireLoss()]"
dat += " | Brute trauma: [U.getBruteLoss()]<br>"
dat += "Radiation Level: [U.radiation] rad<br>"
dat += "Body Temperature: [U.bodytemperature-T0C]&deg;C ([U.bodytemperature*1.8-459.67]&deg;F)<br>"
for(var/datum/disease/D in U.viruses)
dat += "Warning: Virus Detected. Name: [D.name].Type: [D.spread_text]. Stage: [D.stage]/[D.max_stages]. Possible Cure: [D.cure_text].<br>"
dat += "<ul>"
for(var/datum/reagent/R in reagents.reagent_list)
if(R.id=="radium")
continue
dat += "<li><a href='byond://?src=\ref[src];choice=Inject;name=[R.name];tag=[R.id]'><img src=sos_2.png> Inject [R.name]: [(reagents.get_reagent_amount(R.id)-(R.id=="radium"?(a_boost*a_transfer):0))/(R.id=="nutriment"?5:a_transfer)] left</a></li>"
dat += "</ul>"
if(1)
dat += "<h4><img src=sos_5.png> Atmospheric Scan:</h4>"//Headers don't need breaks. They are automatically placed.
var/turf/T = get_turf(U.loc)
if (isnull(T))
dat += "Unable to obtain a reading."
else
var/datum/gas_mixture/environment = T.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
dat += "Air Pressure: [round(pressure,0.1)] kPa"
if (total_moles)
var/o2_level = environment.oxygen/total_moles
var/n2_level = environment.nitrogen/total_moles
var/co2_level = environment.carbon_dioxide/total_moles
var/plasma_level = environment.toxins/total_moles
var/unknown_level = 1-(o2_level+n2_level+co2_level+plasma_level)
dat += "<ul>"
dat += "<li>Nitrogen: [round(n2_level*100)]%</li>"
dat += "<li>Oxygen: [round(o2_level*100)]%</li>"
dat += "<li>Carbon Dioxide: [round(co2_level*100)]%</li>"
dat += "<li>Plasma: [round(plasma_level*100)]%</li>"
dat += "</ul>"
if(unknown_level > 0.01)
dat += "OTHER: [round(unknown_level)]%<br>"
dat += "Temperature: [round(environment.temperature-T0C)]&deg;C"
if(2)
dat += "<h4><img src=sos_12.png> Anonymous Messenger:</h4>"//Anonymous because the receiver will not know the sender's identity.
dat += "<h4><img src=sos_6.png> Detected PDAs:</h4>"
dat += "<ul>"
var/count = 0
for (var/obj/item/device/pda/P in get_viewable_pdas())
dat += "<li><a href='byond://?src=\ref[src];choice=Message;target=\ref[P]'>[P]</a>"
dat += "</li>"
count++
dat += "</ul>"
if (count == 0)
dat += "None detected.<br>"
if(4)
dat += {"
<h4><img src=sos_6.png> Ninja Manual:</h4>
<h5>Who they are:</h5>
Space ninjas are a special type of ninja, specifically one of the space-faring type. The vast majority of space ninjas belong to the Spider Clan, a cult-like sect, which has existed for several hundred years. The Spider Clan practice a sort of augmentation of human flesh in order to achieve a more perfect state of being and follow Postmodern Space Bushido. They also kill people for money. Their leaders are chosen from the oldest of the grand-masters, people that have lived a lot longer than any mortal man should.<br>Being a sect of technology-loving fanatics, the Spider Clan have the very best to choose from in terms of hardware--cybernetic implants, exoskeleton rigs, hyper-capacity batteries, and you get the idea. Some believe that much of the Spider Clan equipment is based on reverse-engineered alien technology while others doubt such claims.<br>Whatever the case, their technology is absolutely superb.
<h5>How they relate to other SS13 organizations:</h5>
<ul>
<li>*<b>Nanotrasen</b> and the Syndicate are two sides of the same coin and that coin is valuable.</li>
<li>*<b>The Space Wizard Federation</b> is a problem, mainly because they are an extremely dangerous group of unpredictable individuals--not to mention the wizards hate technology and are in direct opposition of the Spider Clan. Best avoided or left well-enough alone. How to battle: wizards possess several powerful abilities to steer clear off. Blind in particular is a nasty spell--jaunt away if you are blinded and never approach a wizard in melee. Stealth may also work if the wizard is not wearing thermal scanners--don't count on this. Run away if you feel threatened and await a better opportunity.</li>
<li>*<b>Changeling Hivemind</b>: extremely dangerous and to be killed on sight. How to battle: they will likely try to absorb you. Adrenaline boost, then phase shift into them. If you get stung, use SpiderOS to inject counter-agents. Stealth may also work but detecting a changeling is the real battle.</li>
<li>*<b>Xeno Hivemind</b>: their skulls make interesting kitchen decorations and are challenging to best, especially in larger nests. How to battle: they can see through your stealth guise and energy stars will not work on them. Best killed with a Phase Shift or at range. If you happen on a projectile stun weapon, use it and then close in to melee.</li>
</ul>
<h5>The reason they (you) are here:</h5>
Space ninjas are renowned throughout the known controlled space as fearless spies, infiltrators, and assassins. They are sent on missions of varying nature by Nanotrasen, the Syndicate, and other shady organizations and people. To hire a space ninja means serious business.
<h5>Their playstyle:</h5>
A mix of traitor, changeling, and wizard. Ninjas rely on energy, or electricity to be precise, to keep their suits running (when out of energy, a suit hibernates). Suits gain energy from objects or creatures that contain electrical charge. APCs, cell batteries, rechargers, SMES batteries, cyborgs, mechs, and exposed wires are currently supported. Through energy ninjas gain access to special powers--while all powers are tied to the ninja suit, the most useful of them are verb activated--to help them in their mission.<br>It is a constant struggle for a ninja to remain hidden long enough to recharge the suit and accomplish their objective; despite their arsenal of abilities, ninjas can die like any other. Unlike wizards, ninjas do not possess good crowd control and are typically forced to play more subdued in order to achieve their goals. Some of their abilities are specifically designed to confuse and disorient others.<br>With that said, it should be perfectly possible to completely flip the fuck out and rampage as a ninja.
<h5>Their powers:</h5>
There are two primary types: Equipment and Abilties. Passive effect are always on. Active effect must be turned on and remain active only when there is energy to do so. Ability costs are listed next to them.
<b>Equipment</b>: cannot be tracked by AI (passive), faster speed (passive), stealth (active), vision switch (passive if toggled), voice masking (passive), SpiderOS (passive if toggled), energy drain (passive if toggled).
<ul>
<li><i>Voice masking</i> generates a random name the ninja can use over the radio and in-person. Although, the former use is recommended.</li>
<li><i>Toggling vision</i> cycles to one of the following: thermal, meson, or darkness vision. The starting mode allows one to scout the identity of those in view, revealing their role. Traitors, revolutionaries, wizards, and other such people will be made known to you.</li>
<li><i>Stealth</i>, when activated, drains more battery charge and works similarly to a syndicate cloak. The cloak will deactivate when most Abilities are utilized.</li>
<li><i>On-board AI</i>: The suit is able to download an AI much like an intellicard. Check with SpiderOS for details once downloaded.</li>
<li><i>SpiderOS</i> is a specialized, PDA-like screen that allows for a small variety of functions, such as injecting healing chemicals directly from the suit. You are using it now, if that was not already obvious. You may also download AI modules directly to the OS.</li>
</ul>
<b>Abilities</b>:
<ul>
<li>*<b>Phase Shift</b> (<i>2000E</i>) and <b>Phase Jaunt</b> (<i>1000E</i>) are unique powers in that they can both be used for defense and offense. Jaunt launches the ninja forward facing up to 9 squares, somewhat randomly selecting the final destination. Shift can only be used on turf in view but is precise (cannot be used on walls). Any living mob in the area teleported to is instantly gibbed (mechs are damaged, huggers and other similar critters are killed). It is possible to teleport with a target, provided you grab them before teleporting.</li>
<li>*<b>Energy Blade</b> (<i>500E</i>) is a highly effective weapon. It is summoned directly to the ninja's hand and can also function as an EMAG for certain objects (doors/lockers/etc). You may also use it to cut through walls and disabled doors. Experiment! The blade will crit humans in two hits. This item cannot be placed in containers and when dropped or thrown disappears. Having an energy blade drains more power from the battery each tick.</li>
<li>*<b>EM Pulse</b> (<i>2500E</i>) is a highly useful ability that will create an electromagnetic shockwave around the ninja, disabling technology whenever possible. If used properly it can render a security force effectively useless. Of course, getting beat up with a toolbox is not accounted for.</li>
<li>*<b>Energy Star</b> (<i>500E</i>) is a ninja star made of green energy AND coated in poison. It works by picking a random living target within range and can be spammed to great effect in incapacitating foes. Just remember that the poison used is also used by the Xeno Hivemind (and will have no effect on them).</li>
<li>*<b>Energy Net</b> (<i>2000E</i>) is a non-lethal solution to incapacitating humanoids. The net is made of non-harmful phase energy and will halt movement as long as it remains in effect--it can be destroyed. If the net is not destroyed, after a certain time it will teleport the target to a holding facility for the Spider Clan and then vanish. You will be notified if the net fails or succeeds in capturing a target in this manner. Combine with energy stars or stripping to ensure success. Abduction never looked this leet.</li>
<li>*<b>Adrenaline Boost</b> (<i>1 E. Boost/3</i>) recovers the user from stun, weakness, and paralysis. Also injects 20 units of radium into the bloodstream.</li>
<li>*<b>Smoke Bomb</b> (<i>1 Sm.Bomb/10</i>) is a weak but potentially useful ability. It creates harmful smoke and can be used in tandem with other powers to confuse enemies.</li>
<li>*<b>???</b>: unleash the <b>True Ultimate Power!</b></li>
<h4>IMPORTANT:</h4>
<ul>
<li>*Make sure to toggle Special Interaction from the Ninja Equipment menu to interact differently with certain objects.</li>
<li>*Your starting power cell can be replaced if you find one with higher maximum energy capacity by clicking on your suit with the higher capacity cell.</li>
<li>*Conserve your energy. Without it, you are very vulnerable.</li>
</ul>
That is all you will need to know. The rest will come with practice and talent. Good luck!
<h4>Master /N</h4>
"}
if(6)
dat += {"
<h4><img src=sos_6.png> Activate Abilities:</h4>
<ul>
<li><a href='byond://?src=\ref[src];choice=Trigger Ability;name=Phase Jaunt;cost= (10E)'><img src=sos_13.png> Phase Jaunt</a></li>
<li><a href='byond://?src=\ref[src];choice=Trigger Ability;name=Phase Shift;cost= (20E)'><img src=sos_13.png> Phase Shift</a></li>
<li><a href='byond://?src=\ref[src];choice=Trigger Ability;name=Energy Blade;cost= (5E)'><img src=sos_13.png> Energy Blade</a></li>
<li><a href='byond://?src=\ref[src];choice=Trigger Ability;name=Energy Star;cost= (5E)'><img src=sos_13.png> Energy Star</a></li>
<li><a href='byond://?src=\ref[src];choice=Trigger Ability;name=Energy Net;cost= (20E)'><img src=sos_13.png> Energy Net</a></li>
<li><a href='byond://?src=\ref[src];choice=Trigger Ability;name=EM Burst;cost= (25E)'><img src=sos_13.png> EM Pulse</a></li>
<li><a href='byond://?src=\ref[src];choice=Trigger Ability;name=Smoke Bomb;cost='><img src=sos_13.png> Smoke Bomb</a></li>
<li><a href='byond://?src=\ref[src];choice=Trigger Ability;name=Adrenaline Boost;cost='><img src=sos_13.png> Adrenaline Boost</a></li>
</ul>
"}
if(7)
dat += "<h4><img src=sos_4.png> Research Stored:</h4>"
if(t_disk)
dat += "<a href='byond://?src=\ref[src];choice=Eject Disk'>Eject Disk</a><br>"
dat += "<ul>"
if(istype(stored_research,/list))//If there is stored research. Should be but just in case.
for(var/datum/tech/current_data in stored_research)
dat += "<li>"
dat += "[current_data.name]: [current_data.level]"
if(t_disk)//If there is a disk inserted. We can either write or overwrite.
dat += " <a href='byond://?src=\ref[src];choice=Copy to Disk;target=\ref[current_data]'><i>*Copy to Disk</i></a><br>"
dat += "</li>"
dat += "</ul>"
dat += "</body></html>"
//Setting the can>resize etc to 0 remove them from the drag bar but still allows the window to be draggable.
display_to << browse(dat,"window=spideros;size=400x444;border=1;can_resize=1;can_close=0;can_minimize=0")
//=======//SPIDEROS TOPIC PROC//=======//
/obj/item/clothing/suit/space/space_ninja/Topic(href, href_list)
..()
var/mob/living/carbon/human/U = affecting
var/display_to = U
if(!affecting||U.stat||!s_initialized)//Check to make sure the guy is wearing the suit after clicking and it's on.
U << "<span class='danger'>Your suit must be worn and active to use this function.</span>"
U << browse(null, "window=spideros")//Closes the window.
return
switch(href_list["choice"])
if("Close")
display_to << browse(null, "window=spideros")
return
if("Refresh")//Refresh, goes to the end of the proc.
if("Return")//Return
if(spideros<=9)
spideros=0
else
spideros = round(spideros/10)//Best way to do this, flooring to nearest integer.
if("Message")
var/obj/item/device/pda/P = locate(href_list["target"])
var/t = input(U, "Please enter untraceable message.") as text
t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN)
if(!t||U.stat||U.wear_suit!=src||!s_initialized)//Wow, another one of these. Man...
display_to << browse(null, "window=spideros")
return
if(isnull(P)||P.toff)//So it doesn't freak out if the object no-longer exists.
display_to << "<span class='danger'>Error: unable to deliver message.</span>"
display_spideros()
return
P.tnote += "<i><b>&larr; From an unknown source:</b></i><br>[t]<br>"
if (!P.silent)
playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1)
P.audible_message("\icon[P] *[P.ttone]*", null, 3)
P.overlays.Cut()
P.overlays += image('icons/obj/pda.dmi', "pda-r")
if("Inject")
if( (href_list["tag"]=="radium"? (reagents.get_reagent_amount("radium"))<=(a_boost*a_transfer) : !reagents.get_reagent_amount(href_list["tag"])) )//Special case for radium. If there are only a_boost*a_transfer radium units left.
display_to << "<span class='danger'>Error: the suit cannot perform this function. Out of [href_list["name"]].</span>"
else
reagents.reaction(U, 2)
reagents.trans_id_to(U, href_list["tag"], href_list["tag"]=="nutriment"?5:a_transfer)//Nutriment is a special case since it's very potent. Shouldn't influence actual refill amounts or anything.
display_to << "Injecting..."
U << "You feel a tiny prick and a sudden rush of substance in to your veins."
if("Trigger Ability")
var/ability_name = href_list["name"]+href_list["cost"]//Adds the name and cost to create the full proc name.
var/proc_arguments//What arguments to later pass to the proc, if any.
var/list/targets = list()//To later check for.
var/safety = 0//To later make sure we're triggering the proc when needed.
switch(href_list["name"])//Special case.
if("Phase Shift")
safety = 1
for(var/turf/T in oview(5,loc))
targets.Add(T)
if("Energy Net")
safety = 1
for(var/mob/living/carbon/M in oview(5,loc))
targets.Add(M)
if(targets.len)//Let's create an argument for the proc if needed.
proc_arguments = pick(targets)
safety = 0
if(!safety)
U << "[href_list["name"]] suddenly triggered!"
call(src,ability_name)(proc_arguments)
if("Eject Disk")
var/turf/T = get_turf(loc)
if(!U.get_active_hand())
U.put_in_hands(t_disk)
t_disk.add_fingerprint(U)
t_disk = null
else
if(T)
t_disk.loc = T
t_disk = null
else
U << "<span class='userdanger'>ERROR</span>: Could not eject disk."
if("Copy to Disk")
var/datum/tech/current_data = locate(href_list["target"])
U << "[current_data.name] successfully [(!t_disk.stored) ? "copied" : "overwritten"] to disk."
t_disk.stored = current_data
display_spideros()//Refreshes the screen by calling it again (which replaces current screen with new screen).
return

View File

@@ -0,0 +1,343 @@
/*
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
*/
/obj/item/clothing/gloves/space_ninja
desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
name = "ninja gloves"
icon_state = "s-ninja"
item_state = "s-ninja"
siemens_coefficient = 0
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
strip_delay = 120
var/draining = 0
var/candrain = 0
var/mindrain = 200
var/maxdrain = 400
/*
This runs the gamut of what ninja gloves can do
The other option would be a dedicated ninja touch bullshit proc on everything
which would probably more efficient, but ninjas are pretty rare.
This was mostly introduced to keep ninja code from contaminating other code;
with this in place it would be easier to untangle the rest of it.
For the drain proc, see events/ninja.dm
*/
/obj/item/clothing/gloves/space_ninja/Touch(var/atom/A,var/proximity)
if(!candrain || draining)
return 0
var/mob/living/carbon/human/H = loc
if(!istype(H))
return 0 // what
var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit
if(!istype(suit))
return 0
if(isturf(A))
return 0
if(!proximity) // todo: you could add ninja stars or computer hacking here
return 0
A.add_fingerprint(H)
// steal energy from powered things
if(istype(A,/mob/living/silicon/robot))
drain("CYBORG",A,suit)
return 1
if(istype(A, /obj/item/weapon/stock_parts/cell))
drain("CELL", A,suit)
return 1
if(istype(A,/obj/machinery/power/apc))
drain("APC",A,suit)
return 1
if(istype(A,/obj/structure/cable))
drain("WIRE",A,suit)
return 1
if(istype(A,/obj/structure/grille))
var/obj/structure/cable/C = locate() in A.loc
if(C)
drain("WIRE",C,suit)
return 1
if(istype(A,/obj/machinery/power/smes))
drain("SMES",A,suit)
return 1
if(istype(A,/obj/mecha))
drain("MECHA",A,suit)
return 1
if(istype(A,/obj/machinery/computer/rdconsole)) // download research
drain("RESEARCH",A,suit)
return 1
if(istype(A,/obj/machinery/r_n_d/server))
A.add_fingerprint(H)
var/obj/machinery/r_n_d/server/S = A
if(S.disabled)
return 1
if(S.shocked)
S.shock(H,50)
return 1
drain("RESEARCH",A,suit)
return 1
/obj/item/clothing/gloves/space_ninja/proc/drain(target_type as text, target, obj/suit)
//Var Initialize
var/obj/item/clothing/suit/space/space_ninja/S = suit
var/mob/living/carbon/human/U = S.affecting
var/obj/item/clothing/gloves/space_ninja/G = S.n_gloves
var/drain = 0//To drain from battery.
var/maxcapacity = 0//Safety check for full battery.
var/totaldrain = 0//Total energy drained.
G.draining = 1
if(target_type!="RESEARCH")//I lumped research downloading here for ease of use.
U << "<span class='notice'>Now charging battery...</span>"
switch(target_type)
if("APC")
var/obj/machinery/power/apc/A = target
if(A.cell&&A.cell.charge)
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, A.loc)
while(G.candrain&&A.cell.charge>0&&!maxcapacity)
drain = rand(G.mindrain,G.maxdrain)
if(A.cell.charge<drain)
drain = A.cell.charge
if(S.cell.charge+drain>S.cell.maxcharge)
drain = S.cell.maxcharge-S.cell.charge
maxcapacity = 1//Reached maximum battery capacity.
if (do_after(U,10))
spark_system.start()
playsound(A.loc, "sparks", 50, 1)
A.cell.charge-=drain
S.cell.charge+=drain
totaldrain+=drain
else break
U << "<span class='notice'>Gained <B>[totaldrain]</B> energy from the APC.</span>"
if(!A.emagged)
flick("apc-spark", src)
A.emagged = 1
A.locked = 0
A.update_icon()
else
U << "<span class='danger'>This APC has run dry of power. You must find another source.</span>"
if("SMES")
var/obj/machinery/power/smes/A = target
if(A.charge)
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, A.loc)
while(G.candrain&&A.charge>0&&!maxcapacity)
drain = rand(G.mindrain,G.maxdrain)
if(A.charge<drain)
drain = A.charge
if(S.cell.charge+drain>S.cell.maxcharge)
drain = S.cell.maxcharge-S.cell.charge
maxcapacity = 1
if (do_after(U,10))
spark_system.start()
playsound(A.loc, "sparks", 50, 1)
A.charge-=drain
S.cell.charge+=drain
totaldrain+=drain
else break
U << "<span class='notice'>Gained <B>[totaldrain]</B> energy from the SMES cell.</span>"
else
U << "<span class='danger'>This SMES cell has run dry of power. You must find another source.</span>"
if("CELL")
var/obj/item/weapon/stock_parts/cell/A = target
if(A.charge)
if (G.candrain&&do_after(U,30))
U << "<span class='notice'>Gained <B>[A.charge]</B> energy from the cell.</span>"
if(S.cell.charge+A.charge>S.cell.maxcharge)
S.cell.charge=S.cell.maxcharge
else
S.cell.charge+=A.charge
A.charge = 0
G.draining = 0
A.corrupt()
A.updateicon()
else
U << "<span class='danger'>Procedure interrupted. Protocol terminated.</span>"
else
U << "<span class='danger'>This cell is empty and of no use.</span>"
if("MACHINERY")//Can be applied to generically to all powered machinery. I'm leaving this alone for now.
var/obj/machinery/A = target
if(A.powered())//If powered.
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, A.loc)
var/area/A_Area = get_area(A)
var/obj/machinery/power/apc/B = A_Area.get_apc() //find APC
if(B)//If APC exists. Might not if the area is unpowered like Centcom.
var/datum/powernet/PN = B.terminal.powernet
while(G.candrain&&!maxcapacity&&!isnull(A))//And start a proc similar to drain from wire.
drain = rand(G.mindrain,G.maxdrain)
var/drained = 0
if(PN&&do_after(U,10))
drained = min(drain, PN.avail)
PN.load += 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
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)
totaldrain += (drained-(S.cell.charge-S.cell.maxcharge))
S.cell.charge = S.cell.maxcharge
maxcapacity = 1
else
totaldrain += drained
spark_system.start()
if(drained==0) break
U << "<span class='notice'>Gained <B>[totaldrain]</B> energy from the power network.</span>"
else
U << "<span class='danger'>Power network could not be found. Aborting.</span>"
else
U << "<span class='danger'>This recharger is not providing energy. You must find another source.</span>"
if("RESEARCH")
var/obj/machinery/A = target
U << "<span class='notice'>Hacking \the [A]...</span>"
spawn(0)
var/turf/location = get_turf(U)
for(var/mob/living/silicon/ai/AI in player_list)
AI << "<span class='userdanger'>Network Alert: Hacking attempt detected[location?" in [location]":". Unable to pinpoint location"]</span>."
if(A:files&&A:files.known_tech.len)
for(var/datum/tech/current_data in S.stored_research)
U << "<span class='notice'>Checking \the [current_data.name] database.</span>"
if(do_after(U, S.s_delay)&&G.candrain&&!isnull(A))
for(var/datum/tech/analyzing_data in A:files.known_tech)
if(current_data.id==analyzing_data.id)
if(analyzing_data.level>current_data.level)
U << "<span class='notice'>Database:</span> <b>UPDATED</b>."
current_data.level = analyzing_data.level
break//Move on to next.
else break//Otherwise, quit processing.
U << "<span class='notice'>Data analyzed. Process finished.</span>"
if("WIRE")
var/obj/structure/cable/A = target
var/datum/powernet/PN = A.powernet
while(G.candrain&&!maxcapacity&&!isnull(A))
drain = (round((rand(G.mindrain,G.maxdrain))/2))
var/drained = 0
if(PN&&do_after(U,10))
drained = min(drain, PN.avail)
PN.load += 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
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)
totaldrain += (drained-(S.cell.charge-S.cell.maxcharge))
S.cell.charge = S.cell.maxcharge
maxcapacity = 1
else
totaldrain += drained
S.spark_system.start()
if(drained==0) break
U << "<span class='notice'>Gained <B>[totaldrain]</B> energy from the power network.</span>"
if("MECHA")
var/obj/mecha/A = target
A.occupant_message("<span class='danger'>Warning: Unauthorized access through sub-route 4, block H, detected.</span>")
if(A.get_charge())
while(G.candrain&&A.cell.charge>0&&!maxcapacity)
drain = rand(G.mindrain,G.maxdrain)
if(A.cell.charge<drain)
drain = A.cell.charge
if(S.cell.charge+drain>S.cell.maxcharge)
drain = S.cell.maxcharge-S.cell.charge
maxcapacity = 1
if (do_after(U,10))
A.spark_system.start()
playsound(A.loc, "sparks", 50, 1)
A.cell.use(drain)
S.cell.charge+=drain
totaldrain+=drain
else break
U << "<span class='notice'>Gained <B>[totaldrain]</B> energy from [src].</span>"
else
U << "<span class='danger'>The exosuit's battery has run dry. You must find another source of power.</span>"
if("CYBORG")
var/mob/living/silicon/robot/A = target
A << "<span class='danger'>Warning: Unauthorized access through sub-route 12, block C, detected.</span>"
G.draining = 1
if(A.cell&&A.cell.charge)
while(G.candrain&&A.cell.charge>0&&!maxcapacity)
drain = rand(G.mindrain,G.maxdrain)
if(A.cell.charge<drain)
drain = A.cell.charge
if(S.cell.charge+drain>S.cell.maxcharge)
drain = S.cell.maxcharge-S.cell.charge
maxcapacity = 1
if (do_after(U,10))
A.spark_system.start()
playsound(A.loc, "sparks", 50, 1)
A.cell.charge-=drain
S.cell.charge+=drain
totaldrain+=drain
else break
U << "<span class='notice'>Gained <B>[totaldrain]</B> energy from [A].</span>"
else
U << "<span class='danger'>Their battery has run dry of power. You must find another source.</span>"
else//Else nothing :<
G.draining = 0
return
/obj/item/clothing/gloves/space_ninja/proc/toggled()
set name = "Toggle Interaction"
set desc = "Toggles special interaction on or off."
set category = "Ninja Equip"
var/mob/living/carbon/human/U = loc
U << "You <b>[candrain?"disable":"enable"]</b> special interaction."
candrain=!candrain
/obj/item/clothing/gloves/space_ninja/examine(mob/user)
..()
if(flags & NODROP)
user << "The energy drain mechanism is: <B>[candrain?"active":"inactive"]</B>."

View File

@@ -0,0 +1,11 @@
/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)
strip_delay = 12
unacidable = 1
blockTracking = 1//Roughly the only unique thing about this helmet.

View File

@@ -0,0 +1,137 @@
/*
Contents:
- The Ninja Space Mask
- Ninja Space Mask speech modification
*/
/obj/item/clothing/mask/gas/voice/space_ninja
name = "ninja mask"
desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement."
icon_state = "s-ninja"
item_state = "s-ninja_mask"
vchange = 1
strip_delay = 120
/obj/item/clothing/mask/gas/voice/space_ninja/speechModification(message)
if(voice == "Unknown")
if(copytext(message, 1, 2) != "*")
var/list/temp_message = text2list(message, " ")
var/list/pick_list = list()
for(var/i = 1, i <= temp_message.len, i++)
pick_list += i
for(var/i=1, i <= abs(temp_message.len/3), i++)
var/H = pick(pick_list)
if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
temp_message[H] = ninjaspeak(temp_message[H])
pick_list -= H
message = list2text(temp_message, " ")
//The Alternate speech mod is now the main one.
message = replacetext(message, "l", "r")
message = replacetext(message, "rr", "ru")
message = replacetext(message, "v", "b")
message = replacetext(message, "f", "hu")
message = replacetext(message, "'t", "")
message = replacetext(message, "t ", "to ")
message = replacetext(message, " I ", " ai ")
message = replacetext(message, "th", "z")
message = replacetext(message, "is", "izu")
message = replacetext(message, "ziz", "zis")
message = replacetext(message, "se", "su")
message = replacetext(message, "br", "bur")
message = replacetext(message, "ry", "ri")
message = replacetext(message, "you", "yuu")
message = replacetext(message, "ck", "cku")
message = replacetext(message, "eu", "uu")
message = replacetext(message, "ow", "au")
message = replacetext(message, "are", "aa")
message = replacetext(message, "ay", "ayu")
message = replacetext(message, "ea", "ii")
message = replacetext(message, "ch", "chi")
message = replacetext(message, "than", "sen")
message = replacetext(message, ".", "")
message = lowertext(message)
return message
/obj/item/clothing/mask/gas/voice/space_ninja/New()
verbs += /obj/item/clothing/mask/gas/voice/space_ninja/proc/togglev
//This proc is linked to human life.dm. It determines what hud icons to display based on mind special role for most mobs.
/obj/item/clothing/mask/gas/voice/space_ninja/proc/assess_targets(list/target_list, mob/living/carbon/U)
var/icon/tempHud = 'icons/mob/hud.dmi'
for(var/mob/living/target in target_list)
if(iscarbon(target))
switch(target.mind.special_role)
if("traitor")
U.client.images += image(tempHud,target,"hudtraitor")
if("Revolutionary","Head Revolutionary")
U.client.images += image(tempHud,target,"hudrevolutionary")
if("Cultist")
U.client.images += image(tempHud,target,"hudcultist")
if("Changeling")
U.client.images += image(tempHud,target,"hudchangeling")
if("Wizard","Fake Wizard")
U.client.images += image(tempHud,target,"hudwizard")
if("Hunter","Sentinel","Drone","Queen")
U.client.images += image(tempHud,target,"hudalien")
if("Syndicate")
U.client.images += image(tempHud,target,"hudoperative")
if("Death Commando")
U.client.images += image(tempHud,target,"huddeathsquad")
if("Space Ninja")
U.client.images += image(tempHud,target,"hudninja")
else//If we don't know what role they have but they have one.
U.client.images += image(tempHud,target,"hudunknown1")
else if(issilicon(target))//If the silicon mob has no law datum, no inherent laws, or a law zero, add them to the hud.
var/mob/living/silicon/silicon_target = target
if(!silicon_target.laws||(silicon_target.laws&&(silicon_target.laws.zeroth||!silicon_target.laws.inherent.len)))
if(isrobot(silicon_target))//Different icons for robutts and AI.
U.client.images += image(tempHud,silicon_target,"hudmalborg")
else
U.client.images += image(tempHud,silicon_target,"hudmalai")
return 1
/obj/item/clothing/mask/gas/voice/space_ninja/proc/togglev()
set name = "Toggle Voice"
set desc = "Toggles the voice synthesizer on or off."
set category = "Ninja Equip"
var/mob/U = loc//Can't toggle voice when you're not wearing the mask.
var/vchange = (alert("Would you like to synthesize a new name or turn off the voice synthesizer?",,"New Name","Turn Off"))
if(vchange == "New Name")
var/chance = rand(1,100)
switch(chance)
if(1 to 50)//High chance of a regular name.
voice = "[rand(0,1) == 1 ? pick(first_names_female) : pick(first_names_male)] [pick(last_names)]"
if(51 to 80)//Smaller chance of a clown name.
voice = "[pick(clown_names)]"
if(81 to 90)//Small chance of a wizard name.
voice = "[pick(wizard_first)] [pick(wizard_second)]"
if(91 to 100)//Small chance of an existing crew name.
var/list/names = list()
for(var/mob/living/carbon/human/M in player_list)
if(M == U || !M.client || !M.real_name)
continue
names.Add(M.real_name)
voice = !names.len ? "Cuban Pete" : pick(names)
U << "You are now mimicking <B>[voice]</B>."
else
U << "The voice synthesizer is [voice!="Unknown"?"now":"already"] deactivated."
voice = "Unknown"
return
/obj/item/clothing/mask/gas/voice/space_ninja/examine(mob/user)
..()
user << "Voice mimicking algorithm is set <B>[!vchange?"inactive":"active"]</B>."

View File

@@ -0,0 +1,174 @@
/*
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/effect/energy_net
name = "energy net"
desc = "It's a net made of green energy."
icon = 'icons/effects/effects.dmi'
icon_state = "energynet"
density = 1//Can't pass through.
opacity = 0//Can see through.
mouse_opacity = 1//So you can hit it with stuff.
anchored = 1//Can't drag/grab the trapped mob.
var/health = 25//How much health it has.
var/mob/living/affecting = null//Who it is currently affecting, if anyone.
var/mob/living/master = null//Who shot web. Will let this person know if the net was successful or failed.
/obj/effect/energy_net/proc/healthcheck()
if(health <=0)
density = 0
if(affecting)
var/mob/living/carbon/M = affecting
M.anchored = 0
for(var/mob/O in viewers(src, 3))
O.show_message("[M.name] was recovered from the energy net!", 1, "You hear a grunt.", 2)
if(!isnull(master))//As long as they still exist.
master << "<span class='userdanger'>ERROR</span>: unable to initiate transport protocol. Procedure terminated."
qdel(src)
return
/obj/effect/energy_net/process(var/mob/living/carbon/M as mob)
var/check = 30//30 seconds before teleportation. Could be extended I guess.
var/mob_name = affecting.name//Since they will report as null if terminated before teleport.
//The person can still try and attack the net when inside.
while(!isnull(M)&&!isnull(src)&&check>0)//While M and net exist, and 30 seconds have not passed.
check--
sleep(10)
if(isnull(M)||M.loc!=loc)//If mob is gone or not at the location.
if(!isnull(master))//As long as they still exist.
master << "<span class='userdanger'>ERROR</span>: unable to locate \the [mob_name]. Procedure terminated."
qdel(src)//Get rid of the net.
return
if(!isnull(src))//As long as both net and person exist.
//No need to check for countdown here since while() broke, it's implicit that it finished.
density = 0//Make the net pass-through.
invisibility = 101//Make the net invisible so all the animations can play out.
health = INFINITY//Make the net invincible so that an explosion/something else won't kill it while, spawn() is running.
for(var/obj/item/W in M)
if(istype(M,/mob/living/carbon/human))
if(W==M:w_uniform) continue//So all they're left with are shoes and uniform.
if(W==M:shoes) continue
M.unEquip(W)
spawn(0)
playsound(M.loc, 'sound/effects/sparks4.ogg', 50, 1)
anim(M.loc,M,'icons/mob/mob.dmi',,"phaseout",,M.dir)
M.loc = pick(holdingfacility)//Throw mob in to the holding facility.
M << "<span class='danger'>You appear in a strange place!</span>"
spawn(0)
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, M.loc)
spark_system.start()
playsound(M.loc, 'sound/effects/phasein.ogg', 25, 1)
playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1)
anim(M.loc,M,'icons/mob/mob.dmi',,"phasein",,M.dir)
qdel(src)//Wait for everything to finish, delete the net. Else it will stop everything once net is deleted, including the spawn(0).
for(var/mob/O in viewers(src, 3))
O.show_message("[M] vanished!", 1, "You hear sparks flying!", 2)
if(!isnull(master))//As long as they still exist.
master << "<span class='notice'><b>SUCCESS</b>: transport procedure of \the [affecting] complete.</span>"
M.anchored = 0//Important.
else//And they are free.
M << "<span class='notice'>You are free of the net!</span>"
return
/obj/effect/energy_net/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
healthcheck()
..()
/obj/effect/energy_net/ex_act(severity, target)
switch(severity)
if(1.0)
health-=50
if(2.0)
health-=50
if(3.0)
health-=prob(50)?50:25
healthcheck()
return
/obj/effect/energy_net/blob_act()
health-=50
healthcheck()
return
/obj/effect/energy_net/hitby(AM as mob|obj)
..()
visible_message("<span class='danger'>[src] was hit by [AM].</span>")
var/tforce = 0
if(ismob(AM))
tforce = 10
else
tforce = AM:throwforce
playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1)
health = max(0, health - tforce)
healthcheck()
..()
return
/obj/effect/energy_net/attack_hulk(mob/living/carbon/human/user)
..(user, 1)
user.visible_message("<span class='danger'>[user] rips the energy net apart!</span>", \
"<span class='notice'>You easily destroy the energy net.</span>")
health-=50
healthcheck()
/obj/effect/energy_net/attack_paw(mob/user)
return attack_hand()
/obj/effect/energy_net/attack_alien(mob/living/user as mob)
user.do_attack_animation(src)
if (islarva(user))
return
playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1)
health -= rand(10, 20)
if(health > 0)
user.visible_message("<span class='danger'>[user] claws at the energy net!</span>", \
"\green You claw at the net.")
else
user.visible_message("<span class='danger'>[user] slices the energy net apart!</span>", \
"\green You slice the energy net to pieces.")
healthcheck()
return
/obj/effect/energy_net/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
var/aforce = W.force
health = max(0, health - aforce)
healthcheck()
..()
return

View File

@@ -0,0 +1,26 @@
//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()
set name = "Adrenaline Boost"
set desc = "Inject a secret chemical that will counteract all movement-impairing effect."
set category = "Ninja Ability"
set popup_menu = 0
if(!ninjacost(0,N_ADRENALINE))//Have to make sure stat is not counted for this ability.
var/mob/living/carbon/human/H = affecting
H.SetParalysis(0)
H.SetStunned(0)
H.SetWeakened(0)
H.stat = 0//At least now you should be able to teleport away or shoot ninja stars.
spawn(30)//Slight delay so the enemy does not immedietly know the ability was used. Due to lag, this often came before waking up.
H.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!"))
spawn(70)
reagents.reaction(H, 2)
reagents.trans_id_to(H, "radium", a_transfer)
H << "<span class='danger'>You are beginning to feel the after-effect of the injection.</span>"
a_boost--
s_coold = 3
return

View File

@@ -0,0 +1,29 @@
//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
if((H.stat || H.incorporeal_move) && (specificCheck != N_ADRENALINE))//Will not return if user is using an adrenaline booster since you can use them when stat==1.
H << "<span class='danger'>You must be conscious and solid to do this.</span>"//It's not a problem of stat==2 since the ninja will explode anyway if they die.
return 1
var/actualCost = cost*10
if(cost && cell.charge < actualCost)
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)
H << "<span class='danger'>There are no more smoke bombs remaining.</span>"
return 1
if(N_ADRENALINE)
if(!a_boost)
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.

View File

@@ -0,0 +1,15 @@
//Disables nearby tech equipment.
/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse()
set name = "EM Burst (25E)"
set desc = "Disable any nearby technology with a electro-magnetic pulse."
set category = "Ninja Ability"
set popup_menu = 0
if(!ninjacost(250,N_STEALTH_CANCEL))
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 = 2
return

View File

@@ -0,0 +1,32 @@
//Allows the ninja to kidnap people
/obj/item/clothing/suit/space/space_ninja/proc/ninjanet(mob/living/carbon/C in oview())//Only living carbon mobs.
set name = "Energy Net (20E)"
set desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds."
set category = null
set src = usr.contents
if(!ninjacost(200,N_STEALTH_CANCEL) && iscarbon(C))
var/mob/living/carbon/human/H = affecting
if(C.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame.
if(!locate(/obj/effect/energy_net) in C.loc)//Check if they are already being affected by an energy net.
for(var/turf/T in getline(H.loc, C.loc))
if(T.density)//Don't want them shooting nets through walls. It's kind of cheesy.
H << "You may not use an energy net through solid obstacles!"
return
spawn(0)
H.Beam(C,"n_beam",,15)
C.anchored = 1//Anchors them so they can't move.
H.say("Get over here!")
var/obj/effect/energy_net/E = new /obj/effect/energy_net(C.loc)
E.layer = C.layer+1//To have it appear one layer above the mob.
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>")
E.affecting = C
E.master = H
spawn(0)//Parallel processing.
E.process(C)
else
H << "They are already trapped inside an energy net."
else
H << "They will bring no honor to your Clan!"
return

View File

@@ -0,0 +1,19 @@
//Smoke bomb
/obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke()
set name = "Smoke Bomb"
set desc = "Blind your enemies momentarily with a well-placed smoke bomb."
set category = "Ninja Ability"
set popup_menu = 0//Will not see it when right clicking.
if(!ninjacost(0,N_SMOKE_BOMB))
var/mob/living/carbon/human/H = affecting
H << "<span class='notice'>There are <B>[s_bombs]</B> smoke bombs remaining.</span>"
var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread()
smoke.set_up(10, 0, H.loc)
smoke.start()
playsound(H.loc, 'sound/effects/bamf.ogg', 50, 2)
s_bombs--
s_coold = 1
return

View File

@@ -0,0 +1,33 @@
//Shoots ninja stars at a random target
/obj/item/clothing/suit/space/space_ninja/proc/ninjastar()
set name = "Energy Star (5E)"
set desc = "Launches an energy star at a random living target."
set category = "Ninja Ability"
set popup_menu = 0
if(!ninjacost(50))
var/mob/living/carbon/human/H = affecting
var/list/targets = list()
for(var/mob/living/M in oview(loc))
if(M.stat) continue//Doesn't target corpses or paralyzed persons.
targets.Add(M)
if(targets.len)
var/mob/living/target=pick(targets)//The point here is to pick a random, living mob in oview to shoot stuff at.
var/turf/curloc = get_turf(H)
var/turf/targloc = get_turf(target)
if (!targloc || !curloc)
return
if (targloc == curloc)
return
var/obj/item/projectile/energy/dart/A = new /obj/item/projectile/energy/dart(curloc)
A.current = curloc
A.yo = targloc.y - curloc.y
A.xo = targloc.x - curloc.x
A.fire()
else
H << "<span class='danger'>There are no targets in view.</span>"
return

View File

@@ -0,0 +1,78 @@
/*
Contents:
- Stealth Verbs
- Stealth Icon Stuff
*/
/obj/item/clothing/suit/space/space_ninja/proc/toggle_stealth()
var/mob/living/carbon/human/U = affecting
if(s_active)
cancel_stealth()
else
spawn(0)
anim(U.loc,U,'icons/mob/mob.dmi',,"cloak",,U.dir)
s_active=!s_active
U.alpha = 0
U.visible_message("<span class='warning'>[U.name] vanishes into thin air!</span>", \
"<span class='notice'>You are now invisible to normal detection.</span>")
return
/obj/item/clothing/suit/space/space_ninja/proc/cancel_stealth()
var/mob/living/carbon/human/U = affecting
if(s_active)
spawn(0)
anim(U.loc,U,'icons/mob/mob.dmi',,"uncloak",,U.dir)
s_active=!s_active
U.alpha = 255
U.visible_message("<span class='warning'>[U.name] appears from thin air!</span>", \
"<span class='notice'>You are now visible.</span>")
return 1
return 0
/obj/item/clothing/suit/space/space_ninja/proc/stealth()
set name = "Toggle Stealth"
set desc = "Utilize the internal CLOAK-tech device to activate or deactivate stealth-camo."
set category = "Ninja Equip"
if(!s_busy)
toggle_stealth()
else
affecting << "<span class='danger'>Stealth does not appear to work!</span>"
//Allows the mob to grab a stealth icon.
/mob/proc/NinjaStealthActive(atom/A)//A is the atom which we are using as the overlay.
invisibility = INVISIBILITY_LEVEL_TWO//Set ninja invis to 2.
var/icon/opacity_icon = new(A.icon, A.icon_state)
var/icon/alpha_mask = getIconMask(src)
var/icon/alpha_mask_2 = new('icons/effects/effects.dmi', "at_shield1")
alpha_mask.AddAlphaMask(alpha_mask_2)
opacity_icon.AddAlphaMask(alpha_mask)
for(var/i=0,i<5,i++)//And now we add it as overlays. It's faster than creating an icon and then merging it.
var/image/I = image("icon" = opacity_icon, "icon_state" = A.icon_state, "layer" = layer+0.8)//So it's above other stuff but below weapons and the like.
switch(i)//Now to determine offset so the result is somewhat blurred.
if(1)
I.pixel_x -= 1
if(2)
I.pixel_x += 1
if(3)
I.pixel_y -= 1
if(4)
I.pixel_y += 1
overlays += I//And finally add the overlay.
overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9)
//When ninja steal malfunctions.
/mob/proc/NinjaStealthMalf()
invisibility = 0//Set ninja invis to 0.
overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9)
playsound(loc, 'sound/effects/stealthoff.ogg', 75, 1)

View File

@@ -0,0 +1,89 @@
/*
Contents:
- Proc for handling teleporting while grabbing someone
- Telport Ability
- Right-Click Teleport Ability
*/
//Handles elporting while grabbing someone
/obj/item/clothing/suit/space/space_ninja/proc/handle_teleport_grab(turf/T, mob/living/H)
if(istype(H.get_active_hand(),/obj/item/weapon/grab))//Handles grabbed persons.
var/obj/item/weapon/grab/G = H.get_active_hand()
G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position.
if(istype(H.get_inactive_hand(),/obj/item/weapon/grab))
var/obj/item/weapon/grab/G = H.get_inactive_hand()
G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position.
return
//Jaunt
/obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt()
set name = "Phase Jaunt (10E)"
set desc = "Utilizes the internal VOID-shift device to rapidly transit in direction facing."
set category = "Ninja Ability"
set popup_menu = 0
if(!ninjacost(100,N_STEALTH_CANCEL))
var/mob/living/carbon/human/H = affecting
var/turf/destination = get_teleport_loc(H.loc,H,9,1,3,1,0,1)
var/turf/mobloc = get_turf(H.loc)//Safety
if(destination&&istype(mobloc, /turf))//So we don't teleport out of containers
spawn(0)
playsound(H.loc, "sparks", 50, 1)
anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,H.dir)
handle_teleport_grab(destination, H)
H.loc = destination
spawn(0)
spark_system.start()
playsound(H.loc, 'sound/effects/phasein.ogg', 25, 1)
playsound(H.loc, "sparks", 50, 1)
anim(H.loc,H,'icons/mob/mob.dmi',,"phasein",,H.dir)
spawn(0)
destination.phase_damage_creatures(20,H)//Paralyse and damage mobs and mechas on the turf
s_coold = 1
else
H << "<span class='danger'>The VOID-shift device is malfunctioning, <B>teleportation failed</B>.</span>"
return
//Right-Click teleport: It's basically admin "jump to turf"
/obj/item/clothing/suit/space/space_ninja/proc/ninjashift(turf/T in oview())
set name = "Phase Shift (20E)"
set desc = "Utilizes the internal VOID-shift device to rapidly transit to a destination in view."
set category = null//So it does not show up on the panel but can still be right-clicked.
set src = usr.contents//Fixes verbs not attaching properly for objects. Praise the DM reference guide!
if(!ninjacost(200,N_STEALTH_CANCEL))
var/mob/living/carbon/human/H = affecting
var/turf/mobloc = get_turf(H.loc)//To make sure that certain things work properly below.
if((!T.density)&&istype(mobloc, /turf))
spawn(0)
playsound(H.loc, 'sound/effects/sparks4.ogg', 50, 1)
anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,H.dir)
handle_teleport_grab(T, H)
H.loc = T
spawn(0)
spark_system.start()
playsound(H.loc, 'sound/effects/phasein.ogg', 25, 1)
playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1)
anim(H.loc,H,'icons/mob/mob.dmi',,"phasein",,H.dir)
spawn(0)//Any living mobs in teleport area are gibbed.
T.phase_damage_creatures(20,H)//Paralyse and damage mobs and mechas on the turf
s_coold = 1
else
H << "<span class='danger'>You cannot teleport into solid walls or from solid matter</span>"
return

View File

@@ -0,0 +1,172 @@
/*
Contents:
- The Ninja Space Suit
- Ninja Space Suit Procs
*/
// /obj/item/clothing/suit/space/space_ninja
/obj/item/clothing/suit/space/space_ninja
name = "ninja suit"
desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
icon_state = "s-ninja"
item_state = "s-ninja_suit"
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank/internals,/obj/item/weapon/stock_parts/cell)
slowdown = 0
unacidable = 1
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
strip_delay = 12
//Important parts of the suit.
var/mob/living/carbon/human/affecting = null
var/obj/item/weapon/stock_parts/cell/cell
var/datum/effect/effect/system/spark_spread/spark_system
var/list/reagent_list = list("omnizine","salbutamol","spaceacillin","charcoal","nutriment","radium","potass_iodide")//The reagents ids which are added to the suit at New().
var/list/stored_research = list()//For stealing station research.
var/obj/item/weapon/disk/tech_disk/t_disk//To copy design onto disk.
//Other articles of ninja gear worn together, used to easily reference them after initializing.
var/obj/item/clothing/head/helmet/space/space_ninja/n_hood
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.0//Base energy cost each ntick.
var/s_acost = 25.0//Additional cost for additional powers active.
var/s_delay = 40.0//How fast the suit does certain things, lower is faster. Can be overridden in specific procs. Also determines adverse probability.
var/a_transfer = 20.0//How much reagent is transferred when injecting.
var/r_maxamount = 80.0//How much reagent in total there is.
//Support function variables.
var/spideros = 0//Mode of SpiderOS. This can change so I won't bother listing the modes here (0 is hub). Check ninja_equipment.dm for how it all works.
var/s_active = 0//Stealth off.
var/s_busy = 0//Is the suit busy with a process? Like AI hacking. Used for safety functions.
//Ability function variables.
var/s_bombs = 10.0//Number of starting ninja smoke bombs.
var/a_boost = 3.0//Number of adrenaline boosters.
/obj/item/clothing/suit/space/space_ninja/New()
..()
verbs += /obj/item/clothing/suit/space/space_ninja/proc/init//suit initialize verb
//Spark Init
spark_system = new()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
//Research Init
stored_research = new()
for(var/T in typesof(/datum/tech) - /datum/tech)//Store up on research.
stored_research += new T(src)
//Reagent Init
var/reagent_amount
for(var/reagent_id in reagent_list)
reagent_amount += reagent_id == "radium" ? r_maxamount+(a_boost*a_transfer) : r_maxamount
reagents = new(reagent_amount)
reagents.my_atom = src
for(var/reagent_id in reagent_list)
reagent_id == "radium" ? reagents.add_reagent(reagent_id, r_maxamount+(a_boost*a_transfer)) : reagents.add_reagent(reagent_id, r_maxamount)//It will take into account radium used for adrenaline boosting.
//Cell Init
cell = new/obj/item/weapon/stock_parts/cell/high
cell.charge = 9000
/obj/item/clothing/suit/space/space_ninja/Destroy()
if(affecting)
affecting << browse(null, "window=hack spideros")
..()
//Simply deletes all the attachments and self, killing all related procs.
/obj/item/clothing/suit/space/space_ninja/proc/terminate()
qdel(n_hood)
qdel(n_gloves)
qdel(n_shoes)
qdel(src)
//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, var/checkIcons = 0)
if(!istype(H))
return 0
if(checkIcons)
icon_state = H.gender==FEMALE ? "s-ninjanf" : "s-ninjan"
H.gloves.icon_state = "s-ninjan"
H.gloves.item_state = "s-ninjan"
else
if(H.mind.special_role!="Space Ninja")
H << "\red <B>fÄTaL ÈÈRRoR</B>: 382200-*#00CÖDE <B>RED</B>\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR..."
H.gib()
return 0
if(!istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja))
H << "<span class='userdanger'>ERROR</span>: 100113 UNABLE TO LOCATE HEAD GEAR\nABORTING..."
return 0
if(!istype(H.shoes, /obj/item/clothing/shoes/space_ninja))
H << "<span class='userdanger'>ERROR</span>: 122011 UNABLE TO LOCATE FOOT GEAR\nABORTING..."
return 0
if(!istype(H.gloves, /obj/item/clothing/gloves/space_ninja))
H << "<span class='userdanger'>ERROR</span>: 110223 UNABLE TO LOCATE HAND GEAR\nABORTING..."
return 0
affecting = H
flags |= NODROP //colons make me go all |=
slowdown = 0
n_hood = H.head
n_hood.flags |= NODROP
n_shoes = H.shoes
n_shoes.flags |= NODROP
n_shoes.slowdown--
n_gloves = H.gloves
n_gloves.flags |= NODROP
return 1
//This proc allows the suit to be taken off.
/obj/item/clothing/suit/space/space_ninja/proc/unlock_suit()
affecting = null
flags &= ~NODROP
slowdown = 1
icon_state = "s-ninja"
if(n_hood)//Should be attached, might not be attached.
n_hood.flags &= ~NODROP
if(n_shoes)
n_shoes.flags &= ~NODROP
n_shoes.slowdown++
if(n_gloves)
n_gloves.icon_state = "s-ninja"
n_gloves.item_state = "s-ninja"
n_gloves.flags &= ~NODROP
n_gloves.candrain=0
n_gloves.draining=0
/obj/item/clothing/suit/space/space_ninja/examine(mob/user)
..()
if(s_initialized)
if(user == affecting)
user << "All systems operational. Current energy capacity: <B>[cell.charge]</B>."
user << "The CLOAK-tech device is <B>[s_active?"active":"inactive"]</B>."
user << "There are <B>[s_bombs]</B> smoke bomb\s remaining."
user << "There are <B>[a_boost]</B> adrenaline booster\s remaining."

View File

@@ -0,0 +1,61 @@
/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.
if(istype(I, /obj/item/weapon/reagent_containers/glass))//If it's a glass beaker.
var/total_reagent_transfer//Keep track of this stuff.
for(var/reagent_id in reagent_list)
var/datum/reagent/R = I.reagents.has_reagent(reagent_id)//Mostly to pull up the name of the reagent after calculating. Also easier to use than writing long proc paths.
if(R&&reagents.get_reagent_amount(reagent_id)<r_maxamount+(reagent_id == "radium"?(a_boost*a_transfer):0)&&R.volume>=a_transfer)//Radium is always special.
//Here we determine how much reagent will actually transfer if there is enough to transfer or there is a need of transfer. Minimum of max amount available (using a_transfer) or amount needed.
var/amount_to_transfer = min( (r_maxamount+(reagent_id == "radium"?(a_boost*a_transfer):0)-reagents.get_reagent_amount(reagent_id)) ,(round(R.volume/a_transfer))*a_transfer)//In the end here, we round the amount available, then multiply it again.
R.volume -= amount_to_transfer//Remove from reagent volume. Don't want to delete the reagent now since we need to perserve the name.
reagents.add_reagent(reagent_id, amount_to_transfer)//Add to suit. Reactions are not important.
total_reagent_transfer += amount_to_transfer//Add to total reagent trans.
U << "Added [amount_to_transfer] units of [R.name]."//Reports on the specific reagent added.
I.reagents.update_total()//Now we manually update the total to make sure everything is properly shoved under the rug.
U << "Replenished a total of [total_reagent_transfer ? total_reagent_transfer : "zero"] chemical units."//Let the player know how much total volume was added.
return
else if(istype(I, /obj/item/weapon/stock_parts/cell))
var/obj/item/weapon/stock_parts/cell/CELL
if(CELL.maxcharge > cell.maxcharge && n_gloves && n_gloves.candrain)
U << "<span class='notice'>Higher maximum capacity detected.\nUpgrading...</span>"
if (n_gloves && n_gloves.candrain && do_after(U,s_delay))
U.drop_item()
CELL.loc = src
CELL.charge = min(CELL.charge+cell.charge, CELL.maxcharge)
var/obj/item/weapon/stock_parts/cell/old_cell = cell
old_cell.charge = 0
U.put_in_hands(old_cell)
old_cell.add_fingerprint(U)
old_cell.corrupt()
old_cell.updateicon()
cell = CELL
U << "<span class='notice'>Upgrade complete. Maximum capacity: <b>[round(cell.maxcharge/100)]</b>%</span>"
else
U << "<span class='danger'>Procedure interrupted. Protocol terminated.</span>"
return
else if(istype(I, /obj/item/weapon/disk/tech_disk))//If it's a data disk, we want to copy the research on to the suit.
var/obj/item/weapon/disk/tech_disk/TD = I
if(TD.stored)//If it has something on it.
U << "Research information detected, processing..."
if(do_after(U,s_delay))
for(var/datum/tech/current_data in stored_research)
if(current_data.id==TD.stored.id)
if(current_data.level<TD.stored.level)
current_data.level=TD.stored.level
break
TD.stored = null
U << "<span class='notice'>Data analyzed and updated. Disk erased.</span>"
else
U << "<span class='userdanger'>ERROR</span>: Procedure interrupted. Process terminated."
else
I.loc = src
t_disk = I
U << "<span class='notice'>You slot \the [I] into \the [src].</span>"
return
..()

View File

@@ -0,0 +1,102 @@
//Verbs link to procs because verb-like procs have a bug which prevents their use if the arguments are not readily referenced.
//^ Old coder words may be false these days, Not taking the risk for now.
/obj/item/clothing/suit/space/space_ninja/proc/init()
set name = "Initialize Suit"
set desc = "Initializes the suit for field operation."
set category = "Ninja Equip"
ninitialize()
/obj/item/clothing/suit/space/space_ninja/proc/deinit()
set name = "De-Initialize Suit"
set desc = "Begins procedure to remove the suit."
set category = "Ninja Equip"
if(!s_busy)
deinitialize()
else
affecting << "<span class='danger'>The function did not trigger!</span>"
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize(delay = s_delay, mob/living/carbon/human/U = loc)
if(U.mind && U.mind.assigned_role=="MODE" && !s_initialized && !s_busy)//Shouldn't be busy... but anything is possible I guess.
s_busy = 1
for(var/i,i<7,i++)
switch(i)
if(0)
U << "<span class='notice'>Now initializing...</span>"
if(1)
if(!lock_suit(U))//To lock the suit onto wearer.
break
U << "<span class='notice'>Securing external locking mechanism...\nNeural-net established.</span>"
if(2)
U << "<span class='notice'>Extending neural-net interface...\nNow monitoring brain wave pattern...</span>"
if(3)
if(U.stat==2||U.health<=0)
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()
break
lock_suit(U,1)//Check for icons.
U.regenerate_icons()
U << "<span class='notice'> Linking neural-net interface...\nPattern</span>\green <B>GREEN</B><span class='notice'>, continuing operation.</span>"
if(4)
U << "<span class='notice'>VOID-shift device status: <B>ONLINE</B>.\nCLOAK-tech device status: <B>ONLINE</B>.</span>"
if(5)
U << "<span class='notice'>Primary system status: <B>ONLINE</B>.\nBackup system status: <B>ONLINE</B>.\nCurrent energy capacity: <B>[cell.charge]</B>.</span>"
if(6)
U << "<span class='notice'>All systems operational. Welcome to <B>SpiderOS</B>, [U.real_name].</span>"
grant_ninja_verbs()
grant_equip_verbs()
ntick()
sleep(delay)
s_busy = 0
else
if(!U.mind||U.mind.assigned_role!="MODE")//Your run of the mill persons shouldn't know what it is. Or how to turn it on.
U << "You do not understand how this suit functions. Where the heck did it even come from?"
else if(s_initialized)
U << "<span class='danger'>The suit is already functioning.</span> Please report this bug."
else
U << "<span class='userdanger'>ERROR</span>: You cannot use this function at this time."
return
/obj/item/clothing/suit/space/space_ninja/proc/deinitialize(delay = s_delay)
if(affecting==loc&&!s_busy)
var/mob/living/carbon/human/U = affecting
if(!s_initialized)
U << "<span class='danger'>The suit is not initialized.</span> Please report this bug."
return
if(alert("Are you certain you wish to remove the suit? This will take time and remove all abilities.",,"Yes","No")=="No")
return
if(s_busy)
U << "<span class='userdanger'>ERROR</span>: You cannot use this function at this time."
return
s_busy = 1
for(var/i = 0,i<7,i++)
switch(i)
if(0)
U << "<span class='notice'>Now de-initializing...</span>"
spideros = 0//Spideros resets.
if(1)
U << "<span class='notice'>Logging off, [U:real_name]. Shutting down <B>SpiderOS</B>.</span>"
remove_ninja_verbs()
if(2)
U << "<span class='notice'>Primary system status: <B>OFFLINE</B>.\nBackup system status: <B>OFFLINE</B>.</span>"
if(3)
U << "<span class='notice'>VOID-shift device status: <B>OFFLINE</B>.\nCLOAK-tech device status: <B>OFFLINE</B>.</span>"
cancel_stealth()//Shutdowns stealth.
if(4)
U << "<span class='notice'>Disconnecting neural-net interface...</span>\green<B>Success</B><span class='notice'>.</span>"
if(5)
U << "<span class='notice'>Disengaging neural-net interface...</span>\green<B>Success</B><span class='notice'>.</span>"
if(6)
U << "<span class='notice'>Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: <B>FINISHED</B>.</span>"
remove_equip_verbs()
unlock_suit()
U.regenerate_icons()
sleep(delay)
s_busy = 0
return

View File

@@ -0,0 +1,28 @@
/obj/item/clothing/suit/space/space_ninja/proc/ntick(mob/living/carbon/human/U = affecting)
set background = BACKGROUND_ENABLED
//Runs in the background while the suit is initialized.
spawn while(cell.charge)
//Let's check for some safeties.
if(s_initialized && !affecting)
terminate()//Kills the suit and attached objects.
if(!s_initialized)
return//When turned off the proc stops.
//Now let's do the normal processing.
if(s_coold)
s_coold--//Checks for ability s_cooldown first.
var/A = s_cost//s_cost is the default energy cost each ntick, usually 5.
if(s_active)//If stealth is active.
A += s_acost
cell.charge-=A
if(!cell.charge)
cell.charge=0
cancel_stealth()
sleep(10)//Checks every second.

View File

@@ -0,0 +1,52 @@
/*
Contents:
- Procs that add ninja verbs to ninjas
- Procs that remove ninja verbs from ninjas
- Procs that add ninjasuit verbs to ninjas
- Procs that remove ninjasuit verbs from ninjas
*/
/obj/item/clothing/suit/space/space_ninja/proc/grant_equip_verbs()
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/init
verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit
verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros
verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth
n_gloves.verbs += /obj/item/clothing/gloves/space_ninja/proc/toggled
s_initialized = 1
/obj/item/clothing/suit/space/space_ninja/proc/remove_equip_verbs()
verbs += /obj/item/clothing/suit/space/space_ninja/proc/init
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth
if(n_gloves)
n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled
s_initialized = 0
/obj/item/clothing/suit/space/space_ninja/proc/grant_ninja_verbs()
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjashift
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet
s_initialized=1
slowdown=0
/obj/item/clothing/suit/space/space_ninja/proc/remove_ninja_verbs()
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjashift
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaboost
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjanet

View File

@@ -57,15 +57,6 @@
else
user << "The charge meter reads [round(src.percent() )]%."
/obj/item/weapon/stock_parts/cell/attack_self(mob/user as mob)
src.add_fingerprint(user)
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/clothing/gloves/space_ninja/SNG = H.gloves
if(!istype(SNG) || !SNG.candrain || SNG.draining) return
SNG.drain("CELL",src,H.wear_suit)
return
/obj/item/weapon/stock_parts/cell/attackby(obj/item/W, mob/user, params)
..()

View File

@@ -80,6 +80,7 @@
user << "<span class='notice'>You transfer [trans] unit\s of the solution to [target].</span>"
//Safety for dumping stuff into a ninja suit. It handles everything through attackby() and this is unnecessary. //gee thanks noize
//NINJACODE
else if(istype(target, /obj/item/clothing/suit/space/space_ninja))
return

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -850,7 +850,6 @@
#include "code\modules\clothing\gloves\boxing.dm"
#include "code\modules\clothing\gloves\color.dm"
#include "code\modules\clothing\gloves\miscellaneous.dm"
#include "code\modules\clothing\gloves\ninja.dm"
#include "code\modules\clothing\head\collectable.dm"
#include "code\modules\clothing\head\hardhat.dm"
#include "code\modules\clothing\head\helmet.dm"
@@ -869,7 +868,6 @@
#include "code\modules\clothing\spacesuits\chronosuit.dm"
#include "code\modules\clothing\spacesuits\hardsuit.dm"
#include "code\modules\clothing\spacesuits\miscellaneous.dm"
#include "code\modules\clothing\spacesuits\ninja.dm"
#include "code\modules\clothing\spacesuits\syndi.dm"
#include "code\modules\clothing\suits\armor.dm"
#include "code\modules\clothing\suits\bio.dm"
@@ -919,7 +917,6 @@
#include "code\modules\events\mass_hallucination.dm"
#include "code\modules\events\meateor_wave.dm"
#include "code\modules\events\meteor_wave.dm"
#include "code\modules\events\ninja.dm"
#include "code\modules\events\prison_break.dm"
#include "code\modules\events\radiation_storm.dm"
#include "code\modules\events\shuttle_loan.dm"
@@ -1230,6 +1227,29 @@
#include "code\modules\nano\nanoexternal.dm"
#include "code\modules\nano\nanomanager.dm"
#include "code\modules\nano\nanoui.dm"
#include "code\modules\ninja\__ninjaDefines.dm"
#include "code\modules\ninja\admin_ninja_verbs.dm"
#include "code\modules\ninja\energy_katana.dm"
#include "code\modules\ninja\ninja_event.dm"
#include "code\modules\ninja\Ninja_Readme.dm"
#include "code\modules\ninja\suit\gloves.dm"
#include "code\modules\ninja\suit\head.dm"
#include "code\modules\ninja\suit\mask.dm"
#include "code\modules\ninja\suit\SpiderOS.dm"
#include "code\modules\ninja\suit\suit.dm"
#include "code\modules\ninja\suit\suit_attackby.dm"
#include "code\modules\ninja\suit\suit_initialisation.dm"
#include "code\modules\ninja\suit\suit_process.dm"
#include "code\modules\ninja\suit\suit_verbs_handlers.dm"
#include "code\modules\ninja\suit\n_suit_verbs\energy_net_nets.dm"
#include "code\modules\ninja\suit\n_suit_verbs\ninja_adrenaline.dm"
#include "code\modules\ninja\suit\n_suit_verbs\ninja_cost_check.dm"
#include "code\modules\ninja\suit\n_suit_verbs\ninja_empulse.dm"
#include "code\modules\ninja\suit\n_suit_verbs\ninja_net.dm"
#include "code\modules\ninja\suit\n_suit_verbs\ninja_smoke.dm"
#include "code\modules\ninja\suit\n_suit_verbs\ninja_stars.dm"
#include "code\modules\ninja\suit\n_suit_verbs\ninja_stealth.dm"
#include "code\modules\ninja\suit\n_suit_verbs\ninja_teleporting.dm"
#include "code\modules\paperwork\clipboard.dm"
#include "code\modules\paperwork\filingcabinet.dm"
#include "code\modules\paperwork\folders.dm"