Additional Work on NIFs

Squashed commits:

[9563a9a] All the stuff I forgot to commit
This commit is contained in:
Arokha Sieyes
2017-06-03 00:55:01 -04:00
parent f7c24fb9d0
commit 58ee6891f2
21 changed files with 1368 additions and 7 deletions

View File

@@ -117,6 +117,10 @@ obj/var/phoronproof = 0
if(burn_eyes && head && (head.body_parts_covered & EYES) && (head.item_flags & AIRTIGHT)) if(burn_eyes && head && (head.body_parts_covered & EYES) && (head.item_flags & AIRTIGHT))
burn_eyes = 0 burn_eyes = 0
//VOREStation Edit - NIF Support
if(nif && nif.flag_check(NIF_V_UVFILTER,NIF_FLAGS_VISION))
burn_eyes = 0
//If we still need to, burn their eyes //If we still need to, burn their eyes
if(burn_eyes) if(burn_eyes)
burn_eyes() burn_eyes()

103
code/__defines/nifsoft.dm Normal file
View File

@@ -0,0 +1,103 @@
// List indexes for software datum references on mobs
// This also controls the order they are displayed in the NIF stat panel
//AR Overlays
#define NIF_CIVILIAN_AR 1
#define NIF_MEDICAL_AR 2
#define NIF_SECURITY_AR 3
#define NIF_ENGINE_AR 4
#define NIF_SCIENCE_AR 5
#define NIF_OMNI_AR 6
//Misc Vision
#define NIF_CORRECTIVE_GLASS 7
#define NIF_MESONS 8
#define NIF_MATERIAL 9
#define NIF_THERMALS 10
#define NIF_NIGHTVIS 11
#define NIF_UVFILTER 12
#define NIF_FLASHPROT 13
//Health-related
#define NIF_ORGANIC_HEAL 14
#define NIF_SYNTH_HEAL 15
#define NIF_AUTOSTASIS 16 //These two are just part of
#define NIF_MED_ALARM 17 //medichines right now
#define NIF_TOXHEAL 18
#define NIF_SPAREBREATH 19
//Combat Related
#define NIF_BRUTEARMOR 20
#define NIF_BURNARMOR 21
#define NIF_PAINKILLERS 22
#define NIF_HARDCLAWS 23
#define NIF_HIDDENLASER 24
//Other
#define NIF_COMMLINK 25
#define NIF_SUITSENSORS 26
#define NIF_APCCHARGE 27
#define NIF_PRESSURE 28
#define NIF_HEATSINK 29
// Must be equal to the highest number above
#define TOTAL_NIF_SOFTWARE 29
//////////////////////
// NIF flag list hints
#define NIF_FLAGS_VISION 1
#define NIF_FLAGS_HEALTH 2
#define NIF_FLAGS_COMBAT 3
#define NIF_FLAGS_OTHER 4
// NIF flags
//Vision
#define NIF_V_AR_CIVILIAN 0x1
#define NIF_V_AR_MEDICAL 0x2
#define NIF_V_AR_SECURITY 0x4
#define NIF_V_AR_ENGINE 0x8
#define NIF_V_AR_SCIENCE 0x10
#define NIF_V_AR_OMNI 0x20
#define NIF_V_CORRECTIVE 0x40
#define NIF_V_MESONS 0x80
#define NIF_V_MATERIAL 0x100
#define NIF_V_THERMALS 0x200
#define NIF_V_NIGHTVIS 0x400
#define NIF_V_UVFILTER 0x800
#define NIF_V_FLASHPROT 0x1000
//Health
#define NIF_H_ORGREPAIR 0x1
#define NIF_H_SYNTHREPAIR 0x2
#define NIF_H_AUTOSTASIS 0x4 //These two are just part of
#define NIF_H_ALERTMED 0x8 //medichines right now
#define NIF_H_TOXREGEN 0x10
#define NIF_H_SPAREBREATH 0x20
//Combat
#define NIF_C_BRUTEARMOR 0x1
#define NIF_C_BURNARMOR 0x2
#define NIF_C_PAINKILLERS 0x4
#define NIF_C_HARDCLAWS 0x8
#define NIF_C_HIDELASER 0x10
//Other
#define NIF_O_COMMLINK 0x1
#define NIF_O_SENSORS 0x2
#define NIF_O_APCCHARGE 0x4
#define NIF_O_PRESSURESEAL 0x8
#define NIF_O_HEATSINKS 0x10
///////////////////
// applies_to flags
#define NIF_ORGANIC 0x1
#define NIF_SYNTHETIC 0x2
/////////////
// stat flags
#define NIF_WORKING 0
#define NIF_POWFAIL 1
#define NIF_TEMPFAIL 2
#define NIF_INSTALLING 3
#define NIF_PREINSTALL 4
///////////////////
// tick_flags flags
#define NIF_NEVERTICK 0
#define NIF_ALWAYSTICK 1
#define NIF_ACTIVETICK 2

View File

@@ -81,7 +81,15 @@
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
var/flashfail = 0 var/flashfail = 0
if(iscarbon(M)) //VOREStation Add - NIF
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.nif && H.nif.flag_check(NIF_V_FLASHPROT,NIF_FLAGS_VISION))
flashfail = 1
H.nif.notify("High intensity light detected, and blocked!",TRUE)
//VOREStation Add End
if(iscarbon(M) && !flashfail) //VOREStation Add - NIF
var/mob/living/carbon/C = M var/mob/living/carbon/C = M
if(C.stat != DEAD) if(C.stat != DEAD)
var/safety = C.eyecheck() var/safety = C.eyecheck()

View File

@@ -376,6 +376,7 @@
var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES]
if(!E) if(!E)
return return
if(H.nif && H.nif.flag_check(NIF_V_UVFILTER,NIF_FLAGS_VISION)) return //VOREStation Add - NIF
switch(safety) switch(safety)
if(1) if(1)
usr << "<span class='warning'>Your eyes sting a little.</span>" usr << "<span class='warning'>Your eyes sting a little.</span>"

View File

@@ -22,6 +22,13 @@
else else
//Okay, we can breathe, now check if we can get air //Okay, we can breathe, now check if we can get air
breath = get_breath_from_internal() //First, check for air from internals breath = get_breath_from_internal() //First, check for air from internals
//VOREStation Add - Respirocytes as a NIF implant
if(ishuman(src))
var/mob/living/carbon/human/H = src
if(H.nif && H.nif.flag_check(NIF_H_SPAREBREATH,NIF_FLAGS_HEALTH))
var/datum/nifsoft/spare_breath/SB = H.nif.imp_check(NIF_SPAREBREATH)
breath = SB.resp_breath()
//VOREStation Add End
if(!breath) if(!breath)
breath = get_breath_from_environment() //No breath from internals so let's try to get air from our location breath = get_breath_from_environment() //No breath from internals so let's try to get air from our location
if(!breath) if(!breath)

View File

@@ -254,6 +254,7 @@
src.sleeping = max(0,src.sleeping-5) src.sleeping = max(0,src.sleeping-5)
if(src.sleeping == 0) if(src.sleeping == 0)
src.resting = 0 src.resting = 0
if(H) H.in_stasis = 0 //VOREStation Add - Just In Case
M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [t_him] up!</span>", \ M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [t_him] up!</span>", \
"<span class='notice'>You shake [src] trying to wake [t_him] up!</span>") "<span class='notice'>You shake [src] trying to wake [t_him] up!</span>")
else else

View File

@@ -32,7 +32,7 @@
if(force_process) if(force_process)
bad_external_organs.Cut() bad_external_organs.Cut()
for(var/obj/item/organ/external/Ex in organs) for(var/obj/item/organ/external/Ex in organs)
bad_external_organs |= Ex bad_external_organs += Ex //VOREStation Edit - Silly and slow to |= this
//processing internal organs is pretty cheap, do that first. //processing internal organs is pretty cheap, do that first.
for(var/obj/item/organ/I in internal_organs) for(var/obj/item/organ/I in internal_organs)
@@ -44,6 +44,7 @@
if(!force_process && !bad_external_organs.len) if(!force_process && !bad_external_organs.len)
return return
number_wounds = 0 //VOREStation Add - You have to reduce this at some point...
for(var/obj/item/organ/external/E in bad_external_organs) for(var/obj/item/organ/external/E in bad_external_organs)
if(!E) if(!E)
continue continue

View File

@@ -1267,7 +1267,7 @@
var/obj/item/clothing/glasses/G = glasses var/obj/item/clothing/glasses/G = glasses
if(!G.prescription) if(!G.prescription)
set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1) set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
else else if (!nif || !nif.flag_check(NIF_V_CORRECTIVE,NIF_FLAGS_VISION)) //VOREStation Edit - NIF
set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1) set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
set_fullscreen(eye_blurry, "blurry", /obj/screen/fullscreen/blurry) set_fullscreen(eye_blurry, "blurry", /obj/screen/fullscreen/blurry)
@@ -1282,6 +1282,7 @@
var/obj/item/clothing/glasses/welding/O = glasses var/obj/item/clothing/glasses/welding/O = glasses
if(!O.up) if(!O.up)
found_welder = 1 found_welder = 1
if(!found_welder && nif && nif.flag_check(NIF_V_UVFILTER,NIF_FLAGS_VISION)) found_welder = 1 //VOREStation Add - NIF
if(!found_welder && istype(head, /obj/item/clothing/head/welding)) if(!found_welder && istype(head, /obj/item/clothing/head/welding))
var/obj/item/clothing/head/welding/O = head var/obj/item/clothing/head/welding/O = head
if(!O.up) if(!O.up)

View File

@@ -44,8 +44,9 @@
else else
vantag.icon_state = "hudblank" vantag.icon_state = "hudblank"
//Our call for the NIF to do whatever
/mob/living/carbon/human/proc/handle_nif() /mob/living/carbon/human/proc/handle_nif()
if(!nif) return if(!nif) return
//Process regular life stuff //Process regular life stuff
nif.life() nif.life()

481
code/modules/nifsoft/nif.dm Normal file
View File

@@ -0,0 +1,481 @@
//Holder on humans to prevent having to 'find' it every time
/mob/living/carbon/human/var/obj/item/device/nif/nif
//Nanotech Implant Foundation
/obj/item/device/nif
name = "nanotech implant foundation"
desc = "A somewhat degraded copy of a Kitsuhana working surface, in a box. Can print new \
implants inside living hosts on the fly based on software uploads. Must be surgically \
implanted in the head to work. May eventually wear out and break."
icon = 'icons/obj/device_alt.dmi'
icon_state = "nif_0"
w_class = ITEMSIZE_TINY
var/durability = 100 // Durability remaining
var/burn_factor = 100 // Divisor for power charge from nutrition (efficiency basically)
var/tmp/power_usage = 0 // Nifsoft adds to this
var/tmp/mob/living/carbon/human/human // Our owner!
var/tmp/list/nifsofts[TOTAL_NIF_SOFTWARE] // All our nifsofts
var/tmp/list/nifsofts_life = list() // Ones that want to be talked to on life()
var/owner // Owner character name
var/tmp/vision_flags = 0 // Flags implants set for faster lookups
var/tmp/health_flags = 0
var/tmp/combat_flags = 0
var/tmp/other_flags = 0
var/tmp/stat = NIF_PREINSTALL // Status of the NIF
var/tmp/install_done // Time when install will finish
var/tmp/open = FALSE // If it's open for maintenance (1-3)
var/obj/item/clothing/glasses/hud/nif_hud/nif_hud
var/global/icon/big_icon
var/global/click_sound = 'sound/effects/pop.ogg'
//Constructor comes with a free AR HUD
/obj/item/device/nif/New(var/newloc,var/wear)
..(newloc)
new /datum/nifsoft/ar_civ(src)
nif_hud = new(src)
if(!big_icon)
big_icon = new(icon,icon_state = "nif_full")
//Probably loading from a save
if(ishuman(newloc))
var/mob/living/carbon/human/H = newloc
implant(H)
owner = H.mind.name
name = initial(name) + " ([owner])"
stat = NIF_WORKING
if(wear)
durability = wear
update_icon()
//Destructor cleans up references
/obj/item/device/nif/Destroy()
if(human)
human.nif = null
human = null
for(var/S in nifsofts)
if(S)
qdel(S)
nifsofts.Cut()
..()
//Being implanted in some mob
/obj/item/device/nif/proc/implant(var/mob/living/carbon/human/H)
if(istype(H) && !H.nif && H.species && !(H.species.flags & NO_SCAN) && (loc == H.get_organ(BP_HEAD))) //NO_SCAN is the default 'too complicated' flag.
human = H
human.nif = src
stat = NIF_INSTALLING
return TRUE
return FALSE
//For debug or antag purposes
/obj/item/device/nif/proc/quick_implant(var/mob/living/carbon/human/H)
if(istype(H))
var/obj/item/organ/external/head = H.get_organ(BP_HEAD)
if(!head)
return FALSE
src.forceMove(head)
head.implants += src
owner = H.real_name
return implant(H)
return FALSE
//Being implanted in some mob
/obj/item/device/nif/proc/unimplant(var/mob/living/carbon/human/H)
human = null
stat = NIF_PREINSTALL
install_done = null
if(istype(H))
H.nif = null
update_icon()
//EMP adds wear and disables all nifsoft
/obj/item/device/nif/emp_act(var/severity)
notify("Danger! Significant electromagnetic interference!",TRUE)
for(var/nifsoft in nifsofts)
if(nifsoft)
var/datum/nifsoft/NS = nifsoft
NS.deactivate()
switch (severity)
if (1)
wear(rand(30,40))
if (2)
wear(rand(15,25))
if (3)
wear(rand(8,15))
if (4)
wear(rand(1,8))
//Wear update/check proc
/obj/item/device/nif/proc/wear(var/wear = 0)
if(wear)
durability -= wear * rand(0.85,1.15) // Also +/- 15%
if(durability <= 0)
stat = NIF_TEMPFAIL
update_icon()
notify("Danger! General system insta#^!($",TRUE)
to_chat(human,"<span class='danger'>Your NIF vision overlays disappear and your head suddenly seems very quiet...</span>")
//Attackby proc, for maintenance
/obj/item/device/nif/attackby(obj/item/weapon/W, mob/user as mob)
if(open == 0 && istype(W,/obj/item/weapon/screwdriver))
if(do_after(user, 4 SECONDS, src) && open == 0)
user.visible_message("[user] unscrews and pries open \the [src].","<span class='notice'>You unscrew and pry open \the [src].")
playsound(user, 'sound/items/Screwdriver.ogg', 50, 1)
open = 1
update_icon()
else if(open == 1 && istype(W,/obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = W
if(C.get_amount() < 3)
to_chat(user,"<span class='warning'>You need at least three coils of wire to add them to \the [src].</span>")
return
if(do_after(user, 6 SECONDS, src) && open == 1 && C.use(3))
user.visible_message("[user] replaces some wiring in \the [src].","<span class='notice'>You replace any burned out wiring in \the [src].")
playsound(user, 'sound/items/Deconstruct.ogg', 50, 1)
open = 2
update_icon()
else if(open == 2 && istype(W,/obj/item/device/multitool))
if(do_after(user, 8 SECONDS, src) && open == 2)
user.visible_message("[user] resets several circuits in \the [src].","<span class='notice'>You find and repair any faulty circuits in \the [src].")
open = 3
update_icon()
else if(open == 3 && istype(W,/obj/item/weapon/screwdriver))
if(do_after(user, 3 SECONDS, src) && open == 3)
user.visible_message("[user] closes up \the [src].","<span class='notice'>You re-seal \the [src] for use once more.")
playsound(user, 'sound/items/Screwdriver.ogg', 50, 1)
open = FALSE
durability = initial(durability)
stat = NIF_PREINSTALL
update_icon()
//Wear update/check proc
/obj/item/device/nif/update_icon()
if(open)
icon_state = "nif_open[open]"
else
switch(stat)
if(NIF_PREINSTALL)
icon_state = "nif_1"
if(NIF_INSTALLING)
icon_state = "nif_0"
if(NIF_WORKING)
icon_state = "nif_0"
if(NIF_TEMPFAIL)
icon_state = "nif_2"
else
icon_state = "nif_2"
//The (dramatic) install process
/obj/item/device/nif/proc/handle_install()
if(human.stat) //No stuff while KO. Sleeping it off is viable, and doesn't start until you wake up from surgery
return FALSE
//Firsties
if(!install_done)
if(human.real_name == owner)
install_done = world.time + 1 MINUTE
notify("Welcome back, [owner]! Performing quick-calibration...")
else
install_done = world.time + 30 MINUTES
notify("Adapting to new user...")
sleep(5 SECONDS)
notify("Adjoining optic [human.isSynthetic() ? "interface" : "nerve"], please be patient.",TRUE)
var/percent_done = (world.time - (install_done - (30 MINUTES))) / (30 MINUTES)
human.client.screen.Add(global_hud.whitense)
switch(percent_done) //This is 0.0 to 1.0 kinda percent.
//Connecting to optical nerves
if(0.0 to 0.1)
human.eye_blind = 5
//Mapping brain
if(0.2 to 0.9)
if(prob(99)) return TRUE
var/incident = rand(1,3)
switch(incident)
if(1)
var/message = pick(list(
"Your head throbs around your new implant.",
"The skin around your recent surgery itches.",
"A wave of nausea overtakes you as the world seems to spin.",
"The floor suddenly seems to come up at you.",
"There's a throbbing lump of ice behind your eyes.",
"A wave of pain shoots down your neck."
))
to_chat(human,"<span class='danger'>[message]</span>")
if(2)
human.Weaken(5)
to_chat(human,"<span class='danger'>A wave of weakness rolls over you.</span>")
if(3)
human.Sleeping(5)
to_chat(human,"<span class='danger'>You suddenly black out!</span>")
//Finishing up
if(1.0 to INFINITY)
stat = NIF_WORKING
owner = human.real_name
name = initial(name) + " ([owner])"
notify("Calibration complete! User data stored!")
//Called each life() tick on the mob
/obj/item/device/nif/proc/life()
if(!human || loc != human.get_organ(BP_HEAD))
unimplant(human)
return FALSE
switch(stat)
if(NIF_WORKING)
//Perform our passive drain
if(!use_charge(power_usage))
stat = NIF_POWFAIL
notify("Insufficient energy!",TRUE)
return FALSE
//HUD update!
nif_hud.process_hud(human,1)
//Process all the ones that want that
for(var/S in nifsofts_life)
var/datum/nifsoft/nifsoft = S
nifsoft.life(human)
if(NIF_POWFAIL)
if(human && human.nutrition < 100)
return FALSE
else
stat = NIF_WORKING
notify("System Reboot Complete.")
if(NIF_TEMPFAIL)
//Something else has to take us out of tempfail
return FALSE
if(NIF_INSTALLING)
handle_install()
return FALSE
//Prints 'AR' messages to the user
/obj/item/device/nif/proc/notify(var/message,var/alert = 0)
if(!human) return
to_chat(human,"<b>\[\icon[src.big_icon]NIF\]</b> displays, \"<span class='[alert ? "danger" : "notice"]'>[message]</span>\"")
//Called to spend nutrition, returns 1 if it was able to
/obj/item/device/nif/proc/use_charge(var/use_charge)
//You don't want us to take any? Well okay.
if(!use_charge)
return TRUE
//Not enough nutrition/charge left.
if(!human || human.nutrition < use_charge)
return FALSE
//Was enough, reduce and return.
human.nutrition -= use_charge
return TRUE
//Install a piece of software
/obj/item/device/nif/proc/install(var/datum/nifsoft/new_soft)
if(nifsofts[new_soft.list_pos])
return FALSE
if(human)
var/applies_to = new_soft.applies_to
var/synth = human.isSynthetic()
if(synth && !(applies_to & NIF_SYNTHETIC))
notify("The software \"[new_soft]\" is not supported on your chassis type.",TRUE)
return FALSE
if(!synth && !(applies_to & NIF_ORGANIC))
notify("The software \"[new_soft]\" is not supported in organic life.",TRUE)
return FALSE
nifsofts[new_soft.list_pos] = new_soft
power_usage += new_soft.p_drain
if(new_soft.tick_flags == NIF_ALWAYSTICK)
nifsofts_life += new_soft
if(new_soft.vision_flags)
vision_flags |= new_soft.vision_flags
if(new_soft.health_flags)
health_flags |= new_soft.health_flags
if(new_soft.combat_flags)
combat_flags |= new_soft.combat_flags
if(new_soft.other_flags)
other_flags |= new_soft.other_flags
wear(new_soft.wear)
return TRUE
//Uninstall a piece of software
/obj/item/device/nif/proc/uninstall(var/datum/nifsoft/old_soft)
var/datum/nifsoft/NS = old_soft.list_pos
if(!NS || NS != old_soft)
return FALSE //what??
nifsofts[old_soft.list_pos] = null
power_usage -= old_soft.p_drain
if(old_soft.tick_flags == NIF_ALWAYSTICK)
nifsofts_life -= old_soft
if(old_soft.active)
power_usage -= old_soft.a_drain
if(old_soft.tick_flags == NIF_ACTIVETICK)
nifsofts_life -= old_soft
if(old_soft.vision_flags)
vision_flags &= ~old_soft.vision_flags
if(old_soft.health_flags)
health_flags &= ~old_soft.health_flags
if(old_soft.combat_flags)
combat_flags &= ~old_soft.combat_flags
if(old_soft.other_flags)
other_flags &= ~old_soft.other_flags
return TRUE
//Activate a nifsoft
/obj/item/device/nif/proc/activate(var/datum/nifsoft/soft)
if(human)
var/applies_to = soft.applies_to
var/synth = human.isSynthetic()
if(synth && !(applies_to & NIF_SYNTHETIC))
notify("The software \"[soft]\" is not supported on your chassis type and will be uninstalled.",TRUE)
uninstall(soft)
return FALSE
if(!synth && !(applies_to & NIF_ORGANIC))
notify("The software \"[soft]\" is not supported in organic life and will be uninstalled.",TRUE)
uninstall(soft)
return FALSE
if(!use_charge(soft.a_drain))
return FALSE
if(soft.tick_flags == NIF_ACTIVETICK)
nifsofts_life += soft
power_usage += soft.a_drain
human << click_sound
return TRUE
//Deactivate a nifsoft
/obj/item/device/nif/proc/deactivate(var/datum/nifsoft/soft)
if(soft.tick_flags == NIF_ACTIVETICK)
nifsofts_life -= soft
power_usage -= soft.a_drain
human << click_sound
return TRUE
//Deactivate several nifsofts
/obj/item/device/nif/proc/deactivate_these(var/list/turn_off)
for(var/N in turn_off)
var/datum/nifsoft/NS = nifsofts[N]
if(NS)
NS.deactivate()
//Add a flag to one of the holders
/obj/item/device/nif/proc/set_flag(var/flag,var/hint)
ASSERT(flag && hint)
switch(hint)
if(NIF_FLAGS_VISION)
vision_flags |= flag
if(NIF_FLAGS_HEALTH)
health_flags |= flag
if(NIF_FLAGS_COMBAT)
combat_flags |= flag
if(NIF_FLAGS_OTHER)
other_flags |= flag
else
CRASH("Not a valid NIF flag hint: [hint]")
//Clear a flag from one of the holders
/obj/item/device/nif/proc/clear_flag(var/flag,var/hint)
ASSERT(flag && hint)
switch(hint)
if(NIF_FLAGS_VISION)
vision_flags &= ~flag
if(NIF_FLAGS_HEALTH)
health_flags &= ~flag
if(NIF_FLAGS_COMBAT)
combat_flags &= ~flag
if(NIF_FLAGS_OTHER)
other_flags &= ~flag
else
CRASH("Not a valid NIF flag hint: [hint]")
//Check for an installed implant
/obj/item/device/nif/proc/imp_check(var/soft)
if(!stat == NIF_WORKING) return FALSE
ASSERT(soft)
if(ispath(soft))
var/datum/nifsoft/path = soft
soft = initial(path.list_pos)
var/entry = nifsofts[soft]
if(entry)
return entry
//Check for a set flag
/obj/item/device/nif/proc/flag_check(var/flag,var/hint)
if(!stat == NIF_WORKING) return FALSE
ASSERT(flag && hint)
var/result = FALSE
switch(hint)
if(NIF_FLAGS_VISION)
if(flag & vision_flags) result = TRUE
if(NIF_FLAGS_HEALTH)
if(flag & health_flags) result = TRUE
if(NIF_FLAGS_COMBAT)
if(flag & combat_flags) result = TRUE
if(NIF_FLAGS_OTHER)
if(flag & other_flags) result = TRUE
else
CRASH("Not a valid NIF flag hint: [hint]")
return result
//NIF HUD object becasue HUD handling is trash and should be rewritten
/obj/item/clothing/glasses/hud/nif_hud/var/obj/item/device/nif/nif
/obj/item/clothing/glasses/hud/nif_hud/New(var/newloc)
..(newloc)
nif = newloc
/obj/item/clothing/glasses/hud/nif_hud/process_hud(M,var/thing)
//Faster checking with local var, and this is called often so I want fast.
var/visflags = nif.vision_flags
if(NIF_V_AR_OMNI & visflags)
process_omni_hud(nif.human, "best")
else if(NIF_V_AR_SECURITY & visflags)
process_omni_hud(nif.human, "sec")
else if(NIF_V_AR_MEDICAL & visflags)
process_omni_hud(nif.human, "med")
else if(NIF_V_AR_ENGINE & visflags)
process_omni_hud(nif.human, "eng")
else if(NIF_V_AR_SCIENCE & visflags)
process_omni_hud(nif.human, "sci")
else if(NIF_V_AR_CIVILIAN & visflags)
process_omni_hud(nif.human, "civ")

View File

@@ -0,0 +1,111 @@
//Custom vendors
/obj/machinery/vending/nifsoft_shop
name = "NIFSoft Shop"
desc = "For all your mindware and mindware accessories."
product_ads = "Let us get into your head!;Looking for an upgrade?;Surpass Humanity!;Why be normal when you can be SUPERnormal?;Jack in with NIFSoft!"
icon_state = "nifsoft"
icon_vend = "nifsoft-purchase"
icon_deny = "nifsoft-problem"
products = list()
contraband = list()
premium = list()
var/global/list/starting_legal_nifsoft
var/global/list/starting_illegal_nifsoft
// Special Treatment!
/obj/machinery/vending/nifsoft_shop/build_inventory()
//Firsties
if(!starting_legal_nifsoft)
starting_legal_nifsoft = list()
starting_illegal_nifsoft = list()
for(var/P in subtypesof(/datum/nifsoft) - /datum/nifsoft/package)
var/datum/nifsoft/NS = P
if(initial(NS.initial))
switch(initial(NS.illegal))
if(TRUE)
starting_illegal_nifsoft += NS
if(FALSE)
starting_legal_nifsoft += NS
products = starting_legal_nifsoft.Copy()
contraband = starting_illegal_nifsoft.Copy()
var/list/all_products = list(
list(products, CAT_NORMAL),
list(contraband, CAT_HIDDEN),
list(premium, CAT_COIN))
for(var/current_list in all_products)
var/category = current_list[2]
for(var/entry in current_list[1])
var/datum/nifsoft/NS = entry
var/name = initial(NS.name)
var/datum/stored_item/vending_product/product = new/datum/stored_item/vending_product(src, entry, name)
product.price = initial(NS.cost)
product.amount = 10
product.category = category
product_records.Add(product)
/obj/machinery/vending/nifsoft_shop/allowed(mob/user)
if(!ishuman(user))
return FALSE
var/mob/living/carbon/human/H = user
if(!H.nif || !H.nif.stat == NIF_WORKING)
to_chat(H,"<span class='warning'>[src] seems unable to connect to your NIF...</span>")
flick(icon_deny,src)
return FALSE
return ..()
// Also special treatment!
/obj/machinery/vending/nifsoft_shop/vend(datum/stored_item/vending_product/R, mob/user)
var/mob/living/carbon/human/H = user
if((!allowed(usr)) && !emagged && scan_id && istype(H)) //For SECURE VENDING MACHINES YEAH
usr << "<span class='warning'>Purchase not allowed.</span>" //Unless emagged of course
flick(icon_deny,src)
return
vend_ready = 0 //One thing at a time!!
status_message = "Installing..."
status_error = 0
nanomanager.update_uis(src)
if(R.category & CAT_COIN)
if(!coin)
user << "<span class='notice'>You need to insert a coin to get this item.</span>"
return
if(coin.string_attached)
if(prob(50))
user << "<span class='notice'>You successfully pull the coin out before \the [src] could swallow it.</span>"
else
user << "<span class='notice'>You weren't able to pull the coin out fast enough, the machine ate it, string and all.</span>"
qdel(coin)
coin = null
categories &= ~CAT_COIN
else
qdel(coin)
coin = null
categories &= ~CAT_COIN
if(((last_reply + (vend_delay + 200)) <= world.time) && vend_reply)
spawn(0)
speak(vend_reply)
last_reply = world.time
use_power(vend_power_usage) //actuators and stuff
spawn(vend_delay)
R.amount--
new R.item_path(H.nif)
flick(icon_vend,src)
if(has_logs)
do_logging(R, user, 1)
status_message = ""
status_error = 0
vend_ready = 1
currently_vending = null
nanomanager.update_uis(src)
return 1

View File

@@ -0,0 +1,77 @@
/mob/living/carbon/human/Stat()
. = ..()
if(nif && statpanel("NIF"))
SetupNifStat()
/mob/living/carbon/human/proc/SetupNifStat()
var/nif_status
switch(nif.stat)
if(NIF_WORKING)
nif_status = "Operating Normally"
if(NIF_POWFAIL)
nif_status = "Insufficient Energy!"
if(NIF_TEMPFAIL)
nif_status = "Needs Maintenance!"
if(NIF_INSTALLING)
nif_status = "Adapting To User"
else
nif_status = "Unknown - Error"
stat("NIF Status", nif_status)
if(!nif.stat)
stat("- Modules -", "LMB: Toggle, Shift+LMB: Info/Uninstall")
for(var/nifsoft in nif.nifsofts)
if(!nifsoft) continue
var/datum/nifsoft/NS = nifsoft
var/obj/effect/nif_stat/stat_line = NS.stat_line
stat("[stat_line.nifsoft_name]",stat_line.atom_button_text())
///////////////////
// Stat Line Object
/obj/effect/nif_stat
name = ""
var/nifsoft_name //Prevents deeper lookups, and the name won't change
var/datum/nifsoft/nifsoft //Reference to our nifsoft
var/toggleable = FALSE //Won't change, prevents looking it up deeper
/obj/effect/nif_stat/New(var/datum/nifsoft/new_soft)
..()
nifsoft = new_soft
nifsoft_name = new_soft.name
name = new_soft.name
toggleable = new_soft.activates
/obj/effect/nif_stat/Destroy()
nifsoft = null
..()
/obj/effect/nif_stat/proc/atom_button_text()
if(!toggleable)
name = "Always On"
else
name = "[nifsoft.active ? "Active" : "Disabled"]"
return src
/obj/effect/nif_stat/Click(var/location, var/control, var/params)
if(usr != nifsoft.nif.human) return
var/list/clickprops = params2list(params)
var/opts = clickprops["shift"]
if(opts)
var/choice = alert("Select an option","[nifsoft_name]","Display Info","Cancel","Uninstall")
switch(choice)
if("Display Info")
nifsoft.nif.notify("[nifsoft_name]: [nifsoft.desc] - It consumes [nifsoft.p_drain] energy units \
while installed, and [nifsoft.a_drain] additionally while active. It is [nifsoft.illegal ? "NOT " : ""]\
a legal software package. The MSRP of the package is [nifsoft.cost] Thalers. The difficulty to construct \
the associated implant is Rating [nifsoft.wear].")
if("Uninstall")
var/confirm = alert("Really uninstall [nifsoft_name]?","Are you sure?","Cancel","Uninstall","Cancel")
if(confirm == "Uninstall")
nifsoft.uninstall()
else if(nifsoft.activates)
if(nifsoft.active)
nifsoft.deactivate()
else
nifsoft.activate()

View File

@@ -0,0 +1,110 @@
//A single piece of NIF software
/datum/nifsoft
var/name = "Prototype"
var/desc = "Contact a dev!"
var/obj/item/device/nif/nif //The NIF that the software is stored in
var/list_pos // List position in the nifsoft list
var/cost = 1000 // Cost in cash of buying this software from a terminal
//TODO - While coding
var/initial = TRUE // This is available in NIFSoft Shops at the start of the game
var/wear = 1 // The wear (+/- 10% when applied) that this causes to the NIF
var/list/req_one_access // What access they need to buy it
var/illegal = FALSE // If this is a black-market nifsoft (emag option)
var/active = FALSE // Whether the active mode of this implant is on
var/p_drain = 0 // Passive power drain, can be used in various ways from the software
var/a_drain = 0 // Active power drain, same purpose as above, software can treat however
var/activates = TRUE // Whether or not this has an active power consumption mode
var/tick_flags = 0 // Flags to tell when we'd like to be ticked
var/empable = TRUE // If the implant can be destroyed via EMP attack
var/expiring = FALSE // Trial software! Or self-deleting illegal ones!
var/expires_at // World.time for when they expire
var/applies_to = (NIF_ORGANIC|NIF_SYNTHETIC) // Who this software is useful for
var/vision_flags = 0 // Various flags for fast lookups that are settable on the NIF
var/health_flags = 0 // These are added as soon as the implant is installed
var/combat_flags = 0 // Otherwise use set_flag on the nif in your activate/deactivate
var/other_flags = 0
var/obj/effect/nif_stat/stat_line
//Constructor accepts the NIF it's being loaded into
/datum/nifsoft/New(var/obj/item/device/nif/nif_load)
ASSERT(nif_load)
nif = nif_load
stat_line = new(src)
if(!install(nif))
qdel(src)
//Destructor cleans up the software and nif reference
/datum/nifsoft/Destroy()
if(nif)
uninstall(nif)
nif = null
qdel(stat_line)
stat_line = null
..()
//Called when the software is installed in the NIF
/datum/nifsoft/proc/install()
return nif.install(src)
//Called when the software is removed from the NIF
/datum/nifsoft/proc/uninstall()
if(active)
deactivate()
if(nif)
. = nif.uninstall(src)
qdel(src)
//Called every life() tick on a mob on active implants
/datum/nifsoft/proc/life(var/mob/living/carbon/human/human)
return TRUE
//Called when attempting to activate an implant (could be a 'pulse' activation or toggling it on)
/datum/nifsoft/proc/activate()
var/nif_result = nif.activate(src)
if(nif_result)
active = TRUE
return nif_result
//Called when attempting to deactivate an implant
/datum/nifsoft/proc/deactivate()
var/nif_result = nif.deactivate(src)
if(nif_result)
active = FALSE
return nif_result
//Called when an implant expires
/datum/nifsoft/proc/expire()
uninstall()
return
//////////////////////
//A package of NIF software
/datum/nifsoft/package
var/list/software = list()
wear = 0 //Packages don't cause wear themselves, the software does
//Constructor accepts a NIF and loads all the software
/datum/nifsoft/package/New(var/obj/item/device/nif/nif_load)
ASSERT(nif_load)
for(var/P in software)
new P(nif_load)
qdel(src)
//Clean self up
/datum/nifsoft/package/Destroy()
software.Cut()
software = null
..()

View File

@@ -0,0 +1,253 @@
//////////////////
// AR HUD Overlays
/datum/nifsoft/ar_civ
name = "AR Overlay (Civ)"
desc = "Provides a general identification and health status overlay on your vision with no frills."
list_pos = NIF_CIVILIAN_AR
cost = 500
initial = TRUE
a_drain = 0.05
activate()
if(..())
nif.deactivate_these(NIF_MEDICAL_AR,NIF_SECURITY_AR,NIF_ENGINE_AR,NIF_SCIENCE_AR,NIF_OMNI_AR)
nif.set_flag(NIF_V_AR_CIVILIAN,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_AR_CIVILIAN,NIF_FLAGS_VISION)
/datum/nifsoft/ar_med
name = "AR Overlay (Med)"
desc = "Like the civilian model, but provides medical records access and virus database lookup."
list_pos = NIF_MEDICAL_AR
cost = 750
initial = TRUE
req_one_access = list(access_medical)
a_drain = 0.05
activate()
if(..())
nif.deactivate_these(NIF_CIVILIAN_AR,NIF_SECURITY_AR,NIF_ENGINE_AR,NIF_SCIENCE_AR,NIF_OMNI_AR)
nif.set_flag(NIF_V_AR_MEDICAL,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_AR_MEDICAL,NIF_FLAGS_VISION)
/datum/nifsoft/ar_sec
name = "AR Overlay (Sec)"
desc = "Like the civilian model, but provides access to arrest status and security records."
list_pos = NIF_SECURITY_AR
cost = 750
initial = TRUE
req_one_access = list(access_security)
a_drain = 0.05
activate()
if(..())
nif.deactivate_these(NIF_CIVILIAN_AR,NIF_MEDICAL_AR,NIF_ENGINE_AR,NIF_SCIENCE_AR,NIF_OMNI_AR)
nif.set_flag(NIF_V_AR_SECURITY,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_AR_SECURITY,NIF_FLAGS_VISION)
/datum/nifsoft/ar_eng
name = "AR Overlay (Eng)"
desc = "Like the civilian model, but provides station alert notices."
list_pos = NIF_ENGINE_AR
cost = 750
initial = TRUE
req_one_access = list(access_engine)
a_drain = 0.05
activate()
if(..())
nif.deactivate_these(NIF_CIVILIAN_AR,NIF_MEDICAL_AR,NIF_SECURITY_AR,NIF_SCIENCE_AR,NIF_OMNI_AR)
nif.set_flag(NIF_V_AR_ENGINE,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_AR_ENGINE,NIF_FLAGS_VISION)
/datum/nifsoft/ar_science
name = "AR Overlay (Sci)"
desc = "Like the civilian model, but provides ... well, nothing. For now."
list_pos = NIF_SCIENCE_AR
cost = 750
initial = TRUE
req_one_access = list(access_research)
a_drain = 0.05
activate()
if(..())
nif.deactivate_these(NIF_CIVILIAN_AR,NIF_MEDICAL_AR,NIF_SECURITY_AR,NIF_ENGINE_AR,NIF_OMNI_AR)
nif.set_flag(NIF_V_AR_SCIENCE,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_AR_SCIENCE,NIF_FLAGS_VISION)
/datum/nifsoft/ar_omni
name = "AR Overlay (Omni)"
desc = "Like the civilian model, but provides most of the features of the medical and security overlays as well."
list_pos = NIF_OMNI_AR
cost = 750
initial = TRUE
req_one_access = list(access_captain)
a_drain = 0.05
activate()
if(..())
nif.deactivate_these(NIF_CIVILIAN_AR,NIF_MEDICAL_AR,NIF_SECURITY_AR,NIF_ENGINE_AR,NIF_SCIENCE_AR)
nif.set_flag(NIF_V_AR_OMNI,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_AR_OMNI,NIF_FLAGS_VISION)
//////////////
// Misc Vision
/datum/nifsoft/corrective
name = "Corrective AR"
desc = "Subtly alters perception to compensate for cataracts and retinal misalignment, among other common disabilities."
list_pos = NIF_CORRECTIVE_GLASS
cost = 200
a_drain = 0.025
activate()
if(..())
nif.set_flag(NIF_V_CORRECTIVE,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_CORRECTIVE,NIF_FLAGS_VISION)
/datum/nifsoft/uvblocker
name = "Nictating Membrane"
desc = "A synthetic nictating membrane (aka 'third eyelid') that protects the eyes from UV or hostile atmospheres. Does not protect from photonic stun weapons."
list_pos = NIF_UVFILTER
cost = 450
a_drain = 0.2
activate()
if(..())
nif.set_flag(NIF_V_UVFILTER,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_UVFILTER,NIF_FLAGS_VISION)
/datum/nifsoft/flashprot
name = "Responsive Filter"
desc = "Enables a high-speed shielding response to intense light, such as flashes, to block them."
list_pos = NIF_FLASHPROT
cost = 600
req_one_access = list(access_security)
a_drain = 0.05
activate()
if(..())
nif.set_flag(NIF_V_FLASHPROT,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_FLASHPROT,NIF_FLAGS_VISION)
////////////////
// Goggle-alikes
/datum/nifsoft/mesons
name = "Meson Scanner"
desc = "Similar to the worn Optical Meson Scanner Goggles, these allow you to see the base structure and terrain through walls."
list_pos = NIF_MESONS
cost = 1000
a_drain = 0.1
tick_flags = NIF_ACTIVETICK
activate()
if(..())
nif.deactivate_these(NIF_MATERIAL,NIF_THERMALS,NIF_NIGHTVIS)
nif.set_flag(NIF_V_MESONS,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_MESONS,NIF_FLAGS_VISION)
life()
if(..())
var/mob/living/carbon/human/H = nif.human
H.client.screen |= global_hud.meson
H.sight |= SEE_TURFS
/datum/nifsoft/material
name = "Material Scanner"
desc = "Similar to the worn Optical Material Scanner Goggles, these allow you to see objects through walls."
list_pos = NIF_MATERIAL
cost = 1000
a_drain = 0.1
tick_flags = NIF_ACTIVETICK
activate()
if(..())
nif.deactivate_these(NIF_MESONS,NIF_THERMALS,NIF_NIGHTVIS)
nif.set_flag(NIF_V_MATERIAL,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_MATERIAL,NIF_FLAGS_VISION)
life()
if(..())
nif.human.sight |= SEE_OBJS
/datum/nifsoft/thermals
name = "Thermal Scanner"
desc = "Similar to the worn Thermal Goggles, these allow you to see heat-emitting creatures through walls."
list_pos = NIF_THERMALS
cost = 1000
req_one_access = list(access_security)
a_drain = 0.1
tick_flags = NIF_ACTIVETICK
activate()
if(..())
nif.deactivate_these(NIF_MESONS,NIF_MATERIAL,NIF_NIGHTVIS)
nif.set_flag(NIF_V_THERMALS,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_THERMALS,NIF_FLAGS_VISION)
life()
if(..())
var/mob/living/carbon/human/H = nif.human
H.sight |= SEE_MOBS
H.client.screen |= global_hud.thermal
H.see_invisible = SEE_INVISIBLE_NOLIGHTING
/datum/nifsoft/nightvis
name = "Low-Light Amp"
desc = "Similar to the worn Night Vision Goggles, these allow you to see in complete darkness."
list_pos = NIF_NIGHTVIS
cost = 1000
req_one_access = list(access_security)
a_drain = 0.1
tick_flags = NIF_ACTIVETICK
activate()
if(..())
nif.deactivate_these(NIF_MESONS,NIF_MATERIAL,NIF_THERMALS)
nif.set_flag(NIF_V_NIGHTVIS,NIF_FLAGS_VISION)
deactivate()
if(..())
nif.clear_flag(NIF_V_NIGHTVIS,NIF_FLAGS_VISION)
life()
if(..())
var/mob/living/carbon/human/H = nif.human
H.see_in_dark += 7
H.client.screen |= global_hud.nvg
H.see_invisible = SEE_INVISIBLE_NOLIGHTING

View File

@@ -0,0 +1,184 @@
/*
#define NIF_SPAREBREATH 17
*/
/datum/nifsoft/medichines_org
name = "Medichines (Org)"
desc = "An internal swarm of nanites to make sure you stay in good shape and to promote healing, or to preserve you if you are critically injured."
list_pos = NIF_ORGANIC_HEAL
cost = 2500
p_drain = 0.05
a_drain = 0.1 //This is messed with manually below.
activates = FALSE //It is automatic in emergencies, not manually controllable.
tick_flags = NIF_ALWAYSTICK
applies_to = NIF_ORGANIC
var/mode = 0
//These self-activate on their own, these aren't user-settable to on/off.
activate()
if(..())
nif.set_flag(NIF_H_ORGREPAIR,NIF_FLAGS_HEALTH)
mode = 1
deactivate()
if(..())
nif.clear_flag(NIF_H_ORGREPAIR,NIF_FLAGS_HEALTH)
a_drain = initial(a_drain)
mode = initial(mode)
nif.human.in_stasis = 0
life()
if(..())
var/mob/living/carbon/human/H = nif.human
var/HP_percent = H.health/H.getMaxHealth()
//Mode changing state machine
if(HP_percent >= 0.9)
if(mode)
nif.notify("User Status: NORMAL. Medichines deactivating.")
deactivate()
return TRUE
else if(!mode && HP_percent < 0.8)
nif.notify("User Status: INJURED. Commencing medichine routines.",TRUE)
activate()
else if(mode == 1 && HP_percent < 0.2)
nif.notify("User Status: DANGER. Seek medical attention!",TRUE)
mode = 2
else if(mode == 2 && HP_percent < -0.4)
nif.notify("User Status: CRITICAL. Notifying medical, and starting emergency stasis!",TRUE)
mode = 3
if(!ishuman(H.loc)) //Not notified in case of vore, for gameplay purposes.
var/turf/T = get_turf(H)
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
a.autosay("[H.real_name] has been put in emergency stasis, located at ([T.x],[T.y],[T.z])!", "[H.real_name]'s NIF", "Medical")
qdel(a)
//Handle the actions in each mode
//Injured but not critical
if(mode)
H.adjustToxLoss(-0.1 * mode)
H.adjustBruteLoss(-0.1 * mode)
H.adjustFireLoss(-0.1 * mode)
if(mode >= 2)
nif.use_charge(a_drain) //A second drain if we're in level 2+
//Patient critical - emergency stasis
if(mode >= 3)
if(HP_percent <= 0)
H.in_stasis = 3
if(HP_percent > 0.2)
H.in_stasis = 0
nif.notify("Ending emergency stasis.",TRUE)
mode = 2
return TRUE
/datum/nifsoft/medichines_syn
name = "Medichines (Syn)"
desc = "A swarm of mechanical repair nanites, able to repair relatively minor damage to synthetic bodies. Large repairs must still be performed manually."
list_pos = NIF_SYNTH_HEAL
cost = 2500
p_drain = 0.05
a_drain = 0.00 //This is manually drained below.
activates = FALSE //It is automatic in emergencies, not manually controllable.
tick_flags = NIF_ALWAYSTICK
applies_to = NIF_SYNTHETIC
var/mode = 0
//These self-activate on their own, these aren't user-settable to on/off.
activate()
if(..())
nif.set_flag(NIF_H_SYNTHREPAIR,NIF_FLAGS_HEALTH)
mode = 1
deactivate()
if(..())
nif.clear_flag(NIF_H_SYNTHREPAIR,NIF_FLAGS_HEALTH)
mode = 0
life()
if(..())
//We're good!
if(!nif.human.bad_external_organs.len)
if(mode || active)
nif.notify("User Status: NORMAL. Medichines deactivating.")
deactivate()
return TRUE
if(!mode && !active)
nif.notify("User Status: DAMAGED. Medichines performing minor repairs.",TRUE)
activate()
for(var/eo in nif.human.bad_external_organs)
var/obj/item/organ/external/EO = eo
for(var/w in EO.wounds)
var/datum/wound/W = w
if(W.damage <= 5)
W.heal_damage(0.1)
EO.update_damages()
if(EO.update_icon())
nif.human.UpdateDamageIcon(1)
nif.use_charge(0.1)
return TRUE //Return entirely, we only heal one at a time.
else if(mode == 1)
mode = 2
nif.notify("Medichines unable to repair all damage. Perform manual repairs.",TRUE)
return TRUE
/datum/nifsoft/spare_breath
name = "Respirocytes"
desc = "Nanites simulating red blood cells will filter and recycle oxygen for a short time, preventing suffocation in hostile environments. NOTE: Only capable of supplying OXYGEN."
list_pos = NIF_SPAREBREATH
cost = 650
p_drain = 0.05
a_drain = 0.1
tick_flags = NIF_ALWAYSTICK
applies_to = NIF_ORGANIC
var/filled = 100 //Tracks the internal tank 'refilling', which still uses power
activate()
if(!(filled > 50))
nif.notify("Respirocytes not saturated!",TRUE)
return FALSE
if(..())
nif.set_flag(NIF_H_SPAREBREATH,NIF_FLAGS_HEALTH)
nif.notify("Now taking air from reserves.")
deactivate()
if(..())
nif.clear_flag(NIF_H_SPAREBREATH,NIF_FLAGS_HEALTH)
nif.notify("Now taking air from environment and refilling reserves.")
life()
if(..())
if(active) //Supplying air, not recharging it
switch(filled) //Text warnings
if(75)
nif.notify("Respirocytes at 75% saturation.",TRUE)
if(50)
nif.notify("Respirocytes at 50% saturation!",TRUE)
if(25)
nif.notify("Respirocytes at 25% saturation, seek a habitable environment!",TRUE)
if(5)
nif.notify("Respirocytes at 5% saturation! Failure imminent!",TRUE)
if(filled == 0) //Ran out
deactivate()
else //Drain a little
filled--
else //Recharging air, not supplying it
if(filled == 100)
return TRUE
else if(nif.use_charge(0.1) && ++filled == 100)
nif.notify("Respirocytes now fully saturated.")
proc/resp_breath()
if(!active) return null
var/datum/gas_mixture/breath = new()
breath.adjust_gas("oxygen", 300)
breath.temperature = T20C
return breath

View File

@@ -0,0 +1,7 @@
/*
#define NIF_BRUTEARMOR 18
#define NIF_BURNARMOR 19
#define NIF_PAINKILLERS 20
#define NIF_HARDCLAWS 21
#define NIF_HIDDENLASER 22
*/

View File

@@ -0,0 +1,9 @@
/*
#define NIF_COMMLINK 23
#define NIF_SUITSENSORS 24
#define NIF_APCCHARGE 25
#define NIF_PRESSURE 26
#define NIF_HEATSINK 27
#define NIF_UVFILTER 28
#define NIF_FLASHPROT 29
*/

View File

@@ -546,7 +546,7 @@ This function completely restores a damaged organ to perfect condition.
/obj/item/organ/external/proc/need_process() /obj/item/organ/external/proc/need_process()
if(status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_MUTATED)) if(status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_MUTATED))
return 1 return 1
if((brute_dam || burn_dam) && (robotic < ORGAN_ROBOT)) //Robot limbs don't autoheal and thus don't need to process when damaged if(brute_dam || burn_dam)//VOREStation Edit - But they do for medichines! ---&& (robotic < ORGAN_ROBOT)) //Robot limbs don't autoheal and thus don't need to process when damaged
return 1 return 1
if(last_dam != brute_dam + burn_dam) // Process when we are fully healed up. if(last_dam != brute_dam + burn_dam) // Process when we are fully healed up.
last_dam = brute_dam + burn_dam last_dam = brute_dam + burn_dam

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -1965,11 +1965,13 @@
#include "code\modules\nano\modules\power_monitor.dm" #include "code\modules\nano\modules\power_monitor.dm"
#include "code\modules\nano\modules\rcon.dm" #include "code\modules\nano\modules\rcon.dm"
#include "code\modules\nifsoft\nif.dm" #include "code\modules\nifsoft\nif.dm"
#include "code\modules\nifsoft\nif_interface.dm"
#include "code\modules\nifsoft\nif_softshop.dm" #include "code\modules\nifsoft\nif_softshop.dm"
#include "code\modules\nifsoft\nif_statpanel.dm" #include "code\modules\nifsoft\nif_statpanel.dm"
#include "code\modules\nifsoft\nifsoft.dm" #include "code\modules\nifsoft\nifsoft.dm"
#include "code\modules\nifsoft\software\vision.dm" #include "code\modules\nifsoft\software\01_vision.dm"
#include "code\modules\nifsoft\software\05_health.dm"
#include "code\modules\nifsoft\software\10_combat.dm"
#include "code\modules\nifsoft\software\15_misc.dm"
#include "code\modules\organs\blood.dm" #include "code\modules\organs\blood.dm"
#include "code\modules\organs\misc.dm" #include "code\modules\organs\misc.dm"
#include "code\modules\organs\organ.dm" #include "code\modules\organs\organ.dm"