Merge remote-tracking branch 'upstream/master' into instruments

This commit is contained in:
Fox-McCloud
2017-07-04 17:42:24 -04:00
99 changed files with 1497 additions and 572 deletions
+1 -1
View File
@@ -190,7 +190,7 @@
/mob/living/carbon/human/proc/sec_hud_set_security_status()
var/image/holder = hud_list[WANTED_HUD]
var/perpname = get_face_name(get_id_name(""))
var/perpname = get_visible_name(TRUE) //gets the name of the perp, works if they have an id or if their face is uncovered
if(!ticker) return //wait till the game starts or the monkeys runtime....
if(perpname)
var/datum/data/record/R = find_record("name", perpname, data_core.security)
+3
View File
@@ -112,6 +112,9 @@
id = /obj/item/weapon/card/id/engineering
pda = /obj/item/device/pda/atmos
backpack = /obj/item/weapon/storage/backpack/industrial
satchel = /obj/item/weapon/storage/backpack/satchel_eng
dufflebag = /obj/item/weapon/storage/backpack/duffel/engineering
box = /obj/item/weapon/storage/box/engineer
/datum/job/mechanic
+26 -15
View File
@@ -5,12 +5,12 @@
layer = 3
anchored = 1.0
var/uses = 20
var/disabled = 1
var/disabled = TRUE
var/lethal = 0
var/locked = 1
var/locked = TRUE
var/cooldown_time = 0
var/cooldown_timeleft = 0
var/cooldown_on = 0
var/cooldown_on = FALSE
req_access = list(access_ai_upload)
/obj/machinery/ai_slipper/power_change()
@@ -22,6 +22,7 @@
else
icon_state = "motion0"
stat |= NOPOWER
disabled = TRUE
/obj/machinery/ai_slipper/proc/setState(var/enabled, var/uses)
disabled = disabled
@@ -49,6 +50,24 @@
return
return
/obj/machinery/ai_slipper/proc/ToggleOn()
if(stat & (NOPOWER|BROKEN))
return
disabled = !disabled
icon_state = disabled? "motion0":"motion3"
/obj/machinery/ai_slipper/proc/Activate()
if(stat & (NOPOWER|BROKEN))
return
if(cooldown_on || disabled)
return
else
new /obj/structure/foam(loc)
uses--
cooldown_on = TRUE
cooldown_time = world.timeofday + 100
slip_process()
/obj/machinery/ai_slipper/attack_ai(mob/user)
return attack_hand(user)
@@ -87,18 +106,10 @@
return 1
if(href_list["toggleOn"])
disabled = !disabled
icon_state = disabled? "motion0":"motion3"
ToggleOn()
if(href_list["toggleUse"])
if(cooldown_on || disabled)
return
else
new /obj/structure/foam(loc)
uses--
cooldown_on = 1
cooldown_time = world.timeofday + 100
slip_process()
return
Activate()
attack_hand(usr)
@@ -115,5 +126,5 @@
if(uses <= 0)
return
if(uses >= 0)
cooldown_on = 0
cooldown_on = FALSE
power_change()
+300 -72
View File
@@ -1,3 +1,6 @@
#define BUTTON_COOLDOWN 60 // cant delay the bomb forever
#define BUTTON_DELAY 50 //five seconds
/obj/machinery/syndicatebomb
icon = 'icons/obj/assemblies.dmi'
name = "syndicate bomb"
@@ -6,71 +9,119 @@
anchored = 0
density = 0
layer = MOB_LAYER - 0.1 //so people can't hide it and it's REALLY OBVIOUS
layer = BELOW_MOB_LAYER //so people can't hide it and it's REALLY OBVIOUS
unacidable = 1
var/datum/wires/syndicatebomb/wires = null
var/timer = 120
var/open_panel = 0 //are the wires exposed?
var/active = 0 //is the bomb counting down?
var/defused = 0 //is the bomb capable of exploding?
var/obj/item/weapon/bombcore/payload = /obj/item/weapon/bombcore/
var/minimum_timer = 90
var/timer_set = 90
var/maximum_timer = 60000
var/can_unanchor = TRUE
var/open_panel = FALSE //are the wires exposed?
var/active = FALSE //is the bomb counting down?
var/defused = FALSE //is the bomb capable of exploding?
var/obj/item/weapon/bombcore/payload = /obj/item/weapon/bombcore
var/beepsound = 'sound/items/timer.ogg'
var/delayedbig = FALSE //delay wire pulsed?
var/delayedlittle = FALSE //activation wire pulsed?
var/obj/effect/countdown/syndicatebomb/countdown
var/next_beep
var/detonation_timer
var/explode_now = FALSE
/obj/machinery/syndicatebomb/proc/try_detonate(ignore_active = FALSE)
. = (payload in src) && (active || ignore_active) && !defused
if(.)
payload.detonate()
/obj/machinery/syndicatebomb/process()
if(active && !defused && (timer > 0)) //Tick Tock
var/volume = (timer <= 20 ? 40 : 10) // Tick louder when the bomb is closer to being detonated.
playsound(loc, beepsound, volume, 0)
timer = max(timer - 2,0) // 2 seconds per process()
if(active && !defused && (timer <= 0)) //Boom
active = 0
timer = 120
update_icon()
if(payload in src)
payload.detonate()
if(!active)
fast_processing -= src
detonation_timer = null
next_beep = null
countdown.stop()
return
if(!active || defused) //Counter terrorists win
if(!isnull(next_beep) && (next_beep <= world.time))
var/volume
switch(seconds_remaining())
if(0 to 5)
volume = 50
if(5 to 10)
volume = 40
if(10 to 15)
volume = 30
if(15 to 20)
volume = 20
if(20 to 25)
volume = 10
else
volume = 5
playsound(loc, beepsound, volume, 0)
next_beep = world.time + 10
if(active && !defused && ((detonation_timer <= world.time) || explode_now))
active = FALSE
timer_set = initial(timer_set)
update_icon()
try_detonate(TRUE)
//Counter terrorists win
else if(!active || defused)
if(defused && payload in src)
payload.defuse()
return
countdown.stop()
fast_processing -= src
/obj/machinery/syndicatebomb/New()
wires = new(src)
payload = new payload(src)
if(payload)
payload = new payload(src)
update_icon()
countdown = new(src)
..()
/obj/machinery/syndicatebomb/Destroy()
QDEL_NULL(wires)
QDEL_NULL(countdown)
fast_processing -= src
return ..()
/obj/machinery/syndicatebomb/examine(mob/user)
..(user)
to_chat(user, "A digital display on it reads \"[timer]\".")
to_chat(user, "A digital display on it reads \"[seconds_remaining()]\".")
/obj/machinery/syndicatebomb/update_icon()
icon_state = "[initial(icon_state)][active ? "-active" : "-inactive"][open_panel ? "-wires" : ""]"
/obj/machinery/syndicatebomb/attackby(var/obj/item/I, var/mob/user, params)
if(istype(I, /obj/item/weapon/wrench))
/obj/machinery/syndicatebomb/proc/seconds_remaining()
if(active)
. = max(0, round((detonation_timer - world.time) / 10))
else
. = timer_set
/obj/machinery/syndicatebomb/attackby(obj/item/I, mob/user, params)
if(iswrench(I) && can_unanchor)
if(!anchored)
if(!isturf(src.loc) || istype(src.loc, /turf/space))
to_chat(user, "<span class='notice'>The bomb must be placed on solid ground to attach it</span>")
if(!isturf(loc) || isspaceturf(loc))
to_chat(user, "<span class='notice'>The bomb must be placed on solid ground to attach it.</span>")
else
to_chat(user, "<span class='notice'>You firmly wrench the bomb to the floor</span>")
to_chat(user, "<span class='notice'>You firmly wrench the bomb to the floor.</span>")
playsound(loc, I.usesound, 50, 1)
anchored = 1
if(active)
to_chat(user, "<span class='notice'>The bolts lock in place</span>")
to_chat(user, "<span class='notice'>The bolts lock in place.</span>")
else
if(!active)
to_chat(user, "<span class='notice'>You wrench the bomb from the floor</span>")
to_chat(user, "<span class='notice'>You wrench the bomb from the floor.</span>")
playsound(loc, I.usesound, 50, 1)
anchored = 0
else
to_chat(user, "<span class='warning'>The bolts are locked down!</span>")
else if(istype(I, /obj/item/weapon/screwdriver))
else if(isscrewdriver(I))
open_panel = !open_panel
update_icon()
to_chat(user, "<span class='notice'>You [open_panel ? "open" : "close"] the wire panel.</span>")
@@ -79,28 +130,47 @@
if(open_panel)
wires.Interact(user)
else if(istype(I, /obj/item/weapon/crowbar))
if(open_panel && isWireCut(WIRE_BOOM) && isWireCut(WIRE_UNBOLT) && isWireCut(WIRE_DELAY) && isWireCut(WIRE_PROCEED) && isWireCut(WIRE_ACTIVATE))
else if(iscrowbar(I))
if(open_panel && wires.IsAllCut())
if(payload)
to_chat(user, "<span class='notice'>You carefully pry out [payload].</span>")
payload.loc = user.loc
payload = null
else
to_chat(user, "<span class='notice'>There isn't anything in here to remove!</span>")
to_chat(user, "<span class='warning'>There isn't anything in here to remove!</span>")
else if(open_panel)
to_chat(user, "<span class='notice'>The wires connecting the shell to the explosives are holding it down!</span>")
to_chat(user, "<span class='warning'>The wires connecting the shell to the explosives are holding it down!</span>")
else
to_chat(user, "<span class='notice'>The cover is screwed on, it won't pry off!</span>")
to_chat(user, "<span class='warning'>The cover is screwed on, it won't pry off!</span>")
else if(istype(I, /obj/item/weapon/bombcore))
if(!payload)
if(!user.drop_item())
return
payload = I
to_chat(user, "<span class='notice'>You place [payload] into [src].</span>")
user.drop_item()
payload.loc = src
payload.forceMove(src)
else
to_chat(user, "<span class='notice'>[payload] is already loaded into [src], you'll have to remove it first.</span>")
else if(iswelder(I))
if(payload || !wires.IsAllCut() || !open_panel)
return
var/obj/item/weapon/weldingtool/WT = I
if(!WT.isOn())
return
if(WT.get_fuel() < 5) //uses up 5 fuel.
to_chat(user, "<span class='warning'>You need more fuel to complete this task!</span>")
return
playsound(loc, WT.usesound, 50, 1)
to_chat(user, "<span class='notice'>You start to cut the [src] apart...</span>")
if(do_after(user, 20*I.toolspeed, target = src))
if(!WT.isOn() || !WT.remove_fuel(5, user))
return
to_chat(user, "<span class='notice'>You cut the [src] apart.</span>")
new /obj/item/stack/sheet/plasteel(loc, 5)
qdel(src)
else
..()
return ..()
/obj/machinery/syndicatebomb/attack_ghost(mob/user)
interact(user)
@@ -133,21 +203,27 @@
return FALSE
return TRUE
/obj/machinery/syndicatebomb/proc/activate()
active = TRUE
fast_processing += src
countdown.start()
next_beep = world.time + 10
detonation_timer = world.time + (timer_set * 10)
playsound(loc, 'sound/machines/click.ogg', 30, 1)
/obj/machinery/syndicatebomb/proc/settings(mob/user)
var/newtime = input(user, "Please set the timer.", "Timer", "[timer]") as num
newtime = Clamp(newtime, 120, 60000)
var/new_timer = input(user, "Please set the timer.", "Timer", "[timer_set]") as num
if(can_interact(user)) //No running off and setting bombs from across the station
timer = newtime
loc.visible_message("<span class='notice'>[bicon(src)] timer set for [timer] seconds.</span>")
timer_set = Clamp(new_timer, minimum_timer, maximum_timer)
loc.visible_message("<span class='notice'>[bicon(src)] timer set for [timer_set] seconds.</span>")
if(alert(user,"Would you like to start the countdown now?",,"Yes","No") == "Yes" && can_interact(user))
if(defused || active)
if(defused)
loc.visible_message("<span class='notice'>[bicon(src)] Device error: User intervention required.</span>")
return
else
loc.visible_message("<span class='danger'>[bicon(src)] [timer] seconds until detonation, please clear the area.</span>")
playsound(loc, 'sound/machines/click.ogg', 30, 1)
active = 1
loc.visible_message("<span class='danger'>[bicon(src)] [timer_set] seconds until detonation, please clear the area.</span>")
activate()
update_icon()
add_fingerprint(user)
@@ -167,12 +243,12 @@
name = "training bomb"
icon_state = "training-bomb"
desc = "A salvaged syndicate device gutted of its explosives to be used as a training aid for aspiring bomb defusers."
payload = /obj/item/weapon/bombcore/training/
payload = /obj/item/weapon/bombcore/training
/obj/machinery/syndicatebomb/badmin
name = "generic summoning badmin bomb"
desc = "Oh god what is in this thing?"
payload = /obj/item/weapon/bombcore/badmin/summon/
payload = /obj/item/weapon/bombcore/badmin/summon
/obj/machinery/syndicatebomb/badmin/clown
name = "clown bomb"
@@ -181,8 +257,23 @@
payload = /obj/item/weapon/bombcore/badmin/summon/clown
beepsound = 'sound/items/bikehorn.ogg'
/obj/machinery/syndicatebomb/badmin/varplosion
payload = /obj/item/weapon/bombcore/badmin/explosion/
/obj/machinery/syndicatebomb/empty
name = "bomb"
icon_state = "base-bomb"
desc = "An ominous looking device designed to detonate an explosive payload. Can be bolted down using a wrench."
payload = null
open_panel = TRUE
timer_set = 120
/obj/machinery/syndicatebomb/empty/New()
..()
wires.CutAll()
/obj/machinery/syndicatebomb/self_destruct
name = "self destruct device"
desc = "Do not taunt. Warranty invalid if exposed to high temperature. Not suitable for agents under 3 years of age."
payload = /obj/item/weapon/bombcore/large
can_unanchor = FALSE
///Bomb Cores///
@@ -196,17 +287,26 @@
origin_tech = "syndicate=5;combat=6"
burn_state = FLAMMABLE //Burnable (but the casing isn't)
var/adminlog = null
var/range_heavy = 3
var/range_medium = 9
var/range_light = 17
var/range_flame = 17
/obj/item/weapon/bombcore/ex_act(severity) //Little boom can chain a big boom
src.detonate()
detonate()
/obj/item/weapon/bombcore/burn()
detonate()
..()
/obj/item/weapon/bombcore/proc/detonate()
if(adminlog)
message_admins(adminlog)
log_game(adminlog)
explosion(get_turf(src),3,9,17, flame_range = 17)
if(src.loc && istype(src.loc,/obj/machinery/syndicatebomb/))
qdel(src.loc)
explosion(get_turf(src), range_heavy, range_medium, range_light, flame_range = range_flame)
if(loc && istype(loc, /obj/machinery/syndicatebomb))
qdel(loc)
qdel(src)
/obj/item/weapon/bombcore/proc/defuse()
@@ -223,17 +323,20 @@
var/attempts = 0
/obj/item/weapon/bombcore/training/proc/reset()
var/obj/machinery/syndicatebomb/holder = src.loc
var/obj/machinery/syndicatebomb/holder = loc
if(istype(holder))
if(holder.wires)
holder.wires.Shuffle()
holder.defused = 0
holder.open_panel = 0
holder.delayedbig = FALSE
holder.delayedlittle = FALSE
holder.explode_now = FALSE
holder.update_icon()
holder.updateDialog()
/obj/item/weapon/bombcore/training/detonate()
var/obj/machinery/syndicatebomb/holder = src.loc
var/obj/machinery/syndicatebomb/holder = loc
if(istype(holder))
attempts++
holder.loc.visible_message("<span class='danger'>[bicon(holder)] Alert: Bomb has detonated. Your score is now [defusals] for [attempts]. Resetting wires...</span>")
@@ -242,7 +345,7 @@
qdel(src)
/obj/item/weapon/bombcore/training/defuse()
var/obj/machinery/syndicatebomb/holder = src.loc
var/obj/machinery/syndicatebomb/holder = loc
if(istype(holder))
attempts++
defusals++
@@ -257,11 +360,11 @@
origin_tech = null
/obj/item/weapon/bombcore/badmin/defuse() //because we wouldn't want them being harvested by players
var/obj/machinery/syndicatebomb/B = src.loc
var/obj/machinery/syndicatebomb/B = loc
qdel(B)
qdel(src)
/obj/item/weapon/bombcore/badmin/summon/
/obj/item/weapon/bombcore/badmin/summon
var/summon_path = /obj/item/weapon/reagent_containers/food/snacks/cookie
var/amt_summon = 1
@@ -285,42 +388,165 @@
playsound(src.loc, 'sound/misc/sadtrombone.ogg', 50)
..()
/obj/item/weapon/bombcore/badmin/explosion/
var/HeavyExplosion = 2
var/MediumExplosion = 5
var/LightExplosion = 11
var/Flames = 11
/obj/item/weapon/bombcore/large
name = "large bomb payload"
range_heavy = 5
range_medium = 10
range_light = 20
range_flame = 20
/obj/item/weapon/bombcore/badmin/explosion/detonate()
explosion(get_turf(src),HeavyExplosion,MediumExplosion,LightExplosion, flame_range = Flames)
/obj/item/weapon/bombcore/large/underwall
layer = ABOVE_OPEN_TURF_LAYER
/obj/item/weapon/bombcore/miniature
name = "small bomb core"
w_class = WEIGHT_CLASS_SMALL
range_heavy = 1
range_medium = 2
range_light = 4
range_flame = 2
/obj/item/weapon/bombcore/miniature/detonate()
explosion(src.loc,1,2,4,flame_range = 2) //Identical to a minibomb
/obj/item/weapon/bombcore/chemical
name = "chemical payload"
desc = "An explosive payload designed to spread chemicals, dangerous or otherwise, across a large area. It is able to hold up to four chemical containers, and must be loaded before use."
origin_tech = "combat=4;materials=3"
icon_state = "chemcore"
var/list/beakers = list()
var/max_beakers = 1
var/spread_range = 5
var/temp_boost = 50
var/time_release = 0
/obj/item/weapon/bombcore/chemical/detonate()
if(time_release > 0)
var/total_volume = 0
for(var/obj/item/weapon/reagent_containers/RC in beakers)
total_volume += RC.reagents.total_volume
if(total_volume < time_release) // If it's empty, the detonation is complete.
if(loc && istype(loc, /obj/machinery/syndicatebomb))
qdel(loc)
qdel(src)
return
var/fraction = time_release/total_volume
var/datum/reagents/reactants = new(time_release)
reactants.my_atom = src
for(var/obj/item/weapon/reagent_containers/RC in beakers)
RC.reagents.trans_to(reactants, RC.reagents.total_volume*fraction, 1, 1, 1)
chem_splash(get_turf(src), spread_range, list(reactants), temp_boost)
// Detonate it again in one second, until it's out of juice.
addtimer(src, "detonate", 10)
// If it's not a time release bomb, do normal explosion
var/list/reactants = list()
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
reactants += G.reagents
for(var/obj/item/slime_extract/S in beakers)
if(S.Uses)
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
G.reagents.trans_to(S, G.reagents.total_volume)
if(S && S.reagents && S.reagents.total_volume)
reactants += S.reagents
if(!chem_splash(get_turf(src), spread_range, reactants, temp_boost))
playsound(loc, 'sound/items/Screwdriver2.ogg', 50, 1)
return // The Explosion didn't do anything. No need to log, or disappear.
if(adminlog)
message_admins(adminlog)
log_game(adminlog)
playsound(loc, 'sound/effects/bamf.ogg', 75, 1, 5)
if(loc && istype(loc, /obj/machinery/syndicatebomb))
qdel(loc)
qdel(src)
/obj/item/weapon/bombcore/chemical/attackby(obj/item/I, mob/user, params)
if(iscrowbar(I) && beakers.len > 0)
playsound(loc, I.usesound, 50, 1)
for (var/obj/item/B in beakers)
B.loc = get_turf(src)
beakers -= B
return
else if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker) || istype(I, /obj/item/weapon/reagent_containers/glass/bottle))
if(beakers.len < max_beakers)
if(!user.drop_item())
return
beakers += I
to_chat(user, "<span class='notice'>You load [src] with [I].</span>")
I.loc = src
else
to_chat(user, "<span class='warning'>The [I] wont fit! The [src] can only hold up to [max_beakers] containers.</span>")
return
..()
/obj/item/weapon/bombcore/chemical/CheckParts(list/parts_list)
..()
// Using different grenade casings, causes the payload to have different properties.
var/obj/item/weapon/stock_parts/matter_bin/MB = locate(/obj/item/weapon/stock_parts/matter_bin) in src
if(MB)
max_beakers += MB.rating // max beakers = 2-5.
qdel(MB)
for(var/obj/item/weapon/grenade/chem_grenade/G in src)
if(istype(G, /obj/item/weapon/grenade/chem_grenade/large))
var/obj/item/weapon/grenade/chem_grenade/large/LG = G
max_beakers += 1 // Adding two large grenades only allows for a maximum of 7 beakers.
spread_range += 2 // Extra range, reduced density.
temp_boost += 50 // maximum of +150K blast using only large beakers. Not enough to self ignite.
for(var/obj/item/slime_extract/S in LG.beakers) // And slime cores.
if(beakers.len < max_beakers)
beakers += S
S.loc = src
else
S.loc = get_turf(src)
if(istype(G, /obj/item/weapon/grenade/chem_grenade/cryo))
spread_range -= 1 // Reduced range, but increased density.
temp_boost -= 100 // minimum of -150K blast.
if(istype(G, /obj/item/weapon/grenade/chem_grenade/pyro))
temp_boost += 150 // maximum of +350K blast, which is enough to self ignite. Which means a self igniting bomb can't take advantage of other grenade casing properties. Sorry?
if(istype(G, /obj/item/weapon/grenade/chem_grenade/adv_release))
time_release += 50 // A typical bomb, using basic beakers, will explode over 2-4 seconds. Using two will make the reaction last for less time, but it will be more dangerous overall.
for(var/obj/item/weapon/reagent_containers/glass/B in G)
if(beakers.len < max_beakers)
beakers += B
B.loc = src
else
B.loc = get_turf(src)
qdel(G)
///Syndicate Detonator (aka the big red button)///
/obj/item/device/syndicatedetonator
name = "big red button"
desc = "Nothing good can come of pressing a button this garish..."
desc = "Your standard issue bomb synchronizing button. Five second safety delay to prevent 'accidents'."
icon = 'icons/obj/assemblies.dmi'
icon_state = "bigred"
item_state = "electronic"
w_class = WEIGHT_CLASS_TINY
origin_tech = "syndicate=3"
var/cooldown = 0
var/timer = 0
var/detonated = 0
var/existant = 0
/obj/item/device/syndicatedetonator/attack_self(mob/user as mob)
if(!cooldown)
/obj/item/device/syndicatedetonator/attack_self(mob/user)
if(timer < world.time)
for(var/obj/machinery/syndicatebomb/B in machines)
if(B.active)
B.timer = 0
B.detonation_timer = world.time + BUTTON_DELAY
detonated++
existant++
playsound(user, 'sound/machines/click.ogg', 20, 1)
@@ -334,5 +560,7 @@
log_game("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])")
detonated = 0
existant = 0
cooldown = 1
spawn(30) cooldown = 0
timer = world.time + BUTTON_COOLDOWN
#undef BUTTON_COOLDOWN
#undef BUTTON_DELAY
+1 -1
View File
@@ -26,7 +26,7 @@
/obj/effect/mine/proc/triggermine(mob/living/victim)
if(triggered)
return
visible_message("<span class='danger'>[victim] sets off \icon[src] [src]!</span>")
visible_message("<span class='danger'>[victim] sets off [bicon(src)] [src]!</span>")
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
+33
View File
@@ -201,4 +201,37 @@
icon_state = "memorizer"
item_state = "nullrod"
/obj/item/device/flash/armimplant
name = "photon projector"
desc = "A high-powered photon projector implant normally used for lighting purposes, but also doubles as a flashbulb weapon. Self-repair protocals fix the flashbulb if it ever burns out."
var/flashcd = 20
var/overheat = 0
var/obj/item/organ/internal/cyberimp/arm/flash/I = null
/obj/item/device/flash/armimplant/Destroy()
I = null
return ..()
/obj/item/device/flash/armimplant/burn_out()
if(I && I.owner)
to_chat(I.owner, "<span class='warning'>Your photon projector implant overheats and deactivates!</span>")
I.Retract()
overheat = FALSE
addtimer(src, "cooldown", flashcd * 2)
/obj/item/device/flash/armimplant/try_use_flash(mob/user = null)
if(overheat)
if(I && I.owner)
to_chat(I.owner, "<span class='warning'>Your photon projector is running too hot to be used again so quickly!</span>")
return FALSE
overheat = TRUE
addtimer(src, "cooldown", flashcd)
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
update_icon(1)
return TRUE
/obj/item/device/flash/armimplant/proc/cooldown()
overheat = FALSE
/obj/item/device/flash/synthetic //just a regular flash now
@@ -247,6 +247,13 @@ var/global/list/default_medbay_channels = list(
A.name = from
A.role = role
A.message = message
var/jammed = FALSE
for(var/obj/item/device/jammer/jammer in active_jammers)
if(get_dist(get_turf(src), get_turf(jammer)) < jammer.range)
jammed = TRUE
break
if(jammed)
message = Gibberish(message, 100)
Broadcast_Message(connection, A,
0, "*garbled automated announcement*", src,
message, from, "Automated Announcement", from, "synthesized voice",
@@ -332,6 +339,12 @@ var/global/list/default_medbay_channels = list(
var/datum/radio_frequency/connection = message_mode
var/turf/position = get_turf(src)
var/jammed = FALSE
for(var/obj/item/device/jammer/jammer in active_jammers)
if(get_dist(position, get_turf(jammer)) < jammer.range)
jammed = TRUE
break
//#### Tagging the signal with all appropriate identity values ####//
// ||-- The mob's name identity --||
@@ -345,6 +358,9 @@ var/global/list/default_medbay_channels = list(
var/jobname // the mob's "job"
if(jammed)
message = Gibberish(message, 100)
// --- Human: use their actual job ---
if(ishuman(M))
var/mob/living/carbon/human/H = M
@@ -146,3 +146,22 @@ effective or pretty fucking useless.
attack_self(usr)
add_fingerprint(usr)
return
/obj/item/device/jammer
name = "radio jammer"
desc = "Device used to disrupt nearby radio communication."
icon_state = "jammer"
var/active = FALSE
var/range = 12
/obj/item/device/jammer/Destroy()
active_jammers -= src
return ..()
/obj/item/device/jammer/attack_self(mob/user)
to_chat(user,"<span class='notice'>You [active ? "deactivate" : "activate"] the [src].</span>")
active = !active
if(active)
active_jammers |= src
else
active_jammers -= src
@@ -123,6 +123,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list(
*/
var/global/list/datum/stack_recipe/plasteel_recipes = list(
new /datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = 1),
new /datum/stack_recipe("bomb assembly", /obj/machinery/syndicatebomb/empty, 10, time = 50),
new /datum/stack_recipe("Surgery Table", /obj/machinery/optable, 5, time = 50, one_per_turf = 1, on_floor = 1),
new /datum/stack_recipe("Metal crate", /obj/structure/closet/crate, 10, time = 50, one_per_turf = 1),
new /datum/stack_recipe("Mass Driver frame", /obj/machinery/mass_driver_frame, 3, time = 50, one_per_turf = 1)
@@ -19,6 +19,9 @@
var/obj/item/device/assembly_holder/nadeassembly = null
var/label = null
var/assemblyattacher
var/ignition_temp = 10 // The amount of heat added to the reagents when this grenade goes off.
var/threatscale = 1 // Used by advanced grenades to make them slightly more worthy.
var/no_splash = FALSE //If the grenade deletes even if it has no reagents to splash with. Used for slime core reactions.
/obj/item/weapon/grenade/chem_grenade/New()
create_reagents(1000)
@@ -99,6 +102,7 @@
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])")
bombers += "[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])"
to_chat(user, "<span class='warning'>You prime the [name]! [det_time / 10] second\s!</span>")
playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1)
active = 1
update_icon()
if(iscarbon(user))
@@ -264,13 +268,18 @@
if(stage != READY)
return
var/has_reagents = 0
var/list/datum/reagents/reactants = list()
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
if(G.reagents.total_volume)
has_reagents = 1
reactants += G.reagents
if(!has_reagents)
playsound(loc, usesound, 50, 1)
if(!chem_splash(get_turf(src), affected_area, reactants, ignition_temp, threatscale) && !no_splash)
playsound(loc, 'sound/items/Screwdriver2.ogg', 50, 1)
if(beakers.len)
for(var/obj/O in beakers)
O.forceMove(get_turf(src))
beakers = list()
stage = EMPTY
update_icon()
return
if(nadeassembly)
@@ -281,31 +290,9 @@
message_admins("grenade primed by an assembly, attached by [key_name_admin(M)]<A HREF='?_src_=holder;adminmoreinfo=\ref[M]'>(?)</A> ([admin_jump_link(M)]) and last touched by [key_name_admin(last)]<A HREF='?_src_=holder;adminmoreinfo=\ref[last]'>(?)</A> ([admin_jump_link(last)]) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[A.name] (JMP)</a>.")
log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])")
playsound(loc, 'sound/effects/bamf.ogg', 50, 1)
update_mob()
invisibility = INVISIBILITY_MAXIMUM //kaboom
qdel(nadeassembly) // do this now to stop infrared beams
var/end_temp = 0
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
G.reagents.trans_to(src, G.reagents.total_volume)
end_temp += G.reagents.chem_temp
reagents.chem_temp = end_temp
if(reagents.total_volume) //The possible reactions didnt use up all reagents.
var/datum/effect/system/steam_spread/steam = new /datum/effect/system/steam_spread()
steam.set_up(10, 0, get_turf(src))
steam.attach(src)
steam.start()
for(var/atom/A in view(affected_area, loc))
if(A == src)
continue
reagents.reaction(A, 1, 10)
spawn(15) //Making sure all reagents can work
qdel(src) //correctly before deleting the grenade.
qdel(src)
/obj/item/weapon/grenade/chem_grenade/proc/CreateDefaultTrigger(var/typekey)
if(ispath(typekey,/obj/item/device/assembly))
@@ -327,64 +314,37 @@
//Large chem grenades accept slime cores and use the appropriately.
/obj/item/weapon/grenade/chem_grenade/large
name = "large grenade casing"
desc = "For oversized grenades; fits additional contents and affects a greater area."
desc = "A custom made large grenade. It affects a larger area."
icon_state = "large_grenade"
bomb_state = "largebomb"
allowed_containers = list(/obj/item/weapon/reagent_containers/glass,/obj/item/weapon/reagent_containers/food/condiment,
/obj/item/weapon/reagent_containers/food/drinks)
origin_tech = "combat=3;engineering=3"
affected_area = 4
affected_area = 5
ignition_temp = 25 // Large grenades are slightly more effective at setting off heat-sensitive mixtures than smaller grenades.
threatscale = 1.1 // 10% more effective.
/obj/item/weapon/grenade/chem_grenade/large/prime()
if(stage != READY)
return
var/has_reagents = 0
var/obj/item/slime_extract/valid_core = null
for(var/obj/item/slime_extract/S in beakers)
if(S.Uses)
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
G.reagents.trans_to(S, G.reagents.total_volume)
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
if(!istype(G)) continue
if(G.reagents.total_volume) has_reagents = 1
for(var/obj/item/slime_extract/E in beakers)
if(!istype(E)) continue
if(E.Uses) valid_core = E
if(E.reagents.total_volume) has_reagents = 1
//If there is still a core (sometimes it's used up)
//and there are reagents left, behave normally,
//otherwise drop it on the ground for timed reactions like gold.
if(!has_reagents)
playsound(loc, prime_sound, 50, 1)
return
playsound(loc, 'sound/effects/bamf.ogg', 50, 1)
update_mob()
if(valid_core)
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
G.reagents.trans_to(valid_core, G.reagents.total_volume)
//If there is still a core (sometimes it's used up)
//and there are reagents left, behave normally
if(valid_core && valid_core.reagents && valid_core.reagents.total_volume)
valid_core.reagents.trans_to(src,valid_core.reagents.total_volume)
else
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
G.reagents.trans_to(src, G.reagents.total_volume)
if(reagents.total_volume) //The possible reactions didnt use up all reagents.
var/datum/effect/system/steam_spread/steam = new /datum/effect/system/steam_spread()
steam.set_up(10, 0, get_turf(src))
steam.attach(src)
steam.start()
for(var/atom/A in view(affected_area, loc))
if( A == src ) continue
reagents.reaction(A, 1, 10)
invisibility = INVISIBILITY_MAXIMUM //Why am i doing this?
spawn(50) //To make sure all reagents can work
qdel(src) //correctly before deleting the grenade.
if(S)
if(S.reagents && S.reagents.total_volume)
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
S.reagents.trans_to(G, S.reagents.total_volume)
else
S.forceMove(get_turf(src))
no_splash = TRUE
..()
//I tried to just put it in the allowed_containers list but
@@ -399,6 +359,71 @@
else
return ..()
/obj/item/weapon/grenade/chem_grenade/cryo // Intended for rare cryogenic mixes. Cools the area moderately upon detonation.
name = "cryo grenade"
desc = "A custom made cryogenic grenade. It rapidly cools its contents upon detonation."
icon_state = "cryog"
affected_area = 2
ignition_temp = -100
/obj/item/weapon/grenade/chem_grenade/pyro // Intended for pyrotechnical mixes. Produces a small fire upon detonation, igniting potentially flammable mixtures.
name = "pyro grenade"
desc = "A custom made pyrotechnical grenade. It heats up and ignites its contents upon detonation."
icon_state = "pyrog"
origin_tech = "combat=4;engineering=4"
affected_area = 3
ignition_temp = 500 // This is enough to expose a hotspot.
/obj/item/weapon/grenade/chem_grenade/adv_release // Intended for weaker, but longer lasting effects. Could have some interesting uses.
name = "advanced release grenade"
desc = "A custom made advanced release grenade. It is able to be detonated more than once. Can be configured using a multitool."
icon_state = "timeg"
origin_tech = "combat=3;engineering=4"
var/unit_spread = 10 // Amount of units per repeat. Can be altered with a multitool.
/obj/item/weapon/grenade/chem_grenade/adv_release/attackby(obj/item/I, mob/user, params)
if(ismultitool(I))
switch(unit_spread)
if(0 to 24)
unit_spread += 5
if(25 to 99)
unit_spread += 25
else
unit_spread = 5
to_chat(user, "<span class='notice'> You set the time release to [unit_spread] units per detonation.</span>")
return
..()
/obj/item/weapon/grenade/chem_grenade/adv_release/prime()
if(stage != READY)
return
var/total_volume = 0
for(var/obj/item/weapon/reagent_containers/RC in beakers)
total_volume += RC.reagents.total_volume
if(!total_volume)
qdel(src)
qdel(nadeassembly)
return
var/fraction = unit_spread/total_volume
var/datum/reagents/reactants = new(unit_spread)
reactants.my_atom = src
for(var/obj/item/weapon/reagent_containers/RC in beakers)
RC.reagents.trans_to(reactants, RC.reagents.total_volume*fraction, threatscale, 1, 1)
chem_splash(get_turf(src), affected_area, list(reactants), ignition_temp, threatscale)
if(nadeassembly)
var/mob/M = get_mob_by_ckey(assemblyattacher)
var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
var/turf/T = get_turf(src)
var/area/A = get_area(T)
message_admins("grenade primed by an assembly, attached by [key_name_admin(M)]<A HREF='?_src_=holder;adminmoreinfo=\ref[M]'>(?)</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</A>) and last touched by [key_name_admin(last)]<A HREF='?_src_=holder;adminmoreinfo=\ref[last]'>(?)</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[last]'>FLW</A>) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[A.name] (JMP)</a>.")
log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])")
else
addtimer(src, "prime", det_time)
var/turf/DT = get_turf(src)
var/area/DA = get_area(DT)
log_game("A grenade detonated at [DA.name] ([DT.x], [DT.y], [DT.z])")
/obj/item/weapon/grenade/chem_grenade/metalfoam
payload_name = "metal foam"
@@ -35,7 +35,7 @@
var/mob/M = imp_in
var/area/t = get_area(M)
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(src)
a.follow_target = M
switch(cause)
@@ -52,7 +52,7 @@
else
a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm")
qdel(src)
qdel(a)
/obj/item/weapon/implant/death_alarm/emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this
@@ -150,6 +150,13 @@
origin_tech = "materials=3;combat=4"
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
/obj/item/weapon/kitchen/knife/combat/cyborg
name = "cyborg knife"
icon = 'icons/obj/items_cyborg.dmi'
icon_state = "knife"
desc = "A cyborg-mounted plasteel knife. Extremely sharp and durable."
origin_tech = null
/obj/item/weapon/kitchen/knife/carrotshiv
name = "carrot shiv"
icon_state = "carrotshiv"
@@ -203,26 +203,29 @@
name = "energy blade"
desc = "A concentrated beam of energy in the shape of a blade. Very stylish... and lethal."
icon_state = "blade"
force = 30
sharp = 1
edge = 1
force = 30 //Normal attacks deal esword damage
hitsound = 'sound/weapons/blade1.ogg'
active = 1
throwforce = 1//Throwing or dropping the item deletes it.
throw_speed = 3
throw_range = 1
w_class = WEIGHT_CLASS_BULKY //So you can't hide it in your pocket or some such.
armour_penetration = 50
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
var/datum/effect/system/spark_spread/spark_system
sharp = 1
edge = 1
//Most of the other special functions are handled in their own files. aka special snowflake code so kewl
/obj/item/weapon/melee/energy/blade/New()
..()
spark_system = new /datum/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
/obj/item/weapon/melee/energy/blade/dropped()
..()
qdel(src)
/obj/item/weapon/melee/energy/blade/attack_self(mob/user)
return
/obj/item/weapon/melee/energy/blade/hardlight
name = "hardlight blade"
desc = "An extremely sharp blade made out of hard light. Packs quite a punch."
icon_state = "lightblade"
item_state = "lightblade"
+13 -13
View File
@@ -26,17 +26,17 @@
to_chat(user, "<span class='notice'>You'll need to get closer to see any more.</span>")
return
if(tank)
to_chat(user, "<span class='notice'>\icon [tank] It has \the [tank] mounted onto it.</span>")
to_chat(user, "<span class='notice'>[bicon(tank)] It has [tank] mounted onto it.</span>")
/obj/item/weapon/melee/powerfist/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/tank))
if(!tank)
var/obj/item/weapon/tank/IT = W
if(IT.volume <= 3)
to_chat(user, "<span class='warning'>\The [IT] is too small for \the [src].</span>")
to_chat(user, "<span class='warning'>[IT] is too small for [src].</span>")
return
updateTank(W, 0, user)
else if(istype(W, /obj/item/weapon/wrench))
else if(iswrench(W))
switch(fisto_setting)
if(1)
fisto_setting = 2
@@ -45,8 +45,8 @@
if(3)
fisto_setting = 1
playsound(loc, W.usesound, 50, 1)
to_chat(user, "<span class='notice'>You tweak \the [src]'s piston valve to [fisto_setting].</span>")
else if(istype(W, /obj/item/weapon/screwdriver))
to_chat(user, "<span class='notice'>You tweak [src]'s piston valve to [fisto_setting].</span>")
else if(isscrewdriver(W))
if(tank)
updateTank(tank, 1, user)
@@ -54,29 +54,29 @@
/obj/item/weapon/melee/powerfist/proc/updateTank(obj/item/weapon/tank/thetank, removing = 0, mob/living/carbon/human/user)
if(removing)
if(!tank)
to_chat(user, "<span class='notice'>\The [src] currently has no tank attached to it.</span>")
to_chat(user, "<span class='notice'>[src] currently has no tank attached to it.</span>")
return
to_chat(user, "<span class='notice'>You detach \the [thetank] from \the [src].</span>")
to_chat(user, "<span class='notice'>You detach [thetank] from [src].</span>")
tank.forceMove(get_turf(user))
user.put_in_hands(tank)
tank = null
if(!removing)
if(tank)
to_chat(user, "<span class='warning'>\The [src] already has a tank.</span>")
to_chat(user, "<span class='warning'>[src] already has a tank.</span>")
return
if(!user.unEquip(thetank))
return
to_chat(user, "<span class='notice'>You hook \the [thetank] up to \the [src].</span>")
to_chat(user, "<span class='notice'>You hook [thetank] up to [src].</span>")
tank = thetank
thetank.forceMove(src)
/obj/item/weapon/melee/powerfist/attack(mob/living/target, mob/living/user)
if(!tank)
to_chat(user, "<span class='warning'>\The [src] can't operate without a source of gas!</span>")
to_chat(user, "<span class='warning'>[src] can't operate without a source of gas!</span>")
return
if(tank && !tank.air_contents.remove(gasperfist * fisto_setting))
to_chat(user, "<span class='warning'>\The [src]'s piston-ram lets out a weak hiss, it needs more gas!</span>")
to_chat(user, "<span class='warning'>[src]'s piston-ram lets out a weak hiss, it needs more gas!</span>")
playsound(loc, 'sound/effects/refill.ogg', 50, 1)
return
@@ -90,8 +90,8 @@
playsound(loc, 'sound/weapons/genhit2.ogg', 50, 1)
var/atom/throw_target = get_edge_target_turf(target, get_dir(src, get_step_away(target, src)))
spawn(0)
target.throw_at(throw_target, 5 * fisto_setting, 0.2)
target.throw_at(throw_target, 5 * fisto_setting, 0.2)
add_logs(user, target, "power fisted", src)
@@ -54,7 +54,9 @@
C.update_internals_hud_icon(0)
else
var/can_open_valve = 0
if(C.wear_mask && C.wear_mask.flags & AIRTIGHT)
if(C.get_organ_slot("breathing_tube"))
can_open_valve = 1
else if(C.wear_mask && C.wear_mask.flags & AIRTIGHT)
can_open_valve = 1
else if(ishuman(C))
var/mob/living/carbon/human/H = C
@@ -128,7 +128,7 @@ Frequency:
if(turfs.len)
L["None (Dangerous)"] = pick(turfs)
var/t1 = input(user, "Please select a teleporter to lock in on.", "Hand Teleporter") as null|anything in L
if(!t1 || (user.is_in_active_hand(src) || user.stat || user.restrained()))
if(!t1 || (!user.is_in_active_hand(src) || user.stat || user.restrained()))
return
if(active_portals >= 3)
user.show_message("<span class='notice'>\The [src] is recharging!</span>")
@@ -251,6 +251,10 @@
new /obj/item/clothing/under/rank/medical/skirt(src)
new /obj/item/clothing/under/rank/medical/skirt(src)
new /obj/item/clothing/head/surgery/purple(src)
new /obj/item/clothing/under/medigown(src)
new /obj/item/clothing/under/medigown(src)
new /obj/item/clothing/under/medigown(src)
new /obj/item/clothing/under/medigown(src)
new /obj/item/clothing/shoes/black(src)
new /obj/item/clothing/shoes/black(src)
new /obj/item/clothing/shoes/black(src)
@@ -406,6 +410,10 @@
new /obj/item/clothing/suit/storage/labcoat(src)
new /obj/item/clothing/mask/surgical(src)
new /obj/item/clothing/mask/surgical(src)
new /obj/item/clothing/under/medigown(src)
new /obj/item/clothing/under/medigown(src)
new /obj/item/clothing/under/medigown(src)
new /obj/item/clothing/under/medigown(src)
/obj/structure/closet/wardrobe/grey
+8 -5
View File
@@ -387,12 +387,13 @@ var/ert_request_answered = 0
/obj/item/clothing/head/helmet/space/hardsuit/ert/commander = 1,
/obj/item/clothing/mask/gas/sechailer/swat = 1,
/obj/item/weapon/restraints/handcuffs = 1,
/obj/item/clothing/shoes/magboots = 1,
/obj/item/weapon/storage/lockbox/mindshield = 1
)
/datum/outfit/job/centcom/response_team/commander/gamma
name = "RT Commander (Gamma)"
shoes = /obj/item/clothing/shoes/combat/swat
shoes = /obj/item/clothing/shoes/magboots/advance
gloves = /obj/item/clothing/gloves/combat
suit = /obj/item/clothing/suit/space/hardsuit/ert/commander
glasses = /obj/item/clothing/glasses/hud/security/night
@@ -457,6 +458,7 @@ var/ert_request_answered = 0
backpack_contents = list(
/obj/item/clothing/head/helmet/space/hardsuit/ert/security = 1,
/obj/item/clothing/mask/gas/sechailer = 1,
/obj/item/clothing/shoes/magboots = 1,
/obj/item/weapon/storage/box/handcuffs = 1,
/obj/item/weapon/gun/energy/ionrifle/carbine = 1
)
@@ -464,7 +466,7 @@ var/ert_request_answered = 0
/datum/outfit/job/centcom/response_team/security/gamma
name = "RT Security (Gamma)"
has_grenades = TRUE
shoes = /obj/item/clothing/shoes/combat/swat
shoes = /obj/item/clothing/shoes/magboots/advance
gloves = /obj/item/clothing/gloves/combat
suit = /obj/item/clothing/suit/space/hardsuit/ert/security
suit_store = /obj/item/weapon/gun/energy/gun/nuclear
@@ -509,7 +511,7 @@ var/ert_request_answered = 0
/datum/outfit/job/centcom/response_team/engineer/red
name = "RT Engineer (Red)"
shoes = /obj/item/clothing/shoes/magboots
shoes = /obj/item/clothing/shoes/magboots/advance
gloves = /obj/item/clothing/gloves/color/yellow
suit = /obj/item/clothing/suit/space/hardsuit/ert/engineer
suit_store = /obj/item/weapon/tank/emergency_oxygen/engi
@@ -594,12 +596,13 @@ var/ert_request_answered = 0
/obj/item/weapon/storage/firstaid/toxin = 1,
/obj/item/weapon/storage/firstaid/adv = 1,
/obj/item/weapon/storage/firstaid/surgery = 1,
/obj/item/weapon/gun/energy/gun = 1
/obj/item/weapon/gun/energy/gun = 1,
/obj/item/clothing/shoes/magboots = 1
)
/datum/outfit/job/centcom/response_team/medic/gamma
name = "RT Medic (Gamma)"
shoes = /obj/item/clothing/shoes/combat/swat
shoes = /obj/item/clothing/shoes/magboots/advance
gloves = /obj/item/clothing/gloves/combat
suit = /obj/item/clothing/suit/space/hardsuit/ert/medical
glasses = /obj/item/clothing/glasses/hud/health/night