mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-31 07:57:47 +01:00
#Huge code overhaul and cleanup for ninjas. Basically, the suit is about as modular now as I probably care to make it. Admins, read the commented text under Admin Notes, in space_ninja.dm. Tell your friends.
#Ninja suit now supports pAIs. Further functionality will probably come from their development. #Ninja suit can now replenish chemicals from beakers. Simply use a beaker on the suit and it will do the rest, if the beaker contains the right combination of chemicals. #Draining from a wire is now done through clicking instead of a verb. There is no more delay to it. #Ninja stars cost a bit more energy than before. #Ninja suit will start initializing automatically (and quickly) when ninja spawned. #Minor sprite fix for female ninja suit. #Note: AI-related verbs for the ninja suit will be bugged until BYOND 484 comes out. Not a huge deal but worth noting. #The has_reagent() proc will now return the reagent being checked for, instead of 1. Will return 0 if reagent is not found (or the amount does not match). Removed a duplicate arithrazine entry. #AIs should now properly camera_cancel() when carded/physically transfered. #Fixed a small menu display bug for AI cards. AI cards should now properly auto close their window when appropriate. #AI holograms should now project above everything. #Mal AIs can now choose to display an alternative (and awesome) sprite. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@1655 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, <B>teleportation failed</B>."
|
||||
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.
|
||||
/*
|
||||
===================================================================================
|
||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<KAMIKAZE MODE>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
===================================================================================
|
||||
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, <B>teleportation failed</B>."
|
||||
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
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,70 @@
|
||||
/*
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
+++++++++++++++++++++++++++++++++++++// \\++++++++++++++++++++++++++++++++++
|
||||
+++++++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++
|
||||
======================================SPACE NINJA SETUP====================================
|
||||
___________________________________________________________________________________________
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
|
||||
/proc/space_ninja_arrival()//This is the random event proc. WIP
|
||||
/*
|
||||
README:
|
||||
|
||||
Data:
|
||||
|
||||
>> space_ninja.dm << is this file. It contains a variety of procs related to either spawning space ninjas,
|
||||
modifying their verbs, various help procs, testing debug-related content, or storing unused procs for later.
|
||||
Similar functions should go into this file, along with anything else that may not have an explicit category.
|
||||
IMPORTANT: actual ninja suit, gloves, etc, are stored under the appropriate clothing files. If you need to change
|
||||
variables or look them up, look there. Easiest way is through the map file browser.
|
||||
|
||||
>> ninja_abilities.dm << contains all the ninja-related powers. Spawning energy swords, teleporting, and the like.
|
||||
If more powers are added, or perhaps something related to powers, it should go there. Make sure to describe
|
||||
what an ability/power does so it's easier to reference later without looking at the code.
|
||||
IMPORTANT: verbs are still somewhat funky to work with. If an argument is specified but is not referenced in a way
|
||||
BYOND likes, in the code content, the verb will fail to trigger. Nothing will happen, literally, when clicked.
|
||||
This can be bypassed by either referencing the argument properly, or linking to another proc with the argument
|
||||
attached. The latter is what I like to do for certain cases--sometimes it's necessary to do that regardless.
|
||||
|
||||
>> ninja_equipment.dm << deals with all the equipment-related procs for a ninja. Primarily it has the suit, gloves,
|
||||
and mask. The suit is by far the largest section of code out of the three and includes a lot of code that ties in
|
||||
to other functions. This file has gotten kind of large so breaking it up may be in order. I use section hearders.
|
||||
IMPORTANT: not much to say here. Follow along with the comments and adding new functions should be a breeze. Also
|
||||
know that certain equipment pieces are linked in other files. The energy blade, for example, has special
|
||||
functions defined in the appropriate files (airlock, securestorage, etc).
|
||||
|
||||
General Notes:
|
||||
|
||||
I created space ninjas with the expressed purpose of spicing up boring rounds. That is, ninjas are to xenos as marauders are to
|
||||
death squads. Ninjas are stealthy, tech-savvy, and powerful. Not to say marauders are all of those things, but a clever ninja
|
||||
should have little problem murderampaging their way through just about anything. Short of admin wizards maybe.
|
||||
HOWEVER!
|
||||
Ninjas also have a fairly great weakness as they require energy to use abilities. If, theoretically, there is a game
|
||||
mode based around space ninjas, make sure to account for their energy needs.
|
||||
|
||||
Admin Notes:
|
||||
|
||||
Ninjas are meant for players to respawn as, not admins. They are another way to participate in the game post-death, like pais,
|
||||
xenos, death squads, and cyborgs. Ninjas are not admin PCs--please do not use them for that purpose.
|
||||
I'm currently looking for feedback from regular players since beta testing is largely done. I would appreciate if
|
||||
you spawned regular players as ninjas when rounds are boring. Or exciting, it's all good as long as there is feedback.
|
||||
Admin quick-spawning as ninjas is disabled for that reason. You can spawn ninja gear manually if you want to.
|
||||
|
||||
How to do that:
|
||||
Make sure your character has a mind.
|
||||
Change their assigned_role to "MODE", no quotes. Otherwise, the suit won't initialize.
|
||||
Change their special_role to "Space Ninja", no quotes. Otherwise, the character will be gibbed.
|
||||
Spawn ninja gear, put it on, hit initialize. Let the suit do the rest. You are now a space ninja.
|
||||
I don't recommend messing with suit variables unless you really know what you're doing.
|
||||
|
||||
Miscellaneous Notes:
|
||||
|
||||
Right now I am focused on creating a dynamic objective tree based on round type, in order to create a ninja random event.
|
||||
I'll update when possible.
|
||||
*/
|
||||
|
||||
//=======//RANDOM EVENT//=======//
|
||||
|
||||
/proc/space_ninja_arrival()
|
||||
/*
|
||||
var/datum/game_mode/current_mode = ticker.mode
|
||||
switch (current_mode.config_tag)
|
||||
@@ -34,7 +92,9 @@ ________________________________________________________________________________
|
||||
*/
|
||||
return
|
||||
|
||||
/client/proc/space_ninja()//This is the admin button.
|
||||
//=======//ADMIN VERB//=======//
|
||||
|
||||
/client/proc/space_ninja()
|
||||
set category = "Fun"
|
||||
set name = "Spawn Space Ninja"
|
||||
set desc = "Spawns a space ninja for when you need a teenager with an attitude."
|
||||
@@ -69,7 +129,7 @@ ________________________________________________________________________________
|
||||
var/list/candidates = list()
|
||||
for(G in world)
|
||||
if(G.client&&!G.client.holder)
|
||||
//if(G.client)//Good for testing. Admins can spawn ninja equipment if they want to.
|
||||
//if(G.client)//Good for testing.
|
||||
if(((G.client.inactivity/10)/60) <= 5)
|
||||
candidates.Add(G)
|
||||
if(candidates.len)
|
||||
@@ -85,6 +145,9 @@ ________________________________________________________________________________
|
||||
|
||||
new_ninja.internal = new_ninja.s_store //So the poor ninja has something to breath when they spawn in spess.
|
||||
new_ninja.internals.icon_state = "internal1"
|
||||
spawn(0)//Parallel process. Will speed things up a bit.
|
||||
new_ninja.wear_suit:ninitialize(10,new_ninja)//If you're wondering why I'm passing the argument to the proc when the default should suffice,
|
||||
//I'm also wondering that same thing. This makes sure it does not run time error though.
|
||||
|
||||
new_ninja.mind.store_memory("<B>Mission:</B> \red [input].")
|
||||
new_ninja << "\blue \nYou are an elite mercenary assassin of the Spider Clan, [new_ninja.real_name]. The dreaded \red <B>SPACE NINJA</B>!\blue You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor. Remember your training (initialize your suit by right clicking on it)! \nYour current mission is: \red <B>[input]</B>"
|
||||
@@ -92,6 +155,8 @@ ________________________________________________________________________________
|
||||
message_admins("\blue [admin_name] has spawned [new_ninja.key] as a Space Ninja. Hide yo children!", 1)
|
||||
log_admin("[admin_name] used Spawn Space Ninja.")
|
||||
|
||||
//=======//NINJA CREATION PROCS//=======//
|
||||
|
||||
client/proc/create_space_ninja(obj/spawn_point)
|
||||
var/mob/living/carbon/human/new_ninja = new(spawn_point.loc)
|
||||
var/ninja_title = pick(ninja_titles)
|
||||
@@ -126,7 +191,93 @@ client/proc/create_space_ninja(obj/spawn_point)
|
||||
resistances += "alien_embryo"
|
||||
return 1
|
||||
|
||||
//VERB MODIFIERS===================================
|
||||
//=======//HELPER PROCS//=======//
|
||||
|
||||
//Randomizes suit parameters.
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/randomize_param()
|
||||
s_cost = rand(1,20)
|
||||
s_acost = rand(20,100)
|
||||
k_cost = rand(100,500)
|
||||
k_damage = rand(1,20)
|
||||
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/U, X = 0)
|
||||
if(X)//If you want to check for icons.
|
||||
if(U.gender==FEMALE)
|
||||
icon_state = "s-ninjanf"
|
||||
else
|
||||
icon_state = "s-ninjan"
|
||||
U:gloves.icon_state = "s-ninjan"
|
||||
U:gloves.item_state = "s-ninjan"
|
||||
else
|
||||
if(U.mind.special_role!="Space Ninja")
|
||||
U << "\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..."
|
||||
U.gib()
|
||||
return 0
|
||||
if(!istype(U:head, /obj/item/clothing/head/helmet/space/space_ninja))
|
||||
U << "\red <B>ERROR</B>: 100113 \black UNABLE TO LOCATE HEAD GEAR\nABORTING..."
|
||||
return 0
|
||||
if(!istype(U:shoes, /obj/item/clothing/shoes/space_ninja))
|
||||
U << "\red <B>ERROR</B>: 122011 \black UNABLE TO LOCATE FOOT GEAR\nABORTING..."
|
||||
return 0
|
||||
if(!istype(U:gloves, /obj/item/clothing/gloves/space_ninja))
|
||||
U << "\red <B>ERROR</B>: 110223 \black UNABLE TO LOCATE HAND GEAR\nABORTING..."
|
||||
return 0
|
||||
|
||||
affecting = U
|
||||
canremove = 0
|
||||
slowdown = 0
|
||||
n_hood = U:head
|
||||
n_hood.canremove=0
|
||||
n_shoes = U:shoes
|
||||
n_shoes.canremove=0
|
||||
n_shoes.slowdown--
|
||||
n_gloves = U:gloves
|
||||
n_gloves.canremove=0
|
||||
|
||||
return 1
|
||||
|
||||
//This proc allows the suit to be taken off.
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/unlock_suit()
|
||||
affecting = null
|
||||
canremove = 1
|
||||
slowdown = 1
|
||||
icon_state = "s-ninja"
|
||||
if(n_hood)//Should be attached, might not be attached.
|
||||
n_hood.canremove=1
|
||||
if(n_shoes)
|
||||
n_shoes.canremove=1
|
||||
n_shoes.slowdown++
|
||||
if(n_gloves)
|
||||
n_gloves.icon_state = "s-ninja"
|
||||
n_gloves.item_state = "s-ninja"
|
||||
n_gloves.canremove=1
|
||||
n_gloves.candrain=0
|
||||
n_gloves.draining=0
|
||||
|
||||
//=======//GENERIC VERB MODIFIERS//=======//
|
||||
|
||||
/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
|
||||
@@ -151,7 +302,9 @@ client/proc/create_space_ninja(obj/spawn_point)
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjanet
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/grant_kamikaze_verbs()
|
||||
//=======//KAMIKAZE VERBS//=======//
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/grant_kamikaze(mob/living/carbon/U)
|
||||
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/ninjapulse
|
||||
@@ -165,245 +318,85 @@ client/proc/create_space_ninja(obj/spawn_point)
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth
|
||||
|
||||
kamikaze = 1
|
||||
|
||||
if(U.gender==FEMALE)
|
||||
icon_state = "s-ninjakf"
|
||||
else
|
||||
icon_state = "s-ninjak"
|
||||
if(n_gloves)
|
||||
n_gloves.icon_state = "s-ninjak"
|
||||
n_gloves.item_state = "s-ninjak"
|
||||
n_gloves.candrain = 0
|
||||
n_gloves.draining = 0
|
||||
n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled
|
||||
|
||||
cancel_stealth()
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/remove_kamikaze_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/ninjapulse
|
||||
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
|
||||
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet
|
||||
U << browse(null, "window=spideros")
|
||||
U << "\red Do or Die, <b>LET'S ROCK!!</b>"
|
||||
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjawalk
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjamirage
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/remove_kamikaze(mob/living/carbon/U)
|
||||
if(kamikaze)
|
||||
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/ninjapulse
|
||||
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjastar
|
||||
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ninjanet
|
||||
|
||||
verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjawalk
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ninjamirage
|
||||
|
||||
kamikaze = 0
|
||||
k_unlock = 0
|
||||
verbs += /obj/item/clothing/suit/space/space_ninja/proc/stealth
|
||||
if(n_gloves)
|
||||
n_gloves.verbs -= /obj/item/clothing/gloves/space_ninja/proc/toggled
|
||||
|
||||
U.incorporeal_move = 0
|
||||
U.density = 1
|
||||
kamikaze = 0
|
||||
k_unlock = 0
|
||||
U << "\blue Disengaging mode...\n\black<b>CODE NAME</b>: \red <b>KAMIKAZE</b>"
|
||||
|
||||
//=======//AI VERBS//=======//
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/grant_AI_verbs()
|
||||
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja
|
||||
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_return_control
|
||||
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
|
||||
|
||||
s_busy = 0
|
||||
s_control = 0
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/remove_AI_verbs()
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_return_control
|
||||
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
|
||||
|
||||
s_control = 1
|
||||
|
||||
//AI COUNTER HACKING/SPECIAL FUNCTIONS===================================
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ai_holo(var/turf/T in oview(3,affecting))//To have an internal AI display a hologram to the ninja only.
|
||||
set name = "Display Hologram"
|
||||
set desc = "Channel a holographic image directly to the user's field of vision. Others will not see it."
|
||||
set category = null
|
||||
set src = usr.loc
|
||||
|
||||
if(s_initialized&&affecting&&affecting.client&&istype(affecting.loc, /turf))//If the host exists and they are playing, and their location is a turf.
|
||||
if(!hologram)//If there is not already a hologram.
|
||||
hologram = new(T)//Spawn a blank effect at the location.
|
||||
hologram.invisibility = 101//So that it doesn't show up, ever. This also means one could attach a number of images to a single obj and display them to differently to differnet people.
|
||||
hologram.dir = get_dir_to(T,affecting.loc)
|
||||
var/image/I = image('mob.dmi',hologram,"ai-holo")//Attach an image to object.
|
||||
hologram.i_attached = I//To attach the image in order to later reference.
|
||||
AI << I
|
||||
affecting << I
|
||||
affecting << "<i>An image flicks to life nearby. It appears visible to you only.</i>"
|
||||
|
||||
verbs += /obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear
|
||||
|
||||
ai_holo_process()//Move to initialize
|
||||
else
|
||||
AI << "\red ERROR: \black Image feed in progress."
|
||||
else
|
||||
AI << "\red ERROR: \black Unable to project image."
|
||||
return
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ai_holo_process()
|
||||
set background = 1
|
||||
|
||||
spawn while(hologram&&s_initialized&&AI)//Suit on and there is an AI present.
|
||||
if(!s_initialized||get_dist(affecting,hologram.loc)>3)//Once suit is de-initialized or hologram reaches out of bounds.
|
||||
del(hologram.i_attached)
|
||||
del(hologram)
|
||||
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear
|
||||
return
|
||||
sleep(10)//Checks every second.
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ai_instruction()//Let's the AI know what they can do.
|
||||
set name = "Instructions"
|
||||
set desc = "Displays a list of helpful information."
|
||||
set category = "AI Ninja Equip"
|
||||
set src = usr.loc
|
||||
|
||||
AI << "The menu you are seeing will contain other commands if they become available.\nRight click a nearby turf to display an AI Hologram. It will only be visible to you and your host. You can move it freely using normal movement keys--it will disappear if placed too far away."
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear()
|
||||
set name = "Clear Hologram"
|
||||
set desc = "Stops projecting the current holographic image."
|
||||
set category = "AI Ninja Equip"
|
||||
set src = usr.loc
|
||||
|
||||
del(hologram.i_attached)
|
||||
del(hologram)
|
||||
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_holo_clear
|
||||
return
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ai_hack_ninja()
|
||||
set name = "Hack SpiderOS"
|
||||
set desc = "Hack directly into the Black Widow(tm) neuro-interface."
|
||||
set category = "AI Ninja Equip"
|
||||
set src = usr.loc
|
||||
|
||||
hack_spideros()
|
||||
return
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ai_return_control()
|
||||
set name = "Relinquish Control"
|
||||
set desc = "Return control to the user."
|
||||
set category = "AI Ninja Equip"
|
||||
set src = usr.loc
|
||||
|
||||
AI << browse(null, "window=hack spideros")//Close window
|
||||
AI << "You have seized your hacking attempt. [affecting] has regained control."
|
||||
affecting << "<b>UPDATE</b>: [AI.real_name] has ceased hacking attempt. All systems clear."
|
||||
|
||||
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/ai_return_control
|
||||
return
|
||||
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/hack_spideros()
|
||||
|
||||
if(!affecting||!AI) return//Just in case... something went wrong. Very wrong.
|
||||
var/mob/living/carbon/human/U = affecting
|
||||
var/mob/living/silicon/ai/A = AI
|
||||
|
||||
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>"
|
||||
if(spideros==0)
|
||||
dat += "<a href='byond://?src=\ref[src];choice=Refresh'><img src=sos_7.png> Refresh</a>"
|
||||
else
|
||||
dat += "<a href='byond://?src=\ref[src];choice=Refresh'><img src=sos_7.png> Refresh</a>"
|
||||
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.<b>ERR-RR00123</b></h2>"
|
||||
dat += "<br>"
|
||||
dat += "<img src=sos_10.png> Current Time: [round(world.time / 36000)+12]:[(world.time / 600 % 60) < 10 ? add_zero(world.time / 600 % 60, 1) : world.time / 600 % 60]<br>"
|
||||
dat += "<img src=sos_9.png> Battery Life: [round(cell.charge/100)]%<br>"
|
||||
dat += "<img src=sos_11.png> Smoke Bombs: [s_bombs]<br>"
|
||||
dat += "<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=Shock'><img src=sos_4.png> Shock [U.real_name]</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=4'><img src=sos_6.png> Activate Abilities</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=1'><img src=sos_3.png> Medical Screen</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=2'><img src=sos_5.png> Atmos Scan</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=3'><img src=sos_12.png> Messenger</a></li>"
|
||||
dat += "</ul>"
|
||||
if(1)
|
||||
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.oxyloss]"
|
||||
dat += " | Toxin levels: [U.toxloss]<br>"
|
||||
dat += "Burn severity: [U.fireloss]"
|
||||
dat += " | Brute trauma: [U.bruteloss]<br>"
|
||||
dat += "Body Temperature: [U.bodytemperature-T0C]°C ([U.bodytemperature*1.8-459.67]°F)<br>"
|
||||
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].<br>"
|
||||
dat += "<ul>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Dylovene'><img src=sos_2.png> Inject Dylovene: [reagents.get_reagent_amount("anti_toxin")/20] left</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Dexalin Plus'><img src=sos_2.png> Inject Dexalin Plus: [reagents.get_reagent_amount("dexalinp")/20] left</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Tricordazine'><img src=sos_2.png> Inject Tricordazine: [reagents.get_reagent_amount("tricordrazine")/20] left</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Spacelin'><img src=sos_2.png> Inject Spacelin: [reagents.get_reagent_amount("spaceacillin")/20] left</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Radium'><img src=sos_2.png> Inject Radium: [(reagents.get_reagent_amount("radium")-60)/20] left</a></li>"//There is 120 radium at start. -60 for adrenaline boosts.
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Nutriment'><img src=sos_2.png> Inject Nutriment: [reagents.get_reagent_amount("nutriment")/5] left</a></li>"//Special case since it's so freaking potent.
|
||||
dat += "</ul>"
|
||||
if(2)
|
||||
dat += "<h4><img src=sos_5.png> Atmospheric Scan:</h4>"
|
||||
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 += "<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)]°C"
|
||||
if(3)
|
||||
dat += "<a href='byond://?src=\ref[src];choice=32'><img src=sos_1.png> Hidden Menu</a>"
|
||||
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 world)
|
||||
if (!P.owner||P.toff)
|
||||
continue
|
||||
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(32)//Only leaving this in for funnays. CAN'T LET YOU DO THAT STAR FOX
|
||||
dat += "<h4><img src=sos_1.png> Hidden Menu:</h4>"
|
||||
dat += "Hostile runtime intrusion detected: operation locked. The Spider Clan is watching you, <b>INTRUDER</b>."
|
||||
if(4)
|
||||
dat += "<h4><img src=sos_6.png> Activate Abilities:</h4>"
|
||||
dat += "<ul>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Phase Jaunt'><img src=sos_13.png> Phase Jaunt</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Phase Shift'><img src=sos_13.png> Phase Shift</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Energy Blade'><img src=sos_13.png> Energy Blade</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Energy Star'><img src=sos_13.png> Energy Star</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Energy Net'><img src=sos_13.png> Energy Net</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=EM Pulse'><img src=sos_13.png> EM Pulse</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Smoke Bomb'><img src=sos_13.png> Smoke Bomb</a></li>"
|
||||
dat += "<li><a href='byond://?src=\ref[src];choice=Adrenaline Boost'><img src=sos_13.png> Adrenaline Boost</a></li>"
|
||||
dat += "</ul>"
|
||||
|
||||
dat += "</body></html>"
|
||||
|
||||
A << browse(dat,"window=hack spideros;size=400x444;border=1;can_resize=0;can_close=0;can_minimize=0")
|
||||
|
||||
|
||||
//OLD & UNUSED===================================
|
||||
//=======//OLD & UNUSED//=======//
|
||||
|
||||
/*
|
||||
//Old way of draining from wire.
|
||||
/obj/item/clothing/gloves/space_ninja/proc/drain_wire()
|
||||
set name = "Drain From Wire"
|
||||
set desc = "Drain energy directly from an exposed wire."
|
||||
set category = "Ninja Equip"
|
||||
|
||||
var/obj/cable/attached
|
||||
var/mob/living/carbon/human/U = loc
|
||||
if(candrain&&!draining)
|
||||
var/turf/T = U.loc
|
||||
if(isturf(T) && T.is_plating())
|
||||
attached = locate() in T
|
||||
if(!attached)
|
||||
U << "\red Warning: no exposed cable available."
|
||||
else
|
||||
U << "\blue Connecting to wire, stand still..."
|
||||
if(do_after(U,50)&&!isnull(attached))
|
||||
drain("WIRE",attached,U:wear_suit,src)
|
||||
else
|
||||
U << "\red Procedure interrupted. Protocol terminated."
|
||||
return
|
||||
|
||||
I've tried a lot of stuff but adding verbs to the AI while inside an object, inside another object, did not want to work properly.
|
||||
This was the best work-around I could come up with at the time. Uses objects to then display to panel, based on the object spell system.
|
||||
Can be added on to pretty easily.
|
||||
@@ -493,7 +486,7 @@ BYOND fixed the verb bugs so this is no longer necessary. I prefer verb panels.
|
||||
return
|
||||
*/
|
||||
|
||||
//DEBUG===================================
|
||||
//=======//DEBUG//=======//
|
||||
|
||||
/*
|
||||
Most of these are at various points of incomplete.
|
||||
|
||||
@@ -66,6 +66,9 @@
|
||||
AI_mind.current << "When you feel you have enough APCs under your control, you may begin the takeover attempt."
|
||||
AI_mind.current.verbs += /datum/game_mode/malfunction/proc/takeover
|
||||
AI_mind.current.icon_state = "ai-malf"
|
||||
spawn(10)
|
||||
if(alert(AI_mind.current,"Do you want to use an alternative sprite for your real core?",,"Yes","No")=="Yes")
|
||||
AI_mind.current.icon_state = "ai-malf2"
|
||||
|
||||
spawn (rand(waittime_l, waittime_h))
|
||||
send_intercept()
|
||||
|
||||
@@ -165,8 +165,11 @@
|
||||
user << "\red <b>ERROR</b>: \black Remote access channel disabled."
|
||||
return
|
||||
|
||||
//This is a good place for AI-related object verbs so I'm sticking it here.
|
||||
|
||||
/*
|
||||
This is a good place for AI-related object verbs so I'm sticking it here.
|
||||
If adding stuff to this, don't forget that an AI need to cancel_camera() whenever it physically moves to a different location.
|
||||
That prevents a few funky behaviors.
|
||||
*/
|
||||
//What operation to perform based on target, what ineraction to perform based on object used, target itself, user. The object used is src and calls this proc.
|
||||
/obj/item/proc/transfer_ai(var/choice as text, var/interaction as text, var/target, var/mob/U as mob)
|
||||
if(!src:flush)
|
||||
@@ -194,6 +197,7 @@
|
||||
C.icon_state = "aicard-404"
|
||||
else
|
||||
C.icon_state = "aicard-full"
|
||||
T.cancel_camera()
|
||||
T << "You have been downloaded to a mobile storage device. Remote device connection severed."
|
||||
U << "\blue <b>Transfer successful</b>: \black [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
if("NINJASUIT")
|
||||
@@ -215,6 +219,7 @@
|
||||
T.control_disabled = 1
|
||||
T.loc = C
|
||||
C.AI = T
|
||||
T.cancel_camera()
|
||||
T << "You have been downloaded to a mobile storage device. Remote device connection severed."
|
||||
U << "\blue <b>Transfer successful</b>: \black [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
|
||||
@@ -227,11 +232,12 @@
|
||||
if(A)//If AI exists on the card. Else nothing since both are empty.
|
||||
A.control_disabled = 0
|
||||
A.loc = T.loc//To replace the terminal.
|
||||
A << "You have been uploaded to a stationary terminal. Remote device connection restored."
|
||||
U << "\blue <b>Transfer successful</b>: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
|
||||
C.icon_state = "aicard"
|
||||
C.name = "inteliCard"
|
||||
C.overlays = null
|
||||
A.cancel_camera()
|
||||
A << "You have been uploaded to a stationary terminal. Remote device connection restored."
|
||||
U << "\blue <b>Transfer successful</b>: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
|
||||
del(T)
|
||||
if("NINJASUIT")
|
||||
var/obj/item/clothing/suit/space/space_ninja/C = src
|
||||
@@ -240,6 +246,7 @@
|
||||
A.control_disabled = 0
|
||||
C.AI = null
|
||||
A.loc = T.loc
|
||||
A.cancel_camera()
|
||||
A << "You have been uploaded to a stationary terminal. Remote device connection restored."
|
||||
U << "\blue <b>Transfer succesful</b>: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
|
||||
del(T)
|
||||
@@ -252,8 +259,6 @@
|
||||
if (!C.contents.len)
|
||||
U << "No AI to copy over!"//Well duh
|
||||
else for(var/mob/living/silicon/ai/A in C)
|
||||
A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
|
||||
U << "\blue <b>Transfer successful</b>: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
|
||||
C.icon_state = "aicard"
|
||||
C.name = "inteliCard"
|
||||
C.overlays = null
|
||||
@@ -265,6 +270,9 @@
|
||||
else
|
||||
T.overlays += image('computer.dmi', "ai-fixer-full")
|
||||
T.overlays -= image('computer.dmi', "ai-fixer-empty")
|
||||
A.cancel_camera()
|
||||
A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
|
||||
U << "\blue <b>Transfer successful</b>: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
|
||||
else
|
||||
if(!C.contents.len && T.occupant && !T.active)
|
||||
C.name = "inteliCard - [T.occupant.name]"
|
||||
@@ -278,6 +286,7 @@
|
||||
T.occupant << "You have been downloaded to a mobile storage device. Still no remote access."
|
||||
U << "\blue <b>Transfer succesful</b>: \black [T.occupant.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
T.occupant.loc = C
|
||||
T.occupant.cancel_camera()
|
||||
T.occupant = null
|
||||
else if (C.contents.len)
|
||||
U << "\red <b>ERROR</b>: \black Artificial intelligence detected on terminal."
|
||||
@@ -292,14 +301,15 @@
|
||||
U << "No AI to copy over!"
|
||||
else
|
||||
var/mob/living/silicon/ai/A = C.AI
|
||||
A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
|
||||
U << "\blue <b>Transfer successful</b>: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
|
||||
A.loc = T
|
||||
T.occupant = A
|
||||
C.AI = null
|
||||
A.control_disabled = 1
|
||||
T.overlays += image('computer.dmi', "ai-fixer-full")
|
||||
T.overlays -= image('computer.dmi', "ai-fixer-empty")
|
||||
A.cancel_camera()
|
||||
A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
|
||||
U << "\blue <b>Transfer successful</b>: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
|
||||
else
|
||||
if(!C.AI && T.occupant && !T.active)
|
||||
if (T.occupant.stat)
|
||||
@@ -310,6 +320,7 @@
|
||||
T.occupant << "You have been downloaded to a mobile storage device. Still no remote access."
|
||||
U << "\blue <b>Transfer successful</b>: \black [T.occupant.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
T.occupant.loc = C
|
||||
T.occupant.cancel_camera()
|
||||
T.occupant = null
|
||||
else if (C.AI)
|
||||
U << "\red <b>ERROR</b>: \black Artificial intelligence detected on terminal."
|
||||
@@ -335,6 +346,7 @@
|
||||
C.name = "inteliCard - [A.name]"
|
||||
C.icon_state = "aicard-full"
|
||||
T.AI = null
|
||||
A.cancel_camera()
|
||||
A << "You have been uploaded to a mobile storage device."
|
||||
U << "\blue <b>SUCCESS</b>: \black [A.name] ([rand(1000,9999)].exe) removed from host and stored within local memory."
|
||||
else//If host AI is empty.
|
||||
@@ -347,6 +359,7 @@
|
||||
C.name = "inteliCard"
|
||||
C.overlays = null
|
||||
T.AI = A_T
|
||||
A_T.cancel_camera()
|
||||
A_T << "You have been uploaded to a mobile storage device."
|
||||
U << "\blue <b>SUCCESS</b>: \black [A_T.name] ([rand(1000,9999)].exe) removed from local memory and installed to host."
|
||||
else if(A_T)//If the target AI is dead. Else just go to return since nothing would happen if both are empty.
|
||||
|
||||
@@ -57,6 +57,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
hologram.icon = 'mob.dmi'
|
||||
hologram.icon_state = "ai-holo"
|
||||
hologram.mouse_opacity = 0//So you can't click on it.
|
||||
hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
|
||||
hologram.sd_SetLuminosity(1)//To make it glowy.
|
||||
sd_SetLuminosity(1)//To make the pad glowy.
|
||||
icon_state = "holopad1"
|
||||
|
||||
@@ -300,7 +300,7 @@
|
||||
..()
|
||||
var/mob/living/U = usr
|
||||
//Looking for master was kind of pointless since PDAs don't appear to have one.
|
||||
if (U.contents.Find(src) || (istype(loc, /turf) && get_dist(src, U) <= 1))
|
||||
if ( U.contents.Find(src) || ( istype(loc, /turf) && in_range(src, U) ) )
|
||||
if ( !(U.stat || U.restrained()) )
|
||||
|
||||
add_fingerprint(U)
|
||||
@@ -627,7 +627,7 @@
|
||||
var/input=alert("Would you like to inert the card or update owner information?",,"Insert","Update")
|
||||
//Basic safety check. If either both objects are held by user or PDA is on ground and card is in hand.
|
||||
|
||||
if ( (user.contents.Find(src) && user.contents.Find(C)) || (istype(loc, /turf) && get_dist(src, user) <= 1 && user.contents.Find(C)) )
|
||||
if ( (user.contents.Find(src) && user.contents.Find(C)) || (istype(loc, /turf) && in_range(src, user) && user.contents.Find(C)) )
|
||||
if ( !(user.stat || user.restrained()) )//If they can still act.
|
||||
if(input=="Insert")
|
||||
id_check(user, 2)
|
||||
|
||||
@@ -63,35 +63,52 @@
|
||||
dat += "<b>AI nonfunctional</b>"
|
||||
else
|
||||
if (!src.flush)
|
||||
dat += {"<A href='byond://?src=\ref[src];choice=Wipe'>Wipe AI</A>"}
|
||||
dat += {"<A href='byond://?src=\ref[src];choice=Wipe;user=\ref[user]'>Wipe AI</A>"}
|
||||
else
|
||||
dat += "<b>Wipe in progress</b>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Wireless'>[A.control_disabled ? "Enable" : "Disable"] Wireless Activity</a>"}
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Close'> Close</a>"}
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Wireless;user=\ref[user]'>[A.control_disabled ? "Enable" : "Disable"] Wireless Activity</a>"}
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Close;user=\ref[user]'> Close</a>"}
|
||||
user << browse(dat, "window=aicard")
|
||||
onclose(user, "aicard")
|
||||
return
|
||||
|
||||
Topic(href, href_list)
|
||||
switch(href_list["choice"])
|
||||
/*Let's define the user. It's safer to do it this way, rather than defaulting to usr.
|
||||
For very long menu lines, usr is probably a lot more convenient.*/
|
||||
var/mob/U = href_list["user"]
|
||||
if (!in_range(src, U)||U.machine!=src)//If they are not in range of 1 or less or their machine is not the card (ie, clicked on something else).
|
||||
U << browse(null, "window=aicard")
|
||||
U.machine = null
|
||||
return
|
||||
|
||||
add_fingerprint(U)
|
||||
U.machine = src
|
||||
|
||||
switch(href_list["choice"])//Now we switch based on choice.
|
||||
if ("Close")
|
||||
usr << browse(null, "window=aicard")
|
||||
usr.machine = null
|
||||
U << browse(null, "window=aicard")
|
||||
U.machine = null
|
||||
return
|
||||
|
||||
if ("Wipe")
|
||||
var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No")
|
||||
if(confirm == "Yes")
|
||||
flush = 1
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
A.suiciding = 1
|
||||
A << "Your core files are being wiped!"
|
||||
while (A.stat != 2)
|
||||
A.oxyloss += 2
|
||||
A.updatehealth()
|
||||
sleep(10)
|
||||
flush = 0
|
||||
if(isnull(src)||!in_range(src, U)||U.machine!=src)
|
||||
U << browse(null, "window=aicard")
|
||||
U.machine = null
|
||||
return
|
||||
else
|
||||
flush = 1
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
A.suiciding = 1
|
||||
A << "Your core files are being wiped!"
|
||||
while (A.stat != 2)
|
||||
A.oxyloss += 2
|
||||
A.updatehealth()
|
||||
sleep(10)
|
||||
flush = 0
|
||||
|
||||
if ("Wireless")
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
@@ -101,7 +118,7 @@
|
||||
overlays -= image('pda.dmi', "aicard-on")
|
||||
else
|
||||
overlays += image('pda.dmi', "aicard-on")
|
||||
attack_self(usr)
|
||||
attack_self(U)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
return
|
||||
|
||||
Topic(href, href_list)
|
||||
|
||||
if(href_list["setdna"])
|
||||
if(pai.master_dna)
|
||||
return
|
||||
|
||||
@@ -46,9 +46,12 @@ mob/new_player
|
||||
preferences.lastchangelog = lastchangelog
|
||||
preferences.savefile_save(src)
|
||||
//PDA Resource Initialisation =======================================================>
|
||||
|
||||
|
||||
if (client) //load the PDA iconset into the client
|
||||
/*
|
||||
Quick note: local dream daemon instances don't seem to cache images right. Might be
|
||||
a local problem with my machine but it's annoying nontheless.
|
||||
*/
|
||||
if (client)
|
||||
//load the PDA iconset into the client
|
||||
src << browse_rsc('pda_atmos.png')
|
||||
src << browse_rsc('pda_back.png')
|
||||
src << browse_rsc('pda_bell.png')
|
||||
@@ -87,9 +90,9 @@ mob/new_player
|
||||
src << browse_rsc('sos_11.png')
|
||||
src << browse_rsc('sos_12.png')
|
||||
src << browse_rsc('sos_13.png')
|
||||
src << browse_rsc('sos_14.png')
|
||||
//End PDA Resource Initialisation =====================================================>
|
||||
|
||||
|
||||
Logout()
|
||||
ready = 0
|
||||
..()
|
||||
|
||||
@@ -102,6 +102,12 @@
|
||||
PN = powernets[netnum]
|
||||
return PN
|
||||
|
||||
/obj/cable/attack_hand(mob/user)
|
||||
if(ishuman(user))
|
||||
if(istype(user:gloves, /obj/item/clothing/gloves/space_ninja)&&user:gloves:candrain&&!user:gloves:draining)
|
||||
call(/obj/item/clothing/gloves/space_ninja/proc/drain)("WIRE",src,user:wear_suit)
|
||||
return
|
||||
|
||||
/obj/cable/attackby(obj/item/W, mob/user)
|
||||
|
||||
var/turf/T = src.loc
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 145 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 249 B |
@@ -54,7 +54,6 @@
|
||||
#define FILE_DIR "code/game/machinery/pipe"
|
||||
#define FILE_DIR "code/game/magic"
|
||||
#define FILE_DIR "code/game/magic/cultist"
|
||||
#define FILE_DIR "code/game/magic/playerpower"
|
||||
#define FILE_DIR "code/game/mecha"
|
||||
#define FILE_DIR "code/game/mecha/combat"
|
||||
#define FILE_DIR "code/game/mecha/equipment"
|
||||
@@ -148,7 +147,6 @@
|
||||
#define DEBUG
|
||||
// END_PREFERENCES
|
||||
// BEGIN_INCLUDE
|
||||
#include <shadowdarke\sd_mapsuite\sd_MapSuite.dme>
|
||||
#include "code\names.dm"
|
||||
#include "code\setup.dm"
|
||||
#include "code\stylesheet.dm"
|
||||
|
||||
Reference in New Issue
Block a user