Moved everything to a module-based hardsuit system.

Generalized all ninja power and gear code to work with new rig system.
Added shurikens, weapon mount, more work on deployable items.
Readded energy nets and energy blades.
Grenade launcher/charge stuff, interface stuff.
Renamed previously existing rigs to voidsuits, restructured rig and voidsuit files.
Refactored the energy net and teleportation proc.
Totally rewrote AI core/intellicard transfer procs.
Added rig sprites by Mordeth221, added step by steap suit sealing/inability to interfere with suit sealing process.
Updated map paths to use voidsuits.
Added chemical dispenser functionality, added power sink, added atom/drain_power() proc for later use.
Added rigsuit verbs, added voice changer.
Renamed MASKINTERNALS to AIRTIGHT, added internals checks for airtight helmets.
Added drain_power() procs to vulnerable machinery.
Reimplemented data theft.
Added suit maluses for losing your cell while wearing one.
Transitioned the rig suits to a back-mounted item that also controls a chestpiece.
Converted rig module to a storage item, convert ERT voidsuits to hardsuits.
This commit is contained in:
Zuhayr
2014-11-14 22:57:26 +10:30
parent 40e3ea33f6
commit ebbb9b36b5
102 changed files with 3725 additions and 3829 deletions

View File

@@ -234,8 +234,6 @@
#include "code\game\gamemodes\events\clang.dm"
#include "code\game\gamemodes\events\dust.dm"
#include "code\game\gamemodes\events\miniblob.dm"
#include "code\game\gamemodes\events\ninja_abilities.dm"
#include "code\game\gamemodes\events\ninja_equipment.dm"
#include "code\game\gamemodes\events\power_failure.dm"
#include "code\game\gamemodes\events\space_ninja.dm"
#include "code\game\gamemodes\events\spacevines.dm"
@@ -776,7 +774,6 @@
#include "code\modules\clothing\gloves\boxing.dm"
#include "code\modules\clothing\gloves\color.dm"
#include "code\modules\clothing\gloves\miscellaneous.dm"
#include "code\modules\clothing\gloves\ninja.dm"
#include "code\modules\clothing\head\collectable.dm"
#include "code\modules\clothing\head\hardhat.dm"
#include "code\modules\clothing\head\helmet.dm"
@@ -788,19 +785,35 @@
#include "code\modules\clothing\masks\breath.dm"
#include "code\modules\clothing\masks\gasmask.dm"
#include "code\modules\clothing\masks\miscellaneous.dm"
#include "code\modules\clothing\masks\voice.dm"
#include "code\modules\clothing\shoes\colour.dm"
#include "code\modules\clothing\shoes\magboots.dm"
#include "code\modules\clothing\shoes\miscellaneous.dm"
#include "code\modules\clothing\spacesuits\alien.dm"
#include "code\modules\clothing\spacesuits\breaches.dm"
#include "code\modules\clothing\spacesuits\captain.dm"
#include "code\modules\clothing\spacesuits\ert.dm"
#include "code\modules\clothing\spacesuits\miscellaneous.dm"
#include "code\modules\clothing\spacesuits\ninja.dm"
#include "code\modules\clothing\spacesuits\rig.dm"
#include "code\modules\clothing\spacesuits\spacesuits.dm"
#include "code\modules\clothing\spacesuits\syndi.dm"
#include "code\modules\clothing\spacesuits\void.dm"
#include "code\modules\clothing\spacesuits\rig\rig.dm"
#include "code\modules\clothing\spacesuits\rig\rig_attackby.dm"
#include "code\modules\clothing\spacesuits\rig\rig_pieces.dm"
#include "code\modules\clothing\spacesuits\rig\rig_verbs.dm"
#include "code\modules\clothing\spacesuits\rig\modules\combat.dm"
#include "code\modules\clothing\spacesuits\rig\modules\computer.dm"
#include "code\modules\clothing\spacesuits\rig\modules\modules.dm"
#include "code\modules\clothing\spacesuits\rig\modules\ninja.dm"
#include "code\modules\clothing\spacesuits\rig\modules\utility.dm"
#include "code\modules\clothing\spacesuits\rig\modules\vision.dm"
#include "code\modules\clothing\spacesuits\rig\suits\ert.dm"
#include "code\modules\clothing\spacesuits\rig\suits\hacker.dm"
#include "code\modules\clothing\spacesuits\rig\suits\light.dm"
#include "code\modules\clothing\spacesuits\rig\suits\ninja.dm"
#include "code\modules\clothing\spacesuits\rig\suits\stealth.dm"
#include "code\modules\clothing\spacesuits\void\merc.dm"
#include "code\modules\clothing\spacesuits\void\station.dm"
#include "code\modules\clothing\spacesuits\void\void.dm"
#include "code\modules\clothing\spacesuits\void\wizard.dm"
#include "code\modules\clothing\suits\alien.dm"
#include "code\modules\clothing\suits\armor.dm"
#include "code\modules\clothing\suits\bio.dm"

View File

@@ -50,20 +50,25 @@
var/mob/living/silicon/ai/occupant = null
var/busy = 0
// Ninja gloves check
attack_hand(mob/user as mob)
if(ishuman(user) && istype(user:gloves, /obj/item/clothing/gloves/space_ninja) && user:gloves:candrain && !user:gloves:draining)
if(user:wear_suit:s_control)
user:wear_suit.transfer_ai("AIFIXER","NINJASUIT",src,user)
else
user << "\red <b>ERROR</b>: \black Remote access channel disabled."
return
..()
attackby(obj/I as obj,mob/user as mob)
if(computer && !computer.stat)
if(istype(I, /obj/item/device/aicard))
I:transfer_ai("AIFIXER","AICARD",src,user)
var/obj/item/device/aicard/card = I
var/mob/living/silicon/ai/comp_ai = locate() in src
var/mob/living/silicon/ai/card_ai = locate() in card
if(istype(comp_ai))
if(busy)
user << "\red <b>ERROR</b>: \black Reconstruction in progress."
return
card.grab_ai(comp_ai, user)
if(!(locate(/mob/living/silicon/ai) in src)) occupant = null
else if(istype(card_ai))
load_ai(card_ai,card,user)
occupant = locate(/mob/living/silicon/ai) in src
if(computer.program)
computer.program.update_icon()
computer.update_icon()
@@ -71,6 +76,24 @@
..()
return
/obj/item/part/computer/ai_holder/proc/load_ai(var/mob/living/silicon/ai/transfer, var/obj/item/device/aicard/card, var/mob/user)
if(!transfer)
return
// Transfer over the AI.
transfer << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
user << "\blue <b>Transfer successful</b>: \black [transfer.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed."
transfer.loc = src
transfer.cancel_camera()
transfer.control_disabled = 1
occupant = transfer
if(card)
card.clear()
/*
ID computer cardslot - reading and writing slots
*/

View File

@@ -208,9 +208,22 @@
*/
/mob/proc/MiddleClickOn(var/atom/A)
return
/mob/living/carbon/MiddleClickOn(var/atom/A)
swap_hand()
/mob/living/carbon/human/MiddleClickOn(var/atom/A)
if(back)
var/obj/item/weapon/storage/rig/rig = back
if(istype(rig) && rig.selected_module)
if(world.time <= next_move) return
next_move = world.time + 8
rig.selected_module.engage(A)
return
swap_hand()
// In case of use break glass
/*
/atom/proc/MiddleClick(var/mob/M as mob)

View File

@@ -267,8 +267,15 @@
if(C.internals)
C.internals.icon_state = "internal0"
else
if(!istype(C.wear_mask, /obj/item/clothing/mask))
var/no_mask
if(!(C.wear_mask && C.wear_mask.flags & AIRTIGHT))
var/mob/living/carbon/human/H = C
if(!(H.head && H.head.flags & AIRTIGHT))
C << "<span class='notice'>You are not wearing a mask.</span>"
no_mask = 1
if(no_mask)
return 1
else
var/list/nicename = null

View File

@@ -73,13 +73,13 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
if(!istype(usr, /mob/living/carbon/human))
usr << "You aren't a human, Why are you trying to cast a human spell, silly non-human? Casting human spells is for humans."
return 0
if(!istype(usr:wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(user:wear_suit, /obj/item/clothing/suit/space/rig/wizard))
if(!istype(usr:wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(user:wear_suit, /obj/item/clothing/suit/space/void/wizard))
usr << "I don't feel strong enough without my robe."
return 0
if(!istype(usr:shoes, /obj/item/clothing/shoes/sandal))
usr << "I don't feel strong enough without my sandals."
return 0
if(!istype(usr:head, /obj/item/clothing/head/wizard) && !istype(user:head, /obj/item/clothing/head/helmet/space/rig/wizard))
if(!istype(usr:head, /obj/item/clothing/head/wizard) && !istype(user:head, /obj/item/clothing/head/helmet/space/void/wizard))
usr << "I don't feel strong enough without my hat."
return 0

View File

@@ -356,7 +356,6 @@
if(player.current && !(istype(player.current,/mob/living/carbon/human))) return 0
//Ninja intro crawl goes here.
if(!config.objectives_disabled)
player.objectives += new /datum/objective/ninja_highlander()
player.objectives += new /datum/objective/survive()
@@ -369,9 +368,6 @@
var/mob/living/carbon/human/N = player.current
N.internal = N.s_store
N.internals.icon_state = "internal1"
if(N.wear_suit && istype(N.wear_suit,/obj/item/clothing/suit/space/space_ninja))
var/obj/item/clothing/suit/space/space_ninja/S = N.wear_suit
S:randomize_param()
/datum/game_mode/calamity/proc/spawn_vox_raiders(var/list/candidates)

View File

@@ -1,404 +0,0 @@
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++
==================================SPACE NINJA ABILITIES====================================
___________________________________________________________________________________________
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
//=======//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.
*/
/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.
U << "\red You must be conscious and solid to do this."//It's not a problem of stat==2 since the ninja will explode anyway if they die.
return 1
else if(C&&cell.charge < C*10)
U << "\red Not enough energy."
return 1
switch(X)
if(1)
cancel_stealth()//Get rid of it.
if(2)
if(s_bombs<=0)
U << "\red There are no more smoke bombs remaining."
return 1
if(3)
if(a_boost<=0)
U << "\red You do not have any more adrenaline boosters."
return 1
if(s_coold)
return s_coold
cell.use(C*10)
return 0
//=======//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."
set category = "Ninja Ability"
set popup_menu = 0//Will not see it when right clicking.
if(!ninjacost(,2))
var/mob/living/carbon/human/U = affecting
U << "\blue There are <B>[s_bombs]</B> smoke bombs remaining."
var/datum/effect/effect/system/smoke_spread/bad/smoke = new /datum/effect/effect/system/smoke_spread/bad()
smoke.set_up(10, 0, U.loc)
smoke.start()
playsound(U.loc, 'sound/effects/bamf.ogg', 50, 2)
s_bombs--
s_coold = 1
return
//=======//PHASE SHIFT//=======//
//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 (400E)"
set desc = "Utilizes the internal VOID-shift device to rapidly transit to a destination in view."
set category = null//So it does not show up on the panel but can still be right-clicked.
set src = usr.contents//Fixes verbs not attaching properly for objects. Praise the DM reference guide!
var/C = 40
if(!ninjacost(C,1))
var/mob/living/carbon/human/U = affecting
var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below.
if((!T.density)&&istype(mobloc, /turf))
spawn(0)
playsound(U.loc, 'sound/effects/sparks4.ogg', 50, 1)
anim(mobloc,src,'icons/mob/mob.dmi',,"phaseout",,U.dir)
handle_teleport_grab(T, U)
U.loc = T
s_coold = 1
spawn(0)
spark_system.start()
playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1)
playsound(U.loc, 'sound/effects/sparks2.ogg', 50, 1)
anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
else
U << "\red You cannot teleport into solid walls or from solid matter."
return
//=======//PHASE JAUNT//=======//
/obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt()
set name = "Phase Jaunt (250E)"
set desc = "Utilizes the internal VOID-shift device to rapidly transit to a random destination straight ahead."
set category = "Ninja Ability"
straight_phase()
//=======//EM PULSE//=======//
//Disables nearby tech equipment.
/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse()
set name = "EM Burst (2,000E)"
set desc = "Disable any nearby technology with a electro-magnetic pulse."
set category = "Ninja Ability"
set popup_menu = 0
var/C = 200
if(!ninjacost(C,0)) // EMP's now cost 1,000Energy about 30%
var/mob/living/carbon/human/U = affecting
playsound(U.loc, 'sound/effects/EMPulse.ogg', 60, 2)
empulse(U, 2, 3) //Procs sure are nice. Slightly weaker than wizard's disable tch.
s_coold = 2
return
//=======//ENERGY BLADE//=======//
//Summons a blade of energy in active hand.
/obj/item/clothing/suit/space/space_ninja/proc/ninjablade()
set name = "Energy Blade (500E)"
set desc = "Create a focused beam of energy in your active hand."
set category = "Ninja Ability"
set popup_menu = 0
var/C = 50
if(!ninjacost(C,0)) //Same spawn cost but higher upkeep cost
var/mob/living/carbon/human/U = affecting
if(!kamikaze)
if(!U.get_active_hand()&&!istype(U.get_inactive_hand(), /obj/item/weapon/melee/energy/blade))
var/obj/item/weapon/melee/energy/blade/W = new()
spark_system.start()
playsound(U.loc, "sparks", 50, 1)
U.put_in_hands(W)
else
U << "\red You can only summon one blade. Try dropping an item first."
else//Else you can run around with TWO energy blades. I don't know why you'd want to but cool factor remains.
if(!U.get_active_hand())
var/obj/item/weapon/melee/energy/blade/W = new()
U.put_in_hands(W)
if(!U.get_inactive_hand())
var/obj/item/weapon/melee/energy/blade/W = new()
U.put_in_inactive_hand(W)
spark_system.start()
playsound(U.loc, "sparks", 50, 1)
s_coold = 1
return
//=======//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 (800E)"
set desc = "Launches an energy star at a random living target."
set category = "Ninja Ability"
set popup_menu = 0
var/C = 80
if(!ninjacost(C,1))
var/mob/living/carbon/human/U = affecting
var/targets[] = list()//So yo can shoot while yo throw dawg
for(var/mob/living/M in oview(loc))
if(M.stat) continue//Doesn't target corpses or paralyzed persons.
targets.Add(M)
if(targets.len)
var/mob/living/target=pick(targets)//The point here is to pick a random, living mob in oview to shoot stuff at.
var/turf/curloc = U.loc
var/atom/targloc = get_turf(target)
if (!targloc || !istype(targloc, /turf) || !curloc)
return
if (targloc == curloc)
return
var/obj/item/projectile/energy/dart/A = new /obj/item/projectile/energy/dart(U.loc)
A.current = curloc
A.yo = targloc.y - curloc.y
A.xo = targloc.x - curloc.x
A.process()
else
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.*/
/obj/item/clothing/suit/space/space_ninja/proc/ninjanet(mob/living/carbon/M in oview())//Only living carbon mobs.
set name = "Energy Net (7,000E)"
set desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds."
set category = null
set src = usr.contents
var/C = 700
if(!ninjacost(C,0)&&iscarbon(M))
var/mob/living/carbon/human/U = affecting
if(M.client)//Monkeys without a client can still step_to() and bypass the net. Also, netting inactive people is lame.
//if(M)//DEBUG
if(!locate(/obj/effect/energy_net) in M.loc)//Check if they are already being affected by an energy net.
for(var/turf/T in getline(U.loc, M.loc))
if(T.density)//Don't want them shooting nets through walls. It's kind of cheesy.
U << "You may not use an energy net through solid obstacles!"
return
spawn(0)
U.Beam(M,"n_beam",,15)
M.captured = 1
U.say("Get over here!")
var/obj/effect/energy_net/E = new /obj/effect/energy_net(M.loc)
E.layer = M.layer+1//To have it appear one layer above the mob.
for(var/mob/O in viewers(U, 3))
O.show_message(text("\red [] caught [] with an energy net!", U, M), 1)
E.affecting = M
E.master = U
spawn(0)//Parallel processing.
E.process(M)
else
U << "They are already trapped inside an energy net."
else
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.*/
/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost()
set name = "Adrenaline Boost"
set desc = "Inject a secret chemical that will counteract all movement-impairing effect."
set category = "Ninja Ability"
set popup_menu = 0
if(!ninjacost(,3))//Have to make sure stat is not counted for this ability.
var/mob/living/carbon/human/U = affecting
//Wouldn't need to track adrenaline boosters if there was a miracle injection to get rid of paralysis and the like instantly.
//For now, adrenaline boosters ARE the miracle injection. Well, radium, really.
U.SetParalysis(0)
U.SetWeakened(0)
/*
Due to lag, it was possible to adrenaline boost but remain helpless while life.dm resets player stat.
This lead to me and others spamming adrenaline boosters because they failed to kick in on time.
It's technically possible to come back from crit with this but it is very temporary.
Life.dm will kick the player back into unconsciosness the next process loop.
*/
U.stat = 0//At least now you should be able to teleport away or shoot ninja stars.
spawn(30)//Slight delay so the enemy does not immedietly know the ability was used. Due to lag, this often came before waking up.
U.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!"))
spawn(70)
reagents.reaction(U, 2)
reagents.trans_id_to(U, "radium", a_transfer)
U << "\red You are beginning to feel the after-effect of the injection."
a_boost--
s_coold = 3
return
/*
===================================================================================
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<KAMIKAZE MODE>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
===================================================================================
Or otherwise known as anime mode. Which also happens to be ridiculously powerful.
*/
//=======//NINJA MOVEMENT//=======//
//Also makes you move like you're on crack.
/obj/item/clothing/suit/space/space_ninja/proc/ninjawalk()
set name = "Shadow Walk"
set desc = "Combines the VOID-shift and CLOAK-tech devices to freely move between solid matter. Toggle on or off."
set category = "Ninja Ability"
set popup_menu = 0
var/mob/living/carbon/human/U = affecting
if(!U.incorporeal_move)
U.incorporeal_move = 2
U << "\blue You will now phase through solid matter."
else
U.incorporeal_move = 0
U << "\blue You will no-longer phase through solid matter."
return
//=======//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."
set category = "Ninja Ability"
set popup_menu = 0
if(straight_phase(1, 5, 5, 0))
var/mob/living/carbon/human/U = affecting
U.say("Ai Satsugai!")
//=======//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."
set category = "Ninja Ability"
set popup_menu = 0
if(!ninjacost())//Simply checks for stat.
var/mob/living/carbon/human/U = affecting
var/targets[]
targets = new()
for(var/mob/living/M in oview(6))
if(M.stat) continue//Doesn't target corpses or paralyzed people.
targets.Add(M)
if(targets.len)
var/mob/living/target=pick(targets)
var/locx
var/locy
var/turf/mobloc = get_turf(target.loc)
var/safety = 0
switch(target.dir)
if(NORTH)
locx = mobloc.x
locy = (mobloc.y-1)
if(locy<1)
safety = 1
if(SOUTH)
locx = mobloc.x
locy = (mobloc.y+1)
if(locy>world.maxy)
safety = 1
if(EAST)
locy = mobloc.y
locx = (mobloc.x-1)
if(locx<1)
safety = 1
if(WEST)
locy = mobloc.y
locx = (mobloc.x+1)
if(locx>world.maxx)
safety = 1
else safety=1
if(!safety&&istype(mobloc, /turf))
U.say("Kumo no Shinkiro!")
var/turf/picked = locate(locx,locy,mobloc.z)
spawn(0)
playsound(U.loc, "sparks", 50, 1)
anim(mobloc,U,'icons/mob/mob.dmi',,"phaseout",,U.dir)
spawn(0)
var/limit = 4
for(var/turf/T in oview(5))
if(prob(20))
spawn(0)
anim(T,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
limit--
if(limit<=0) break
handle_teleport_grab(picked, U)
U.loc = picked
U.dir = target.dir
spawn(0)
spark_system.start()
playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1)
playsound(U.loc, "sparks", 50, 1)
anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
s_coold = 1
else
U << "\red The VOID-shift device is malfunctioning, <B>teleportation failed</B>."
else
U << "\red There are no targets in view."
return
/obj/item/clothing/suit/space/space_ninja/proc/straight_phase(var/slay = 0, var/min_range=5, var/max_range = 9, var/cost = 25)
if(!ninjacost(cost,1))
var/mob/living/carbon/human/U = affecting
var/turf/destination = get_teleport_loc(U.loc,U, rand(min_range, max_range))
var/turf/mobloc = get_turf(U.loc)//To make sure that certain things work properly below.
if(destination && istype(mobloc, /turf))
spawn(0)
playsound(U.loc, "sparks", 50, 1)
anim(mobloc,U,'icons/mob/mob.dmi',,"phaseout",,U.dir)
if(slay)
spawn(0)
for(var/turf/T in getline(mobloc, destination))
spawn(0)
T.kill_creatures(U)
if(T==mobloc||T==destination) continue
spawn(0)
anim(T,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
handle_teleport_grab(destination, U)
U.loc = destination
s_coold = slay
spawn(0)
spark_system.start()
playsound(U.loc, 'sound/effects/phasein.ogg', 25, 1)
playsound(U.loc, "sparks", 50, 1)
anim(U.loc,U,'icons/mob/mob.dmi',,"phasein",,U.dir)
return 1
else
U << "\red The VOID-shift device is malfunctioning, <B>teleportation failed</B>."
return 0

File diff suppressed because it is too large Load Diff

View File

@@ -208,7 +208,6 @@ Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective comp
//The ninja will be created on the right spawn point or at late join.
var/mob/living/carbon/human/new_ninja = create_space_ninja(pick(ninjastart.len ? ninjastart : latejoin))
new_ninja.key = ninja_key
new_ninja.wear_suit:randomize_param()//Give them a random set of suit parameters.
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"
@@ -446,14 +445,11 @@ As such, it's hard-coded for now. No reason for it not to be, really.
if(confirm != "Yes") return
if(ishuman(M))
var/mob/living/carbon/human/H = M
log_admin("[key_name(src)] turned [M.key] into a Space Ninja.")
spawn(10)
M:create_mind_space_ninja()
M:equip_space_ninja(1)
if(istype(M:wear_suit, /obj/item/clothing/suit/space/space_ninja))
M:wear_suit:randomize_param()
spawn(0)
M:wear_suit:ninitialize(10,M)
H.create_mind_space_ninja()
H.equip_space_ninja(1)
else
alert("Invalid mob")
@@ -534,533 +530,9 @@ As such, it's hard-coded for now. No reason for it not to be, really.
equip_to_slot_or_del(new /obj/item/clothing/under/color/blackf(src), slot_w_uniform)
else
equip_to_slot_or_del(new /obj/item/clothing/under/color/black(src), slot_w_uniform)
equip_to_slot_or_del(new /obj/item/clothing/shoes/space_ninja(src), slot_shoes)
equip_to_slot_or_del(new /obj/item/clothing/suit/space/space_ninja(src), slot_wear_suit)
equip_to_slot_or_del(new /obj/item/clothing/gloves/space_ninja(src), slot_gloves)
equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/space_ninja(src), slot_head)
equip_to_slot_or_del(new /obj/item/weapon/storage/rig/light/ninja(src), slot_back)
equip_to_slot_or_del(new /obj/item/clothing/mask/gas/voice/space_ninja(src), slot_wear_mask)
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_belt)
equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_r_store)
equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/weapon/tank/oxygen(src), slot_s_store)
return 1
//=======//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.
icon_state = U.gender==FEMALE ? "s-ninjanf" : "s-ninjan"
U:gloves.icon_state = "s-ninjan"
U:gloves.item_state = "s-ninjan"
else
if(U.mind.special_role!="Ninja")
U << "\red <B>f<>TaL <20><>RRoR</B>: 382200-*#00C<30>DE <B>RED</B>\nUNAU<41>HORIZED US<55> DET<45>C<EFBFBD><43><EFBFBD>eD\nCoMM<4D>NCING SUB-R0U<30>IN3 13...\nT<6E>RMInATING U-U-US<55>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
//Allows the mob to grab a stealth icon.
/mob/proc/NinjaStealthActive(atom/A)//A is the atom which we are using as the overlay.
invisibility = INVISIBILITY_LEVEL_TWO//Set ninja invis to 2.
var/icon/opacity_icon = new(A.icon, A.icon_state)
var/icon/alpha_mask = getIconMask(src)
var/icon/alpha_mask_2 = new('icons/effects/effects.dmi', "at_shield1")
alpha_mask.AddAlphaMask(alpha_mask_2)
opacity_icon.AddAlphaMask(alpha_mask)
for(var/i=0,i<5,i++)//And now we add it as overlays. It's faster than creating an icon and then merging it.
var/image/I = image("icon" = opacity_icon, "icon_state" = A.icon_state, "layer" = layer+0.8)//So it's above other stuff but below weapons and the like.
switch(i)//Now to determine offset so the result is somewhat blurred.
if(1)
I.pixel_x -= 1
if(2)
I.pixel_x += 1
if(3)
I.pixel_y -= 1
if(4)
I.pixel_y += 1
overlays += I//And finally add the overlay.
overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9)
//When ninja steal malfunctions.
/mob/proc/NinjaStealthMalf()
invisibility = 0//Set ninja invis to 0.
overlays += image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = layer+0.9)
playsound(loc, 'sound/effects/stealthoff.ogg', 75, 1)
//=======//GENERIC VERB MODIFIERS//=======//
var/list/ninja_verbs_default = list(
/obj/item/clothing/suit/space/space_ninja/proc/ninjashift,
/obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke,
/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost,
/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse,
/obj/item/clothing/suit/space/space_ninja/proc/ninjablade,
/obj/item/clothing/suit/space/space_ninja/proc/ninjastar,
/obj/item/clothing/suit/space/space_ninja/proc/ninjanet,
/obj/item/clothing/suit/space/space_ninja/proc/ninjajaunt
)
var/list/ninja_verbs_kamikaze = list(
/obj/item/clothing/suit/space/space_ninja/proc/ninjasmoke,
/obj/item/clothing/suit/space/space_ninja/proc/ninjaboost,
/obj/item/clothing/suit/space/space_ninja/proc/ninjapulse,
/obj/item/clothing/suit/space/space_ninja/proc/ninjablade,
/obj/item/clothing/suit/space/space_ninja/proc/ninjastar,
/obj/item/clothing/suit/space/space_ninja/proc/ninjaslayer,
/obj/item/clothing/suit/space/space_ninja/proc/ninjawalk,
/obj/item/clothing/suit/space/space_ninja/proc/ninjamirage
)
var/list/ninja_verbs_equip = list(
/obj/item/clothing/suit/space/space_ninja/proc/deinit,
/obj/item/clothing/suit/space/space_ninja/proc/spideros,
/obj/item/clothing/suit/space/space_ninja/proc/stealth
)
/obj/item/clothing/suit/space/space_ninja/proc/grant_equip_verbs()
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/init
verbs |= ninja_verbs_equip
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 -= ninja_verbs_equip
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 |= ninja_verbs_default
s_initialized=1
slowdown=0
/obj/item/clothing/suit/space/space_ninja/proc/remove_ninja_verbs()
verbs -= ninja_verbs_default
//=======//KAMIKAZE VERBS//=======//
/obj/item/clothing/suit/space/space_ninja/proc/grant_kamikaze(mob/living/carbon/U)
verbs -= ninja_verbs_default
verbs |= ninja_verbs_kamikaze
verbs -= /obj/item/clothing/suit/space/space_ninja/proc/stealth
kamikaze = 1
icon_state = U.gender==FEMALE ? "s-ninjakf" : "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()
U << browse(null, "window=spideros")
U << "\red Do or Die, <b>LET'S ROCK!!</b>"
/obj/item/clothing/suit/space/space_ninja/proc/remove_kamikaze(mob/living/carbon/U)
if(kamikaze)
verbs -= ninja_verbs_kamikaze
verbs += ninja_verbs_default
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
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
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
s_control = 1
//=======//OLD & UNUSED//=======//
/*
Deprecated. get_dir() does the same thing. Still a nice proc.
Returns direction that the mob or whomever should be facing in relation to the target.
This proc does not grant absolute direction and is mostly useful for 8dir sprite positioning.
I personally used it with getline() to great effect.
/proc/get_dir_to(turf/start,turf/end)//N
var/xdiff = start.x - end.x//The sign is important.
var/ydiff = start.y - end.y
var/direction_x = xdiff<1 ? 4:8//East - west
var/direction_y = ydiff<1 ? 1:2//North - south
var/direction_xy = xdiff==0 ? -4:0//If x is the same, subtract 4.
var/direction_yx = ydiff==0 ? -1:0//If y is the same, subtract 1.
var/direction_f = direction_x+direction_y+direction_xy+direction_yx//Finally direction tally.
direction_f = direction_f==0 ? 1:direction_f//If direction is 0(same spot), return north. Otherwise, direction.
return direction_f
Alternative and inferior method of calculating spideros.
var/temp = num2text(spideros)
var/return_to = copytext(temp, 1, (length(temp)))//length has to be to the length of the thing because by default it's length+1
spideros = text2num(return_to)//Maximum length here is 6. Use (return_to, X) to specify larger strings if needed.
//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/structure/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.
BYOND fixed the verb bugs so this is no longer necessary. I prefer verb panels.
/obj/item/clothing/suit/space/space_ninja/proc/grant_AI_verbs()
var/obj/effect/proc_holder/ai_return_control/A_C = new(AI)
var/obj/effect/proc_holder/ai_hack_ninja/B_C = new(AI)
var/obj/effect/proc_holder/ai_instruction/C_C = new(AI)
new/obj/effect/proc_holder/ai_holo_clear(AI)
AI.proc_holder_list += A_C
AI.proc_holder_list += B_C
AI.proc_holder_list += C_C
s_control = 0
/obj/item/clothing/suit/space/space_ninja/proc/remove_AI_verbs()
var/obj/effect/proc_holder/ai_return_control/A_C = locate() in AI
var/obj/effect/proc_holder/ai_hack_ninja/B_C = locate() in AI
var/obj/effect/proc_holder/ai_instruction/C_C = locate() in AI
var/obj/effect/proc_holder/ai_holo_clear/D_C = locate() in AI
del(A_C)
del(B_C)
del(C_C)
del(D_C)
AI.proc_holder_list = list()
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
//Workaround
/obj/effect/proc_holder/ai_holo_clear
name = "Clear Hologram"
desc = "Stops projecting the current holographic image."
panel = "AI Ninja Equip"
density = 0
opacity = 0
/obj/effect/proc_holder/ai_holo_clear/Click()
var/obj/item/clothing/suit/space/space_ninja/S = loc.loc//This is so stupid but makes sure certain things work. AI.SUIT
del(S.hologram.i_attached)
del(S.hologram)
var/obj/effect/proc_holder/ai_holo_clear/D_C = locate() in S.AI
S.AI.proc_holder_list -= D_C
return
/obj/effect/proc_holder/ai_instruction//Let's the AI know what they can do.
name = "Instructions"
desc = "Displays a list of helpful information."
panel = "AI Ninja Equip"
density = 0
opacity = 0
/obj/effect/proc_holder/ai_instruction/Click()
loc << "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/effect/proc_holder/ai_hack_ninja//Generic proc holder to make sure the two verbs below work propely.
name = "Hack SpiderOS"
desc = "Hack directly into the Black Widow(tm) neuro-interface."
panel = "AI Ninja Equip"
density = 0
opacity = 0
/obj/effect/proc_holder/ai_hack_ninja/Click()//When you click on it.
var/obj/item/clothing/suit/space/space_ninja/S = loc.loc
S.hack_spideros()
return
/obj/effect/proc_holder/ai_return_control
name = "Relinquish Control"
desc = "Return control to the user."
panel = "AI Ninja Equip"
density = 0
opacity = 0
/obj/effect/proc_holder/ai_return_control/Click()
var/mob/living/silicon/ai/A = loc
var/obj/item/clothing/suit/space/space_ninja/S = A.loc
A << browse(null, "window=hack spideros")//Close window
A << "You have seized your hacking attempt. [S.affecting] has regained control."
S.affecting << "<b>UPDATE</b>: [A.real_name] has ceased hacking attempt. All systems clear."
S.remove_AI_verbs()
return
*/
//=======//DEBUG//=======//
/*
/obj/item/clothing/suit/space/space_ninja/proc/display_verb_procs()
//DEBUG
//Does nothing at the moment. I am trying to see if it's possible to mess around with verbs as variables.
//for(var/P in verbs)
// if(P.set.name)
// usr << "[P.set.name], path: [P]"
return
Most of these are at various points of incomplete.
/mob/verb/grant_object_panel()
set name = "Grant AI Ninja Verbs Debug"
set category = "Ninja Debug"
var/obj/effect/proc_holder/ai_return_control/A_C = new(src)
var/obj/effect/proc_holder/ai_hack_ninja/B_C = new(src)
usr:proc_holder_list += A_C
usr:proc_holder_list += B_C
mob/verb/remove_object_panel()
set name = "Remove AI Ninja Verbs Debug"
set category = "Ninja Debug"
var/obj/effect/proc_holder/ai_return_control/A = locate() in src
var/obj/effect/proc_holder/ai_hack_ninja/B = locate() in src
usr:proc_holder_list -= A
usr:proc_holder_list -= B
del(A)//First.
del(B)//Second, to keep the proc going.
return
/client/verb/grant_verb_ninja_debug1(var/mob/M in view())
set name = "Grant AI Ninja Verbs Debug"
set category = "Ninja Debug"
M.verbs += /mob/living/silicon/ai/verb/ninja_return_control
M.verbs += /mob/living/silicon/ai/verb/ninja_spideros
return
/client/verb/grant_verb_ninja_debug2(var/mob/living/carbon/human/M in view())
set name = "Grant Back Ninja Verbs"
set category = "Ninja Debug"
M.wear_suit.verbs += /obj/item/clothing/suit/space/space_ninja/proc/deinit
M.wear_suit.verbs += /obj/item/clothing/suit/space/space_ninja/proc/spideros
return
/obj/proc/grant_verb_ninja_debug3(var/mob/living/silicon/ai/A as mob)
set name = "Grant AI Ninja Verbs"
set category = "null"
set hidden = 1
A.verbs -= /obj/item/clothing/suit/space/space_ninja/proc/deinit
A.verbs -= /obj/item/clothing/suit/space/space_ninja/proc/spideros
return
/mob/verb/get_dir_to_target(var/mob/M in oview())
set name = "Get Direction to Target"
set category = "Ninja Debug"
world << "DIR: [get_dir_to(src.loc,M.loc)]"
return
//
/mob/verb/kill_self_debug()
set name = "DEBUG Kill Self"
set category = "Ninja Debug"
src:death()
/client/verb/switch_client_debug()
set name = "DEBUG Switch Client"
set category = "Ninja Debug"
mob = mob:loc:loc
/mob/verb/possess_mob(var/mob/M in oview())
set name = "DEBUG Possess Mob"
set category = "Ninja Debug"
client.mob = M
/client/verb/switcharoo(var/mob/M in oview())
set name = "DEBUG Switch to AI"
set category = "Ninja Debug"
var/mob/last_mob = mob
mob = M
last_mob:wear_suit:AI:key = key
//
/client/verb/ninjaget(var/mob/M in oview())
set name = "DEBUG Ninja GET"
set category = "Ninja Debug"
mob = M
M.gib()
space_ninja()
/mob/verb/set_debug_ninja_target()
set name = "Set Debug Target"
set category = "Ninja Debug"
ninja_debug_target = src//The target is you, brohime.
world << "Target: [src]"
/mob/verb/hack_spideros_debug()
set name = "Debug Hack Spider OS"
set category = "Ninja Debug"
var/mob/living/silicon/ai/A = loc:AI
if(A)
if(!A.key)
A.client.mob = loc:affecting
else
loc:affecting:client:mob = A
return
//Tests the net and what it does.
/mob/verb/ninjanet_debug()
set name = "Energy Net Debug"
set category = "Ninja Debug"
var/obj/effect/energy_net/E = new /obj/effect/energy_net(loc)
E.layer = layer+1//To have it appear one layer above the mob.
stunned = 10//So they are stunned initially but conscious.
anchored = 1//Anchors them so they can't move.
E.affecting = src
spawn(0)//Parallel processing.
E.process(src)
return
I made this as a test for a possible ninja ability (or perhaps more) for a certain mob to see hallucinations.
The thing here is that these guys have to be coded to do stuff as they are simply images that you can't even click on.
That is why you attached them to objects.
/mob/verb/TestNinjaShadow()
set name = "Test Ninja Ability"
set category = "Ninja Debug"
if(client)
var/safety = 4
for(var/turf/T in oview(5))
if(prob(20))
var/current_clone = image('icons/mob/mob.dmi',T,"s-ninja")
safety--
spawn(0)
src << current_clone
spawn(300)
del(current_clone)
spawn while(!isnull(current_clone))
step_to(current_clone,src,1)
sleep(5)
if(safety<=0) break
return */
//Alternate ninja speech replacement.
/*This text is hilarious but also absolutely retarded.
message = replacetext(message, "l", "r")
message = replacetext(message, "rr", "ru")
message = replacetext(message, "v", "b")
message = replacetext(message, "f", "hu")
message = replacetext(message, "'t", "")
message = replacetext(message, "t ", "to ")
message = replacetext(message, " I ", " ai ")
message = replacetext(message, "th", "z")
message = replacetext(message, "ish", "isu")
message = replacetext(message, "is", "izu")
message = replacetext(message, "ziz", "zis")
message = replacetext(message, "se", "su")
message = replacetext(message, "br", "bur")
message = replacetext(message, "ry", "ri")
message = replacetext(message, "you", "yuu")
message = replacetext(message, "ck", "cku")
message = replacetext(message, "eu", "uu")
message = replacetext(message, "ow", "au")
message = replacetext(message, "are", "aa")
message = replacetext(message, "ay", "ayu")
message = replacetext(message, "ea", "ii")
message = replacetext(message, "ch", "chi")
message = replacetext(message, "than", "sen")
message = replacetext(message, ".", "")
message = lowertext(message)
*/

View File

@@ -1331,11 +1331,13 @@ datum
return 0
if(!owner.current || owner.current.stat == 2)
return 0
if(!(istype(owner.current:wear_suit, /obj/item/clothing/suit/space/space_ninja)&&owner.current:wear_suit:s_initialized))
return 0
var/current_amount
var/obj/item/clothing/suit/space/space_ninja/S = owner.current:wear_suit
if(!S.stored_research.len)
var/obj/item/weapon/storage/rig/S
if(istype(owner.current,/mob/living/carbon/human))
var/mob/living/carbon/human/H = owner.current
S = H.back
if(!S || !istype(S) || !S.stored_research.len)
return 0
else
for(var/datum/tech/current_data in S.stored_research)

View File

@@ -61,9 +61,7 @@
var/mob/living/carbon/human/N = ninja.current
N.internal = N.s_store
N.internals.icon_state = "internal1"
if(N.wear_suit && istype(N.wear_suit,/obj/item/clothing/suit/space/space_ninja))
var/obj/item/clothing/suit/space/space_ninja/S = N.wear_suit
S:randomize_param()
spawn (rand(waittime_l, waittime_h))
send_intercept()
return ..()

View File

@@ -222,28 +222,6 @@ var/global/list/turf/synd_spawn = list()
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(synd_mob.back), slot_in_backpack)
synd_mob.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(synd_mob), slot_in_backpack)
/* Commented; nukes now have a suit cycler for changing rig-suits, they don't need to spawn with them
var/obj/item/clothing/suit/space/rig/syndi/new_suit = new(synd_mob)
var/obj/item/clothing/head/helmet/space/rig/syndi/new_helmet = new(synd_mob)
if(synd_mob.species)
var/race = synd_mob.species.name
switch(race)
if("Unathi")
new_suit.species_restricted = list("Unathi")
if("Tajara")
new_suit.species_restricted = list("Tajara")
if("Skrell")
new_suit.species_restricted = list("Skrell")
synd_mob.equip_to_slot_or_del(new_suit, slot_in_backpack)
synd_mob.equip_to_slot_or_del(new_helmet, slot_in_backpack)*/
// var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(synd_mob)
// E.imp_in = synd_mob
// E.implanted = 1
synd_mob.update_icons()
return 1

View File

@@ -488,7 +488,7 @@ datum/objective/steal
"a functional AI" = /obj/item/device/aicard,
"a pair of magboots" = /obj/item/clothing/shoes/magboots,
"the station blueprints" = /obj/item/blueprints,
"a nasa voidsuit" = /obj/item/clothing/suit/space/nasavoid,
"a nasa voidsuit" = /obj/item/clothing/suit/space/void,
"28 moles of phoron (full tank)" = /obj/item/weapon/tank,
"a sample of slime extract" = /obj/item/slime_extract,
"a piece of corgi meat" = /obj/item/weapon/reagent_containers/food/snacks/meat/corgi,
@@ -571,16 +571,15 @@ datum/objective/steal
return found_amount>=target
if("a functional AI")
for(var/obj/item/device/aicard/C in all_items) //Check for ai card
for(var/mob/living/silicon/ai/M in C)
if(istype(M, /mob/living/silicon/ai) && M.stat != 2) //See if any AI's are alive inside that card.
return 1
for(var/obj/item/clothing/suit/space/space_ninja/S in all_items) //Let an AI downloaded into a space ninja suit count
if(S.AI && S.AI.stat != 2)
return 1
for(var/mob/living/silicon/ai/ai in world)
if(istype(ai.loc, /turf))
var/turf/T = get_turf(ai)
if(istype(T))
var/area/check_area = get_area(ai)
if(istype(check_area, /area/shuttle/escape/centcom))
return 1
@@ -613,19 +612,25 @@ datum/objective/download
return 0
if(!owner.current || owner.current.stat == 2)
return 0
if(!(istype(owner.current:wear_suit, /obj/item/clothing/suit/space/space_ninja)&&owner.current:wear_suit:s_initialized))
return 0
var/current_amount
var/obj/item/clothing/suit/space/space_ninja/S = owner.current:wear_suit
if(!S.stored_research.len)
var/obj/item/weapon/storage/rig/S
if(istype(owner.current,/mob/living/carbon/human))
var/mob/living/carbon/human/H = owner.current
S = H.back
if(!istype(S) || !S.installed_modules || !S.installed_modules.len)
return 0
else
for(var/datum/tech/current_data in S.stored_research)
if(current_data.level>1) current_amount+=(current_data.level-1)
if(current_amount<target_amount) return 0
return 1
var/obj/item/rig_module/datajack/stolen_data = locate() in S.installed_modules
if(!istype(stolen_data))
return 0
for(var/datum/tech/current_data in stolen_data.stored_research)
if(current_data.level > 1)
current_amount += (current_data.level-1)
return (current_amount<target_amount) ? 0 : 1
datum/objective/capture
proc/gen_amount_goal()

View File

@@ -181,8 +181,8 @@
feedback_add_details("wizard_spell_learned","HS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells
new /obj/item/clothing/shoes/sandal(get_turf(H)) //In case they've lost them.
new /obj/item/clothing/gloves/purple(get_turf(H))//To complete the outfit
new /obj/item/clothing/suit/space/rig/wizard(get_turf(H))
new /obj/item/clothing/head/helmet/space/rig/wizard(get_turf(H))
new /obj/item/clothing/suit/space/void/wizard(get_turf(H))
new /obj/item/clothing/head/helmet/space/void/wizard(get_turf(H))
temp = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space."
max_uses--
if("staffanimation")

View File

@@ -136,7 +136,9 @@
//Cameras can't track people wearing an agent card or a ninja hood.
if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
continue
if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja))
if(istype(H.head, /obj/item/clothing/head/helmet/space/rig))
var/obj/item/clothing/head/helmet/space/rig/helmet = H.head
if(helmet.prevent_track())
continue
// Now, are they viewable by a camera? (This is last because it's the most intensive check)
@@ -186,9 +188,6 @@
var/mob/living/silicon/ai/U = usr
U.cameraFollow = target
//U << text("Now tracking [] on camera.", target.name)
//if (U.machine == null)
// U.machine = U
U << "Now tracking [target.name] on camera."
spawn (0)
@@ -200,7 +199,9 @@
if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
U.ai_cancel_tracking(1)
return
if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja))
if(istype(H.head, /obj/item/clothing/head/helmet/space/rig))
var/obj/item/clothing/head/helmet/space/rig/helmet = H.head
if(helmet.prevent_track())
U.ai_cancel_tracking(1)
return
if(H.digitalcamo)

View File

@@ -11,6 +11,7 @@
/obj/structure/AIcore/attackby(obj/item/P as obj, mob/user as mob)
switch(state)
if(0)
if(istype(P, /obj/item/weapon/wrench))
@@ -117,7 +118,6 @@
laws.clear_inherent_laws()
usr << "Law module applied."
if(istype(P, /obj/item/weapon/aiModule/freeform))
var/obj/item/weapon/aiModule/freeform/M = P
laws.add_inherent_law(M.newFreeFormLaw)
@@ -180,212 +180,40 @@
anchored = 1
state = 20//So it doesn't interact based on the above. Not really necessary.
attackby(var/obj/item/device/aicard/A as obj, var/mob/user as mob)
if(istype(A, /obj/item/device/aicard))//Is it?
A.transfer_ai("INACTIVE","AICARD",src,user)
/obj/structure/AIcore/deactivated/proc/load_ai(var/mob/living/silicon/ai/transfer, var/obj/item/device/aicard/card, var/mob/user)
if(!istype(transfer) || locate(/mob/living/silicon/ai) in src)
return
/*
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)
switch(choice)
if("AICORE")//AI mob.
var/mob/living/silicon/ai/T = target
switch(interaction)
if("AICARD")
var/obj/item/device/aicard/C = src
if(C.contents.len)//If there is an AI on card.
U << "\red <b>Transfer failed</b>: \black Existing AI found on this terminal. Remove existing AI to install a new one."
else
transfer.aiRestorePowerRoutine = 0
transfer.control_disabled = 0
transfer.aiRadio.disabledAi = 0
transfer.loc = get_turf(src)
transfer.cancel_camera()
user << "\blue <b>Transfer successful</b>: \black [transfer.name] ([rand(1000,9999)].exe) downloaded to host terminal. Local copy wiped."
transfer << "You have been uploaded to a stationary terminal. Remote device connection restored."
if(card)
card.clear()
del(src)
/obj/structure/AIcore/deactivated/proc/check_malf(var/mob/living/silicon/ai/ai)
if(!ai) return
if (ticker.mode.name == "AI malfunction")
var/datum/game_mode/malfunction/malf = ticker.mode
for (var/datum/mind/malfai in malf.malf_ai)
if (T.mind == malfai)
U << "\red <b>ERROR</b>: \black Remote transfer interface disabled."//Do ho ho ho~
return
new /obj/structure/AIcore/deactivated(T.loc)//Spawns a deactivated terminal at AI location.
T.aiRestorePowerRoutine = 0//So the AI initially has power.
T.control_disabled = 1//Can't control things remotely if you're stuck in a card!
T.loc = C//Throw AI into the card.
C.name = "inteliCard - [T.name]"
if (T.stat == 2)
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")
var/obj/item/clothing/suit/space/space_ninja/C = src
if(C.AI)//If there is an AI on card.
U << "\red <b>Transfer failed</b>: \black Existing AI found on this terminal. Remove existing AI to install a new one."
else
if (ticker.mode.name == "AI malfunction")
var/datum/game_mode/malfunction/malf = ticker.mode
for (var/datum/mind/malfai in malf.malf_ai)
if (T.mind == malfai)
U << "\red <b>ERROR</b>: \black Remote transfer interface disabled."
return
if(T.stat)//If the ai is dead/dying.
U << "\red <b>ERROR</b>: \black [T.name] data core is corrupted. Unable to install."
else
new /obj/structure/AIcore/deactivated(T.loc)
T.aiRestorePowerRoutine = 0
T.control_disabled = 1
T.aiRadio.disabledAi = 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."
if (ai.mind == malfai)
return 1
if("INACTIVE")//Inactive AI object.
var/obj/structure/AIcore/deactivated/T = target
switch(interaction)
if("AICARD")
var/obj/item/device/aicard/C = src
var/mob/living/silicon/ai/A = locate() in C//I love locate(). Best proc ever.
if(A)//If AI exists on the card. Else nothing since both are empty.
A.control_disabled = 0
A.aiRadio.disabledAi = 0
A.loc = T.loc//To replace the terminal.
C.icon_state = "aicard"
C.name = "inteliCard"
C.overlays.Cut()
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
var/mob/living/silicon/ai/A = C.AI
if(A)
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 successful</b>: \black [A.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed."
del(T)
if("AIFIXER")//AI Fixer terminal.
var/obj/machinery/computer/aifixer/T = target
switch(interaction)
if("AICARD")
var/obj/item/device/aicard/C = src
if(!T.contents.len)
if (!C.contents.len)
U << "No AI to copy over!"//Well duh
else for(var/mob/living/silicon/ai/A in C)
C.icon_state = "aicard"
C.name = "inteliCard"
C.overlays.Cut()
A.loc = T
T.occupant = A
A.control_disabled = 1
if (A.stat == 2)
T.overlays += image('icons/obj/computer.dmi', "ai-fixer-404")
else
T.overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
T.overlays -= image('icons/obj/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 successfully. Local copy has been removed."
else
if(!C.contents.len && T.occupant && !T.active)
C.name = "inteliCard - [T.occupant.name]"
T.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty")
if (T.occupant.stat == 2)
C.icon_state = "aicard-404"
T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-404")
else
C.icon_state = "aicard-full"
T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-full")
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.contents.len)
U << "\red <b>ERROR</b>: \black Artificial intelligence detected on terminal."
else if (T.active)
U << "\red <b>ERROR</b>: \black Reconstruction in progress."
else if (!T.occupant)
U << "\red <b>ERROR</b>: \black Unable to locate artificial intelligence."
if("NINJASUIT")
var/obj/item/clothing/suit/space/space_ninja/C = src
if(!T.contents.len)
if (!C.AI)
U << "No AI to copy over!"
else
var/mob/living/silicon/ai/A = C.AI
A.loc = T
T.occupant = A
C.AI = null
A.control_disabled = 1
T.overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
T.overlays -= image('icons/obj/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 successfully. Local copy has been removed."
else
if(!C.AI && T.occupant && !T.active)
if (T.occupant.stat)
U << "\red <b>ERROR</b>: \black [T.occupant.name] data core is corrupted. Unable to install."
else
T.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty")
T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-full")
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."
else if (T.active)
U << "\red <b>ERROR</b>: \black Reconstruction in progress."
else if (!T.occupant)
U << "\red <b>ERROR</b>: \black Unable to locate artificial intelligence."
if("NINJASUIT")//Ninjasuit
var/obj/item/clothing/suit/space/space_ninja/T = target
switch(interaction)
if("AICARD")
var/obj/item/device/aicard/C = src
if(T.s_initialized&&U==T.affecting)//If the suit is initialized and the actor is the user.
/obj/structure/AIcore/deactivated/attackby(var/obj/item/device/aicard/card, var/mob/user)
var/mob/living/silicon/ai/A_T = locate() in C//Determine if there is an AI on target card. Saves time when checking later.
var/mob/living/silicon/ai/A = T.AI//Deterine if there is an AI in suit.
if(A)//If the host AI card is not empty.
if(A_T)//If there is an AI on the target card.
U << "\red <b>ERROR</b>: \black [A_T.name] already installed. Remove [A_T.name] to install a new one."
if(istype(card))
var/mob/living/silicon/ai/transfer = locate() in card
if(transfer)
load_ai(transfer,card,user)
else
A.loc = C//Throw them into the target card. Since they are already on a card, transfer is easy.
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.
if(C.flush)//If the other card is flushing.
U << "\red <b>ERROR</b>: \black AI flush is in progress, cannot execute transfer protocol."
else
if(A_T&&!A_T.stat)//If there is an AI on the target card and it's not inactive.
A_T.loc = T//Throw them into suit.
C.icon_state = "aicard"
C.name = "inteliCard"
C.overlays.Cut()
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.
U << "\red <b>ERROR</b>: \black [A_T.name] data core is corrupted. Unable to install."
else
U << "\red <b>ERROR</b>: \black AI flush is in progress, cannot execute transfer protocol."
user << "\red <b>ERROR</b>: \black Unable to locate artificial intelligence."
return
..()

View File

@@ -8,16 +8,51 @@
var/active = 0
/obj/machinery/computer/aifixer/New()
src.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty")
update_icon()
/obj/machinery/computer/aifixer/proc/load_ai(var/mob/living/silicon/ai/transfer, var/obj/item/device/aicard/card, var/mob/user)
if(!transfer)
return
// Transfer over the AI.
transfer << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
user << "\blue <b>Transfer successful</b>: \black [transfer.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed."
transfer.loc = src
transfer.cancel_camera()
transfer.control_disabled = 1
occupant = transfer
if(card)
card.clear()
update_icon()
/obj/machinery/computer/aifixer/attackby(I as obj, user as mob)
if(istype(I, /obj/item/device/aicard))
if(stat & (NOPOWER|BROKEN))
user << "This terminal isn't functioning right now, get it working!"
return
I:transfer_ai("AIFIXER","AICARD",src,user)
if(istype(I, /obj/item/device/aicard))
if(stat & (NOPOWER|BROKEN))
user << "This terminal isn't functioning right now."
return
var/obj/item/device/aicard/card = I
var/mob/living/silicon/ai/comp_ai = locate() in src
var/mob/living/silicon/ai/card_ai = locate() in card
if(istype(comp_ai))
if(active)
user << "\red <b>ERROR</b>: \black Reconstruction in progress."
return
card.grab_ai(comp_ai, user)
if(!(locate(/mob/living/silicon/ai) in src)) occupant = null
else if(istype(card_ai))
load_ai(card_ai,card,user)
occupant = locate(/mob/living/silicon/ai) in src
update_icon()
return
..()
return
@@ -112,17 +147,16 @@
/obj/machinery/computer/aifixer/update_icon()
..()
// Broken / Unpowered
if((stat & BROKEN) || (stat & NOPOWER))
overlays.Cut()
// Working / Powered
else
if((stat & BROKEN) || (stat & NOPOWER))
return
if(occupant)
switch (occupant.stat)
if (0)
overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
if (2)
if(occupant.stat)
overlays += image('icons/obj/computer.dmi', "ai-fixer-404")
else
overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
else
overlays += image('icons/obj/computer.dmi', "ai-fixer-empty")

View File

@@ -111,6 +111,23 @@ Class Procs:
var/manual = 0
var/global/gl_uid = 1
/obj/machinery/drain_power(var/drain_check)
if(drain_check)
return 1
if(!powered())
return 0
var/area/area = get_area(src)
if(!area)
return 0
var/obj/machinery/power/apc/apc = area.get_apc()
if(!apc)
return 0
return apc.drain_power()
/obj/machinery/New()
..()
if(!machinery_sort_required && ticker)

View File

@@ -573,7 +573,7 @@
/obj/machinery/suit_cycler
name = "suit cycler"
desc = "An industrial machine for painting and refitting hardsuits."
desc = "An industrial machine for painting and refitting voidsuits."
anchored = 1
density = 1
@@ -589,7 +589,7 @@
var/model_text = "" // Some flavour text for the topic box.
var/locked = 1 // If locked, nothing can be taken from or added to the cycler.
var/panel_open = 0 // Hacking!
var/can_repair // If set, the cycler can repair hardsuits.
var/can_repair // If set, the cycler can repair voidsuits.
var/electrified = 0
//Departments that the cycler can paint suits to look like.
@@ -601,7 +601,7 @@
var/target_species
var/mob/living/carbon/human/occupant = null
var/obj/item/clothing/suit/space/rig/suit = null
var/obj/item/clothing/suit/space/void/suit = null
var/obj/item/clothing/head/helmet/space/helmet = null
var/datum/wires/suit_storage_unit/wires = null
@@ -680,14 +680,14 @@
return
if(locked)
user << "\red The suit cycler is locked."
user << "<span class='danger'>The suit cycler is locked.</span>"
return
if(src.contents.len > 0)
user << "\red There is no room inside the cycler for [G.affecting.name]."
user << "<span class='danger'>There is no room inside the cycler for [G.affecting.name].</span>"
return
visible_message("[user] starts putting [G.affecting.name] into the suit cycler.", 3)
visible_message("[user] starts putting [G.affecting.name] into the suit cycler.</span>", 3)
if(do_after(user, 20))
if(!G || !G.affecting) return
@@ -714,7 +714,7 @@
else if(istype(I,/obj/item/weapon/card/emag))
if(emagged)
user << "\red The cycler has already been subverted."
user << "<span class='danger'>The cycler has already been subverted.</span>"
return
var/obj/item/weapon/card/emag/E = I
@@ -722,21 +722,21 @@
E.uses--
//Clear the access reqs, disable the safeties, and open up all paintjobs.
user << "\red You run the sequencer across the interface, corrupting the operating protocols."
user << "<span class='danger'>You run the sequencer across the interface, corrupting the operating protocols.</span>"
departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$")
emagged = 1
safeties = 0
req_access = list()
return
else if(istype(I,/obj/item/clothing/head/helmet/space))
else if(istype(I,/obj/item/clothing/head/helmet/space) && !istype(I, /obj/item/clothing/head/helmet/space/rig))
if(locked)
user << "\red The suit cycler is locked."
user << "<span class='danger'>The suit cycler is locked.</span>"
return
if(helmet)
user << "The cycler already contains a helmet."
user << "<span class='danger'>The cycler already contains a helmet.</span>"
return
user << "You fit \the [I] into the suit cycler."
@@ -748,24 +748,14 @@
src.updateUsrDialog()
return
else if(istype(I,/obj/item/clothing/suit/space/rig))
else if(istype(I,/obj/item/clothing/suit/space/void))
if(locked)
user << "\red The suit cycler is locked."
user << "<span class='danger'>The suit cycler is locked.</span>"
return
if(suit)
user << "The cycler already contains a hardsuit."
return
var/obj/item/clothing/suit/space/rig/S = I
if(S.helmet)
user << "\The [S] will not fit into the cycler with a helmet attached."
return
if(S.boots)
user << "\The [S] will not fit into the cycler with boots attached."
user << "<span class='danger'>The cycler already contains a voidsuit.</span>"
return
user << "You fit \the [I] into the suit cycler."
@@ -875,12 +865,12 @@
locked = !locked
usr << "You [locked ? "" : "un"]lock \the [src]."
else
usr << "\red Access denied."
usr << "<span class='danger'>Access denied.</span>"
else if(href_list["begin_decontamination"])
if(safeties && occupant)
usr << "\red The cycler has detected an occupant. Please remove the occupant before commencing the decontamination cycle."
usr << "<span class='danger'>The cycler has detected an occupant. Please remove the occupant before commencing the decontamination cycle.</span>"
return
active = 1
@@ -994,63 +984,63 @@
switch(target_department)
if("Engineering")
if(helmet)
helmet.name = "engineering hardsuit helmet"
helmet.name = "engineering voidsuit helmet"
helmet.icon_state = "rig0-engineering"
helmet.item_state = "eng_helm"
helmet.item_color = "engineering"
if(suit)
suit.name = "engineering hardsuit"
suit.name = "engineering voidsuit"
suit.icon_state = "rig-engineering"
suit.item_state = "eng_hardsuit"
suit.item_state = "eng_voidsuit"
if("Mining")
if(helmet)
helmet.name = "mining hardsuit helmet"
helmet.name = "mining voidsuit helmet"
helmet.icon_state = "rig0-mining"
helmet.item_state = "mining_helm"
helmet.item_color = "mining"
if(suit)
suit.name = "mining hardsuit"
suit.name = "mining voidsuit"
suit.icon_state = "rig-mining"
suit.item_state = "mining_hardsuit"
suit.item_state = "mining_voidsuit"
if("Medical")
if(helmet)
helmet.name = "medical hardsuit helmet"
helmet.name = "medical voidsuit helmet"
helmet.icon_state = "rig0-medical"
helmet.item_state = "medical_helm"
helmet.item_color = "medical"
if(suit)
suit.name = "medical hardsuit"
suit.name = "medical voidsuit"
suit.icon_state = "rig-medical"
suit.item_state = "medical_hardsuit"
suit.item_state = "medical_voidsuit"
if("Security")
if(helmet)
helmet.name = "security hardsuit helmet"
helmet.name = "security voidsuit helmet"
helmet.icon_state = "rig0-sec"
helmet.item_state = "sec_helm"
helmet.item_color = "sec"
if(suit)
suit.name = "security hardsuit"
suit.name = "security voidsuit"
suit.icon_state = "rig-sec"
suit.item_state = "sec_hardsuit"
suit.item_state = "sec_voidsuit"
if("Atmos")
if(helmet)
helmet.name = "atmospherics hardsuit helmet"
helmet.name = "atmospherics voidsuit helmet"
helmet.icon_state = "rig0-atmos"
helmet.item_state = "atmos_helm"
helmet.item_color = "atmos"
if(suit)
suit.name = "atmospherics hardsuit"
suit.name = "atmospherics voidsuit"
suit.icon_state = "rig-atmos"
suit.item_state = "atmos_hardsuit"
suit.item_state = "atmos_voidsuit"
if("^%###^%$" || "Mercenary")
if(helmet)
helmet.name = "blood-red hardsuit helmet"
helmet.name = "blood-red voidsuit helmet"
helmet.icon_state = "rig0-syndie"
helmet.item_state = "syndie_helm"
helmet.item_color = "syndie"
if(suit)
suit.name = "blood-red hardsuit"
suit.item_state = "syndie_hardsuit"
suit.name = "blood-red voidsuit"
suit.item_state = "syndie_voidsuit"
suit.icon_state = "rig-syndie"
if(helmet) helmet.name = "refitted [helmet.name]"

View File

@@ -69,6 +69,16 @@
var/max_equip = 3
var/datum/events/events
/obj/mecha/drain_power(var/drain_check)
if(drain_check)
return 1
if(!cell)
return 0
return cell.drain_power(drain_check)
/obj/mecha/New()
..()
events = new

View File

@@ -223,7 +223,13 @@ steam.start() -- spawns the effect
/obj/effect/effect/smoke/proc/affect(var/mob/living/carbon/M)
if (istype(M))
return 0
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS))
if (M.internal != null)
if(M.wear_mask && (M.wear_mask.flags & AIRTIGHT))
return 0
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.head && (H.head.flags & AIRTIGHT))
return 0
return 0
return 1

View File

@@ -277,6 +277,9 @@
if(slot_wear_mask)
if(H.wear_mask)
return 0
if(H.head && !(H.head.canremove) && (H.head.flags & HEADCOVERSMOUTH))
H << "\red \The [H.head] is in the way."
return 0
if( !(slot_flags & SLOT_MASK) )
return 0
return 1
@@ -317,6 +320,9 @@
if(slot_glasses)
if(H.glasses)
return 0
if(H.head && !(H.head.canremove) && (H.head.flags & HEADCOVERSEYES))
H << "\red \The [H.head] is in the way."
return 0
if( !(slot_flags & SLOT_EYES) )
return 0
return 1

View File

@@ -9,26 +9,14 @@
var/flush = null
origin_tech = "programming=4;materials=4"
attack(mob/living/silicon/ai/M as mob, mob/user as mob)
if(!istype(M, /mob/living/silicon/ai))//If target is not an AI.
return ..()
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been carded with [src.name] by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to card [M.name] ([M.ckey])</font>")
msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to card [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
transfer_ai("AICORE", "AICARD", M, user)
return
attack(mob/living/silicon/decoy/M as mob, mob/user as mob)
/obj/item/device/aicard/attack(mob/living/silicon/decoy/M as mob, mob/user as mob)
if (!istype (M, /mob/living/silicon/decoy))
return ..()
else
M.death()
user << "<b>ERROR ERROR ERROR</b>"
attack_self(mob/user)
/obj/item/device/aicard/attack_self(mob/user)
if (!in_range(src, user))
return
user.set_machine(src)
@@ -76,9 +64,10 @@
onclose(user, "aicard")
return
Topic(href, href_list)
/obj/item/device/aicard/Topic(href, href_list)
var/mob/U = usr
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).
if (!(get_turf(U) == get_turf(src)) || 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.unset_machine()
return
@@ -120,13 +109,61 @@
for(var/mob/living/silicon/ai/A in src)
A.control_disabled = !A.control_disabled
A << "The intelicard's wireless port has been [A.control_disabled ? "disabled" : "enabled"]!"
if (A.control_disabled)
update_icon()
attack_self(U)
/obj/item/device/aicard/update_icon()
var/mob/living/silicon/ai/occupant = locate() in src
overlays.Cut()
if(occupant)
if (occupant.control_disabled)
overlays -= image('icons/obj/pda.dmi', "aicard-on")
else
overlays += image('icons/obj/pda.dmi', "aicard-on")
attack_self(U)
if(occupant.stat)
icon_state = "aicard-404"
else
icon_state = "aicard-full"
else
icon_state = "aicard"
/obj/item/device/aicard/proc/grab_ai(var/mob/living/silicon/ai/ai, var/mob/living/user)
if(!ai.client)
user << "\red <b>ERROR</b>: \black [name] data core is offline. Unable to download."
return 0
if(locate(/mob/living/silicon/ai) in src)
user << "\red <b>Transfer failed</b>: \black Existing AI found on remote terminal. Remove existing AI to install a new one."
return 0
if(ai.is_malf())
user << "\red <b>ERROR</b>: \black Remote transfer interface disabled."
return 0
if(istype(ai.loc, /turf/))
new /obj/structure/AIcore/deactivated(get_turf(ai))
src.name = "inteliCard - [ai.name]"
ai.loc = src
ai.cancel_camera()
ai.control_disabled = 1
ai.aiRestorePowerRoutine = 0
ai.aiRadio.disabledAi = 1
ai.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been carded with [src.name] by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to card [ai.name] ([ai.ckey])</font>")
msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to card [ai.name] ([ai.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
if(ai.client)
ai << "You have been downloaded to a mobile storage device. Remote access lost."
if(user.client)
user << "\blue <b>Transfer successful</b>: \black [ai.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
update_icon()
return 1
/obj/item/device/aicard/proc/clear()
name = "inteliCard"
update_icon()

View File

@@ -10,8 +10,8 @@
var/target_species = "Human"
var/list/permitted_types = list(
/obj/item/clothing/head/helmet/space/rig,
/obj/item/clothing/suit/space/rig
/obj/item/clothing/head/helmet/space/void,
/obj/item/clothing/suit/space/void
)
/obj/item/device/modkit/afterattack(obj/O, mob/user as mob, proximity)

View File

@@ -164,15 +164,39 @@
w_class = 4.0//So you can't hide it in your pocket or some such.
flags = FPRINT | TABLEPASS | NOSHIELD | NOBLOODY
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
var/mob/living/creator
var/datum/effect/effect/system/spark_spread/spark_system
/obj/item/weapon/melee/energy/blade/New()
spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
/obj/item/weapon/melee/energy/blade/dropped()
del(src)
processing_objects |= src
/obj/item/weapon/melee/energy/blade/proc/throw()
del(src)
/obj/item/weapon/melee/energy/blade/Del()
processing_objects -= src
..()
/obj/item/weapon/melee/energy/blade/attack_self(mob/user as mob)
user.drop_from_inventory(src)
spawn(1) if(src) del(src)
/obj/item/weapon/melee/energy/blade/dropped()
spawn(1) if(src) del(src)
/obj/item/weapon/melee/energy/blade/process()
if(!creator || loc != creator || (creator.l_hand != src && creator.r_hand != src))
// Tidy up a bit.
if(istype(loc,/mob/living))
var/mob/living/carbon/human/host = loc
if(istype(host))
for(var/datum/organ/external/organ in host.organs)
for(var/obj/item/O in organ.implants)
if(O == src)
organ.implants -= src
host.pinned -= src
host.embedded -= src
host.drop_from_inventory(src)
spawn(1) if(src) del(src)

View File

@@ -25,6 +25,10 @@
var/use_sound = "rustle" //sound played when used. null for no sound.
/obj/item/weapon/storage/MouseDrop(obj/over_object as obj)
if(!canremove)
return
if (ishuman(usr) || ismonkey(usr)) //so monkeys can take off their backpacks -- Urist
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech

View File

@@ -135,7 +135,12 @@
data["maskConnected"] = 0
if(istype(loc,/mob/living/carbon))
var/mob/living/carbon/location = loc
if(location.internal == src || (location.wear_mask && (location.wear_mask.flags & MASKINTERNALS)))
if(location.internal == src)
if(location.wear_mask && (location.wear_mask.flags & AIRTIGHT))
data["maskConnected"] = 1
else if(istype(location, /mob/living/carbon/human))
var/mob/living/carbon/human/H = location
if(H.head && (H.head.flags & AIRTIGHT))
data["maskConnected"] = 1
// update the ui if it exists, returns null if no ui is passed/found
@@ -177,7 +182,16 @@
if (location.internals)
location.internals.icon_state = "internal0"
else
if(location.wear_mask && (location.wear_mask.flags & MASKINTERNALS))
var/can_open_valve
if(location.wear_mask && (location.wear_mask.flags & AIRTIGHT))
can_open_valve = 1
else if(istype(location,/mob/living/carbon/human))
var/mob/living/carbon/human/H = location
if(H.head && (H.head.flags & AIRTIGHT))
can_open_valve = 1
if(can_open_valve)
location.internal = src
usr << "\blue You open \the [src] valve."
if (location.internals)

View File

@@ -294,3 +294,195 @@ obj/item/weapon/wirerod/attackby(var/obj/item/I, mob/user as mob)
del(src)
update_icon(user)
update_icon(user)
/obj/item/weapon/star
name = "shuriken"
desc = "A sharp, perfectly weighted piece of metal."
icon_state = "star"
force = 5
throw_speed = 10
throwforce = 15
throw_range = 15
sharp = 1
edge = 1
matter = list("metal" = 500)
var/poisoned = 0
/obj/item/weapon/star/New()
..()
src.pixel_x = rand(-12, 12)
src.pixel_y = rand(-12, 12)
//TODO: consider making this something done with reagents.
/obj/item/weapon/star/throw_impact(atom/hit_atom)
..()
if(poisoned && istype(hit_atom,/mob/living))
var/mob/living/M = hit_atom
M.adjustToxLoss(rand(20,40))
poisoned = 0
color = null
/obj/item/weapon/star/ninja
color = "#007700"
poisoned = 1
/obj/item/weapon/energy_net
name = "energy net"
desc = "It's a net made of green energy."
icon = 'icons/effects/effects.dmi'
icon_state = "energynet"
throwforce = 0
force = 0
var/net_type = /obj/effect/energy_net
/obj/item/weapon/energy_net/dropped()
spawn(10)
if(src) del(src)
/obj/item/weapon/energy_net/throw_impact(atom/hit_atom)
..()
var/mob/living/M = hit_atom
if(!istype(M) || locate(/obj/effect/energy_net) in M.loc)
del(src)
return 0
var/turf/T = get_turf(M)
if(T)
var/obj/effect/energy_net/net = new net_type(T)
net.layer = M.layer+1
M.captured = 1
net.affecting = M
T.visible_message("[M] was caught in an energy net!")
del(src)
// If we miss or hit an obstacle, we still want to delete the net.
spawn(10)
if(src) del(src)
/obj/effect/energy_net
name = "energy net"
desc = "It's a net made of green energy."
icon = 'icons/effects/effects.dmi'
icon_state = "energynet"
density = 1
opacity = 0
mouse_opacity = 1
anchored = 1
var/health = 25
var/mob/living/affecting = null //Who it is currently affecting, if anyone.
var/mob/living/master = null //Who shot web. Will let this person know if the net was successful.
var/countdown = -1
/obj/effect/energy_net/teleport
countdown = 60
/obj/effect/energy_net/New()
..()
processing_objects |= src
/obj/effect/energy_net/Del()
if(affecting)
var/mob/living/carbon/M = affecting
M.anchored = initial(affecting.anchored)
M.captured = 0
M << "You are free of the net!"
processing_objects -= src
..()
/obj/effect/energy_net/proc/healthcheck()
if(health <=0)
density = 0
src.visible_message("The energy net is torn apart!")
del(src)
return
/obj/effect/energy_net/process()
if(isnull(affecting) || affecting.loc != loc)
del(src)
return
// Countdown begin set to -1 will stop the teleporter from firing.
// Clientless mobs can be netted but they will not teleport or decrement the timer.
var/mob/living/M = affecting
if(countdown == -1 || (istype(M) && !M.client))
return
if(countdown > 0)
countdown--
return
// TODO: consider removing or altering this; energy nets are useful on their own
// merits and the teleportation was never properly implemented; it's halfassed.
density = 0
invisibility = 101 //Make the net invisible so all the animations can play out.
health = INFINITY //Make the net invincible so that an explosion/something else won't kill it during anims.
playsound(affecting.loc, 'sound/effects/sparks4.ogg', 50, 1)
anim(affecting.loc,affecting,'icons/mob/mob.dmi',,"phaseout",,affecting.dir)
affecting.visible_message("[affecting] vanishes in a flare of light!")
if(holdingfacility.len)
affecting.loc = pick(holdingfacility)
affecting << "You appear in a strange place!"
playsound(affecting.loc, 'sound/effects/phasein.ogg', 25, 1)
playsound(affecting.loc, 'sound/effects/sparks2.ogg', 50, 1)
anim(affecting.loc,affecting,'icons/mob/mob.dmi',,"phasein",,affecting.dir)
del(src)
/obj/effect/energy_net/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
healthcheck()
return 0
/obj/effect/energy_net/ex_act()
health = 0
healthcheck()
/obj/effect/energy_net/blob_act()
health = 0
healthcheck()
/obj/effect/energy_net/meteorhit()
health = 0
healthcheck()
/obj/effect/energy_net/attack_hand(var/mob/user)
var/mob/living/carbon/human/H = user
if(istype(H))
if(H.species.can_shred(H))
playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1)
health -= rand(10, 20)
else
health -= rand(1,3)
else if (HULK in user.mutations)
health = 0
else
health -= rand(5,8)
H << "<span class='danger'>You claw at the energy net.</span>"
healthcheck()
return
/obj/effect/energy_net/attack_paw(var/mob/user)
return attack_hand(user)
/obj/effect/energy_net/attackby(obj/item/weapon/W as obj, mob/user as mob)
health -= W.force
healthcheck()
..()

View File

@@ -9,8 +9,8 @@
..()
new /obj/item/weapon/tank/jetpack/void(src)
new /obj/item/clothing/mask/breath(src)
new /obj/item/clothing/head/helmet/space/nasavoid(src)
new /obj/item/clothing/suit/space/nasavoid(src)
new /obj/item/clothing/head/helmet/space/void(src)
new /obj/item/clothing/suit/space/void(src)
new /obj/item/weapon/crowbar(src)
new /obj/item/weapon/cell(src)
new /obj/item/device/multitool(src)

View File

@@ -14,8 +14,8 @@
new /obj/item/weapon/tank/jetpack/oxygen(src)
new /obj/item/clothing/mask/gas/syndicate(src)
new /obj/item/clothing/under/syndicate(src)
new /obj/item/clothing/head/helmet/space/rig/syndi(src)
new /obj/item/clothing/suit/space/rig/syndi(src)
new /obj/item/clothing/head/helmet/space/void/merc(src)
new /obj/item/clothing/suit/space/void/merc(src)
new /obj/item/weapon/crowbar/red(src)
new /obj/item/weapon/cell/high(src)
new /obj/item/weapon/card/id/syndicate(src)
@@ -25,15 +25,15 @@
/obj/structure/closet/syndicate/suit
desc = "It's a storage unit for rig suits."
desc = "It's a storage unit for voidsuits."
/obj/structure/closet/syndicate/suit/New()
..()
new /obj/item/weapon/tank/jetpack/oxygen(src)
new /obj/item/clothing/shoes/magboots(src)
new /obj/item/clothing/suit/space/rig/syndi(src)
new /obj/item/clothing/suit/space/void/merc(src)
new /obj/item/clothing/mask/gas/syndicate(src)
new /obj/item/clothing/head/helmet/space/rig/syndi(src)
new /obj/item/clothing/head/helmet/space/void/merc(src)
/obj/structure/closet/syndicate/nuclear

View File

@@ -106,12 +106,12 @@
/obj/effect/landmark/corpse/syndicatecommando
name = "Syndicate Commando"
corpseuniform = /obj/item/clothing/under/syndicate
corpsesuit = /obj/item/clothing/suit/space/rig/syndi
corpsesuit = /obj/item/clothing/suit/space/void/merc
corpseshoes = /obj/item/clothing/shoes/swat
corpsegloves = /obj/item/clothing/gloves/swat
corpseradio = /obj/item/device/radio/headset
corpsemask = /obj/item/clothing/mask/gas/syndicate
corpsehelmet = /obj/item/clothing/head/helmet/space/rig/syndi
corpsehelmet = /obj/item/clothing/head/helmet/space/void/merc
corpseback = /obj/item/weapon/tank/jetpack/oxygen
corpsepocket1 = /obj/item/weapon/tank/emergency_oxygen
corpseid = 1
@@ -161,9 +161,9 @@
corpseidaccess = "Station Engineer"
/obj/effect/landmark/corpse/engineer/rig
corpsesuit = /obj/item/clothing/suit/space/rig/engineering
corpsesuit = /obj/item/clothing/suit/space/void/engineering
corpsemask = /obj/item/clothing/mask/breath
corpsehelmet = /obj/item/clothing/head/helmet/space/rig/engineering
corpsehelmet = /obj/item/clothing/head/helmet/space/void/engineering
/obj/effect/landmark/corpse/clown
name = "Clown"
@@ -199,9 +199,9 @@
corpseidaccess = "Shaft Miner"
/obj/effect/landmark/corpse/miner/rig
corpsesuit = /obj/item/clothing/suit/space/rig/mining
corpsesuit = /obj/item/clothing/suit/space/void/mining
corpsemask = /obj/item/clothing/mask/breath
corpsehelmet = /obj/item/clothing/head/helmet/space/rig/mining
corpsehelmet = /obj/item/clothing/head/helmet/space/void/mining
/////////////////Officers//////////////////////

View File

@@ -1,114 +0,0 @@
/*
Dear ninja gloves
This isn't because I like you
this is because your father is a bastard
...
I guess you're a little cool.
-Sayu
*/
/obj/item/clothing/gloves/space_ninja
desc = "These nano-enhanced gloves insulate from electricity and provide fire resistance."
name = "ninja gloves"
icon_state = "s-ninja"
item_state = "s-ninja"
siemens_coefficient = 0
var/draining = 0
var/candrain = 0
var/mindrain = 200
var/maxdrain = 400
species_restricted = null
/*
This runs the gamut of what ninja gloves can do
The other option would be a dedicated ninja touch bullshit proc on everything
which would probably more efficient, but ninjas are pretty rare.
This was mostly introduced to keep ninja code from contaminating other code;
with this in place it would be easier to untangle the rest of it.
For the drain proc, see events/ninja.dm
*/
/obj/item/clothing/gloves/space_ninja/Touch(var/atom/A,var/proximity)
if(!candrain || draining) return 0
var/mob/living/carbon/human/H = loc
if(!istype(H)) return 0 // what
var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit
if(!istype(suit)) return 0
if(isturf(A)) return 0
if(!proximity) // todo: you could add ninja stars or computer hacking here
return 0
// Move an AI into and out of things
if(istype(A,/mob/living/silicon/ai))
if(suit.s_control)
A.add_fingerprint(H)
suit.transfer_ai("AICORE", "NINJASUIT", A, H)
return 1
else
H << "\red <b>ERROR</b>: \black Remote access channel disabled."
return 0
if(istype(A,/obj/structure/AIcore/deactivated))
if(suit.s_control)
A.add_fingerprint(H)
suit.transfer_ai("INACTIVE","NINJASUIT",A, H)
return 1
else
H << "\red <b>ERROR</b>: \black Remote access channel disabled."
return 0
if(istype(A,/obj/machinery/computer/aifixer))
if(suit.s_control)
A.add_fingerprint(H)
suit.transfer_ai("AIFIXER","NINJASUIT",A, H)
return 1
else
H << "\red <b>ERROR</b>: \black Remote access channel disabled."
return 0
// steal energy from powered things
if(istype(A,/mob/living/silicon/robot))
A.add_fingerprint(H)
drain("CYBORG",A,suit)
return 1
if(istype(A,/obj/machinery/power/apc))
A.add_fingerprint(H)
drain("APC",A,suit)
return 1
if(istype(A,/obj/structure/cable))
A.add_fingerprint(H)
drain("WIRE",A,suit)
return 1
if(istype(A,/obj/structure/grille))
var/obj/structure/cable/C = locate() in A.loc
if(C)
drain("WIRE",C,suit)
return 1
if(istype(A,/obj/machinery/power/smes))
A.add_fingerprint(H)
drain("SMES",A,suit)
return 1
if(istype(A,/obj/mecha))
A.add_fingerprint(H)
drain("MECHA",A,suit)
return 1
// download research
if(istype(A,/obj/machinery/computer/rdconsole))
A.add_fingerprint(H)
drain("RESEARCH",A,suit)
return 1
if(istype(A,/obj/machinery/r_n_d/server))
A.add_fingerprint(H)
var/obj/machinery/r_n_d/server/S = A
if(S.disabled)
return 1
if(S.shocked)
S.shock(H,50)
return 1
drain("RESEARCH",A,suit)
return 1

View File

@@ -3,7 +3,7 @@
name = "breath mask"
icon_state = "breath"
item_state = "breath"
flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKINTERNALS
flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | AIRTIGHT
body_parts_covered = 0
w_class = 2
gas_transfer_coefficient = 0.10
@@ -24,14 +24,14 @@
if(!src.hanging)
src.hanging = !src.hanging
gas_transfer_coefficient = 1 //gas is now escaping to the turf and vice versa
flags &= ~(MASKCOVERSMOUTH | MASKINTERNALS)
flags &= ~(MASKCOVERSMOUTH | AIRTIGHT)
icon_state = "breathdown"
usr << "Your mask is now hanging on your neck."
else
src.hanging = !src.hanging
gas_transfer_coefficient = 0.10
flags |= MASKCOVERSMOUTH | MASKINTERNALS
flags |= MASKCOVERSMOUTH | AIRTIGHT
icon_state = "breath"
usr << "You pull the mask up to cover your face."
update_clothing_icon()

View File

@@ -2,7 +2,7 @@
name = "gas mask"
desc = "A face-covering mask that can be connected to an air supply. Filters harmful gases from the air."
icon_state = "gas_alt"
flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS
flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | AIRTIGHT
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE
body_parts_covered = FACE|EYES
w_class = 3.0
@@ -48,22 +48,6 @@
icon_state = "swat"
siemens_coefficient = 0.7
/obj/item/clothing/mask/gas/voice
name = "gas mask"
//desc = "A face-covering mask that can be connected to an air supply. It seems to house some odd electronics."
var/mode = 0// 0==Scouter | 1==Night Vision | 2==Thermal | 3==Meson
var/voice = "Unknown"
var/vchange = 0//This didn't do anything before. It now checks if the mask has special functions/N
origin_tech = "syndicate=4"
/obj/item/clothing/mask/gas/voice/space_ninja
name = "ninja mask"
desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement."
icon_state = "s-ninja"
item_state = "s-ninja_mask"
vchange = 1
siemens_coefficient = 0.2
/obj/item/clothing/mask/gas/clown_hat
name = "clown wig and mask"
desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask."

View File

@@ -0,0 +1,22 @@
/obj/item/voice_changer
name = "voice changer"
desc = "A voice scrambling module. If you can see this, report it as a bug on the tracker."
var/voice //If set and item is present in mask/suit, this name will be used for the wearer's speech.
var/active
/obj/item/clothing/mask/gas/voice
name = "gas mask"
desc = "A face-covering mask that can be connected to an air supply. It seems to house some odd electronics."
var/obj/item/voice_changer/changer
origin_tech = "syndicate=4"
/obj/item/clothing/mask/gas/voice/New()
..()
changer = new(src)
/obj/item/clothing/mask/gas/voice/space_ninja
name = "ninja mask"
desc = "A close-fitting mask that acts both as an air filter and a post-modern fashion statement."
icon_state = "s-ninja"
item_state = "s-ninja_mask"
siemens_coefficient = 0.2

View File

@@ -36,21 +36,6 @@
heat_protection = FEET
max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE
/obj/item/clothing/shoes/space_ninja
name = "ninja shoes"
desc = "A pair of running shoes. Excellent for running and even better for smashing skulls."
icon_state = "s-ninja"
permeability_coefficient = 0.01
flags = NOSLIP
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0.2
cold_protection = FEET
min_cold_protection_temperature = SHOE_MIN_COLD_PROTECTION_TEMPERATURE
heat_protection = FEET
max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE
species_restricted = null
/obj/item/clothing/shoes/sandal
desc = "A pair of rather plain, wooden sandals."
name = "sandals"

View File

@@ -1,89 +0,0 @@
/obj/item/clothing/head/helmet/space/rig/ert
name = "emergency response team helmet"
desc = "A helmet worn by members of the NanoTrasen Emergency Response Team. Armoured and space ready."
icon_state = "rig0-ert_commander"
item_state = "helm-command"
armor = list(melee = 50, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 60)
siemens_coefficient = 0.6
var/obj/machinery/camera/camera
/obj/item/clothing/head/helmet/space/rig/ert/attack_self(mob/user)
if(camera)
..(user)
else
camera = new /obj/machinery/camera(src)
camera.network = list("ERT")
cameranet.removeCamera(camera)
camera.c_tag = user.name
user << "\blue User scanned as [camera.c_tag]. Camera activated."
/obj/item/clothing/head/helmet/space/rig/ert/examine(mob/user)
if(..(user, 1))
user << "This helmet has a built-in camera. It's [camera ? "" : "in"]active."
/obj/item/clothing/suit/space/rig/ert
name = "emergency response team suit"
desc = "A suit worn by members of the NanoTrasen Emergency Response Team. Armoured, space ready, and fire resistant."
icon_state = "ert_commander"
item_state = "suit-command"
w_class = 3
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank/emergency_oxygen)
slowdown = 1
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100)
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, \
/obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/device/multitool, \
/obj/item/device/radio, /obj/item/device/analyzer, /obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/pulse_rifle, \
/obj/item/weapon/gun/energy/taser, /obj/item/weapon/melee/baton, /obj/item/weapon/gun/energy/gun)
siemens_coefficient = 0.6
//Commander
/obj/item/clothing/head/helmet/space/rig/ert/commander
name = "emergency response team commander helmet"
desc = "A helmet worn by the commander of a NanoTrasen Emergency Response Team. Has blue highlights. Armoured and space ready."
icon_state = "rig0-ert_commander"
item_state = "helm-command"
item_color = "ert_commander"
/obj/item/clothing/suit/space/rig/ert/commander
name = "emergency response team commander suit"
desc = "A suit worn by the commander of a NanoTrasen Emergency Response Team. Has blue highlights. Armoured, space ready, and fire resistant."
icon_state = "ert_commander"
item_state = "suit-command"
//Security
/obj/item/clothing/head/helmet/space/rig/ert/security
name = "emergency response team security helmet"
desc = "A helmet worn by security members of a NanoTrasen Emergency Response Team. Has red highlights. Armoured and space ready."
icon_state = "rig0-ert_security"
item_state = "syndicate-helm-black-red"
item_color = "ert_security"
/obj/item/clothing/suit/space/rig/ert/security
name = "emergency response team security suit"
desc = "A suit worn by security members of a NanoTrasen Emergency Response Team. Has red highlights. Armoured, space ready, and fire resistant."
icon_state = "ert_security"
item_state = "syndicate-black-red"
//Engineer
/obj/item/clothing/head/helmet/space/rig/ert/engineer
name = "emergency response team engineer helmet"
desc = "A helmet worn by engineering members of a NanoTrasen Emergency Response Team. Has orange highlights. Armoured and space ready."
icon_state = "rig0-ert_engineer"
item_color = "ert_engineer"
/obj/item/clothing/suit/space/rig/ert/engineer
name = "emergency response team engineer suit"
desc = "A suit worn by the engineering of a NanoTrasen Emergency Response Team. Has orange highlights. Armoured, space ready, and fire resistant."
icon_state = "ert_engineer"
//Medical
/obj/item/clothing/head/helmet/space/rig/ert/medical
name = "emergency response team medical helmet"
desc = "A helmet worn by medical members of a NanoTrasen Emergency Response Team. Has white highlights. Armoured and space ready."
icon_state = "rig0-ert_medical"
item_color = "ert_medical"
/obj/item/clothing/suit/space/rig/ert/medical
name = "emergency response team medical suit"
desc = "A suit worn by medical members of a NanoTrasen Emergency Response Team. Has white highlights. Armoured and space ready."
icon_state = "ert_medical"

View File

@@ -1,71 +0,0 @@
/obj/item/clothing/head/helmet/space/space_ninja
desc = "What may appear to be a simple black garment is in fact a highly sophisticated nano-weave helmet. Standard issue ninja gear."
name = "ninja hood"
icon_state = "s-ninja"
item_state = "s-ninja_mask"
allowed = list(/obj/item/weapon/cell)
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 25)
siemens_coefficient = 0.2
species_restricted = null
body_parts_covered = HEAD|FACE
flags_inv = HIDEEARS|HIDEEYES|HIDEFACE
/obj/item/clothing/suit/space/space_ninja
name = "ninja suit"
desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
icon_state = "s-ninja"
item_state = "s-ninja_suit"
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/cell)
slowdown = 0
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0.2
species_restricted = null //Workaround for spawning alien ninja without internals.
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEJUMPSUIT|HIDETAIL
supporting_limbs = list()
// Hardsuit breaching data
breach_threshold = 30 //A suit breach is a major issue for ninjas. This should maybe help.
can_breach = 1
//Important parts of the suit.
var/mob/living/carbon/affecting = null//The wearer.
var/obj/item/weapon/cell/cell//Starts out with a high-capacity cell using New().
var/datum/effect/effect/system/spark_spread/spark_system//To create sparks.
var/reagent_list[] = list("tricordrazine","tramadol","dexalinp","spaceacillin","anti_toxin","nutriment","radium","hyronalin")//The reagents ids which are added to the suit at New().
var/stored_research[]//For stealing station research.
var/obj/item/weapon/disk/tech_disk/t_disk//To copy design onto disk.
//Other articles of ninja gear worn together, used to easily reference them after initializing.
var/obj/item/clothing/head/helmet/space/space_ninja/n_hood
var/obj/item/clothing/shoes/space_ninja/n_shoes
var/obj/item/clothing/gloves/space_ninja/n_gloves
//Main function variables.
var/s_initialized = 0//Suit starts off.
var/s_coold = 0//If the suit is on cooldown. Can be used to attach different cooldowns to abilities. Ticks down every second based on suit ntick().
var/s_cost = 5.0//Base energy cost each ntick.
var/s_acost = 25.0//Additional cost for additional powers active.
var/k_cost = 200.0//Kamikaze energy cost each ntick.
var/k_damage = 1.0//Brute damage potentially done by Kamikaze each ntick.
var/s_delay = 40.0//How fast the suit does certain things, lower is faster. Can be overridden in specific procs. Also determines adverse probability.
var/a_transfer = 20.0//How much reagent is transferred when injecting.
var/r_maxamount = 80.0//How much reagent in total there is.
//Support function variables.
var/spideros = 0//Mode of SpiderOS. This can change so I won't bother listing the modes here (0 is hub). Check ninja_equipment.dm for how it all works.
var/s_active = 0//Stealth off.
var/s_busy = 0//Is the suit busy with a process? Like AI hacking. Used for safety functions.
var/kamikaze = 0//Kamikaze on or off.
var/k_unlock = 0//To unlock Kamikaze.
//Ability function variables.
var/s_bombs = 10.0//Number of starting ninja smoke bombs.
var/a_boost = 3.0//Number of adrenaline boosters.
//Onboard AI related variables.
var/mob/living/silicon/ai/AI//If there is an AI inside the suit.
var/obj/item/device/paicard/pai//A slot for a pAI device
var/obj/effect/overlay/hologram//Is the AI hologram on or off? Visible only to the wearer of the suit. This works by attaching an image to a blank overlay.
var/flush = 0//If an AI purge is in progress.
var/s_control = 1//If user in control of the suit.

View File

@@ -1,477 +0,0 @@
//Regular rig suits
/obj/item/clothing/head/helmet/space/rig
name = "hardsuit helmet"
desc = "A special helmet designed for work in a hazardous, low-pressure environment."
icon_state = "rig0-engineering"
item_state = "eng_helm"
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
allowed = list(/obj/item/device/flashlight)
var/brightness_on = 4 //luminosity when on
var/on = 0
item_color = "engineering" //Determines used sprites: rig[on]-[color] and rig[on]-[color]2 (lying down sprite)
icon_action_button = "action_hardhat"
heat_protection = HEAD
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
//Species-specific stuff.
species_restricted = list("exclude","Unathi","Tajara","Skrell","Diona","Vox")
sprite_sheets_refit = list(
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
"Tajara" = 'icons/mob/species/tajaran/helmet.dmi',
"Skrell" = 'icons/mob/species/skrell/helmet.dmi',
)
sprite_sheets_obj = list(
"Unathi" = 'icons/obj/clothing/species/unathi/hats.dmi',
"Tajara" = 'icons/obj/clothing/species/tajaran/hats.dmi',
"Skrell" = 'icons/obj/clothing/species/skrell/hats.dmi',
)
attack_self(mob/user)
if(!isturf(user.loc))
user << "You cannot turn the light on while in this [user.loc]" //To prevent some lighting anomalities.
return
on = !on
icon_state = "rig[on]-[item_color]"
// item_state = "rig[on]-[color]"
if(on) user.SetLuminosity(user.luminosity + brightness_on)
else user.SetLuminosity(user.luminosity - brightness_on)
if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
H.update_inv_head()
pickup(mob/user)
if(on)
user.SetLuminosity(user.luminosity + brightness_on)
// user.UpdateLuminosity()
SetLuminosity(0)
dropped(mob/user)
if(on)
user.SetLuminosity(user.luminosity - brightness_on)
// user.UpdateLuminosity()
SetLuminosity(brightness_on)
/obj/item/clothing/suit/space/rig
name = "hardsuit"
desc = "A special space suit for environments that might pose hazards beyond just the vacuum of space. Provides more protection than a standard space suit."
icon_state = "rig-engineering"
item_state = "eng_hardsuit"
slowdown = 1
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit)
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
species_restricted = list("exclude","Unathi","Tajara","Diona","Vox")
sprite_sheets_refit = list(
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
"Tajara" = 'icons/mob/species/tajaran/suit.dmi',
"Skrell" = 'icons/mob/species/skrell/suit.dmi',
)
sprite_sheets_obj = list(
"Unathi" = 'icons/obj/clothing/species/unathi/suits.dmi',
"Tajara" = 'icons/obj/clothing/species/tajaran/suits.dmi',
"Skrell" = 'icons/obj/clothing/species/skrell/suits.dmi',
)
//Breach thresholds, should ideally be inherited by most (if not all) hardsuits.
breach_threshold = 18
can_breach = 1
//Component/device holders.
var/obj/item/weapon/stock_parts/gloves = null // Basic capacitor allows insulation, upgrades allow shock gloves etc.
var/attached_boots = 1 // Can't wear boots if some are attached
var/obj/item/clothing/shoes/magboots/boots = null // Deployable boots, if any.
var/attached_helmet = 1 // Can't wear a helmet if one is deployable.
var/obj/item/clothing/head/helmet/helmet = null // Deployable helmet, if any.
var/list/max_mounted_devices = 0 // Maximum devices. Easy.
var/list/can_mount = null // Types of device that can be hardpoint mounted.
var/list/mounted_devices = null // Holder for the above device.
var/obj/item/active_device = null // Currently deployed device, if any.
/obj/item/clothing/suit/space/rig/equipped(mob/M)
..()
var/mob/living/carbon/human/H = M
if(!istype(H)) return
if(H.wear_suit != src)
return
if(attached_helmet && helmet)
if(H.head)
M << "You are unable to deploy your suit's helmet as \the [H.head] is in the way."
else
M << "Your suit's helmet deploys with a hiss."
//TODO: Species check, skull damage for forcing an unfitting helmet on?
helmet.loc = H
H.equip_to_slot(helmet, slot_head)
helmet.canremove = 0
if(attached_boots && boots)
if(H.shoes)
M << "You are unable to deploy your suit's magboots as \the [H.shoes] are in the way."
else
M << "Your suit's boots deploy with a hiss."
boots.loc = H
H.equip_to_slot(boots, slot_shoes)
boots.canremove = 0
/obj/item/clothing/suit/space/rig/dropped()
..()
var/mob/living/carbon/human/H
if(helmet)
H = helmet.loc
if(istype(H))
if(helmet && H.head == helmet)
helmet.canremove = 1
H.drop_from_inventory(helmet)
helmet.loc = src
if(boots)
H = boots.loc
if(istype(H))
if(boots && H.shoes == boots)
boots.canremove = 1
H.drop_from_inventory(boots)
boots.loc = src
/*
/obj/item/clothing/suit/space/rig/verb/get_mounted_device()
set name = "Deploy Mounted Device"
set category = "Object"
set src in usr
if(!can_mount)
verbs -= /obj/item/clothing/suit/space/rig/verb/get_mounted_device
verbs -= /obj/item/clothing/suit/space/rig/verb/stow_mounted_device
return
if(!istype(usr, /mob/living)) return
if(usr.stat) return
if(active_device)
usr << "You already have \the [active_device] deployed."
return
if(!mounted_devices.len)
usr << "You do not have any devices mounted on \the [src]."
return
/obj/item/clothing/suit/space/rig/verb/stow_mounted_device()
set name = "Stow Mounted Device"
set category = "Object"
set src in usr
if(!can_mount)
verbs -= /obj/item/clothing/suit/space/rig/verb/get_mounted_device
verbs -= /obj/item/clothing/suit/space/rig/verb/stow_mounted_device
return
if(!istype(usr, /mob/living)) return
if(usr.stat) return
if(!active_device)
usr << "You have no device currently deployed."
return
*/
/obj/item/clothing/suit/space/rig/verb/toggle_helmet()
set name = "Toggle Helmet"
set category = "Object"
set src in usr
if(!istype(src.loc,/mob/living)) return
if(!helmet)
usr << "There is no helmet installed."
return
var/mob/living/carbon/human/H = usr
if(!istype(H)) return
if(H.stat) return
if(H.wear_suit != src) return
if(H.head == helmet)
helmet.canremove = 1
H.drop_from_inventory(helmet)
helmet.loc = src
H << "\blue You retract your hardsuit helmet."
else
if(H.head)
H << "\red You cannot deploy your helmet while wearing another helmet."
return
//TODO: Species check, skull damage for forcing an unfitting helmet on?
helmet.loc = H
helmet.pickup(H)
H.equip_to_slot(helmet, slot_head)
helmet.canremove = 0
H << "\blue You deploy your hardsuit helmet, sealing you off from the world."
/obj/item/clothing/suit/space/rig/attackby(obj/item/W as obj, mob/user as mob)
if(!istype(user,/mob/living)) return
if(user.a_intent == "help")
if(istype(src.loc,/mob/living))
user << "How do you propose to modify a hardsuit while it is being worn?"
return
var/target_zone = user.zone_sel.selecting
if(target_zone == "head")
//Installing a component into or modifying the contents of the helmet.
if(!attached_helmet)
user << "\The [src] does not have a helmet mount."
return
if(istype(W,/obj/item/weapon/screwdriver))
if(!helmet)
user << "\The [src] does not have a helmet installed."
else
user << "You detatch \the [helmet] from \the [src]'s helmet mount."
helmet.loc = get_turf(src)
src.helmet = null
return
else if(istype(W,/obj/item/clothing/head/helmet/space))
if(helmet)
user << "\The [src] already has a helmet installed."
else
user << "You attach \the [W] to \the [src]'s helmet mount."
user.drop_item()
W.loc = src
src.helmet = W
return
else
return ..()
else if(target_zone == "l_leg" || target_zone == "r_leg" || target_zone == "l_foot" || target_zone == "r_foot")
//Installing a component into or modifying the contents of the feet.
if(!attached_boots)
user << "\The [src] does not have boot mounts."
return
if(istype(W,/obj/item/weapon/screwdriver))
if(!boots)
user << "\The [src] does not have any boots installed."
else
user << "You detatch \the [boots] from \the [src]'s boot mounts."
boots.loc = get_turf(src)
boots = null
return
else if(istype(W,/obj/item/clothing/shoes/magboots))
if(boots)
user << "\The [src] already has magboots installed."
else
user << "You attach \the [W] to \the [src]'s boot mounts."
user.drop_item()
W.loc = src
boots = W
else
return ..()
/*
else if(target_zone == "l_arm" || target_zone == "r_arm" || target_zone == "l_hand" || target_zone == "r_hand")
//Installing a component into or modifying the contents of the hands.
else if(target_zone == "torso" || target_zone == "groin")
//Modifying the cell or mounted devices
if(!mounted_devices)
return
*/
else //wat
return ..()
..()
//Engineering rig
/obj/item/clothing/head/helmet/space/rig/engineering
name = "engineering hardsuit helmet"
desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding."
icon_state = "rig0-engineering"
item_state = "eng_helm"
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80)
/obj/item/clothing/suit/space/rig/engineering
name = "engineering hardsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding."
icon_state = "rig-engineering"
item_state = "eng_hardsuit"
slowdown = 1
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
//Chief Engineer's rig
/obj/item/clothing/head/helmet/space/rig/engineering/chief
name = "advanced hardsuit helmet"
desc = "An advanced helmet designed for work in a hazardous, low pressure environment. Shines with a high polish."
icon_state = "rig0-white"
item_state = "ce_helm"
item_color = "white"
sprite_sheets_refit = null
sprite_sheets_obj = null
/obj/item/clothing/suit/space/rig/engineering/chief
icon_state = "rig-white"
name = "advanced hardsuit"
desc = "An advanced suit that protects against hazardous, low pressure environments. Shines with a high polish."
item_state = "ce_hardsuit"
sprite_sheets_refit = null
sprite_sheets_obj = null
//Mining rig
/obj/item/clothing/head/helmet/space/rig/mining
name = "mining hardsuit helmet"
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has reinforced plating."
icon_state = "rig0-mining"
item_state = "mining_helm"
item_color = "mining"
armor = list(melee = 50, bullet = 5, laser = 20,energy = 5, bomb = 55, bio = 100, rad = 20)
/obj/item/clothing/suit/space/rig/mining
icon_state = "rig-mining"
name = "mining hardsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has reinforced plating."
item_state = "mining_hardsuit"
armor = list(melee = 50, bullet = 5, laser = 20,energy = 5, bomb = 55, bio = 100, rad = 20)
//Syndicate rig
/obj/item/clothing/head/helmet/space/rig/syndi
name = "blood-red hardsuit helmet"
desc = "An advanced helmet designed for work in special operations. Property of Gorlex Marauders."
icon_state = "rig0-syndie"
item_state = "syndie_helm"
item_color = "syndie"
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.6
var/obj/machinery/camera/camera
species_restricted = list("exclude","Unathi","Tajara","Skrell","Vox")
/obj/item/clothing/head/helmet/space/rig/syndi/attack_self(mob/user)
if(camera)
..(user)
else
camera = new /obj/machinery/camera(src)
camera.network = list("NUKE")
cameranet.removeCamera(camera)
camera.c_tag = user.name
user << "\blue User scanned as [camera.c_tag]. Camera activated."
/obj/item/clothing/head/helmet/space/rig/syndi/examine(mob/user)
if(..(user, 1))
user << "This helmet has a built-in camera. It's [camera ? "" : "in"]active."
/obj/item/clothing/suit/space/rig/syndi
icon_state = "rig-syndie"
name = "blood-red hardsuit"
desc = "An advanced suit that protects against injuries during special operations. Property of Gorlex Marauders."
item_state = "syndie_hardsuit"
slowdown = 1
w_class = 3
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
siemens_coefficient = 0.6
species_restricted = list("exclude","Unathi","Tajara","Skrell","Vox")
//Wizard Rig
/obj/item/clothing/head/helmet/space/rig/wizard
name = "gem-encrusted hardsuit helmet"
desc = "A bizarre gem-encrusted helmet that radiates magical energies."
icon_state = "rig0-wiz"
item_state = "wiz_helm"
item_color = "wiz"
unacidable = 1 //No longer shall our kind be foiled by lone chemists with spray bottles!
armor = list(melee = 40, bullet = 20, laser = 20,energy = 20, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.7
sprite_sheets_refit = null
sprite_sheets_obj = null
/obj/item/clothing/suit/space/rig/wizard
icon_state = "rig-wiz"
name = "gem-encrusted hardsuit"
desc = "A bizarre gem-encrusted suit that radiates magical energies."
item_state = "wiz_hardsuit"
slowdown = 1
w_class = 3
unacidable = 1
armor = list(melee = 40, bullet = 20, laser = 20,energy = 20, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.7
sprite_sheets_refit = null
sprite_sheets_obj = null
//Medical Rig
/obj/item/clothing/head/helmet/space/rig/medical
name = "medical hardsuit helmet"
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has minor radiation shielding."
icon_state = "rig0-medical"
item_state = "medical_helm"
item_color = "medical"
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50)
/obj/item/clothing/suit/space/rig/medical
icon_state = "rig-medical"
name = "medical hardsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding."
item_state = "medical_hardsuit"
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical)
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50)
//Security
/obj/item/clothing/head/helmet/space/rig/security
name = "security hardsuit helmet"
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor."
icon_state = "rig0-sec"
item_state = "sec_helm"
item_color = "sec"
armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10)
siemens_coefficient = 0.7
/obj/item/clothing/suit/space/rig/security
icon_state = "rig-sec"
name = "security hardsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor."
item_state = "sec_hardsuit"
armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10)
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton)
siemens_coefficient = 0.7
//Atmospherics Rig (BS12)
/obj/item/clothing/head/helmet/space/rig/atmos
desc = "A special helmet designed for work in a hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding."
name = "atmospherics hardsuit helmet"
icon_state = "rig0-atmos"
item_state = "atmos_helm"
item_color = "atmos"
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 50)
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
/obj/item/clothing/suit/space/rig/atmos
desc = "A special suit that protects against hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding."
icon_state = "rig-atmos"
name = "atmos hardsuit"
item_state = "atmos_hardsuit"
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 50)
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE

View File

@@ -0,0 +1,214 @@
/*
* Contains
* /obj/item/rig_module/grenade_launcher
* /obj/item/rig_module/mounted
* /obj/item/rig_module/mounted/taser
* /obj/item/rig_module/shield
* /obj/item/rig_module/fabricator
*/
/obj/item/rig_module/grenade_launcher
name = "mounted grenade launcher"
desc = "A shoulder-mounted micro-explosive dispenser."
selectable = 1
interface_name = "integrated grenade launcher"
interface_desc = "Discharges loaded grenades against the wearer's location."
var/fire_force = 30
var/fire_distance = 10
charges = list(
list("flashbang", "flashbang", /obj/item/weapon/grenade/flashbang, 3),
list("smoke bomb", "smoke bomb", /obj/item/weapon/grenade/smokebomb, 3),
list("EMP grenade", "EMP grenade", /obj/item/weapon/grenade/empgrenade, 3),
)
/obj/item/rig_module/grenade_launcher/accepts_item(var/obj/item/input_device, var/mob/living/user)
if(!istype(input_device) || !istype(user))
return 0
var/datum/rig_charge/accepted_item
for(var/charge in charges)
var/datum/rig_charge/charge_datum = charges[charge]
if(input_device.type == charge_datum.product_type)
accepted_item = charge_datum
break
if(!accepted_item)
return 0
if(accepted_item.charges >= 5)
user << "<span class='danger'>Another grenade of that type will not fit into the module.</span>"
return 0
user << "<font color='blue'><b>You slot \the [input_device] into the suit module.</b></font>"
user.drop_from_inventory(input_device)
del(input_device)
accepted_item.charges++
return 1
/obj/item/rig_module/grenade_launcher/engage(atom/target)
if(!..())
return 0
if(!target)
return 0
var/mob/living/carbon/human/H = holder.wearer
if(!charge_selected)
H << "<span class='danger'>You have not selected a grenade type.</span>"
return 0
var/datum/rig_charge/charge = charges[charge_selected]
if(!charge)
return 0
if(charge.charges <= 0)
H << "<span class='danger'>Insufficient grenades!</span>"
return 0
charge.charges--
var/obj/item/weapon/grenade/new_grenade = new charge.product_type(get_turf(H))
H.visible_message("<span class='danger'>[H] launches \a [new_grenade]!")
new_grenade.activate(H)
new_grenade.throw_at(target,fire_force,fire_distance)
/obj/item/rig_module/mounted
name = "mounted laser cannon"
desc = "A shoulder-mounted battery-powered M1911A pulse rifle mount."
selectable = 1
usable = 1
use_power_cost = 10
interface_name = "mounted laser cannon"
interface_desc = "A shoulder-mounted cell-powered laser cannon."
var/gun_type = /obj/item/weapon/gun/energy/lasercannon/mounted
var/obj/item/weapon/gun/gun
/obj/item/rig_module/mounted/New()
..()
gun = new gun_type(src)
/obj/item/rig_module/mounted/engage(atom/target)
if(!..())
return 0
if(!target)
gun.attack_self(holder.wearer)
return 1
gun.Fire(target,holder.wearer)
return 1
/obj/item/rig_module/mounted/taser
name = "mounted taser"
desc = "A shoulder-mounted energy projector."
suit_overlay_active = "mounted-taser"
suit_overlay_inactive = "mounted-taser"
interface_name = "mounted energy gun"
interface_desc = "A shoulder-mounted cell-powered energy gun."
gun_type = /obj/item/weapon/gun/energy/gun/mounted
/obj/item/rig_module/mounted/energy_blade
name = "energy blade projector"
desc = "A powerful cutting beam projector."
interface_name = "spider fang blade"
interface_desc = "A lethal energy projector that can shape a blade projected from the hand of the wearer or launch radioactive darts."
usable = 0
selectable = 1
toggleable = 1
use_power_cost = 50
active_power_cost = 5
gun_type = /obj/item/weapon/gun/energy/crossbow/ninja
/obj/item/rig_module/mounted/energy_blade/process()
if(holder && holder.wearer)
if(!(locate(/obj/item/weapon/melee/energy/blade) in holder.wearer))
deactivate()
return 0
..()
/obj/item/rig_module/mounted/energy_blade/activate()
..()
var/mob/living/M = holder.wearer
if(M.l_hand && M.r_hand)
M << "<span class='danger'>Your hands are full.</span>"
deactivate()
return
var/obj/item/weapon/melee/energy/blade/blade = new(M)
blade.creator = M
M.put_in_hands(blade)
/obj/item/rig_module/mounted/energy_blade/deactivate()
..()
var/mob/living/M = holder.wearer
if(!M)
return
for(var/obj/item/weapon/melee/energy/blade/blade in M.contents)
M.drop_from_inventory(blade)
del(blade)
/obj/item/rig_module/fabricator
name = "matter fabricator"
desc = "A self-contained microfactory system for hardsuit integration."
selectable = 1
usable = 1
use_power_cost = 15
interface_name = "death blossom launcher"
interface_desc = "An integrated microfactory that produces poisoned throwing stars from thin air and electricity."
var/fabrication_type = /obj/item/weapon/star/ninja
var/fire_force = 30
var/fire_distance = 10
/obj/item/rig_module/fabricator/engage(atom/target)
if(!..())
return 0
var/mob/living/H = holder.wearer
if(target)
var/obj/item/firing = new fabrication_type()
firing.loc = get_turf(src)
H.visible_message("<span class='danger'>[H] launches \a [firing]!</span>")
firing.throw_at(target,fire_force,fire_distance)
else
if(H.l_hand && H.r_hand)
H << "<span class='danger'>Your hands are full."
else
var/obj/item/new_weapon = new fabrication_type()
new_weapon.loc = H
H << "<font color='blue'><b>You quickly fabricate \a [new_weapon].</b></font>"
H.put_in_hands(new_weapon)
return 1

View File

@@ -0,0 +1,395 @@
/*
* Contains
* /obj/item/rig_module/ai_container
* /obj/item/rig_module/datajack
* /obj/item/rig_module/power_sink
* /obj/item/rig_module/electrowarfare_suite
*/
/obj/item/rig_module/ai_container
name = "IIS module"
desc = "An integrated intelligence system module suitable for most hardsuits."
toggleable = 1
usable = 1
disruptive = 0
activates_on_touch = 1
interface_name = "integrated intelligence system"
interface_desc = "A socket that supports a range of artificial intelligence systems."
var/mob/integrated_ai // Direct reference to the actual mob held in the suit.
var/obj/item/ai_card // Reference to the MMI, posibrain, intellicard or pAI card previously holding the AI.
/obj/item/rig_module/ai_container/accepts_item(var/obj/item/input_device, var/mob/living/user)
// Check if there's actually an AI to deal with.
var/mob/living/silicon/ai/target_ai
if(istype(input_device, /mob/living/silicon/ai))
target_ai = input_device
else
target_ai = locate(/mob/living/silicon/ai) in input_device.contents
var/obj/item/device/aicard/card = ai_card
// Downloading from/loading to a terminal.
if(istype(input_device,/obj/machinery/computer/aifixer) || istype(input_device,/mob/living/silicon/ai) || istype(input_device,/obj/structure/AIcore/deactivated))
// If we're stealing an AI, make sure we have a card for it.
if(!card)
card = new /obj/item/device/aicard(src)
// Terminal interaction only works with an intellicarded AI.
if(!istype(card))
return 0
// Since we've explicitly checked for three types, this should be safe.
input_device.attackby(card,user)
// If the transfer failed we can delete the card.
if(locate(/mob/living/silicon/ai) in card)
ai_card = card
else
eject_ai()
return 1
if(istype(input_device,/obj/item/device/aicard))
// We are carding the AI in our suit.
if(integrated_ai)
integrated_ai.attackby(input_device,user)
// If the transfer was successful, we can clear out our vars.
if(integrated_ai.loc != src)
integrated_ai = null
eject_ai()
else
// You're using an empty card on an empty suit, idiot.
if(!target_ai)
return 0
integrate_ai(input_device,user)
return 1
// Okay, it wasn't a terminal being touched, check for all the simple insertions.
if(input_device.type in list(/obj/item/device/paicard, /obj/item/device/mmi, /obj/item/device/mmi/posibrain))
integrate_ai(input_device,user)
return 1
return 0
/obj/item/rig_module/ai_container/engage(atom/target)
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
if(!target)
if(ai_card)
if(istype(ai_card,/obj/item/device/aicard))
ai_card.attack_self(H)
else
eject_ai(H)
return 1
if(accepts_item(target,H))
return 1
return 0
/obj/item/rig_module/ai_container/removed()
eject_ai()
..()
/obj/item/rig_module/ai_container/proc/eject_ai(var/mob/user)
if(ai_card)
if(istype(ai_card, /obj/item/device/aicard))
if(integrated_ai && integrated_ai.client)
if(user)
user << "<span class='danger'>You cannot eject your currently stored AI. Purge it manually.</span>"
return 0
del(ai_card)
else if(user)
user.put_in_hands(ai_card)
else
ai_card.loc = get_turf(src)
ai_card = null
if(integrated_ai)
integrated_ai.verbs -= /mob/living/proc/hardsuit_interface_ai
integrated_ai = null
/obj/item/rig_module/ai_container/proc/integrate_ai(var/obj/item/ai,var/mob/user)
if(!ai) return
// The ONLY THING all the different AI systems have in common is that they all store the mob inside an item.
var/mob/living/ai_mob = locate(/mob/living) in ai.contents
if(ai_mob)
if(ai_mob.key && ai_mob.client)
if(istype(ai, /obj/item/device/aicard))
if(!ai_card)
ai_card = new /obj/item/device/aicard(src)
var/obj/item/device/aicard/source_card = ai
var/obj/item/device/aicard/target_card = ai_card
if(istype(source_card) && istype(target_card))
if(target_card.grab_ai(ai_mob, user))
source_card.clear()
else
return 0
else
return 0
else
user.drop_from_inventory(ai)
ai.loc = src
ai_card = ai
ai_mob << "<font color='blue'>You have been transferred to \the [holder]'s [src].</font>"
user << "<font color='blue'>You load [ai_mob] into \the [holder]'s [src].</font>"
integrated_ai = ai_mob
if(!(locate(integrated_ai) in ai_card))
integrated_ai = null
eject_ai()
else
integrated_ai.verbs |= /mob/living/proc/hardsuit_interface_ai
else
user << "<span class='warning'>There is no active AI within \the [ai].</span>"
else
user << "<span class='warning'>There is no active AI within \the [ai].</span>"
return
/obj/item/rig_module/datajack
name = "datajack module"
desc = "A simple induction datalink module."
toggleable = 1
activates_on_touch = 1
usable = 0
interface_name = "contact datajack"
interface_desc = "An induction-powered high-throughput datalink suitable for hacking encrypted networks."
var/list/stored_research
/obj/item/rig_module/datajack/New()
..()
stored_research = list()
/obj/item/rig_module/datajack/engage(atom/target)
if(!..())
return 0
if(target)
var/mob/living/carbon/human/H = holder.wearer
if(!accepts_item(target,H))
return 0
return 1
/obj/item/rig_module/datajack/accepts_item(var/obj/item/input_device, var/mob/living/user)
if(istype(input_device,/obj/item/weapon/disk/tech_disk))
user << "You slot the disk into [src]."
var/obj/item/weapon/disk/tech_disk/disk = input_device
if(disk.stored)
if(load_data(disk.stored))
user << "<font color='blue'>Download successful; disk erased.</font>"
disk.stored = null
else
user << "<span class='warning'>The disk is corrupt. It is useless to you.</span>"
else
user << "<span class='warning'>The disk is blank. It is useless to you.</span>"
return 1
// I fucking hate R&D code. This typecheck spam would be totally unnecessary in a sane setup.
else if(istype(input_device,/obj/machinery))
var/datum/research/incoming_files
if(istype(input_device,/obj/machinery/computer/rdconsole))
var/obj/machinery/computer/rdconsole/input_machine = input_device
incoming_files = input_machine.files
else if(istype(input_device,/obj/machinery/r_n_d/server))
var/obj/machinery/r_n_d/server/input_machine = input_device
incoming_files = input_machine.files
else if(istype(input_device,/obj/machinery/mecha_part_fabricator))
var/obj/machinery/mecha_part_fabricator/input_machine = input_device
incoming_files = input_machine.files
if(!incoming_files || !incoming_files.known_tech || !incoming_files.known_tech.len)
user << "<span class='warning'>Memory failure. There is nothing accessible stored on this terminal.</span>"
else
// Maybe consider a way to drop all your data into a target repo in the future.
if(load_data(incoming_files.known_tech))
user << "<font color='blue'>Download successful; local and remote repositories synchronized.</font>"
else
user << "<span class='warning'>Scan complete. There is nothing useful stored on this terminal.</span>"
return 1
return 0
/obj/item/rig_module/datajack/proc/load_data(var/incoming_data)
if(islist(incoming_data))
for(var/entry in incoming_data)
load_data(entry)
return 1
if(istype(incoming_data, /datum/tech))
var/data_found
var/datum/tech/new_data = incoming_data
for(var/datum/tech/current_data in stored_research)
if(current_data.id == new_data.id)
data_found = 1
if(current_data.level < new_data.level)
current_data.level = new_data.level
break
if(!data_found)
stored_research += incoming_data
return 1
return 0
/obj/item/rig_module/electrowarfare_suite
name = "electrowarfare module"
desc = "A bewilderingly complex bundle of fiber optics and chips."
toggleable = 1
usable = 0
interface_name = "electrowarfare system"
interface_desc = "An active counter-electronic warfare suite that disrupts AI tracking."
/obj/item/rig_module/electrowarfare_suite/activate()
if(!..())
return
// This is not the best way to handle this, but I don't want it to mess with ling camo
var/mob/living/M = holder.wearer
M.digitalcamo++
/obj/item/rig_module/electrowarfare_suite/deactivate()
if(!..())
return
var/mob/living/M = holder.wearer
M.digitalcamo = max(0,(M.digitalcamo-1))
/obj/item/rig_module/power_sink
name = "hardsuit power sink"
desc = "An heavy-duty power sink."
toggleable = 1
activates_on_touch = 1
disruptive = 0
interface_name = "niling d-sink"
interface_desc = "Colloquially known as a power siphon, this module drains power through the suit hands into the suit battery."
var/atom/interfaced_with // Currently draining power from this device.
var/total_power_drained = 0
/obj/item/rig_module/power_sink/deactivate()
if(interfaced_with)
if(holder && holder.wearer)
holder.wearer << "<span class = 'warning'>Your power sink retracts as the module deactivates.</span>"
drain_complete()
interfaced_with = null
total_power_drained = 0
return ..()
/obj/item/rig_module/power_sink/activate()
interfaced_with = null
total_power_drained = 0
return ..()
/obj/item/rig_module/power_sink/engage(atom/target)
if(!..())
return 0
//Target wasn't supplied or we're already draining.
if(interfaced_with)
return 0
if(!target)
return 1
// Are we close enough?
var/mob/living/carbon/human/H = holder.wearer
if(!target.Adjacent(H))
return 0
// Is it a valid power source?
if(target.drain_power(1) <= 0)
return 0
H << "<span class = 'danger'>You begin draining power from [target]!</span>"
interfaced_with = target
holder.spark_system.start()
playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1)
return 1
/obj/item/rig_module/power_sink/accepts_item(var/obj/item/input_device, var/mob/living/user)
var/can_drain = input_device.drain_power(1)
if(can_drain > 0)
engage(input_device)
return 1
return 0
/obj/item/rig_module/power_sink/process()
if(!interfaced_with)
return ..()
var/mob/living/carbon/human/H
if(holder && holder.wearer)
H = holder.wearer
if(!H || !istype(H))
return 0
holder.spark_system.start()
playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1)
if(!holder.cell)
H << "<span class = 'danger'>Your power sink flashes an error; there is no cell in your rig.</span>"
drain_complete(H)
return
if(!interfaced_with || !interfaced_with.Adjacent(H))
H << "<span class = 'warning'>Your power sink retracts into its casing.</span>"
drain_complete(H)
return
var/target_drained = interfaced_with.drain_power()
if(target_drained <= 0)
H << "<span class = 'danger'>Your power sink flashes a red light; there is no power left in [interfaced_with].</span>"
drain_complete(H)
return
holder.cell.charge += target_drained
total_power_drained += target_drained
if(holder.cell.charge > holder.cell.maxcharge)
H << "<span class = 'warning'>Your power sink flashes an amber light; your rig cell is full.</span>"
holder.cell.charge = holder.cell.maxcharge
drain_complete(H)
return
return 1
/obj/item/rig_module/power_sink/proc/drain_complete(var/mob/living/M)
if(!interfaced_with)
if(M) M << "<font color='blue'><b>Total power drained:</b> [total_power_drained]W.</font>"
else
if(M) M << "<font color='blue'><b>Total power drained from [interfaced_with]:</b> [total_power_drained]W.</font>"
interfaced_with.drain_power(0,1) // Damage the victim.
interfaced_with = null
total_power_drained = 0

View File

@@ -0,0 +1,147 @@
/*
* Rigsuit upgrades/abilities.
*/
/datum/rig_charge
var/short_name = "undef"
var/display_name = "undefined"
var/product_type = "undefined"
var/charges = 0
/obj/item/rig_module
name = "hardsuit upgrade"
desc = "It looks pretty sciency."
icon = 'icons/obj/rig_modules.dmi'
icon_state = "module"
matter = list("metal" = 20000, "plastic" = 30000, "glass" = 5000)
var/obj/item/weapon/storage/rig/holder
var/module_cooldown = 10
var/next_use = 0
var/toggleable // Set to 1 for the device to show up as an active effect.
var/usable // Set to 1 for the device to have an on-use effect.
var/selectable // Set to 1 to be able to assign the device as primary system.
var/redundant // Set to 1 to ignore duplicate module checking when installing.
var/permanent // If set, the module can't be removed.
var/disruptive = 1 // Can disrupt by other effects.
var/activates_on_touch // If set, unarmed attacks will call engage() on the target.
var/active // Basic module status
var/disruptable // Will deactivate if some other powers are used.
var/use_power_cost = 0 // Power used when single-use ability called.
var/active_power_cost = 0 // Power used when turned on.
var/passive_power_cost = 0 // Power used when turned off.
var/list/charges // Associative list of charge types and remaining numbers.
var/charge_selected // Currently selected option used for charge dispensing.
// Icons.
var/suit_overlay
var/suit_overlay_active // If set, drawn over icon and mob when effect is active.
var/suit_overlay_inactive // As above, inactive.
var/suit_overlay_used // As above, when engaged. TODO
//Display fluff
var/interface_name = "hardsuit upgrade"
var/interface_desc = "A generic hardsuit upgrade."
/obj/item/rig_module/New()
..()
if(suit_overlay_inactive)
suit_overlay = suit_overlay_inactive
if(charges && charges.len)
var/list/processed_charges = list()
for(var/list/charge in charges)
var/datum/rig_charge/charge_dat = new
charge_dat.short_name = charge[1]
charge_dat.display_name = charge[2]
charge_dat.product_type = charge[3]
charge_dat.charges = charge[4]
if(!charge_selected) charge_selected = charge_dat.short_name
processed_charges[charge_dat.short_name] = charge_dat
charges = processed_charges
..()
// Called when the module is installed into a suit.
/obj/item/rig_module/proc/installed(var/obj/item/weapon/storage/rig/new_holder)
holder = new_holder
return
//Proc for one-use abilities like teleport.
/obj/item/rig_module/proc/engage()
if(world.time < next_use)
usr << "<span class='warning'>You cannot use the [interface_name] again so soon.</span>"
return 0
if(!holder || holder.canremove)
usr << "<span class='warning'>The suit is not initialized.</span>"
return 0
if(!holder.check_power_cost(usr, use_power_cost, 0, src, (istype(usr,/mob/living/silicon ? 1 : 0) ) ) )
return 0
next_use = world.time + module_cooldown
return 1
// Proc for toggling on active abilities.
/obj/item/rig_module/proc/activate()
if(active || !engage())
return 0
active = 1
spawn(1)
if(suit_overlay_active)
suit_overlay = suit_overlay_active
else
suit_overlay = null
holder.update_icon()
return 1
// Proc for toggling off active abilities.
/obj/item/rig_module/proc/deactivate()
if(!active)
return 0
active = 0
spawn(1)
if(suit_overlay_inactive)
suit_overlay = suit_overlay_inactive
else
suit_overlay = null
if(holder)
holder.update_icon()
return 1
// Called when the module is uninstalled from a suit.
/obj/item/rig_module/proc/removed()
deactivate()
holder = null
return
// Called by the hardsuit each rig process tick.
/obj/item/rig_module/process()
if(active)
return active_power_cost
else
return passive_power_cost
// Called by holder rigsuit attackby()
// Checks if an item is usable with this module and handles it if it is
/obj/item/rig_module/proc/accepts_item(var/obj/item/input_device)
return 0

View File

@@ -0,0 +1,166 @@
/*
* Contains
* /obj/item/rig_module/stealth_field
* /obj/item/rig_module/teleporter
* /obj/item/rig_module/fabricator/energy_net
* /obj/item/rig_module/self_destruct
*/
/obj/item/rig_module/stealth_field
name = "active camouflage module"
desc = "A robust hardsuit-integrated stealth module."
icon_state = "stealth"
toggleable = 1
disruptable = 1
disruptive = 0
use_power_cost = 5
active_power_cost = 1
passive_power_cost = 0
interface_name = "integrated stealth system"
interface_desc = "An integrated active camouflage system."
suit_overlay_active = "stealth_active"
suit_overlay_inactive = "stealth_inactive"
/obj/item/rig_module/stealth_field/activate()
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
H << "<font color='blue'><b>You are now invisible to normal detection.</b></font>"
H.invisibility = INVISIBILITY_LEVEL_TWO
anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity",null,20,null)
H.visible_message("[H.name] vanishes into thin air!",1)
/obj/item/rig_module/stealth_field/deactivate()
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
H << "<span class='danger'>You are now visible.</span>"
H.invisibility = 0
anim(get_turf(H), H,'icons/mob/mob.dmi',,"uncloak",,H.dir)
anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity",null,20,null)
for(var/mob/O in oviewers(H))
O.show_message("[H.name] appears from thin air!",1)
playsound(get_turf(H), 'sound/effects/stealthoff.ogg', 75, 1)
/obj/item/rig_module/teleporter
name = "teleportation module"
desc = "A complex, sleek-looking, hardsuit-integrated teleportation module."
use_power_cost = 40
redundant = 1
usable = 1
selectable = 1
interface_name = "VOID-shift phase projector"
interface_desc = "An advanced teleportation system. It is capable of pinpoint precision or random leaps forward."
/obj/item/rig_module/teleporter/proc/phase_in(var/mob/M,var/turf/T)
if(!M || !T)
return
holder.spark_system.start()
playsound(T, 'sound/effects/phasein.ogg', 25, 1)
playsound(T, 'sound/effects/sparks2.ogg', 50, 1)
anim(T,M,'icons/mob/mob.dmi',,"phasein",,M.dir)
/obj/item/rig_module/teleporter/proc/phase_out(var/mob/M,var/turf/T)
if(!M || !T)
return
playsound(T, "sparks", 50, 1)
anim(T,M,'icons/mob/mob.dmi',,"phaseout",,M.dir)
/obj/item/rig_module/teleporter/engage(atom/target)
if(!..()) return 0
var/mob/living/carbon/human/H = holder.wearer
var/turf/T
if(target)
T = get_turf(target)
else
T = get_teleport_loc(get_turf(H), H, rand(5, 9))
if(!T || T.density)
H << "<span class='warning'>You cannot teleport into solid walls.</span>"
return 0
phase_out(H,get_turf(H))
H.loc = T
phase_in(H,get_turf(H))
for(var/obj/item/weapon/grab/G in H.contents)
if(G.affecting)
phase_out(G.affecting,get_turf(G.affecting))
G.affecting.loc = locate(T.x+rand(-1,1),T.y+rand(-1,1),T.z)
phase_in(G.affecting,get_turf(G.affecting))
return 1
/obj/item/rig_module/fabricator/energy_net
name = "net projector"
desc = "Some kind of complex energy projector with a hardsuit mount."
interface_name = "energy net launcher"
interface_desc = "An advanced energy-patterning projector used to capture targets."
fabrication_type = /obj/item/weapon/energy_net
use_power_cost = 70
/obj/item/rig_module/fabricator/energy_net/engage(atom/target)
if(holder && holder.wearer)
if(..(target) && target)
holder.wearer.Beam(target,"n_beam",,10)
return 1
return 0
/obj/item/rig_module/self_destruct
name = "self-destruct module"
desc = "Oh my God, Captain. A bomb."
usable = 1
active = 1
permanent = 1
interface_name = "dead man's switch"
interface_desc = "An integrated self-destruct module. When the wearer dies, so does the surrounding area. Do not press this button."
/obj/item/rig_module/self_destruct/activate()
return
/obj/item/rig_module/self_destruct/deactivate()
return
/obj/item/rig_module/self_destruct/process()
// Not being worn, leave it alone.
if(!holder || !holder.wearer || !holder.wearer.wear_suit == holder)
return 0
//OH SHIT.
if(holder.wearer.stat == 2)
engage()
/obj/item/rig_module/self_destruct/engage()
explosion(get_turf(src), 0, 0, 3, 4)

View File

@@ -0,0 +1,173 @@
/* Contains:
* /obj/item/rig_module/device
* /obj/item/rig_module/device/plasma_cutter
* /obj/item/rig_module/device/injector
* /obj/item/rig_module/device/healthscanner
* /obj/item/rig_module/device/drill
* /obj/item/rig_module/device/orescanner
* /obj/item/rig_module/maneuvering_jets
* /obj/item/rig_module/foam_sprayer
* /obj/item/rig_module/device/broadcaster
* /obj/item/rig_module/chem_dispenser
* /obj/item/rig_module/voice
*/
/obj/item/rig_module/chem_dispenser
name = "mounted chemical dispenser"
desc = "A complex web of tubing and needles suitable for hardsuit use."
usable = 1
selectable = 0
toggleable = 0
disruptive = 0
interface_name = "integrated chemical dispenser"
interface_desc = "Dispenses loaded chemicals directly into the wearer's bloodstream."
charges = list(
list("tricordrazine", "tricordrazine", 0, 80),
list("tramadol", "tramadol", 0, 80),
list("dexalin plus", "dexalinp", 0, 80),
list("antibiotics", "spaceacillin", 0, 80),
list("antitoxins", "anti_toxin", 0, 80),
list("nutrients", "nutriment", 0, 80),
list("hyronalin", "hyronalin", 0, 80),
list("radium", "radium", 0, 80)
)
var/max_reagent_volume = 80 //Used when refilling.
/obj/item/rig_module/chem_dispenser/accepts_item(var/obj/item/input_item, var/mob/living/user)
if(!input_item.is_open_container())
return 0
if(!input_item.reagents || !input_item.reagents.total_volume)
user << "\The [input_item] is empty."
return 0
// Magical chemical filtration system, do not question it.
var/total_transferred = 0
for(var/datum/reagent/R in input_item.reagents.reagent_list)
for(var/chargetype in charges)
var/datum/rig_charge/charge = charges[chargetype]
if(charge.display_name == R.id)
var/chems_to_transfer = R.volume
if((charge.charges + chems_to_transfer) > max_reagent_volume)
chems_to_transfer = max_reagent_volume - charge.charges
charge.charges += chems_to_transfer
input_item.reagents.remove_reagent(R.id, chems_to_transfer)
total_transferred += chems_to_transfer
break
if(total_transferred)
user << "<font color='blue'>You transfer [total_transferred] units into the suit reservoir.</font>"
else
user << "<span class='danger'>None of the reagents seem suitable.</span>"
return 1
/obj/item/rig_module/chem_dispenser/engage(atom/target)
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
if(!charge_selected)
H << "<span class='danger'>You have not selected a chemical type.</span>"
return 0
var/datum/rig_charge/charge = charges[charge_selected]
if(!charge)
return 0
var/chems_to_use = 10
if(charge.charges <= 0)
H << "<span class='danger'>Insufficient chems!</span>"
return 0
else if(charge.charges < chems_to_use)
chems_to_use = charge.charges
var/mob/living/target_mob
if(target)
if(istype(target,/mob/living))
target_mob = target
else
return 0
else
target_mob = H
if(target_mob != H)
H << "<span class='danger'>You inject [target_mob] with [chems_to_use] unit[chems_to_use == 1 ? "" : "s"] of [charge.display_name].</span>"
target_mob << "<span class='danger'>You feel a rushing in your veins as [chems_to_use] unit[chems_to_use == 1 ? "" : "s"] of [charge.display_name] [chems_to_use == 1 ? "is" : "are"] injected.</span>"
target_mob.reagents.add_reagent(charge.display_name, chems_to_use)
charge.charges -= chems_to_use
if(charge.charges < 0) charge.charges = 0
return 1
/obj/item/rig_module/chem_dispenser/injector
name = "mounted chemical injector"
desc = "A complex web of tubing and a large needle suitable for hardsuit use."
usable = 0
selectable = 1
disruptive = 1
interface_name = "mounted chem injector"
interface_desc = "Dispenses loaded chemicals via an arm-mounted injector."
/obj/item/rig_module/voice
name = "hardsuit voice synthesiser"
desc = "A speaker box and sound processor."
usable = 1
selectable = 0
toggleable = 0
disruptive = 0
interface_name = "voice synthesiser"
interface_desc = "A flexible and powerful voice modulator system."
var/obj/item/voice_changer/voice_holder
/obj/item/rig_module/voice/New()
..()
voice_holder = new(src)
voice_holder.active = 0
/obj/item/rig_module/voice/installed()
..()
holder.speech = src
/obj/item/rig_module/voice/engage()
if(!..())
return 0
var/choice= input("Would you like to toggle the synthesiser or set the name?") as null|anything in list("Enable","Disable","Set Name")
if(!choice)
return 0
switch(choice)
if("Enable")
active = 1
voice_holder.active = 1
usr << "<font color='blue'>You enable the speech synthesiser.</font>"
if("Disable")
active = 0
voice_holder.active = 0
usr << "<font color='blue'>You disable the speech synthesiser.</font>"
if("Set Name")
var/raw_choice = input(usr, "Please enter a new name.") as text|null
if(!raw_choice)
return 0
voice_holder.voice = sanitize(copytext(raw_choice,1,MAX_MESSAGE_LEN))
usr << "You are now mimicking <B>[voice_holder.voice]</B>.</font>"
return 1

View File

@@ -0,0 +1,80 @@
/datum/rig_vision
var/mode
var/obj/item/clothing/glasses/glasses
/datum/rig_vision/nvg
mode = "night vision"
/datum/rig_vision/nvg/New()
glasses = new /obj/item/clothing/glasses/night
/datum/rig_vision/thermal
mode = "thermal scanner"
/datum/rig_vision/thermal/New()
glasses = new /obj/item/clothing/glasses/thermal
/datum/rig_vision/meson
mode = "meson scanner"
/datum/rig_vision/meson/New()
glasses = new /obj/item/clothing/glasses/meson
/obj/item/rig_module/vision
name = "hardsuit visor"
desc = "A layered, translucent visor system for a hardsuit."
interface_name = "optical scanners"
interface_desc = "An integrated multi-mode vision system."
usable = 1
toggleable = 1
disruptive = 0
var/datum/rig_vision/vision
var/list/vision_modes = list(
/datum/rig_vision/nvg,
/datum/rig_vision/thermal,
/datum/rig_vision/meson
)
var/vision_index
// There should only ever be one vision module installed in a suit.
/obj/item/rig_module/vision/installed()
..()
holder.visor = src
/obj/item/rig_module/vision/engage()
var/starting_up = !active
if(!..() || !vision_modes)
return 0
// Don't cycle if this engage() is being called by activate().
if(starting_up)
holder.wearer << "<font color='blue'>You activate your visual sensors.</font>"
return 1
vision_index++
if(vision_index > vision_modes.len)
vision_index = 1
vision = vision_modes[vision_index]
holder.wearer << "<font color='blue'>You cycle your sensors to <b>[vision.mode]</b> mode.</font>"
return 1
/obj/item/rig_module/vision/New()
..()
if(!vision_modes)
return
vision_index = 1
var/list/processed_vision = list()
for(var/vision_mode in vision_modes)
var/datum/rig_vision/vision_datum = new vision_mode
if(!vision) vision = vision_datum
processed_vision += vision_datum
vision_modes = processed_vision

View File

@@ -0,0 +1,572 @@
#define ONLY_DEPLOY 1
#define ONLY_RETRACT 2
#define SEAL_DELAY 30
/*
* Defines the behavior of hardsuits/rigs/power armour.
*/
/obj/item/weapon/storage/rig
name = "hardsuit control module"
icon = 'icons/obj/rig_modules.dmi'
desc = "A back-mounted hardsuit deployment and control mechanism."
slot_flags = SLOT_BACK
w_class = 4
// These values are passed on to all component pieces.
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
siemens_coefficient = 0
permeability_coefficient = 0
max_w_class = 3
max_combined_w_class = 35
// Keeps track of what this rig should spawn with.
var/suit_type = "hardsuit"
var/list/initial_modules
var/chest_type = /obj/item/clothing/suit/space/rig
var/helm_type = /obj/item/clothing/head/helmet/space/rig
var/boot_type = /obj/item/clothing/shoes/rig
var/glove_type = /obj/item/clothing/gloves/rig
//Component/device holders.
var/obj/item/weapon/cell/cell
var/obj/item/clothing/shoes/rig/boots = null // Deployable boots, if any.
var/obj/item/clothing/suit/space/rig/chest // Deployable chestpiece, if any.
var/obj/item/clothing/head/helmet/space/rig/helmet = null // Deployable helmet, if any.
var/obj/item/clothing/gloves/rig/gloves = null // Deployable gauntlets, if any.
var/obj/item/rig_module/selected_module = null // Primary system (used with right-click)
var/obj/item/rig_module/vision/visor // Kinda shitty to have a var for a module, but saves time.
var/obj/item/rig_module/voice/speech // As above.
var/mob/living/carbon/human/wearer // The person currently wearing the rig.
var/image/mob_icon // Holder for on-mob icon.
var/list/installed_modules = list() // Power consumption/use bookkeeping.
// Rig status vars.
var/sealing // Keeps track of seal status independantly of canremove.
var/offline = 1 // Should we be applying suit maluses?
var/offline_slowdown = 10 // If the suit is deployed and unpowered, it sets slowdown to this.
var/offline_vision_restriction = 1 // 0 - none, 1 - welder vision, 2 - blind. Maybe move this to helmets.
// Spark system, since we seem to need this a bunch.
var/datum/effect/effect/system/spark_spread/spark_system
/obj/item/weapon/storage/rig/New()
..()
spark_system = new()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
if(!cell)
cell = new /obj/item/weapon/cell/high(src)
processing_objects |= src
if(initial_modules && initial_modules.len)
for(var/path in initial_modules)
var/obj/item/rig_module/module = new path(src)
installed_modules += module
module.installed(src)
// Create and initialize our various segments.
if(glove_type) gloves = new glove_type(src)
if(helm_type) helmet = new helm_type(src)
if(boot_type) boots = new boot_type(src)
if(chest_type) chest = new chest_type(src)
for(var/obj/item/piece in list(gloves,helmet,boots,chest))
if(!piece)
continue
piece.name = "[suit_type] [initial(piece.name)]"
piece.desc = "Seems to be part of \a [src]."
piece.icon_state = "[initial(icon_state)]"
piece.armor = armor
piece.min_cold_protection_temperature = min_cold_protection_temperature
piece.max_heat_protection_temperature = max_heat_protection_temperature
piece.siemens_coefficient = siemens_coefficient
piece.permeability_coefficient = permeability_coefficient
spawn(1)
var/mob/M = loc
if(istype(M))
toggle_seals(M,1)
update_icon()
/obj/item/weapon/storage/rig/Del()
for(var/obj/item/piece in list(gloves,boots,helmet,chest))
var/mob/living/M = piece.loc
if(istype(M))
M.drop_from_inventory(piece)
del(piece)
processing_objects -= src
..()
/obj/item/weapon/storage/rig/proc/suit_is_deployed()
if(!istype(wearer))
return 0
if(helm_type && (!helmet || wearer.head != helmet))
return 0
if(glove_type && (!gloves || wearer.gloves != gloves))
return 0
if(boot_type && (!boots || wearer.shoes != boots))
return 0
if(chest_type && (!chest || wearer.wear_suit != chest))
return 0
return 1
/obj/item/weapon/storage/rig/proc/toggle_seals(var/mob/living/carbon/human/M,var/instant)
if(sealing) return
if(M && !(istype(M) && M.back == src ) && !istype(M,/mob/living/silicon) )
return 0
if(!check_power_cost(M))
return 0
deploy(M,instant)
var/seal_target = !canremove
var/failed_to_seal
canremove = 0 // No removing the suit while unsealing.
sealing = 1
if(!seal_target && !suit_is_deployed())
M << "<span class='danger'>The suit flashes an error light. It can't function properly without being fully deployed.</span>"
failed_to_seal = 1
if(!failed_to_seal && instant)
for(var/obj/item/piece in list(helmet,boots,gloves,chest,src))
if(!piece) continue
piece.icon_state = "[initial(icon_state)]_sealed"
update_icon()
else if(!failed_to_seal)
M << "<font color='blue'>With a quiet hum, the suit begins running checks and adjusting components.</font>"
if(!do_after(M,SEAL_DELAY))
if(M) M << "<span class='warning'>You must remain still while the suit is adjusting the components.</span>"
failed_to_seal = 1
if(!M)
failed_to_seal = 1
else
for(var/list/piece_data in list(list(M.shoes,boots,"boots"),list(M.gloves,gloves,"gloves"),list(M.head,helmet,"helmet"),list(M.wear_suit,chest,"chest")))
var/obj/item/piece = piece_data[1]
var/obj/item/compare_piece = piece_data[2]
var/msg_type = piece_data[3]
if(!piece)
continue
if(!istype(M) || !istype(piece) || !istype(compare_piece) || !msg_type)
if(!failed_to_seal)
if(M) M << "<span class='warning'>You must remain still while the suit is adjusting the components.</span>"
failed_to_seal = 1
break
if(M.back == src && piece == compare_piece && do_after(M,SEAL_DELAY))
piece.icon_state = "[initial(icon_state)][!seal_target ? "_sealed" : ""]"
switch(msg_type)
if("boots")
M << "<font color='blue'>\The [piece] [!seal_target ? "seal around your feet" : "relax their grip on your legs"].</font>"
M.update_inv_shoes()
if("gloves")
M << "<font color='blue'>\The [piece] [!seal_target ? "tighten around your fingers and wrists" : "become loose around your fingers"].</font>"
M.update_inv_gloves()
if("chest")
M << "<font color='blue'>\The [piece] [!seal_target ? "cinches tight again your chest" : "releases your chest"].</font>"
M.update_inv_wear_suit()
if("helmet")
M << "<font color='blue'>\The [piece] hisses [!seal_target ? "closed" : "open"].</font>"
M.update_inv_head()
if(!seal_target)
if(flags & AIRTIGHT)
helmet.flags |= AIRTIGHT
helmet.flags_inv |= (HIDEEYES|HIDEFACE)
helmet.body_parts_covered |= (FACE|EYES)
else
helmet.flags &= ~AIRTIGHT
helmet.flags_inv &= ~(HIDEEYES|HIDEFACE)
helmet.body_parts_covered &= ~(FACE|EYES)
else
failed_to_seal = 1
if((M && !(istype(M) && M.back == src) && !istype(M,/mob/living/silicon)) || (!seal_target && !suit_is_deployed()))
failed_to_seal = 1
sealing = null
if(failed_to_seal)
for(var/obj/item/piece in list(helmet,boots,gloves,chest))
if(!piece) continue
piece.icon_state = "[initial(icon_state)][!seal_target ? "" : "_sealed"]"
piece.canremove = !seal_target
canremove = !seal_target
if(helmet)
if(canremove)
helmet.flags_inv |= (HIDEEYES|HIDEFACE)
helmet.body_parts_covered |= (FACE|EYES)
else
helmet.flags_inv &= ~(HIDEEYES|HIDEFACE)
helmet.body_parts_covered &= ~(FACE|EYES)
update_icon(1)
return 0
// Success!
canremove = seal_target
M << "<font color='blue'><b>Your entire suit [canremove ? "loosens as the components relax" : "tightens around you as the components lock into place"].</b></font>"
if(canremove)
for(var/obj/item/rig_module/module in installed_modules)
module.deactivate()
for(var/obj/item/piece in list(helmet,boots,gloves,chest,src))
if(!piece) continue
if(canremove && (flags & AIRTIGHT))
piece.flags &= ~STOPSPRESSUREDMAGE
piece.flags &= ~AIRTIGHT
else
piece.flags |= STOPSPRESSUREDMAGE
piece.flags |= AIRTIGHT
update_icon(1)
/obj/item/weapon/storage/rig/process()
if(!istype(wearer) || loc != wearer || wearer.back != src || canremove || !cell || cell.charge <= 0)
if(!cell || cell.charge <= 0)
if(!offline)
if(istype(wearer))
if(!canremove)
if (offline_slowdown < 3)
wearer << "<span class='danger'>Your suit beeps stridently, and suddenly goes dead.</span>"
else
wearer << "<span class='danger'>Your suit beeps stridently, and suddenly you're wearing a leaden mass of metal and plastic instead of a powered suit.</span>"
if(offline_vision_restriction == 1)
wearer << "<span class='danger'>The suit optics flicker and die, leaving you with restricted vision.</span>"
else if(offline_vision_restriction == 2)
wearer << "<span class='danger'>The suit optics drop out completely, drowning you in darkness.</span>"
if(!offline)
offline = 1
else
if(offline)
offline = 0
slowdown = initial(slowdown)
if(offline)
if(offline == 1)
for(var/obj/item/rig_module/module in installed_modules)
module.deactivate()
offline = 2
slowdown = offline_slowdown
return
for(var/obj/item/rig_module/module in installed_modules)
cell.use(module.process()*10)
/obj/item/weapon/storage/rig/proc/check_power_cost(var/mob/living/user, var/cost, var/use_unconcious, var/obj/item/rig_module/mod, var/user_is_ai)
if(!istype(user))
return 0
var/fail_msg
if(!user_is_ai)
var/mob/living/carbon/human/H = user
if(istype(H) && H.back != src)
fail_msg = "<span class='warning'>You must be wearing \the [src] to do this.</span>"
else if(user.incorporeal_move)
fail_msg = "<span class='warning'>You must be solid to do this.</span>"
if(sealing)
fail_msg = "<span class='warning'>The hardsuit is in the process of adjusting seals and cannot be activated.</span>"
else if(!fail_msg && ((use_unconcious && user.stat > 1) || (!use_unconcious && user.stat)))
fail_msg = "<span class='warning'>You are in no fit state to do that."
else if(!cell)
fail_msg = "<span class='warning'>There is no cell installed in the suit.</span>"
else if(cost && cell.charge < cost * 10) //TODO: Cellrate?
fail_msg = "<span class='warning'>Not enough stored power.</span>"
if(fail_msg)
user << "[fail_msg]"
return 0
// This is largely for cancelling stealth and whatever.
if(mod && mod.disruptive)
for(var/obj/item/rig_module/module in (installed_modules - mod))
if(module.active && module.disruptable)
module.deactivate()
cell.use(cost*10)
return 1
/obj/item/weapon/storage/rig/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(!user)
return
var/list/data = list()
if(selected_module)
data["primarysystem"] = "[selected_module.interface_name]"
data["seals"] = "[src.canremove]"
data["sealing"] = "[src.sealing]"
data["helmet"] = (helmet ? "[helmet.name]" : "None.")
data["gauntlets"] = (gloves ? "[gloves.name]" : "None.")
data["boots"] = (boots ? "[boots.name]" : "None.")
data["chest"] = (chest ? "[chest.name]" : "None.")
data["charge"] = cell ? cell.charge : 0
data["maxcharge"] = cell ? cell.maxcharge : 0
data["chargestatus"] = cell ? Floor((cell.charge/cell.maxcharge)*50) : 0
var/list/module_list = list()
var/i = 1
for(var/obj/item/rig_module/module in installed_modules)
var/list/module_data = list(
"index" = i,
"name" = "[module.interface_name]",
"desc" = "[module.interface_desc]",
"can_use" = "[module.usable]",
"can_select" = "[module.selectable]",
"can_toggle" = "[module.toggleable]",
"is_active" = "[module.active]",
"engagecost" = module.use_power_cost*10,
"activecost" = module.active_power_cost*10,
"passivecost" = module.passive_power_cost*10
)
if(module.charges && module.charges.len)
module_data["charges"] = list()
var/datum/rig_charge/selected = module.charges[module.charge_selected]
module_data["chargetype"] = selected ? "[selected.display_name]" : "none"
for(var/chargetype in module.charges)
var/datum/rig_charge/charge = module.charges[chargetype]
module_data["charges"] += list(list("caption" = "[chargetype] ([charge.charges])", "index" = "[chargetype]"))
module_list += list(module_data)
i++
if(module_list.len)
data["modules"] = module_list
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "hardsuit.tmpl", "Hardsuit Controller", 500, 600)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/item/weapon/storage/rig/update_icon(var/update_mob_icon)
//TODO: Maybe consider a cache for this (use mob_icon as blank canvas, use suit icon overlay).
overlays.Cut()
if(mob_icon)
mob_icon.overlays.Cut()
if(!mob_icon || update_mob_icon)
var/species_icon = 'icons/mob/back.dmi'
// Since setting mob_icon will override the species checks in
// update_inv_wear_suit(), handle species checks here.
if(wearer && sprite_sheets && sprite_sheets[wearer.species.name])
species_icon = sprite_sheets[wearer.species.name]
mob_icon = image("icon" = species_icon, "icon_state" = "[icon_state]")
if(installed_modules.len)
for(var/obj/item/rig_module/module in installed_modules)
if(module.suit_overlay)
mob_icon.overlays += image("icon" = 'icons/mob/rig_modules.dmi', "icon_state" = "[module.suit_overlay]")
if(chest)
chest.overlays += image("icon" = 'icons/mob/rig_modules.dmi', "icon_state" = "[module.suit_overlay]", "dir" = SOUTH)
if(wearer)
wearer.update_inv_shoes()
wearer.update_inv_gloves()
wearer.update_inv_head()
wearer.update_inv_wear_suit()
wearer.update_inv_back()
return
/obj/item/weapon/storage/rig/Topic(href,href_list)
if(..())
return 1
var/mob/living/carbon/human/H = usr
if((istype(H) && H.back == src) || (istype(H,/mob/living/silicon)))
if(href_list["toggle_piece"])
toggle_piece(href_list["toggle_piece"], H)
else if(href_list["toggle_seals"])
toggle_seals(H)
else if(href_list["interact_module"])
var/module_index = text2num(href_list["interact_module"])
if(module_index > 0 && module_index <= installed_modules.len)
var/obj/item/rig_module/module = installed_modules[module_index]
switch(href_list["module_mode"])
if("activate")
module.activate()
if("deactivate")
module.deactivate()
if("engage")
module.engage()
if("select")
selected_module = module
if("select_charge_type")
module.charge_selected = href_list["charge_type"]
usr.set_machine(src)
src.add_fingerprint(usr)
return
/obj/item/weapon/storage/rig/equipped(mob/living/carbon/human/M)
..()
if(istype(M) && M.back == src)
M.visible_message("<font color='blue'>[M] starts putting on \the [src]...</font>", "<font color='blue'>You start putting on \the [src]...</font>")
if(!do_after(M,SEAL_DELAY))
if(M && M.back == src)
M.back = null
M.drop_from_inventory(src)
src.loc = get_turf(src)
return
if(istype(M) && M.back == src)
M.visible_message("<font color='blue'><b>[M] struggles into \the [src].</b></font>", "<font color='blue'><b>You struggle into \the [src].</b></font>")
wearer = M
update_icon()
/obj/item/weapon/storage/rig/proc/toggle_piece(var/piece, var/mob/living/carbon/human/H, var/deploy_mode)
if(sealing)
return
if(!cell || !cell.charge)
H << "<span class='warning'>The suit is out of power.</span>"
return
if(!istype(wearer) || !wearer.back == src)
H << "<span class='warning'>The hardsuit is not being worn.</span>"
return
var/check_slot
var/equip_to
var/obj/item/use_obj
var/plural
if(!canremove)
return
if(!H)
return
switch(piece)
if("helmet")
equip_to = slot_head
use_obj = helmet
check_slot = H.head
if("gauntlets")
equip_to = slot_gloves
use_obj = gloves
check_slot = H.gloves
plural = 1
if("boots")
equip_to = slot_shoes
use_obj = boots
check_slot = H.shoes
plural = 1
if("chest")
equip_to = slot_wear_suit
use_obj = chest
check_slot = H.wear_suit
if(use_obj)
if(check_slot == use_obj && deploy_mode != ONLY_DEPLOY)
var/mob/living/carbon/human/holder
if(use_obj)
holder = use_obj.loc
if(istype(holder))
if(use_obj && check_slot == use_obj)
H << "<font color='blue'><b>Your [use_obj.name] [plural ? "retract" : "retracts"] swiftly.</b></font>"
use_obj.canremove = 1
holder.drop_from_inventory(use_obj)
use_obj.loc = null
else if (deploy_mode != ONLY_RETRACT)
if(check_slot)
if(check_slot != use_obj)
H << "<span class='danger'>You are unable to deploy \the [piece] as \the [check_slot] is in the way.</span>"
return
else
H << "<font color='blue'><b>Your [use_obj.name] [plural ? "deploy" : "deploys"] swiftly.</b></span>"
use_obj.loc = H
H.equip_to_slot(use_obj, equip_to)
use_obj.canremove = 0
if(piece == "helmet" && helmet)
helmet.update_light(H)
/obj/item/weapon/storage/rig/proc/deploy(mob/M,var/sealed)
var/mob/living/carbon/human/H = M
if(!H || !istype(H)) return
if(H.back != src)
return
if(sealed)
if(H.head)
var/obj/item/garbage = H.head
H.drop_from_inventory(garbage)
H.head = null
del(garbage)
if(H.gloves)
var/obj/item/garbage = H.gloves
H.drop_from_inventory(garbage)
H.gloves = null
del(garbage)
if(H.shoes)
var/obj/item/garbage = H.shoes
H.drop_from_inventory(garbage)
H.shoes = null
del(garbage)
if(H.wear_suit)
var/obj/item/garbage = H.wear_suit
H.drop_from_inventory(garbage)
H.wear_suit = null
del(garbage)
for(var/piece in list("helmet","gauntlets","chest","boots"))
toggle_piece(piece, H, ONLY_DEPLOY)
/obj/item/weapon/storage/rig/dropped()
..()
for(var/piece in list("helmet","gauntlets","chest","boots"))
toggle_piece(piece, wearer, ONLY_RETRACT)
wearer = null
#undef ONLY_DEPLOY
#undef ONLY_RETRACT
#undef SEAL_DELAY

View File

@@ -0,0 +1,100 @@
/obj/item/weapon/storage/rig/attackby(obj/item/W as obj, mob/user as mob)
if(!istype(user,/mob/living)) return 0
// Pass repair items on to the chestpiece.
if(chest && (istype(W,/obj/item/stack/sheet/mineral/plastic) || istype(W,/obj/item/stack/sheet/metal) || istype(W, /obj/item/weapon/weldingtool)))
return chest.attackby(W,user)
// Check if this is a hardsuit upgrade or a modification.
if(istype(W,/obj/item/rig_module))
if(istype(src.loc,/mob/living/carbon/human))
var/mob/living/carbon/human/H = src.loc
if(H.back == src)
user << "You can't install a hardsuit module while the suit is being worn."
return 1
if(!installed_modules) installed_modules = list()
if(installed_modules.len)
for(var/obj/item/rig_module/installed_mod in installed_modules)
if(!installed_mod.redundant && istype(installed_mod,W))
user << "The hardsuit already has a module of that class installed."
return 1
var/obj/item/rig_module/mod = W
user << "You carefully install \the [mod] into \the [src]."
user.drop_from_inventory(mod)
installed_modules |= mod
mod.loc = null
mod.installed(src)
update_icon()
return 1
else if(!cell && istype(W,/obj/item/weapon/cell))
user << "You jack \the [W] into \the [src]'s battery mount."
user.drop_from_inventory(W)
W.loc = null
src.cell = W
return
else if(istype(W,/obj/item/weapon/screwdriver))
var/list/current_mounts = list()
if(cell) current_mounts += "cell"
if(installed_modules && installed_modules.len) current_mounts += "system module"
var/to_remove = input("Which would you like to modify?") as null|anything in current_mounts
if(!to_remove)
return
if(istype(src.loc,/mob/living/carbon/human) && to_remove != "cell")
var/mob/living/carbon/human/H = src.loc
if(H.back == src)
user << "You can't remove an installed device while the hardsuit is being worn."
return
switch(to_remove)
if("cell")
if(cell)
user << "You detatch \the [cell] from \the [src]'s battery mount."
for(var/obj/item/rig_module/module in installed_modules)
module.deactivate()
cell.loc = user.put_in_hands(cell)
cell = null
else
user << "There is nothing loaded in that mount."
if("system module")
var/list/possible_removals = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.permanent)
continue
possible_removals[module.name] = module
if(!possible_removals.len)
user << "There are no installed modules to remove."
return
var/removal_choice = input("Which module would you like to remove?") as null|anything in possible_removals
if(!removal_choice)
return
var/obj/item/rig_module/removed = possible_removals[removal_choice]
user << "You detatch \the [removed] from \the [src]."
removed.loc = get_turf(src)
removed.removed()
installed_modules -= removed
update_icon()
return
else
for(var/obj/item/rig_module/module in installed_modules)
if(module.accepts_item(W,user)) //Item is handled in this proc
return
..()

View File

@@ -0,0 +1,64 @@
/*
* Defines the helmets, gloves and shoes for rigs.
*/
/obj/item/clothing/head/helmet/space/rig
name = "helmet"
flags = FPRINT | TABLEPASS | HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | THICKMATERIAL
flags_inv = HIDEEARS
body_parts_covered = HEAD
heat_protection = HEAD
cold_protection = HEAD
brightness_on = 4
species_restricted = null
/obj/item/clothing/gloves/rig
name = "gauntlets"
flags = FPRINT | TABLEPASS | THICKMATERIAL
body_parts_covered = HANDS
heat_protection = HANDS
cold_protection = HANDS
species_restricted = null
/obj/item/clothing/shoes/rig
name = "boots"
cold_protection = FEET
heat_protection = FEET
species_restricted = null
/obj/item/clothing/suit/space/rig
name = "chestpiece"
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEJUMPSUIT|HIDETAIL
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | THICKMATERIAL | AIRTIGHT
slowdown = 0
breach_threshold = 35
can_breach = 1
supporting_limbs = list()
//TODO: move this to modules
/obj/item/clothing/head/helmet/space/rig/proc/prevent_track()
return 0
/obj/item/clothing/gloves/rig/Touch(var/atom/A, var/proximity)
if(!A || !proximity)
return 0
var/mob/living/carbon/human/H = loc
if(!istype(H) || !H.back)
return 0
var/obj/item/weapon/storage/rig/suit = H.back
if(!suit || !istype(suit) || !suit.installed_modules.len)
return 0
for(var/obj/item/rig_module/module in suit.installed_modules)
if(module.active && module.activates_on_touch)
if(module.engage(A))
return 1
return 0

View File

@@ -0,0 +1,227 @@
// Interface for humans.
/obj/item/weapon/storage/rig/verb/hardsuit_interface()
set name = "Open Hardsuit Interface"
set desc = "Open the hardsuit system interface."
set category = "Hardsuit"
set src = usr.contents
if(wearer && wearer.back == src)
ui_interact(usr)
/obj/item/weapon/storage/rig/verb/toggle_vision()
set name = "Toggle Visor"
set desc = "Turns your rig visor off or on."
set category = "Hardsuit"
set src = usr.contents
if(!check_power_cost(usr))
return
if(canremove)
usr << "<span class='warning'>The suit is not active.</span>"
return
if(!visor)
usr << "<span class='warning'>The hardsuit does not have a configurable visor.</span>"
return
if(!visor.active)
visor.activate()
else
visor.deactivate()
/obj/item/weapon/storage/rig/verb/toggle_helmet()
set name = "Toggle Helmet"
set desc = "Deploys or retracts your helmet."
set category = "Hardsuit"
set src = usr.contents
toggle_piece("helmet",wearer)
/obj/item/weapon/storage/rig/verb/toggle_chest()
set name = "Toggle Chestpiece"
set desc = "Deploys or retracts your chestpiece."
set category = "Hardsuit"
set src = usr.contents
toggle_piece("chest",wearer)
/obj/item/weapon/storage/rig/verb/toggle_gauntlets()
set name = "Toggle Gauntlets"
set desc = "Deploys or retracts your gauntlets."
set category = "Hardsuit"
set src = usr.contents
toggle_piece("gauntlets",wearer)
/obj/item/weapon/storage/rig/verb/toggle_boots()
set name = "Toggle Boots"
set desc = "Deploys or retracts your boots."
set category = "Hardsuit"
set src = usr.contents
toggle_piece("boots",wearer)
/obj/item/weapon/storage/rig/verb/deploy_suit()
set name = "Deploy Hardsuit"
set desc = "Deploys helmet, gloves and boots."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
usr << "<span class='warning'>The hardsuit is not being worn.</span>"
return
if(!check_power_cost(usr))
return
deploy(wearer)
/obj/item/weapon/storage/rig/verb/toggle_seals_verb()
set name = "Toggle Seals"
set desc = "Activates or deactivates your rig seals."
set category = "Hardsuit"
set src = usr.contents
if(!istype(wearer) || !wearer.back == src)
usr << "<span class='warning'>The hardsuit is not being worn.</span>"
return
toggle_seals(wearer)
/obj/item/weapon/storage/rig/verb/switch_vision_mode()
set name = "Switch Vision Mode"
set desc = "Switches between available vision modes."
set category = "Hardsuit"
set src = usr.contents
if(!check_power_cost(usr, 0, 0, 0, 0))
return
if(canremove)
usr << "<span class='warning'>The suit is not active.</span>"
return
if(!visor)
usr << "<span class='warning'>The hardsuit does not have a configurable visor.</span>"
return
if(!visor.active)
visor.activate()
if(!visor.active)
usr << "<span class='warning'>The visor is suffering a hardware fault and cannot be configured.</span>"
return
visor.engage()
/obj/item/weapon/storage/rig/verb/alter_voice()
set name = "Configure Voice Synthesiser"
set desc = "Toggles or configures your voice synthesizer."
set category = "Hardsuit"
set src = usr.contents
if(canremove)
usr << "<span class='warning'>The suit is not active.</span>"
return
if(!speech)
usr << "<span class='warning'>The hardsuit does not have a speech synthesiser.</span>"
return
speech.engage()
/obj/item/weapon/storage/rig/verb/select_module()
set name = "Select Module"
set desc = "Selects a module as your primary system."
set category = "Hardsuit"
set src = usr.contents
if(!check_power_cost(usr, 0, 0, 0, 0))
return
if(canremove)
usr << "<span class='warning'>The suit is not active.</span>"
return
var/list/selectable = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.selectable)
selectable |= module
var/obj/item/rig_module/module = input("Which module do you wish to select?") as null|anything in selectable
if(!istype(module))
return
selected_module = module
usr << "<font color='blue'><b>Primary system is now: [selected_module.interface_name].</b></font>"
/obj/item/weapon/storage/rig/verb/toggle_module()
set name = "Toggle Module"
set desc = "Toggle a system module."
set category = "Hardsuit"
set src = usr.contents
if(!check_power_cost(usr, 0, 0, 0, 0))
return
if(canremove)
usr << "<span class='warning'>The suit is not active.</span>"
return
var/list/selectable = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.toggleable)
selectable |= module
var/obj/item/rig_module/module = input("Which module do you wish to toggle?") as null|anything in selectable
if(!istype(module))
return
if(module.active)
usr << "<font color='blue'><b>You attempt to deactivate \the [module.interface_name].</b></font>"
module.deactivate()
else
usr << "<font color='blue'><b>You attempt to activate \the [module.interface_name].</b></font>"
module.activate()
/obj/item/weapon/storage/rig/verb/engage_module()
set name = "Engage Module"
set desc = "Engages a system module."
set category = "Hardsuit"
set src = usr.contents
if(canremove)
usr << "<span class='warning'>The suit is not active.</span>"
return
if(!check_power_cost(usr, 0, 0, 0, 0))
return
var/list/selectable = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.usable)
selectable |= module
var/obj/item/rig_module/module = input("Which module do you wish to engage?") as null|anything in selectable
if(!istype(module))
return
usr << "<font color='blue'><b>You attempt to engage the [module.interface_name].</b></font>"
module.engage()

View File

@@ -0,0 +1,33 @@
/obj/item/weapon/storage/rig/ert
name = "ERT-C hardsuit control module"
desc = "A suit worn by the commander of a NanoTrasen Emergency Response Team. Has blue highlights. Armoured and space ready."
suit_type = "ERT commander"
icon_state = "ert_commander_rig"
siemens_coefficient = 0.6
offline_slowdown = 3
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100)
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, \
/obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/device/multitool, \
/obj/item/device/radio, /obj/item/device/analyzer, /obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/pulse_rifle, \
/obj/item/weapon/gun/energy/taser, /obj/item/weapon/melee/baton, /obj/item/weapon/gun/energy/gun)
initial_modules = list()
/obj/item/weapon/storage/rig/ert/engineer
name = "ERT-E suit control module"
desc = "A suit worn by the commander of a NanoTrasen Emergency Response Team. Has orange highlights. Armoured and space ready."
suit_type = "ERT engineer"
icon_state = "ert_engineer_rig"
/obj/item/weapon/storage/rig/ert/medical
name = "ERT-M suit control module"
desc = "A suit worn by the commander of a NanoTrasen Emergency Response Team. Has white highlights. Armoured and space ready."
suit_type = "ERT medic"
icon_state = "ert_medical_rig"
/obj/item/weapon/storage/rig/ert/security
name = "ERT-S suit control module"
desc = "A suit worn by the commander of a NanoTrasen Emergency Response Team. Has red highlights. Armoured and space ready."
suit_type = "ERT security"
icon_state = "ert_security_rig"

View File

@@ -0,0 +1,17 @@
/obj/item/weapon/storage/rig/light/hacker
name = "cybersuit control module"
suit_type = "cyber"
desc = "An advanced powered armour suit with many cyberwarfare enhancements."
icon_state = "hacker_rig"
helm_type = /obj/item/clothing/head/helmet/space/rig/mask
initial_modules = list(
/obj/item/rig_module/ai_container,
/obj/item/rig_module/power_sink,
/obj/item/rig_module/datajack
)
/obj/item/clothing/head/helmet/space/rig/mask
name = "mask"
flags = FPRINT | TABLEPASS | THICKMATERIAL

View File

@@ -0,0 +1,29 @@
// Light rigs are not space-capable, but don't suffer excessive slowdown or sight issues when depowered.
/obj/item/weapon/storage/rig/light
name = "light suit control module"
desc = "A lighter, less armoured rig suit."
icon_state = "ninja_rig"
suit_type = "light suit"
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/cell)
armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
slowdown = 0
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | THICKMATERIAL
offline_slowdown = 0
offline_vision_restriction = 0
chest_type = /obj/item/clothing/suit/space/rig/light
helm_type = /obj/item/clothing/head/helmet/space/rig/light
boot_type = /obj/item/clothing/shoes/rig/light
glove_type = /obj/item/clothing/gloves/rig/light
/obj/item/clothing/suit/space/rig/light
name = "suit"
/obj/item/clothing/gloves/rig/light
name = "gloves"
/obj/item/clothing/shoes/rig/light
name = "shoes"
/obj/item/clothing/head/helmet/space/rig/light
name = "hood"

View File

@@ -0,0 +1,25 @@
/obj/item/weapon/storage/rig/light/ninja
name = "ominous suit control module"
suit_type = "ominous"
desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
icon_state = "ninja_rig"
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/cell)
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
slowdown = 0
initial_modules = list(
/obj/item/rig_module/teleporter,
/obj/item/rig_module/stealth_field,
/obj/item/rig_module/mounted/energy_blade,
/obj/item/rig_module/vision,
/obj/item/rig_module/voice,
/obj/item/rig_module/fabricator/energy_net,
/obj/item/rig_module/chem_dispenser,
/obj/item/rig_module/grenade_launcher,
/obj/item/rig_module/ai_container,
/obj/item/rig_module/power_sink,
/obj/item/rig_module/datajack,
/obj/item/rig_module/self_destruct
)
..()

View File

@@ -0,0 +1,11 @@
/obj/item/weapon/storage/rig/light/stealth
name = "stealth suit control module"
suit_type = "stealth"
desc = "A highly advanced and expensive suit designed for covert operations."
icon_state = "ninja_rig"
initial_modules = list(
/obj/item/rig_module/teleporter,
/obj/item/rig_module/stealth_field,
/obj/item/rig_module/vision
)

View File

@@ -1,11 +1,12 @@
//Spacesuit
//Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together.
// Meaning the the suit is defined directly after the corrisponding helmet. Just like below!
/obj/item/clothing/head/helmet/space
name = "Space helmet"
icon_state = "space"
desc = "A special helmet designed for work in a hazardous, low-pressure environment."
flags = FPRINT | TABLEPASS | HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL
flags = FPRINT | TABLEPASS | HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL | AIRTIGHT
item_state = "space"
permeability_coefficient = 0.01
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
@@ -16,6 +17,68 @@
siemens_coefficient = 0.9
species_restricted = list("exclude","Diona","Vox")
var/obj/machinery/camera/camera
var/list/camera_networks
var/brightness_on
var/on = 0
/obj/item/clothing/head/helmet/space/attack_self(mob/user)
if(!camera && camera_networks)
camera = new /obj/machinery/camera(src)
camera.network = camera_networks
cameranet.removeCamera(camera)
camera.c_tag = user.name
user << "\blue User scanned as [camera.c_tag]. Camera activated."
return 1
else if(brightness_on)
if(!isturf(user.loc))
user << "You cannot turn the light on while in this [user.loc]" //To prevent some lighting anomalities.
return
on = !on
icon_state = "rig[on]-[item_color]"
if(on)
user.SetLuminosity(user.luminosity + brightness_on)
else
user.SetLuminosity(user.luminosity - brightness_on)
if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
H.update_inv_head()
else
return ..(user)
/obj/item/clothing/head/helmet/space/proc/update_light(mob/user)
if(!brightness_on)
return
if(on)
user.SetLuminosity(user.luminosity - brightness_on)
SetLuminosity(brightness_on)
/obj/item/clothing/head/helmet/space/equipped(mob/user)
..()
update_light(user)
/obj/item/clothing/head/helmet/space/pickup(mob/user)
..()
update_light(user)
/obj/item/clothing/head/helmet/space/dropped(mob/user)
..()
update_light(user)
/obj/item/clothing/head/helmet/space/examine()
..()
if(camera_networks && get_dist(usr,src) <= 1)
usr << "This helmet has a built-in camera. It's [camera ? "" : "in"]active."
/obj/item/clothing/suit/space
name = "Space suit"
desc = "A suit that protects against low pressure environments. \"NSS EXODUS\" is written in large block letters on the back."

View File

@@ -139,7 +139,6 @@
icon_state = "syndicate-black-red"
item_state = "syndicate-black-red"
//Black with yellow/red engineering syndicate space suit
/obj/item/clothing/head/helmet/space/syndicate/black/engie
name = "Black Space Helmet"

View File

@@ -1,14 +0,0 @@
//NASA Voidsuit
/obj/item/clothing/head/helmet/space/nasavoid
name = "NASA Void Helmet"
desc = "A high tech, NASA Centcom branch designed, dark red space suit helmet. Used for AI satellite maintenance."
icon_state = "void"
item_state = "void"
/obj/item/clothing/suit/space/nasavoid
name = "NASA Voidsuit"
icon_state = "void"
item_state = "void"
desc = "A high tech, NASA Centcom branch designed, dark red Space suit. Used for AI satellite maintenance."
slowdown = 1

View File

@@ -0,0 +1,27 @@
//Syndicate rig
/obj/item/clothing/head/helmet/space/void/merc
name = "blood-red voidsuit helmet"
desc = "An advanced helmet designed for work in special operations. Property of Gorlex Marauders."
icon_state = "rig0-syndie"
item_state = "syndie_helm"
item_color = "syndie"
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.6
species_restricted = list("exclude","Unathi","Tajara","Skrell","Vox")
camera_networks = list("NUKE")
/obj/item/clothing/head/helmet/space/void/merc/examine(mob/user)
if(..(user, 1))
user << "This helmet has a built-in camera. It's [camera ? "" : "in"]active."
/obj/item/clothing/suit/space/void/merc
icon_state = "rig-syndie"
name = "blood-red voidsuit"
desc = "An advanced suit that protects against injuries during special operations. Property of Gorlex Marauders."
item_state = "syndie_voidsuit"
slowdown = 1
w_class = 3
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
siemens_coefficient = 0.6
species_restricted = list("exclude","Unathi","Tajara","Skrell","Vox")

View File

@@ -0,0 +1,105 @@
// Station voidsuits
//Engineering rig
/obj/item/clothing/head/helmet/space/void/engineering
name = "engineering voidsuit helmet"
desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding."
icon_state = "rig0-engineering"
item_state = "eng_helm"
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80)
/obj/item/clothing/suit/space/void/engineering
name = "engineering voidsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding."
icon_state = "rig-engineering"
item_state = "eng_voidsuit"
slowdown = 1
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
//Chief Engineer's rig
/obj/item/clothing/head/helmet/space/void/engineering/chief
name = "advanced voidsuit helmet"
desc = "An advanced helmet designed for work in a hazardous, low pressure environment. Shines with a high polish."
icon_state = "rig0-white"
item_state = "ce_helm"
item_color = "white"
sprite_sheets_refit = null
sprite_sheets_obj = null
/obj/item/clothing/suit/space/void/engineering/chief
icon_state = "rig-white"
name = "advanced voidsuit"
desc = "An advanced suit that protects against hazardous, low pressure environments. Shines with a high polish."
item_state = "ce_voidsuit"
sprite_sheets_refit = null
sprite_sheets_obj = null
//Mining rig
/obj/item/clothing/head/helmet/space/void/mining
name = "mining voidsuit helmet"
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has reinforced plating."
icon_state = "rig0-mining"
item_state = "mining_helm"
item_color = "mining"
armor = list(melee = 50, bullet = 5, laser = 20,energy = 5, bomb = 55, bio = 100, rad = 20)
/obj/item/clothing/suit/space/void/mining
icon_state = "rig-mining"
name = "mining voidsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has reinforced plating."
item_state = "mining_voidsuit"
armor = list(melee = 50, bullet = 5, laser = 20,energy = 5, bomb = 55, bio = 100, rad = 20)
//Medical Rig
/obj/item/clothing/head/helmet/space/void/medical
name = "medical voidsuit helmet"
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has minor radiation shielding."
icon_state = "rig0-medical"
item_state = "medical_helm"
item_color = "medical"
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50)
/obj/item/clothing/suit/space/void/medical
icon_state = "rig-medical"
name = "medical voidsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding."
item_state = "medical_voidsuit"
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical)
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50)
//Security
/obj/item/clothing/head/helmet/space/void/security
name = "security voidsuit helmet"
desc = "A special helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor."
icon_state = "rig0-sec"
item_state = "sec_helm"
item_color = "sec"
armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10)
siemens_coefficient = 0.7
/obj/item/clothing/suit/space/void/security
icon_state = "rig-sec"
name = "security voidsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor."
item_state = "sec_voidsuit"
armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10)
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton)
siemens_coefficient = 0.7
//Atmospherics Rig (BS12)
/obj/item/clothing/head/helmet/space/void/atmos
desc = "A special helmet designed for work in a hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding."
name = "atmospherics voidsuit helmet"
icon_state = "rig0-atmos"
item_state = "atmos_helm"
item_color = "atmos"
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 50)
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
/obj/item/clothing/suit/space/void/atmos
desc = "A special suit that protects against hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding."
icon_state = "rig-atmos"
name = "atmos voidsuit"
item_state = "atmos_voidsuit"
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 50)
max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE

View File

@@ -0,0 +1,50 @@
//NASA Voidsuit
/obj/item/clothing/head/helmet/space/void
name = "void helmet"
desc = "A high-tech dark red space suit helmet. Used for AI satellite maintenance."
icon_state = "void"
item_state = "void"
heat_protection = HEAD
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
//Species-specific stuff.
species_restricted = list("exclude","Unathi","Tajara","Skrell","Diona","Vox")
sprite_sheets_refit = list(
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
"Tajara" = 'icons/mob/species/tajaran/helmet.dmi',
"Skrell" = 'icons/mob/species/skrell/helmet.dmi',
)
sprite_sheets_obj = list(
"Unathi" = 'icons/obj/clothing/species/unathi/hats.dmi',
"Tajara" = 'icons/obj/clothing/species/tajaran/hats.dmi',
"Skrell" = 'icons/obj/clothing/species/skrell/hats.dmi',
)
/obj/item/clothing/suit/space/void
name = "voidsuit"
icon_state = "void"
item_state = "void"
desc = "A high-tech dark red space suit. Used for AI satellite maintenance."
slowdown = 1
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit)
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
species_restricted = list("exclude","Unathi","Tajara","Diona","Vox")
sprite_sheets_refit = list(
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
"Tajara" = 'icons/mob/species/tajaran/suit.dmi',
"Skrell" = 'icons/mob/species/skrell/suit.dmi',
)
sprite_sheets_obj = list(
"Unathi" = 'icons/obj/clothing/species/unathi/suits.dmi',
"Tajara" = 'icons/obj/clothing/species/tajaran/suits.dmi',
"Skrell" = 'icons/obj/clothing/species/skrell/suits.dmi',
)
//Breach thresholds, should ideally be inherited by most (if not all) voidsuits.
breach_threshold = 18
can_breach = 1

View File

@@ -0,0 +1,25 @@
//Wizard Rig
/obj/item/clothing/head/helmet/space/void/wizard
name = "gem-encrusted voidsuit helmet"
desc = "A bizarre gem-encrusted helmet that radiates magical energies."
icon_state = "rig0-wiz"
item_state = "wiz_helm"
item_color = "wiz"
unacidable = 1 //No longer shall our kind be foiled by lone chemists with spray bottles!
armor = list(melee = 40, bullet = 20, laser = 20,energy = 20, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.7
sprite_sheets_refit = null
sprite_sheets_obj = null
/obj/item/clothing/suit/space/void/wizard
icon_state = "rig-wiz"
name = "gem-encrusted voidsuit"
desc = "A bizarre gem-encrusted suit that radiates magical energies."
item_state = "wiz_voidsuit"
slowdown = 1
w_class = 3
unacidable = 1
armor = list(melee = 40, bullet = 20, laser = 20,energy = 20, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.7
sprite_sheets_refit = null
sprite_sheets_obj = null

View File

@@ -119,7 +119,7 @@
New()
..()
var/blocked = list(/obj/item/clothing/suit/chameleon, /obj/item/clothing/suit/space/space_ninja,
var/blocked = list(/obj/item/clothing/suit/chameleon,
/obj/item/clothing/suit/golem, /obj/item/clothing/suit/suit, /obj/item/clothing/suit/cyborg_suit, /obj/item/clothing/suit/justice,
/obj/item/clothing/suit/greatcoat)//Prevent infinite loops and bad suits.
for(var/U in typesof(/obj/item/clothing/suit)-blocked)

View File

@@ -554,13 +554,13 @@
user.drop_item()
del(O)
/obj/item/clothing/suit/space/rig/attackby(var/obj/item/O as obj, mob/user as mob)
/obj/item/clothing/suit/space/void/attackby(var/obj/item/O as obj, mob/user as mob)
..()
if(istype(O,/obj/item/device/kit/suit/fluff))
var/obj/item/device/kit/suit/fluff/kit = O
name = "[kit.new_name] hardsuit"
name = "[kit.new_name] voidsuit"
desc = kit.new_suit_desc
icon_state = kit.suit_icon
item_state = kit.suit_icon

View File

@@ -346,7 +346,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
/obj/item/weapon/hand_tele, /obj/item/weapon/rcd, /obj/item/weapon/tank/jetpack,\
/obj/item/clothing/under/rank/captain, /obj/item/device/aicard,\
/obj/item/clothing/shoes/magboots, /obj/item/blueprints, /obj/item/weapon/disk/nuclear,\
/obj/item/clothing/suit/space/nasavoid, /obj/item/weapon/tank)
/obj/item/clothing/suit/space/void, /obj/item/weapon/tank)
/proc/fake_attack(var/mob/living/target)
// var/list/possible_clones = new/list()

View File

@@ -15,7 +15,7 @@ var/const/MAX_ACTIVE_TIME = 400
icon_state = "facehugger"
item_state = "facehugger"
w_class = 1 //note: can be picked up by aliens unlike most other items of w_class below 4
flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKCOVERSEYES | MASKINTERNALS
flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKCOVERSEYES | AIRTIGHT
body_parts_covered = FACE|EYES
throw_range = 5

View File

@@ -102,12 +102,6 @@
emote("deathgasp") //let the world KNOW WE ARE DEAD // Doing this with the deathgasp emote seems odd.
if(species && species.death_sound) playsound(loc, species.death_sound, 80, 1, 1)
//For ninjas exploding when they die.
if( istype(wear_suit, /obj/item/clothing/suit/space/space_ninja) && wear_suit:s_initialized )
src << browse(null, "window=spideros")//Just in case.
var/location = loc
explosion(location, 0, 0, 3, 4)
update_canmove()
if(client) blind.layer = 0

View File

@@ -70,15 +70,18 @@
var/datum/organ/internal/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"]
if(P)
stat(null, "Phoron Stored: [P.stored_plasma]/[P.max_plasma]")
if(back && istype(back,/obj/item/weapon/storage/rig))
var/obj/item/weapon/storage/rig/suit = back
var/cell_status = "ERROR"
if(suit.cell) cell_status = "[suit.cell.charge]/[suit.cell.maxcharge]"
stat(null, "Suit charge: [cell_status]")
if(mind)
if(mind.changeling)
stat("Chemical Storage", mind.changeling.chem_charges)
stat("Genetic Damage Time", mind.changeling.geneticdamage)
if (istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)&&wear_suit:s_initialized)
stat("Energy Charge", round(wear_suit:cell:charge/100))
/mob/living/carbon/human/ex_act(severity)
if(!blinded)
flick("flash", flash)
@@ -762,6 +765,10 @@
if(istype(src.head, /obj/item/clothing/head/welding))
if(!src.head:up)
number += 2
if(istype(back, /obj/item/weapon/storage/rig))
var/obj/item/weapon/storage/rig/O = back
if(O.helmet && O.helmet == head && (O.helmet.body_parts_covered & EYES))
number += 2
if(istype(src.head, /obj/item/clothing/head/helmet/space))
number += 2
if(istype(src.glasses, /obj/item/clothing/glasses/thermal))

View File

@@ -33,7 +33,6 @@
var/temperature_alert = 0
var/in_stasis = 0
/mob/living/carbon/human/Life()
@@ -423,9 +422,7 @@
proc/get_breath_from_internal(volume_needed)
if(internal)
if (!contents.Find(internal))
internal = null
if (!wear_mask || !(wear_mask.flags & MASKINTERNALS) )
if (!contents.Find(internal) || !((wear_mask && (wear_mask.flags & AIRTIGHT)) || (head && (head.flags & AIRTIGHT))))
internal = null
if(internal)
return internal.remove_air_volume(volume_needed)
@@ -1180,6 +1177,13 @@
//Eyes
//Check rig first because it's two-check and other checks will override it.
if(istype(back,/obj/item/weapon/storage/rig))
var/obj/item/weapon/storage/rig/O = back
if(O.offline && O.offline_vision_restriction == 2 && O.helmet && O.helmet == head && (O.helmet.body_parts_covered & EYES))
blinded = 1
// Check everything else.
if(!species.has_organ["eyes"]) // Presumably if a species has no eyes, they see via something else.
eye_blind = 0
blinded = 0
@@ -1356,10 +1360,13 @@
seer = 0
var/tmp/glasses_processed = 0
if(istype(wear_mask, /obj/item/clothing/mask/gas/voice/space_ninja))
var/obj/item/clothing/mask/gas/voice/space_ninja/O = wear_mask
var/obj/item/weapon/storage/rig/rig = back
if(istype(rig) && rig.visor)
if(rig.visor.vision && rig.visor.active && rig.visor.vision.glasses)
glasses_processed = 1
process_glasses(O.ninja_vision.glasses)
process_glasses(rig.visor.vision.glasses)
if(glasses)
glasses_processed = 1
process_glasses(glasses)
@@ -1473,16 +1480,24 @@
if(istype(head, /obj/item/clothing/head/welding) || istype(head, /obj/item/clothing/head/helmet/space/unathi))
var/obj/item/clothing/head/welding/O = head
if(!O.up && tinted_weldhelh)
client.screen += global_hud.darkMask
client.screen |= global_hud.darkMask
masked = 1
if(!masked && istype(glasses, /obj/item/clothing/glasses/welding))
var/obj/item/clothing/glasses/welding/O = glasses
if(!O.up && tinted_weldhelh)
client.screen += global_hud.darkMask
client.screen |= global_hud.darkMask
masked = 1
if(!masked && istype(back, /obj/item/weapon/storage/rig))
var/obj/item/weapon/storage/rig/O = back
// Ugh, why is this done on a case by case basis? Why is there no flag for causing weldervision?
if(O.offline && O.offline_vision_restriction == 1 && O.helmet && O.helmet == head && (O.helmet.body_parts_covered & EYES))
client.screen |= global_hud.darkMask
if(machine)
if(!machine.check_eye(src)) reset_view(null)
if(!machine.check_eye(src))
reset_view(null)
else
var/isRemoteObserve = 0
if((mRemote in mutations) && remoteview_target)

View File

@@ -202,12 +202,22 @@
return ..()
/mob/living/carbon/human/GetVoice()
if(istype(src.wear_mask, /obj/item/clothing/mask/gas/voice))
var/obj/item/clothing/mask/gas/voice/V = src.wear_mask
if(V.vchange)
return V.voice
var/voice_sub
if(istype(back,/obj/item/weapon/storage/rig))
var/obj/item/weapon/storage/rig/rig = back
// todo: fix this shit
if(rig.speech && rig.speech.voice_holder && rig.speech.voice_holder.active && rig.speech.voice_holder.voice)
voice_sub = rig.speech.voice_holder.voice
else
return name
for(var/obj/item/gear in list(wear_mask,wear_suit,head))
if(!gear)
continue
var/obj/item/voice_changer/changer = locate() in gear
if(changer && changer.active && changer.voice)
voice_sub = changer.voice
if(voice_sub)
return voice_sub
if(mind && mind.changeling && mind.changeling.mimicing)
return mind.changeling.mimicing
if(GetSpecialVoice())

View File

@@ -752,10 +752,12 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1)
if( wear_suit && istype(wear_suit, /obj/item/clothing/suit) ) //TODO check this
wear_suit.screen_loc = ui_oclothing //TODO
var/image/standing
if(wear_suit.icon_override)
standing = image("icon" = wear_suit.icon_override, "icon_state" = "[wear_suit.icon_state]")
else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.name])
@@ -818,8 +820,12 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/update_inv_back(var/update_icons=1)
if(back)
back.screen_loc = ui_back //TODO
var/obj/item/weapon/storage/rig/rig = back
if(back.icon_override)
overlays_standing[BACK_LAYER] = image("icon" = back.icon_override, "icon_state" = "[back.icon_state]")
//If this is a rig and a mob_icon is set, it will take species into account in the rig update_icon() proc.
else if(istype(rig) && rig.mob_icon)
overlays_standing[BACK_LAYER] = rig.mob_icon
else if(back.sprite_sheets && back.sprite_sheets[species.name])
overlays_standing[BACK_LAYER] = image("icon" = back.sprite_sheets[species.name], "icon_state" = "[back.icon_state]")
else

View File

@@ -61,7 +61,21 @@
return
//looks like this only appears in whisper. Should it be elsewhere as well? Maybe handle_speech_problems?
if(istype(src.wear_mask, /obj/item/clothing/mask/gas/voice/space_ninja)&&src.wear_mask:voice=="Unknown")
var/voice_sub
if(istype(back,/obj/item/weapon/storage/rig))
var/obj/item/weapon/storage/rig/rig = back
// todo: fix this shit
if(rig.speech && rig.speech.voice_holder && rig.speech.voice_holder.active && rig.speech.voice_holder.voice)
voice_sub = rig.speech.voice_holder.voice
else
for(var/obj/item/gear in list(wear_mask,wear_suit,head))
if(!gear)
continue
var/obj/item/voice_changer/changer = locate() in gear
if(changer && changer.active && changer.voice)
voice_sub = changer.voice
if(voice_sub == "Unknown")
if(copytext(message, 1, 2) != "*")
var/list/temp_message = text2list(message, " ")
var/list/pick_list = list()

View File

@@ -260,7 +260,7 @@
if(internal)
if (!contents.Find(internal))
internal = null
if (!wear_mask || !(wear_mask.flags|MASKINTERNALS) )
if (!(wear_mask && (wear_mask.flags & AIRTIGHT)))
internal = null
if(internal)
if (internals)

View File

@@ -16,3 +16,19 @@
else
layer = MOB_LAYER
src << text("\blue You have stopped hiding.")
// Hardsuit interface proc for AI. Defined here so MMIs can also use it.
/mob/living/proc/hardsuit_interface_ai()
set name = "Open Hardsuit Interface"
set desc = "Open the hardsuit system interface."
set category = "Hardsuit"
var/obj/item/rig_module/module = src.loc
if(!istype(module) || !module.holder)
verbs -= /mob/living/proc/hardsuit_interface_ai
return 0
if(module.holder.check_power_cost(src, 0, 0, 0, 1))
ui_interact(src)

View File

@@ -305,16 +305,19 @@ var/list/ai_verbs_default = list(
//usr <<"You can only change your display once!"
//return
// displays the malf_ai information if the AI is the malf
/mob/living/silicon/ai/show_malf_ai()
/mob/living/silicon/ai/proc/is_malf()
if(ticker.mode.name == "AI malfunction")
var/datum/game_mode/malfunction/malf = ticker.mode
for (var/datum/mind/malfai in malf.malf_ai)
if (mind == malfai) // are we the evil one?
if (malf.apcs >= 3)
stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/(malf.apcs/3), 0)] seconds")
if (mind == malfai)
return malf
return 0
// displays the malf_ai information if the AI is the malf
/mob/living/silicon/ai/show_malf_ai()
var/datum/game_mode/malfunction/malf = is_malf()
if(malf && malf.apcs >= 3)
stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/(malf.apcs/3), 0)] seconds")
/mob/living/silicon/ai/proc/ai_alerts()
set category = "AI Commands"
@@ -769,7 +772,12 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench))
if(istype(W, /obj/item/device/aicard))
var/obj/item/device/aicard/card = W
card.grab_ai(src, user)
else if(istype(W, /obj/item/weapon/wrench))
if(anchored)
user.visible_message("\blue \The [user] starts to unbolt \the [src] from the plating...")
if(!do_after(user,40))

View File

@@ -52,7 +52,8 @@
spawn( 0 )
O.mode = 2
if (istype(loc, /obj/item/device/aicard))
loc.icon_state = "aicard-404"
var/obj/item/device/aicard/card = loc
card.update_icon()
tod = worldtime2text() //weasellos time of death patch
if(mind) mind.store_memory("Time of death: [tod]", 0)

View File

@@ -284,19 +284,20 @@
return
last_special = world.time + 100
canmove = 1
//I'm not sure how much of this is necessary, but I would rather avoid issues.
if(istype(card.loc,/mob))
if(istype(card.loc,/obj/item/rig_module))
src << "There is no room to unfold inside this rig module. You're good and stuck."
return 0
else if(istype(card.loc,/mob))
var/mob/holder = card.loc
holder.drop_from_inventory(card)
else if(istype(card.loc,/obj/item/clothing/suit/space/space_ninja))
var/obj/item/clothing/suit/space/space_ninja/holder = card.loc
holder.pai = null
else if(istype(card.loc,/obj/item/device/pda))
var/obj/item/device/pda/holder = card.loc
holder.pai = null
canmove = 1
src.client.perspective = EYE_PERSPECTIVE
src.client.eye = src
src.forceMove(get_turf(card))

View File

@@ -75,6 +75,24 @@ var/list/robot_verbs_default = list(
var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
var/braintype = "Cyborg"
/mob/living/silicon/robot/drain_power(var/drain_check)
if(drain_check)
return 1
if(!cell || !cell.charge)
return 0
if(cell.charge)
src << "<span class='danger'>Warning: Unauthorized access through power channel 12 detected.</span>"
var/drained_power = rand(200,400)
if(cell.charge < drained_power)
drained_power = cell.charge
cell.use(drained_power)
return drained_power
return 0
/mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0)
spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src)

View File

@@ -103,12 +103,12 @@
/obj/effect/landmark/mobcorpse/syndicatecommando
name = "Syndicate Commando"
corpseuniform = /obj/item/clothing/under/syndicate
corpsesuit = /obj/item/clothing/suit/space/rig/syndi
corpsesuit = /obj/item/clothing/suit/space/void/merc
corpseshoes = /obj/item/clothing/shoes/swat
corpsegloves = /obj/item/clothing/gloves/swat
corpseradio = /obj/item/device/radio/headset
corpsemask = /obj/item/clothing/mask/gas/syndicate
corpsehelmet = /obj/item/clothing/head/helmet/space/rig/syndi
corpsehelmet = /obj/item/clothing/head/helmet/space/void/merc
corpseback = /obj/item/weapon/tank/jetpack/oxygen
corpsepocket1 = /obj/item/weapon/tank/emergency_oxygen
corpseid = 1

View File

@@ -62,6 +62,13 @@
for(var/mob/M in viewers(src))
M.show_message( message, 1, blind_message, 2)
// Returns an amount of power drawn from the object (-1 if it's not viable).
// If drain_check is set it will not actually drain power, just return a value.
// If surge is set, it will destroy/damage the recipient and not return any power.
// Not sure where to define this, so it can sit here for the rest of time.
/atom/proc/drain_power(var/drain_check,var/surge)
return -1
// Show a message to all mobs in earshot of this one
// This would be for audible actions by the src mob
// message is the message output to anyone who can hear.
@@ -1069,7 +1076,7 @@ mob/proc/yank_out_object()
var/datum/organ/external/affected
for(var/datum/organ/external/organ in H.organs) //Grab the organ holding the implant.
for(var/obj/item/weapon/O in organ.implants)
for(var/obj/item/O in organ.implants)
if(O == selection)
affected = organ

View File

@@ -116,6 +116,23 @@
if(terminal)
terminal.connect_to_network()
/obj/machinery/power/apc/drain_power(var/drain_check, var/surge)
if(drain_check)
return 1
if(!cell)
return 0
if(surge && !emagged)
flick("apc-spark", src)
emagged = 1
locked = 0
update_icon()
return 0
return cell.drain_power(drain_check)
/obj/machinery/power/apc/New(turf/loc, var/ndir, var/building=0)
..()
wires = new(src)

View File

@@ -36,6 +36,27 @@ By design, d1 is the smallest direction and d2 is the highest
color = COLOR_RED
var/obj/machinery/power/breakerbox/breaker_box
/obj/structure/cable/drain_power(var/drain_check)
if(drain_check)
return 1
var/datum/powernet/PN = get_powernet()
if(!PN) return 0
var/drained_power = round(rand(200,400)/2)
var/drained_this_tick = PN.draw_power(drained_power)
if(drained_this_tick < drained_power)
for(var/obj/machinery/power/terminal/T in PN.nodes)
if(istype(T.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/AP = T.master
if(AP.emagged)
continue
drained_power += AP.drain_power() //Indirect draw won't emag the APC, should this be amended?
return drained_power
/obj/structure/cable/yellow
color = COLOR_YELLOW

View File

@@ -9,6 +9,17 @@
spawn(5)
updateicon()
/obj/item/weapon/cell/drain_power(var/drain_check)
if(drain_check)
return 1
var/drained_power = rand(200,400)
if(charge < drained_power)
drained_power = charge
use(drained_power)
return drained_power
/obj/item/weapon/cell/proc/updateicon()
overlays.Cut()
@@ -64,16 +75,6 @@
if(crit_fail)
user << "\red This power cell seems to be faulty."
/obj/item/weapon/cell/attack_self(mob/user as mob)
src.add_fingerprint(user)
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/clothing/gloves/space_ninja/SNG = H.gloves
if(!istype(SNG) || !SNG.candrain || !SNG.draining) return
SNG.drain("CELL",src,H.wear_suit)
return
/obj/item/weapon/cell/attackby(obj/item/W, mob/user)
..()
if(istype(W, /obj/item/weapon/reagent_containers/syringe))

View File

@@ -33,6 +33,23 @@
var/input_level_max = 200000
var/output_level_max = 200000
/obj/machinery/power/smes/drain_power(var/drain_check)
if(drain_check)
return 1
if(!charge)
return 0
if(charge)
var/drained_power = rand(200,400)
if(charge < drained_power)
drained_power = charge
charge -= drained_power
return drained_power
return 0
/obj/machinery/power/smes/New()
..()
spawn(5)

View File

@@ -77,6 +77,18 @@ obj/item/weapon/gun/energy/laser/retro
isHandgun()
return 0
/obj/item/weapon/gun/energy/lasercannon/mounted/load_into_chamber()
if(in_chamber)
return 1
var/mob/living/carbon/human/H = loc
if(istype(H) && H.back)
var/obj/item/weapon/storage/rig/suit = H.back
if(istype(suit) && suit.cell && suit.cell.charge >= 250)
suit.cell.use(250)
in_chamber = new /obj/item/projectile/beam/heavylaser(src)
return 1
return 0
/obj/item/weapon/gun/energy/lasercannon/cyborg/load_into_chamber()
if(in_chamber)
return 1
@@ -84,7 +96,7 @@ obj/item/weapon/gun/energy/laser/retro
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
R.cell.use(250)
in_chamber = new/obj/item/projectile/beam(src)
in_chamber = new/obj/item/projectile/beam/heavylaser(src)
return 1
return 0

View File

@@ -35,8 +35,18 @@
else
user.update_inv_r_hand()
/obj/item/weapon/gun/energy/gun/mounted/load_into_chamber()
if(in_chamber)
return 1
var/mob/living/carbon/human/H = loc
if(istype(H) && H.back)
var/obj/item/weapon/storage/rig/suit = H.back
if(istype(suit) && suit.cell && suit.cell.charge >= 250)
suit.cell.use(250)
var/prog_path = text2path(projectile_type)
in_chamber = new prog_path(src)
return 1
return 0
/obj/item/weapon/gun/energy/gun/nuclear
name = "Advanced Energy Gun"

View File

@@ -96,7 +96,9 @@
update_icon()
return
/obj/item/weapon/gun/energy/crossbow/ninja
name = "energy dart thrower"
projectile_type = "/obj/item/projectile/energy/dart"
/obj/item/weapon/gun/energy/crossbow/largecrossbow
name = "Energy Crossbow"

View File

@@ -1358,6 +1358,21 @@ datum
..()
return
adrenaline
name = "Adrenaline"
id = "adrenaline"
description = "Adrenaline is a hormone used as a drug to treat cardiac arrest and other cardiac dysrhythmias resulting in diminished or absent cardiac output."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.SetParalysis(0)
M.SetWeakened(0)
M.adjustToxLoss(rand(3))
..()
return
cryoxadone
name = "Cryoxadone"
id = "cryoxadone"

View File

@@ -40,7 +40,8 @@
/obj/machinery/sleeper,
/obj/machinery/smartfridge/,
/obj/machinery/biogenerator,
/obj/machinery/constructable_frame)
/obj/machinery/constructable_frame
)
New()
..()
@@ -119,10 +120,6 @@
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(istype(target, /obj/machinery/bunsen_burner))
return

View File

@@ -191,18 +191,15 @@ var/MAX_EXPLOSION_RANGE = 14
#define STOPSPRESSUREDMAGE 1 //This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere
//To successfully stop you taking all pressure damage you must have both a suit and head item with this flag.
#define TABLEPASS 2 // can pass by a table or rack
#define MASKINTERNALS 8 // mask allows internals
//#define SUITSPACE 8 // suit protects against space
#define NOBLUDGEON 4 // when an item has this it produces no "X has been hit by Y with Z" message with the default handler
#define AIRTIGHT 8 // functions with internals
#define USEDELAY 16 // 1 second extra delay on use (Can be used once every 2s)
#define NODELAY 32768 // 1 second attackby delay skipped (Can be used once every 0.2s). Most objects have a 1s attackby delay, which doesn't require a flag.
#define NOSHIELD 32 // weapon not affected by shield
#define CONDUCT 64 // conducts electricity (metal etc.)
#define FPRINT 256 // takes a fingerprint
#define ON_BORDER 512 // item has priority to check when entering or leaving
#define NOBLUDGEON 4 // when an item has this it produces no "X has been hit by Y with Z" message with the default handler
#define NOBLOODY 2048 // used to items if they don't want to get a blood overlay
#define NODELAY 32768 // 1 second attackby delay skipped (Can be used once every 0.2s). Most objects have a 1s attackby delay, which doesn't require a flag.
#define GLASSESCOVERSEYES 1024
#define MASKCOVERSEYES 1024 // get rid of some of the other retardation in these flags

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 130 KiB

BIN
icons/mob/rig_modules.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 KiB

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 92 KiB

BIN
icons/obj/rig_modules.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Some files were not shown because too many files have changed in this diff Show More