diff --git a/code/WorkInProgress/Chemistry-Holder.dm b/code/WorkInProgress/Chemistry-Holder.dm index 5c57a0b98f7..500a7a2a793 100644 --- a/code/WorkInProgress/Chemistry-Holder.dm +++ b/code/WorkInProgress/Chemistry-Holder.dm @@ -101,7 +101,7 @@ datum src.update_total() R.update_total() R.handle_reactions() - //src.handle_reactions() Don't need to handle reactions on the source since you're (presumably isolating) and transferring a specific reagent. + //src.handle_reactions() Don't need to handle reactions on the source since you're (presumably isolating and) transferring a specific reagent. return amount /* @@ -315,9 +315,9 @@ datum for(var/A in reagent_list) var/datum/reagent/R = A if (R.id == reagent) - if(!amount) return 1 + if(!amount) return R else - if(R.volume >= amount) return 1 + if(R.volume >= amount) return R else return 0 return 0 diff --git a/code/WorkInProgress/Chemistry-Reagents.dm b/code/WorkInProgress/Chemistry-Reagents.dm index 8c1091435aa..c2109822170 100644 --- a/code/WorkInProgress/Chemistry-Reagents.dm +++ b/code/WorkInProgress/Chemistry-Reagents.dm @@ -701,19 +701,19 @@ datum */ gold - name = "gold" + name = "Gold" id = "gold" description = "Gold is a dense, soft, shiny metal and the most malleable and ductile metal known." reagent_state = SOLID silver - name = "silver" + name = "Silver" id = "silver" description = "A soft, white, lustrous transition metal, it has the highest electrical conductivity of any element and the highest thermal conductivity of any metal." reagent_state = SOLID uranium - name ="uranium" + name ="Uranium" id = "uranium" description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive." reagent_state = SOLID @@ -730,7 +730,7 @@ datum new /obj/decal/cleanable/greenglow(T) aluminum - name = "aluminum" + name = "Aluminum" id = "aluminum" description = "A silvery white and ductile member of the boron group of chemical elements." reagent_state = SOLID @@ -1065,9 +1065,9 @@ datum id = "arithrazine" description = "Arithrazine is an unstable medication used for the most extreme cases of radiation poisoning." reagent_state = LIQUID - on_mob_life(var/mob/living/M) + on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom - M:radiation = 0 + M:radiation = max(M:radiation-7,0) if(M:toxloss) M:toxloss-- if(prob(15)) M.take_organ_damage(1, 0) @@ -1099,20 +1099,6 @@ datum ..() return - arithrazine - name = "Arithrazine" - id = "arithrazine" - description = "Arithrazine is an unstable medication used for the most extreme cases of radiation poisoning." - reagent_state = LIQUID - on_mob_life(var/mob/living/M as mob) - if(!M) M = holder.my_atom - M:radiation = max(M:radiation-3,0) - if(M:toxloss) M:toxloss-- - if(prob(15)) - M.take_organ_damage(1, 0) - ..() - return - bicaridine name = "Bicaridine" id = "bicaridine" diff --git a/code/WorkInProgress/Chemistry-Tools.dm b/code/WorkInProgress/Chemistry-Tools.dm index 7147a8e541c..230e67cc456 100644 --- a/code/WorkInProgress/Chemistry-Tools.dm +++ b/code/WorkInProgress/Chemistry-Tools.dm @@ -584,6 +584,10 @@ var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this) user << "\blue You transfer [trans] units of the solution to [target]." + //Safety for dumping stuff into a ninja suit. It handles everything through attackby() and this is unnecessary. + else if(istype(target, /obj/item/clothing/suit/space/space_ninja)) + return + else if(reagents.total_volume) user << "\blue You splash the solution onto [target]." src.reagents.reaction(target, TOUCH) diff --git a/code/defines/obj/clothing/suit.dm b/code/defines/obj/clothing/suit.dm index 139475f8672..e6b027aa282 100644 --- a/code/defines/obj/clothing/suit.dm +++ b/code/defines/obj/clothing/suit.dm @@ -403,6 +403,7 @@ mob/living/carbon/affecting = null//The wearer. obj/item/weapon/cell/cell//Starts out with a high-capacity cell using New(). datum/effects/system/spark_spread/spark_system//To create sparks. + reagent_list[] = list("tricordrazine","dexalinp","spaceacillin","anti_toxin","nutriment","radium","hyronalin")//The reagents ids which are added to the suit at New(). //Other articles of ninja gear worn together, used to easily reference them after initializing. obj/item/clothing/head/helmet/space/space_ninja/n_hood @@ -412,21 +413,31 @@ //Main function variables. s_initialized = 0//Suit starts off. 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(). + s_cost = 5.0//Base energy cost each ntick. + s_acost = 25.0//Additional cost for additional powers active. + k_cost = 200.0//Kamikaze energy cost each ntick. + k_damage = 1.0//Brute damage potentially done by Kamikaze each ntick. + s_delay = 40.0//How fast the suit does certain things, lower is faster. Can be overridden in specific procs. Also determines adverse probability. + a_transfer = 20.0//How much reagent is transferred when injecting. + r_maxamount = 80.0//How much reagent in total there is. + + //Support function variables. 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. s_active = 0//Stealth off. - k_unlock = 0//To unlock Kamikaze. + s_busy = 0//Is the suit busy with a process? Like AI hacking. Used for safety functions. kamikaze = 0//Kamikaze on or off. + k_unlock = 0//To unlock Kamikaze. //Ability function variables. s_bombs = 10.0//Number of starting ninja smoke bombs. a_boost = 3.0//Number of adrenaline boosters. - a_transfer = 20//How much reagent is transferred when injecting. //Onboard AI related variables. - mob/living/silicon/AI//If there is an AI inside the suit. Paths to target. + mob/living/silicon/AI//If there is an AI inside the suit. + obj/item/device/paicard/pai//A slot for a pAI device obj/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. flush = 0//If an AI purge is in progress. - s_control = 1//If in control of the suit. + s_control = 1//If user in control of the suit. /obj/item/clothing/suit/space/pirate name = "pirate coat" diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm index 8c802cd2996..1658d9a98d7 100644 --- a/code/defines/procs/helpers.dm +++ b/code/defines/procs/helpers.dm @@ -381,11 +381,13 @@ //Returns location. Returns null if no location was found. /proc/get_teleport_loc(turf/location,mob/target,distance = 1, density = 0, errorx = 0, errory = 0, eoffsetx = 0, eoffsety = 0) -//Location where the teleport begins, target that will teleport, distance to go, density checking 0/1(yes/no). -//Random error in tile placement x, error in tile placement y, and block offset. -//Block offset tells the proc how to place the box. Behind teleport location, relative to starting location, forward, etc. -//Negative values for offset are accepted, think of it in relation to North, -x is west, -y is south. Error defaults to positive. -//Turf and target are seperate in case you want to teleport some distance from a turf the target is not standing on or something. +/* +Location where the teleport begins, target that will teleport, distance to go, density checking 0/1(yes/no). +Random error in tile placement x, error in tile placement y, and block offset. +Block offset tells the proc how to place the box. Behind teleport location, relative to starting location, forward, etc. +Negative values for offset are accepted, think of it in relation to North, -x is west, -y is south. Error defaults to positive. +Turf and target are seperate in case you want to teleport some distance from a turf the target is not standing on or something. +*/ var/dirx = 0//Generic location finding variable. var/diry = 0 diff --git a/code/game/gamemodes/extra/ninja_abilities.dm b/code/game/gamemodes/extra/ninja_abilities.dm index f625421639c..bda996c6d24 100644 --- a/code/game/gamemodes/extra/ninja_abilities.dm +++ b/code/game/gamemodes/extra/ninja_abilities.dm @@ -1,18 +1,19 @@ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+++++++++++++++++++++++++++++++++// \\++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++ ==================================SPACE NINJA ABILITIES==================================== ___________________________________________________________________________________________ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/*X is optional, tells the proc to check for specific stuff. C is also optional. +//=======//SAFETY CHECK//=======// +/* +X is optional, tells the proc to check for specific stuff. C is also optional. All the procs here assume that the character is wearing the ninja suit if they are using the procs. They should, as I have made every effort for that to be the case. In the case that they are not, I imagine the game will run-time error like crazy. +s_cooldown ticks off each second based on the suit recharge proc, in seconds. Default of 1 seconds. Some abilities have no cool down. */ - -//s_cooldown ticks off each second based on the suit recharge proc, in seconds. Default of 1 seconds. Some abilities have no cool down. /obj/item/clothing/suit/space/space_ninja/proc/ninjacost(C = 0,X = 0) var/mob/living/carbon/human/U = affecting if( (U.stat||U.incorporeal_move)&&X!=3 )//Will not return if user is using an adrenaline booster since you can use them when stat==1. @@ -34,9 +35,19 @@ In the case that they are not, I imagine the game will run-time error like crazy return 1 return (s_coold)//Returns the value of the variable which counts down to zero. -//Smoke -//Summons smoke in radius of user. -//Not sure why this would be useful (it's not) but whatever. Ninjas need their smoke bombs. +//=======//TELEPORT GRAB CHECK//=======// +/obj/item/clothing/suit/space/space_ninja/proc/handle_teleport_grab(turf/T, mob/living/U) + if(istype(U.get_active_hand(),/obj/item/weapon/grab))//Handles grabbed persons. + var/obj/item/weapon/grab/G = U.get_active_hand() + G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position. + if(istype(U.get_inactive_hand(),/obj/item/weapon/grab)) + var/obj/item/weapon/grab/G = U.get_inactive_hand() + G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position. + return + +//=======//SMOKE//=======// +/*Summons smoke in radius of user. +Not sure why this would be useful (it's not) but whatever. Ninjas need their smoke bombs.*/ /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." @@ -54,7 +65,7 @@ In the case that they are not, I imagine the game will run-time error like crazy s_coold = 1 return -//9-10 Tile Teleport +//=======//9-8 TILE TELEPORT//=======// //Click to to teleport 9-10 tiles in direction facing. /obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt() set name = "Phase Jaunt (10E)" @@ -72,12 +83,7 @@ In the case that they are not, I imagine the game will run-time error like crazy playsound(U.loc, "sparks", 50, 1) anim(mobloc,src,'mob.dmi',,"phaseout") - if(istype(U.get_active_hand(),/obj/item/weapon/grab))//Handles grabbed persons. - var/obj/item/weapon/grab/G = U.get_active_hand() - G.affecting.loc = locate(destination.x+rand(-1,1),destination.y+rand(-1,1),destination.z)//variation of position. - if(istype(U.get_inactive_hand(),/obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = U.get_inactive_hand() - G.affecting.loc = locate(destination.x+rand(-1,1),destination.y+rand(-1,1),destination.z)//variation of position. + handle_teleport_grab(destination, U) U.loc = destination spawn(0) @@ -94,7 +100,7 @@ In the case that they are not, I imagine the game will run-time error like crazy U << "\red The VOID-shift device is malfunctioning, teleportation failed." return -//Right Click Teleport +//=======//RIGHT CLICK TELEPORT//=======// //Right click to teleport somewhere, almost exactly like admin jump to turf. /obj/item/clothing/suit/space/space_ninja/proc/ninjashift(turf/T in oview()) set name = "Phase Shift (20E)" @@ -111,12 +117,7 @@ In the case that they are not, I imagine the game will run-time error like crazy playsound(U.loc, 'sparks4.ogg', 50, 1) anim(mobloc,src,'mob.dmi',,"phaseout") - if(istype(U.get_active_hand(),/obj/item/weapon/grab))//Handles grabbed persons. - var/obj/item/weapon/grab/G = U.get_active_hand() - G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position. - if(istype(U.get_inactive_hand(),/obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = U.get_inactive_hand() - G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)//variation of position. + handle_teleport_grab(T, U) U.loc = T spawn(0) @@ -133,7 +134,7 @@ In the case that they are not, I imagine the game will run-time error like crazy U << "\red You cannot teleport into solid walls or from solid matter" return -//EMP Pulse +//=======//EM PULSE//=======// //Disables nearby tech equipment. /obj/item/clothing/suit/space/space_ninja/proc/ninjapulse() set name = "EM Burst (25E)" @@ -150,7 +151,7 @@ In the case that they are not, I imagine the game will run-time error like crazy cell.charge-=(C*10) return -//Summon Energy Blade +//=======//ENERGY BLADE//=======// //Summons a blade of energy in active hand. /obj/item/clothing/suit/space/space_ninja/proc/ninjablade() set name = "Energy Blade (5E)" @@ -182,16 +183,16 @@ In the case that they are not, I imagine the game will run-time error like crazy s_coold = 1 return -//Shoot Ninja Stars -//Shoots ninja stars at random people. -//This could be a lot better but I'm too tired atm. +//=======//NINJA STARS//=======// +/*Shoots ninja stars at random people. +This could be a lot better but I'm too tired atm.*/ /obj/item/clothing/suit/space/space_ninja/proc/ninjastar() - set name = "Energy Star (3E)" + set name = "Energy Star (5E)" set desc = "Launches an energy star at a random living target." set category = "Ninja Ability" set popup_menu = 0 - var/C = 30 + var/C = 50 if(!ninjacost(C)) var/mob/living/carbon/human/U = affecting var/targets[] = list()//So yo can shoot while yo throw dawg @@ -217,9 +218,9 @@ In the case that they are not, I imagine the game will run-time error like crazy U << "\red There are no targets in view." return -//Energy Net -//Allows the ninja to capture people, I guess. -//Must right click on a mob to activate. +//=======//ENERGY NET//=======// +/*Allows the ninja to capture people, I guess. +Must right click on a mob to activate.*/ /obj/item/clothing/suit/space/space_ninja/proc/ninjanet(mob/living/carbon/M 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." @@ -255,9 +256,9 @@ In the case that they are not, I imagine the game will run-time error like crazy U << "They will bring no honor to your Clan!" return -//Adrenaline Boost -//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. +//=======//ADRENALINE BOOST//=======// +/*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 effects." @@ -282,10 +283,14 @@ In the case that they are not, I imagine the game will run-time error like crazy return -//KAMIKAZE============================= -//Or otherwise known as anime mode. Which also happens to be ridiculously powerful. +/* +=================================================================================== +<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +=================================================================================== +Or otherwise known as anime mode. Which also happens to be ridiculously powerful. +*/ -//Allows for incorporeal movement. +//=======//NINJA MOVEMENT//=======// //Also makes you move like you're on crack. /obj/item/clothing/suit/space/space_ninja/proc/ninjawalk() set name = "Shadow Walk" @@ -304,8 +309,8 @@ In the case that they are not, I imagine the game will run-time error like crazy U << "\blue You will no-longer phase through solid matter." return -/* -Allows to gib up to five squares in a straight line. Seriously.*/ +//=======//5 TILE TELEPORT/GIB//=======// +//Allows to gib up to five squares in a straight line. Seriously. /obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer() set name = "Phase Slayer" set desc = "Utilizes the internal VOID-shift device to mutilate creatures in a straight line." @@ -330,6 +335,7 @@ Allows to gib up to five squares in a straight line. Seriously.*/ spawn(0) anim(T,U,'mob.dmi',,"phasein") + handle_teleport_grab(destination, U) U.loc = destination spawn(0) @@ -342,8 +348,9 @@ Allows to gib up to five squares in a straight line. Seriously.*/ U << "\red The VOID-shift device is malfunctioning, teleportation failed." return -//Appear behind a randomly chosen mob while a few decoy teleports appear. -//This is so anime it hurts. But that's the point. +//=======//TELEPORT BEHIND MOB//=======// +/*Appear behind a randomly chosen mob while a few decoy teleports appear. +This is so anime it hurts. But that's the point.*/ /obj/item/clothing/suit/space/space_ninja/proc/ninjamirage() set name = "Spider Mirage" set desc = "Utilizes the internal VOID-shift device to create decoys and teleport behind a random target." @@ -401,6 +408,7 @@ Allows to gib up to five squares in a straight line. Seriously.*/ limit-- if(limit<=0) break + handle_teleport_grab(picked, U) U.loc = picked U.dir = target.dir diff --git a/code/game/gamemodes/extra/ninja_equipment.dm b/code/game/gamemodes/extra/ninja_equipment.dm index b27dcb1b28d..bcfcba14e1c 100644 --- a/code/game/gamemodes/extra/ninja_equipment.dm +++ b/code/game/gamemodes/extra/ninja_equipment.dm @@ -1,61 +1,95 @@ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+++++++++++++++++++++++++++++++++// \\++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++ ===================================SPACE NINJA EQUIPMENT=================================== ___________________________________________________________________________________________ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -//SUIT=================================== +/* +=================================================================================== +<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +=================================================================================== +*/ + +//=======//NEW AND DEL//=======// /obj/item/clothing/suit/space/space_ninja/New() ..() verbs += /obj/item/clothing/suit/space/space_ninja/proc/init//suit initialize verb - //verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_instruction//for AIs + verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_instruction//for AIs verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_holo spark_system = new /datum/effects/system/spark_spread()//spark initialize spark_system.set_up(5, 0, src) spark_system.attach(src) - var/datum/reagents/R = new/datum/reagents(520)//reagent initialize - reagents = R - R.my_atom = src - reagents.add_reagent("tricordrazine", 80) - reagents.add_reagent("dexalinp", 80) - reagents.add_reagent("spaceacillin", 80) - reagents.add_reagent("anti_toxin", 80) - reagents.add_reagent("radium", 120)//AI can inject radium directly. There should be at least 60 units left over after adrenaline boosting. - reagents.add_reagent("nutriment", 80) + var/reagent_amount//reagent initialize + for(var/reagent_id in reagent_list) + reagent_amount += reagent_id == "radium" ? r_maxamount+(a_boost*a_transfer) : r_maxamount//AI can inject radium directly. + 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 = new/obj/item/weapon/cell/high//The suit should *always* have a battery because so many things rely on it. cell.charge = 9000//Starting charge should not be higher than maximum charge. It leads to problems with recharging. /obj/item/clothing/suit/space/space_ninja/Del() + if(affecting)//To make sure the window is closed. + affecting << browse(null, "window=hack spideros") if(AI)//If there are AIs present when the ninja kicks the bucket. - killai(AI) + killai() + if(hologram)//If there is a hologram + del(hologram.i_attached)//Delete it and the attached image. + del(hologram) ..() return -/obj/item/clothing/suit/space/space_ninja/proc/terminate() //Simply deletes all the attachments and self, killing all related procs. +/obj/item/clothing/suit/space/space_ninja/proc/terminate() del(n_hood) del(n_gloves) del(n_shoes) del(src) -/obj/item/clothing/suit/space/space_ninja/proc/killai(var/mob/living/silicon/ai/A as mob) +/obj/item/clothing/suit/space/space_ninja/proc/killai(var/mob/living/silicon/ai/A = AI) if(A.client) A << "\red Self-erase protocol dete-- *bzzzzz*" A << browse(null, "window=hack spideros") AI = null - A.death(1)//Kill - del(AI) + A.death(1)//Kill, deleting mob. + del(A) return -/obj/item/clothing/suit/space/space_ninja/attackby(var/obj/item/device/aicard/aicard_temp as obj, U as mob)//When the suit is attacked by an AI card. - if(istype(aicard_temp, /obj/item/device/aicard))//If it's actually an AI card. - if(s_control) - aicard_temp.transfer_ai("NINJASUIT","AICARD",src,U) - else - U << "\red ERROR: \black Remote access channel disabled." +//=======//SUIT VERBS//=======// +//Verbs link to procs because verb-like procs have a bug which prevents their use if the arguments are not readily referenced. + +/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() + return + +/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_control&&!s_busy) + deinitialize() + else + affecting << "\red The function did not trigger!" + return + +/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_control&&!s_busy&&!kamikaze) + display_spideros() + else + affecting << "\red The interface is locked!" return /obj/item/clothing/suit/space/space_ninja/proc/stealth() @@ -63,9 +97,702 @@ ________________________________________________________________________________ set desc = "Utilize the internal CLOAK-tech device to activate or deactivate stealth-camo." set category = "Ninja Equip" - toggle_stealth() + if(s_control&&!s_busy) + toggle_stealth() + else + affecting << "\red Stealth does not appear to work!" return +//=======//PROCESS PROCS//=======// + +/obj/item/clothing/suit/space/space_ninja/proc/ntick(var/mob/living/carbon/human/U as mob) + set background = 1 + + //Runs in the background while the suit is initialized. + spawn while(cell.charge>=0) + + //Let's check for some safeties. + if(affecting&&affecting.monkeyizing) terminate()//Kills the suit and attached objects. + if(!s_initialized) return//When turned off the proc stops. + if(AI&&AI.stat==2)//If there is an AI and it's ded. Shouldn't happen without purging, could happen. + if(!s_control) + ai_return_control()//Return control to ninja if the AI was previously in control. + killai()//Delete AI. + + //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(!kamikaze) + if(blade_check(U))//If there is a blade held in hand. + A += s_acost + if(s_active)//If stealth is active. + A += s_acost + else + if(prob(s_delay))//Suit delay is used as probability. May change later. + U.bruteloss += k_damage//Default damage done, usually 1. + A = k_cost//kamikaze cost. + cell.charge-=A + if(cell.charge<=0) + if(kamikaze) + U.say("I DIE TO LIVE AGAIN!") + U << browse(null, "window=spideros")//Just in case. + U.death() + return + cell.charge=0 + cancel_stealth() + sleep(10)//Checks every second. + +//=======//INITIALIZE//=======// + +/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 = 0,i<7,i++) + switch(i) + if(0) + U << "\blue Now initializing..." + if(1) + if(!lock_suit(U))//To lock the suit onto wearer. + break + U << "\blue Securing external locking mechanism...\nNeural-net established." + if(2) + U << "\blue Extending neural-net interface...\nNow monitoring brain wave pattern..." + if(3) + if(U.stat==2||U.health<=0) + U << "\red FĆAL ÈRrÖR: 344--93#†&&21 BRÄÌN |/|/aVÈ PATT$RN RED\nA-A-aBÖrTÌNG..." + unlock_suit() + break + lock_suit(U,1)//Check for icons. + U.update_clothing() + U << "\blue Linking neural-net interface...\nPattern \green GREEN\blue, continuing operation." + if(4) + U << "\blue VOID-shift device status: ONLINE.\nCLOAK-tech device status: ONLINE." + if(5) + U << "\blue Primary system status: ONLINE.\nBackup system status: ONLINE.\nCurrent energy capacity: [cell.charge]." + if(6) + U << "\blue All systems operational. Welcome to SpiderOS, [U.real_name]." + grant_ninja_verbs() + grant_equip_verbs() + ntick(U) + 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 << "\red The suit is already functioning. \black Please report this bug." + else + U << "\red ERROR: \black You cannot use this function at this time." + return + +//=======//DEINITIALIZE//=======// + +/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 << "\red The suit is not initialized. \black 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||flush) + U << "\red ERROR: \black You cannot use this function at this time." + return + s_busy = 1 + for(var/i = 0,i<7,i++) + switch(i) + if(0) + U << "\blue Now de-initializing..." + remove_kamikaze(U)//Shutdowns kamikaze. + spideros = 0//Spideros resets. + if(1) + U << "\blue Logging off, [U:real_name]. Shutting down SpiderOS." + remove_ninja_verbs() + if(2) + U << "\blue Primary system status: OFFLINE.\nBackup system status: OFFLINE." + if(3) + U << "\blue VOID-shift device status: OFFLINE.\nCLOAK-tech device status: OFFLINE." + cancel_stealth()//Shutdowns stealth. + if(4) + U << "\blue Disconnecting neural-net interface...\greenSuccess\blue." + if(5) + U << "\blue Disengaging neural-net interface...\greenSuccess\blue." + if(6) + U << "\blue Unsecuring external locking mechanism...\nNeural-net abolished.\nOperation status: FINISHED." + blade_check(U,2) + remove_equip_verbs() + unlock_suit() + U.update_clothing() + sleep(delay) + s_busy = 0 + return + +//=======//SPIDEROS PROC//=======// + +/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/mob/living/silicon/ai/A = AI + var/display_to = s_control ? U : A//Who do we want to display certain messages to? + + var/dat = "SpiderOS" + if(spideros==0) + dat += " Refresh" + else + dat += " Refresh" + dat += " | Return" + dat += " | Close" + dat += "
" + if(s_control) + dat += "

SpiderOS v.1.337

" + dat += "Welcome, [U.real_name].
" + else + dat += "

SpiderOS v.ERR-RR00123

" + dat += "
" + dat += " Current Time: [round(world.time / 36000)+12]:[(world.time / 600 % 60) < 10 ? add_zero(world.time / 600 % 60, 1) : world.time / 600 % 60]
" + dat += " Battery Life: [round(cell.charge/100)]%
" + dat += " Smoke Bombs: [s_bombs]
" + dat += " pai Device: " + if(pai) + dat += "Configure" + dat += " | " + dat += "Eject" + else + dat += "None Detected" + dat += "

" + + switch(spideros) + if(0) + dat += "

Available Functions:

" + dat += "" + if(1) + dat += "

Medical Report:

" + if(U.dna) + dat += "Fingerprints: [md5(U.dna.uni_identity)]
" + dat += "Unique identity: [U.dna.unique_enzymes]
" + dat += "

Overall Status: [U.stat > 1 ? "dead" : "[U.health]% healthy"]

" + dat += "

Nutrition Status: [U.nutrition]

" + dat += "Oxygen loss: [U.oxyloss]" + dat += " | Toxin levels: [U.toxloss]
" + dat += "Burn severity: [U.fireloss]" + dat += " | Brute trauma: [U.bruteloss]
" + dat += "Radiation Level: [U.radiation] rad
" + dat += "Body Temperature: [U.bodytemperature-T0C]°C ([U.bodytemperature*1.8-459.67]°F)
" + if(U.virus) + dat += "Warning Virus Detected. Name: [U.virus.name].Type: [U.virus.spread]. Stage: [U.virus.stage]/[U.virus.max_stages]. Possible Cure: [U.virus.cure].
" + dat += "" + if(2) + dat += "

Atmospheric Scan:

"//Headers don't need breaks. They are automatically placed. + var/turf/T = get_turf_or_move(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 += "" + if(unknown_level > 0.01) + dat += "OTHER: [round(unknown_level)]%
" + + dat += "Temperature: [round(environment.temperature-T0C)]°C" + if(3) + if(k_unlock==7||!s_control) + dat += " Hidden Menu" + dat += "

Anonymous Messenger:

"//Anonymous because the receiver will not know the sender's identity. + dat += "

Detected PDAs:

" + dat += "" + if (count == 0) + dat += "None detected.
" + if(32) + dat += "

Hidden Menu:

" + if(s_control) + dat += "Please input password: " + dat += "HERE
" + dat += "
" + dat += "Remember, you will not be able to recharge energy during this function. If energy runs out, the suit will auto self-destruct.
" + dat += "Use with caution. De-initialize the suit when energy is low." + else + //Only leaving this in for funnays. CAN'T LET YOU DO THAT STAR FOX + dat += "WARNING: Hostile runtime intrusion detected: operation locked. The Spider Clan is watching you, INTRUDER." + dat += "ERROR: TARANTULA.v.4.77.12 encryption algorithm detected. Unable to decrypt archive.
" + if(4) + dat += "

Ninja Manual:

" + dat += "
Who they are:
" + dat += "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.
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.
Whatever the case, their technology is absolutely superb." + dat += "
How they relate to other SS13 organizations:
" + dat += "" + dat += "
The reason they (you) are here:
" + dat += "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." + dat += "
Their playstyle:
" + dat += "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.
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.
With that said, it should be perfectly possible to completely flip the fuck out and rampage as a ninja." + dat += "
Their powers:
" + dat += "There are two primary types: Equipment and Abilties. Passive effects are always on. Active effects must be turned on and remain active only when there is energy to do so. Ability costs are listed next to them." + dat += "Equipment: 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)." + dat += "" + dat += "Abilities:" + dat += "