Merge remote-tracking branch 'upstream/master' into instruments
@@ -42,4 +42,4 @@ var/global/list/global_radios = list() //list of all radios, across all z-lev
|
||||
|
||||
var/global/list/meteor_list = list() //list of all meteors
|
||||
var/global/list/poi_list = list() //list of points of interest for observe/follow
|
||||
|
||||
var/global/list/active_jammers = list() // List of active radio jammers
|
||||
|
||||
@@ -199,6 +199,11 @@
|
||||
Topic(src, list("src" = UID(), "command"="lights", "activate" = "0"), 1)
|
||||
return
|
||||
|
||||
/obj/machinery/ai_slipper/AICtrlClick() //Turns liquid dispenser on or off
|
||||
ToggleOn()
|
||||
|
||||
/obj/machinery/ai_slipper/AIAltClick() //Dispenses liquid if on
|
||||
Activate()
|
||||
|
||||
//
|
||||
// Override AdjacentQuick for AltClicking
|
||||
|
||||
@@ -169,6 +169,12 @@
|
||||
/obj/machinery/turretid/BorgAltClick() //turret lethal on/off. Forwards to AI code.
|
||||
AIAltClick()
|
||||
|
||||
/obj/machinery/ai_slipper/BorgCtrlClick() //Turns liquid dispenser on or off
|
||||
ToggleOn()
|
||||
|
||||
/obj/machinery/ai_slipper/BorgAltClick() //Dispenses liquid if on
|
||||
Activate()
|
||||
|
||||
/*
|
||||
As with AI, these are not used in click code,
|
||||
because the code for robots is specific, not generic.
|
||||
|
||||
@@ -108,11 +108,12 @@
|
||||
icon_state = "internal0"
|
||||
else
|
||||
var/no_mask = FALSE
|
||||
if(!C.wear_mask || !(C.wear_mask.flags & AIRTIGHT))
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(!H.head || !(H.head.flags & AIRTIGHT))
|
||||
no_mask = TRUE
|
||||
if(!C.get_organ_slot("breathing_tube"))
|
||||
if(!C.wear_mask || !(C.wear_mask.flags & AIRTIGHT))
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(!H.head || !(H.head.flags & AIRTIGHT))
|
||||
no_mask = TRUE
|
||||
|
||||
if(no_mask)
|
||||
to_chat(C, "<span class='notice'>You are not wearing a suitable mask or helmet.</span>")
|
||||
|
||||
@@ -332,7 +332,7 @@ var/list/uplink_items = list()
|
||||
reference = "TPB"
|
||||
item = /obj/item/weapon/reagent_containers/glass/bottle/traitor
|
||||
cost = 2
|
||||
job = list("Research Director", "Chief Medical Officer", "Medical Doctor", "Psychiatrist", "Paramedic", "Virologist", "Bartender", "Chef")
|
||||
job = list("Research Director", "Chief Medical Officer", "Medical Doctor", "Psychiatrist", "Chemist", "Paramedic", "Virologist", "Bartender", "Chef")
|
||||
|
||||
// Paper contact poison pen
|
||||
|
||||
@@ -1124,6 +1124,13 @@ var/list/uplink_items = list()
|
||||
cost = 1
|
||||
surplus = 0
|
||||
|
||||
/datum/uplink_item/device_tools/jammer
|
||||
name = "Radio Jammer"
|
||||
desc = "This device will disrupt any nearby outgoing radio communication when activated."
|
||||
reference = "RJ"
|
||||
item = /obj/item/device/jammer
|
||||
cost = 5
|
||||
|
||||
/datum/uplink_item/device_tools/teleporter
|
||||
name = "Teleporter Circuit Board"
|
||||
desc = "A printed circuit board that completes the teleporter onboard the mothership. Advise you test fire the teleporter before entering it, as malfunctions can occur."
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/wires/syndicatebomb
|
||||
random = 1
|
||||
random = TRUE
|
||||
holder_type = /obj/machinery/syndicatebomb
|
||||
wire_count = 5
|
||||
|
||||
@@ -13,83 +13,90 @@ var/const/WIRE_ACTIVATE = 16 // Will start a bombs timer if pulsed, will hint if
|
||||
switch(index)
|
||||
if(WIRE_BOOM)
|
||||
return "Explode"
|
||||
|
||||
|
||||
if(WIRE_UNBOLT)
|
||||
return "Unbolt"
|
||||
|
||||
|
||||
if(WIRE_DELAY)
|
||||
return "Delay"
|
||||
|
||||
|
||||
if(WIRE_PROCEED)
|
||||
return "Proceed"
|
||||
|
||||
|
||||
if(WIRE_ACTIVATE)
|
||||
return "Activate"
|
||||
|
||||
/datum/wires/syndicatebomb/CanUse(mob/living/L)
|
||||
var/obj/machinery/syndicatebomb/P = holder
|
||||
if(P.open_panel)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/wires/syndicatebomb/UpdatePulsed(index)
|
||||
var/obj/machinery/syndicatebomb/P = holder
|
||||
var/obj/machinery/syndicatebomb/B = holder
|
||||
switch(index)
|
||||
if(WIRE_BOOM)
|
||||
if(P.active)
|
||||
P.loc.visible_message("<span class='danger'>[bicon(holder)] An alarm sounds! It's go-</span>")
|
||||
P.timer = 0
|
||||
if(B.active)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] An alarm sounds! It's go-</span>")
|
||||
B.explode_now = TRUE
|
||||
if(WIRE_UNBOLT)
|
||||
P.loc.visible_message("<span class='notice'>[bicon(holder)] The bolts spin in place for a moment.</span>")
|
||||
holder.visible_message("<span class='notice'>[bicon(holder)] The bolts spin in place for a moment.</span>")
|
||||
if(WIRE_DELAY)
|
||||
playsound(P.loc, 'sound/machines/chime.ogg', 30, 1)
|
||||
P.loc.visible_message("<span class='notice'>[bicon(holder)] The bomb chirps.</span>")
|
||||
P.timer += 10
|
||||
if(WIRE_PROCEED)
|
||||
playsound(P.loc, 'sound/machines/buzz-sigh.ogg', 30, 1)
|
||||
P.loc.visible_message("<span class='danger'>[bicon(holder)] The bomb buzzes ominously!</span>")
|
||||
if(P.timer >= 61) //Long fuse bombs can suddenly become more dangerous if you tinker with them
|
||||
P.timer = 60
|
||||
if(P.timer >= 21)
|
||||
P.timer -= 10
|
||||
else if(P.timer >= 11) //both to prevent negative timers and to have a little mercy
|
||||
P.timer = 10
|
||||
if(WIRE_ACTIVATE)
|
||||
if(!P.active && !P.defused)
|
||||
playsound(P.loc, 'sound/machines/click.ogg', 30, 1)
|
||||
P.loc.visible_message("<span class='danger'>[bicon(holder)] You hear the bomb start ticking!</span>")
|
||||
P.active = 1
|
||||
P.icon_state = "[initial(P.icon_state)]-active[P.open_panel ? "-wires" : ""]"
|
||||
if(B.delayedbig)
|
||||
holder.visible_message("<span class='notice'>[bicon(B)] The bomb has already been delayed.</span>")
|
||||
else
|
||||
P.loc.visible_message("<span class='notice'>[bicon(holder)] The bomb seems to hesitate for a moment.</span>")
|
||||
P.timer += 5
|
||||
holder.visible_message("<span class='notice'>[bicon(B)] The bomb chirps.</span>")
|
||||
playsound(B, 'sound/machines/chime.ogg', 30, 1)
|
||||
B.detonation_timer += 300
|
||||
B.delayedbig = TRUE
|
||||
if(WIRE_PROCEED)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] The bomb buzzes ominously!</span>")
|
||||
playsound(B, 'sound/machines/buzz-sigh.ogg', 30, 1)
|
||||
var/seconds = B.seconds_remaining()
|
||||
if(seconds >= 61) // Long fuse bombs can suddenly become more dangerous if you tinker with them.
|
||||
B.detonation_timer = world.time + 600
|
||||
else if(seconds >= 21)
|
||||
B.detonation_timer -= 100
|
||||
else if(seconds >= 11) // Both to prevent negative timers and to have a little mercy.
|
||||
B.detonation_timer = world.time + 100
|
||||
if(WIRE_ACTIVATE)
|
||||
if(!B.active && !B.defused)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] You hear the bomb start ticking!</span>")
|
||||
B.activate()
|
||||
B.update_icon()
|
||||
else if(B.delayedlittle)
|
||||
holder.visible_message("<span class='notice'>[bicon(B)] Nothing happens.</span>")
|
||||
else
|
||||
holder.visible_message("<span class='notice'>[bicon(B)] The bomb seems to hesitate for a moment.</span>")
|
||||
B.detonation_timer += 100
|
||||
B.delayedlittle = TRUE
|
||||
..()
|
||||
|
||||
/datum/wires/syndicatebomb/UpdateCut(index, mended)
|
||||
var/obj/machinery/syndicatebomb/P = holder
|
||||
var/obj/machinery/syndicatebomb/B = holder
|
||||
switch(index)
|
||||
if(WIRE_EXPLODE)
|
||||
if(!mended)
|
||||
if(P.active)
|
||||
P.loc.visible_message("<span class='danger'>[bicon(holder)] An alarm sounds! It's go-</span>")
|
||||
P.timer = 0
|
||||
else
|
||||
P.defused = 1
|
||||
if(mended)
|
||||
B.defused = FALSE // Cutting and mending all the wires of an inactive bomb will thus cure any sabotage.
|
||||
else
|
||||
P.defused = 0 //cutting and mending all the wires of an inactive bomb will thus cure any sabotage
|
||||
if(B.active)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] An alarm sounds! It's go-</span>")
|
||||
B.explode_now = TRUE
|
||||
else
|
||||
B.defused = TRUE
|
||||
if(WIRE_UNBOLT)
|
||||
if(!mended && P.anchored)
|
||||
playsound(P.loc, 'sound/effects/stealthoff.ogg', 30, 1)
|
||||
P.loc.visible_message("<span class='notice'>[bicon(holder)] The bolts lift out of the ground!</span>")
|
||||
P.anchored = 0
|
||||
if(!mended && B.anchored)
|
||||
holder.visible_message("<span class='notice'>[bicon(B)] The bolts lift out of the ground!</span>")
|
||||
playsound(B, 'sound/effects/stealthoff.ogg', 30, 1)
|
||||
B.anchored = FALSE
|
||||
if(WIRE_PROCEED)
|
||||
if(!mended && P.active)
|
||||
P.loc.visible_message("<span class='danger'>[bicon(holder)] An alarm sounds! It's go-</span>")
|
||||
P.timer = 0
|
||||
if(!mended && B.active)
|
||||
holder.visible_message("<span class='danger'>[bicon(B)] An alarm sounds! It's go-</span>")
|
||||
B.explode_now = TRUE
|
||||
if(WIRE_ACTIVATE)
|
||||
if(!mended && P.active)
|
||||
P.loc.visible_message("<span class='notice'>[bicon(holder)] The timer stops! The bomb has been defused!</span>")
|
||||
P.icon_state = "[initial(P.icon_state)]-inactive[P.open_panel ? "-wires" : ""]"
|
||||
P.active = 0
|
||||
P.defused = 1
|
||||
if(!mended && B.active)
|
||||
holder.visible_message("<span class='notice'>[bicon(B)] The timer stops! The bomb has been defused!</span>")
|
||||
B.active = FALSE
|
||||
B.defused = TRUE
|
||||
B.update_icon()
|
||||
..()
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
return
|
||||
if(alert("Do you want to spawn a Gimmick Team at YOUR CURRENT LOCATION?",,"Yes","No")=="No")
|
||||
return
|
||||
var/turf/T = get_turf(mob)
|
||||
var/pick_manually = 0
|
||||
if(alert("Pick the team members manually? If you select yes, you pick from ghosts. If you select no, ghosts get offered the chance to join.",,"Yes","No")=="Yes")
|
||||
pick_manually = 1
|
||||
@@ -34,6 +35,9 @@
|
||||
var/dresscode = input("Select Outfit", "Dress-a-mob") as null|anything in outfit_list
|
||||
if(isnull(dresscode))
|
||||
return
|
||||
var/is_syndicate = 0
|
||||
if(alert("Do you want these characters automatically classified as antagonists?",,"Yes","No")=="Yes")
|
||||
is_syndicate = 1
|
||||
|
||||
var/list/players_to_spawn = list()
|
||||
if(pick_manually)
|
||||
@@ -55,7 +59,8 @@
|
||||
return 0
|
||||
|
||||
var/datum/outfit/O = outfit_list[dresscode]
|
||||
var/turf/T = get_turf(mob)
|
||||
|
||||
var/players_spawned = 0
|
||||
for(var/mob/thisplayer in players_to_spawn)
|
||||
var/mob/living/carbon/human/H = new /mob/living/carbon/human(T)
|
||||
H.name = random_name(pick(MALE,FEMALE))
|
||||
@@ -67,13 +72,20 @@
|
||||
H.mind_initialize()
|
||||
H.mind.assigned_role = "MODE"
|
||||
H.mind.special_role = "Event Character"
|
||||
ticker.mode.traitors |= H.mind //Adds them to extra antag list
|
||||
|
||||
H.key = thisplayer.key
|
||||
|
||||
H.equipOutfit(O, FALSE)
|
||||
|
||||
to_chat(H, "<BR><span class='danger'><B>[themission]</B></span>")
|
||||
H.mind.store_memory("<B>[themission]</B><BR><BR>")
|
||||
|
||||
if(is_syndicate)
|
||||
ticker.mode.traitors |= H.mind //Adds them to extra antag list
|
||||
|
||||
players_spawned++
|
||||
if(players_spawned >= teamsize)
|
||||
break
|
||||
|
||||
|
||||
message_admins("[key_name_admin(src)] has spawned a Gimmick Team.", 1)
|
||||
|
||||
@@ -332,7 +332,7 @@ BLIND // can't see anything
|
||||
mask_adjusted = 1
|
||||
if(adjusted_flags)
|
||||
slot_flags = adjusted_flags
|
||||
if(ishuman(user) && H.internal && user.wear_mask == src) /*If the user was wearing the mask providing internals on their face at the time it was adjusted, turn off internals.
|
||||
if(ishuman(user) && H.internal && !H.get_organ_slot("breathing_tube") && user.wear_mask == src) /*If the user was wearing the mask providing internals on their face at the time it was adjusted, turn off internals.
|
||||
Otherwise, they adjusted it while it was in their hands or some such so we won't be needing to turn off internals.*/
|
||||
H.update_internals_hud_icon(0)
|
||||
H.internal = null
|
||||
|
||||
@@ -90,7 +90,8 @@
|
||||
scan_reagents = 1 //You can see reagents while wearing science goggles
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi'
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/eyes.dmi'
|
||||
)
|
||||
actions_types = list(/datum/action/item_action/toggle_research_scanner)
|
||||
|
||||
@@ -138,7 +139,8 @@
|
||||
item_state = "eyepatch"
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi'
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/eyes.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/glasses/monocle
|
||||
@@ -150,7 +152,8 @@
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/eyes.dmi'
|
||||
"Drask" = 'icons/mob/species/drask/eyes.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/eyes.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/glasses/material
|
||||
@@ -163,7 +166,8 @@
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/eyes.dmi'
|
||||
"Drask" = 'icons/mob/species/drask/eyes.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/eyes.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/glasses/material/cyber
|
||||
@@ -182,7 +186,8 @@
|
||||
prescription = 1
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi'
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/eyes.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/glasses/regular/hipster
|
||||
@@ -198,7 +203,8 @@
|
||||
item_state = "3d"
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi'
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/eyes.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/glasses/gglasses
|
||||
@@ -208,7 +214,8 @@
|
||||
item_state = "gglasses"
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi'
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/eyes.dmi'
|
||||
)
|
||||
prescription_upgradable = 1
|
||||
|
||||
@@ -379,7 +386,8 @@
|
||||
flash_protect = -1
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi'
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/eyes.dmi'
|
||||
)
|
||||
|
||||
emp_act(severity)
|
||||
|
||||
@@ -62,7 +62,8 @@
|
||||
HUDType = DATA_HUD_DIAGNOSTIC
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi'
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/eyes.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/glasses/hud/diagnostic/night
|
||||
@@ -85,7 +86,8 @@
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/eyes.dmi'
|
||||
"Drask" = 'icons/mob/species/drask/eyes.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/eyes.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/glasses/hud/security/chameleon
|
||||
@@ -138,7 +140,8 @@
|
||||
HUDType = DATA_HUD_HYDROPONIC
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi'
|
||||
"Vox" = 'icons/mob/species/vox/eyes.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/eyes.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/glasses/hud/hydroponic/night
|
||||
|
||||
@@ -70,4 +70,8 @@
|
||||
heat_protection = HEAD
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
|
||||
species_fit = list("Grey")
|
||||
sprite_sheets = list(
|
||||
"Grey" = 'icons/mob/species/grey/helmet.dmi'
|
||||
)
|
||||
@@ -13,10 +13,11 @@
|
||||
max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT
|
||||
strip_delay = 60
|
||||
burn_state = FIRE_PROOF
|
||||
species_fit = list("Vox", "Drask")
|
||||
species_fit = list("Vox", "Drask", "Grey")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/helmet.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/helmet.dmi'
|
||||
"Drask" = 'icons/mob/species/drask/helmet.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/helmet.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/head/helmet/attack_self(mob/user)
|
||||
|
||||
@@ -24,12 +24,13 @@
|
||||
flags_inv = (HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE)
|
||||
actions_types = list(/datum/action/item_action/toggle)
|
||||
burn_state = FIRE_PROOF
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin")
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/head.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/helmet.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/helmet.dmi'
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/helmet.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/helmet.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/head/welding/flamedecal
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
adjusted_flags = SLOT_HEAD
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin")
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/mask.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/mask.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/mask.dmi'
|
||||
)
|
||||
|
||||
@@ -28,12 +29,13 @@
|
||||
flags = BLOCKHAIR
|
||||
flags_inv = HIDEFACE
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin")
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/mask.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/mask.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/mask.dmi'
|
||||
)
|
||||
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
permeability_coefficient = 0.50
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
burn_state = FIRE_PROOF
|
||||
species_fit = list("Vox", "Vox Armalis", "Unathi", "Tajaran", "Vulpkanin")
|
||||
species_fit = list("Vox", "Vox Armalis", "Unathi", "Tajaran", "Vulpkanin", "Grey" )
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/mask.dmi',
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/mask.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/mask.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/mask.dmi'
|
||||
)
|
||||
|
||||
@@ -30,7 +31,7 @@
|
||||
item_state = "medical"
|
||||
permeability_coefficient = 0.01
|
||||
put_on_delay = 10
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin")
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey")
|
||||
|
||||
/obj/item/clothing/mask/breath/vox
|
||||
desc = "A weirdly-shaped breath mask."
|
||||
|
||||
@@ -34,12 +34,13 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
resist_time = 150
|
||||
mute = 0
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin")
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/mask.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi'
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/mask.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/mask/muzzle/tapegag/dropped(mob/living/carbon/human/user)
|
||||
@@ -65,12 +66,13 @@
|
||||
permeability_coefficient = 0.01
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 25, rad = 0)
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin")
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/mask.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi'
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/mask.dmi'
|
||||
)
|
||||
|
||||
|
||||
@@ -83,12 +85,13 @@
|
||||
icon_state = "fake-moustache"
|
||||
flags_inv = HIDEFACE
|
||||
actions_types = list(/datum/action/item_action/pontificate)
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin")
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/mask.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi'
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/mask.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/mask/fakemoustache/attack_self(mob/user)
|
||||
@@ -267,12 +270,13 @@
|
||||
slot_flags = SLOT_MASK
|
||||
adjusted_flags = SLOT_HEAD
|
||||
icon_state = "bandbotany"
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin")
|
||||
species_fit = list("Vox", "Unathi", "Tajaran", "Vulpkanin", "Grey")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/mask.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
|
||||
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi'
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/mask.dmi'
|
||||
)
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
var/obj/machinery/camera/camera
|
||||
var/has_camera = TRUE
|
||||
strip_delay = 130
|
||||
species_fit = list("Grey")
|
||||
sprite_sheets = list(
|
||||
"Grey" = 'icons/mob/species/grey/helmet.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/ert/attack_self(mob/user)
|
||||
if(camera || !has_camera)
|
||||
|
||||
@@ -20,14 +20,15 @@
|
||||
"Skrell" = 'icons/mob/species/skrell/helmet.dmi',
|
||||
"Vox" = 'icons/mob/species/vox/helmet.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/helmet.dmi',
|
||||
"Drask" = 'icons/mob/species/drask/helmet.dmi'
|
||||
"Drask" = 'icons/mob/species/drask/helmet.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/helmet.dmi'
|
||||
)
|
||||
sprite_sheets_obj = list(
|
||||
"Unathi" = 'icons/obj/clothing/species/unathi/hats.dmi',
|
||||
"Tajaran" = 'icons/obj/clothing/species/tajaran/hats.dmi',
|
||||
"Skrell" = 'icons/obj/clothing/species/skrell/hats.dmi',
|
||||
"Vox" = 'icons/obj/clothing/species/vox/hats.dmi',
|
||||
"Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/hats.dmi',
|
||||
"Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/hats.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/equip_to_best_slot(mob/M)
|
||||
@@ -83,7 +84,7 @@
|
||||
"Tajaran" = 'icons/obj/clothing/species/tajaran/suits.dmi',
|
||||
"Skrell" = 'icons/obj/clothing/species/skrell/suits.dmi',
|
||||
"Vox" = 'icons/obj/clothing/species/vox/suits.dmi',
|
||||
"Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/suits.dmi',
|
||||
"Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/suits.dmi'
|
||||
)
|
||||
|
||||
//Breach thresholds, should ideally be inherited by most (if not all) hardsuits.
|
||||
@@ -440,7 +441,10 @@
|
||||
heat_protection = HEAD //Uncomment to enable firesuit protection
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
|
||||
unacidable = 1
|
||||
sprite_sheets = null
|
||||
species_fit = list("Grey")
|
||||
sprite_sheets = list(
|
||||
"Grey" = 'icons/mob/species/grey/helmet.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/wizard
|
||||
icon_state = "hardsuit-wiz"
|
||||
@@ -538,7 +542,6 @@
|
||||
icon_state = "hardsuit0-hos"
|
||||
item_color = "hos"
|
||||
armor = list(melee = 45, bullet = 25, laser = 30,energy = 10, bomb = 25, bio = 100, rad = 50)
|
||||
sprite_sheets = null
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/security/hos
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
permeability_coefficient = 0.01
|
||||
armor = list(melee = 40, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50)
|
||||
species_restricted = list("exclude", "Diona", "Wryn")
|
||||
species_fit = list("Vox")
|
||||
species_fit = list("Vox", "Grey")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/helmet.dmi'
|
||||
"Vox" = 'icons/mob/species/vox/helmet.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/helmet.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/capspace/equipped(mob/living/carbon/human/user, slot)
|
||||
@@ -136,9 +137,10 @@
|
||||
desc = "A paramedic EVA helmet. Used in the recovery of bodies from space."
|
||||
icon_state = "paramedic-eva-helmet"
|
||||
item_state = "paramedic-eva-helmet"
|
||||
species_fit = list("Vox")
|
||||
species_fit = list("Vox", "Grey")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/helmet.dmi'
|
||||
"Vox" = 'icons/mob/species/vox/helmet.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/helmet.dmi'
|
||||
)
|
||||
sprite_sheets_obj = list(
|
||||
"Vox" = 'icons/obj/clothing/species/vox/hats.dmi'
|
||||
@@ -187,12 +189,13 @@
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20)
|
||||
flash_protect = 0
|
||||
species_restricted = list("exclude", "Diona", "Wryn")
|
||||
species_fit = list("Tajaran", "Unathi", "Vox", "Vulpkanin")
|
||||
species_fit = list("Tajaran", "Unathi", "Vox", "Vulpkanin", "Grey")
|
||||
sprite_sheets = list(
|
||||
"Tajaran" = 'icons/mob/species/tajaran/helmet.dmi',
|
||||
"Unathi" = 'icons/mob/species/unathi/helmet.dmi',
|
||||
"Vox" = 'icons/mob/species/vox/helmet.dmi',
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/helmet.dmi'
|
||||
"Vulpkanin" = 'icons/mob/species/vulpkanin/helmet.dmi',
|
||||
"Grey" = 'icons/mob/species/grey/helmet.dmi'
|
||||
)
|
||||
sprite_sheets_obj = list(
|
||||
"Vox" = 'icons/obj/clothing/species/vox/hats.dmi',
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 0)
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
|
||||
flash_protect = 2
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/eva/plasmaman/engineer
|
||||
name = "plasmaman engineer suit"
|
||||
icon_state = "plasmamanEngineer_suit"
|
||||
@@ -128,7 +128,7 @@
|
||||
base_state = "plasmamanEngineer_helmet"
|
||||
armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 75)
|
||||
flash_protect = 2
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/eva/plasmaman/engineer/ce
|
||||
name = "plasmaman chief engineer suit"
|
||||
icon_state = "plasmaman_CE"
|
||||
@@ -269,6 +269,24 @@
|
||||
icon_state = "plasmaman_CMO_helmet0"
|
||||
base_state = "plasmaman_CMO_helmet"
|
||||
|
||||
/obj/item/clothing/suit/space/eva/plasmaman/medical/coroner
|
||||
name = "plasmaman coroner suit"
|
||||
icon_state = "plasmaman_Coroner"
|
||||
|
||||
/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/coroner
|
||||
name = "plasmaman coroner helmet"
|
||||
icon_state = "plasmaman_Coroner_helmet0"
|
||||
base_state = "plasmaman_Coroner_helmet"
|
||||
|
||||
/obj/item/clothing/suit/space/eva/plasmaman/medical/virologist
|
||||
name = "plasmaman virologist suit"
|
||||
icon_state = "plasmaman_Virologist"
|
||||
|
||||
/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/virologist
|
||||
name = "plasmaman virologist helmet"
|
||||
icon_state = "plasmaman_Virologist_helmet0"
|
||||
base_state = "plasmaman_Virologist_helmet"
|
||||
|
||||
/obj/item/clothing/suit/space/eva/plasmaman/science
|
||||
name = "plasmaman scientist suit"
|
||||
icon_state = "plasmamanScience_suit"
|
||||
@@ -278,6 +296,15 @@
|
||||
icon_state = "plasmamanScience_helmet0"
|
||||
base_state = "plasmamanScience_helmet"
|
||||
|
||||
/obj/item/clothing/suit/space/eva/plasmaman/science/geneticist
|
||||
name = "plasmaman geneticist suit"
|
||||
icon_state = "plasmaman_Geneticist"
|
||||
|
||||
/obj/item/clothing/head/helmet/space/eva/plasmaman/science/geneticist
|
||||
name = "plasmaman geneticist helmet"
|
||||
icon_state = "plasmaman_Geneticist_helmet0"
|
||||
base_state = "plasmaman_Geneticist_helmet"
|
||||
|
||||
/obj/item/clothing/suit/space/eva/plasmaman/science/rd
|
||||
name = "plasmaman research director suit"
|
||||
icon_state = "plasmaman_RD"
|
||||
|
||||
@@ -620,7 +620,7 @@
|
||||
return
|
||||
|
||||
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)
|
||||
if(istype(t, /area/syndicate_station) || istype(t, /area/syndicate_mothership) || istype(t, /area/shuttle/syndicate_elite) )
|
||||
//give the syndicats a bit of stealth
|
||||
a.autosay("[M] has been vandalized in Space!", "[M]'s Death Alarm")
|
||||
|
||||
@@ -822,3 +822,11 @@
|
||||
icon_state = "victorianredvest"
|
||||
item_state = "victorianredvest"
|
||||
item_color = "victorianredvest"
|
||||
|
||||
/obj/item/clothing/under/medigown
|
||||
name = "medical gown"
|
||||
desc = "a flimsy examination gown, the back ties never close."
|
||||
icon_state = "medicalgown"
|
||||
item_state = "medicalgown"
|
||||
item_color = "medicalgown"
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO
|
||||
|
||||
@@ -9,15 +9,19 @@
|
||||
var/atom/attached_to
|
||||
color = "#ff0000"
|
||||
var/text_size = 4
|
||||
var/started = 0
|
||||
var/started = FALSE
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
anchored = 1
|
||||
layer = 5
|
||||
anchored = TRUE
|
||||
layer = GHOST_LAYER
|
||||
|
||||
/obj/effect/countdown/New(atom/A)
|
||||
. = ..()
|
||||
attach(A)
|
||||
|
||||
/obj/effect/countdown/examine(mob/user)
|
||||
. = ..()
|
||||
to_chat(user, "This countdown is displaying: [displayed_text]")
|
||||
|
||||
/obj/effect/countdown/proc/attach(atom/A)
|
||||
attached_to = A
|
||||
loc = get_turf(A)
|
||||
@@ -25,13 +29,13 @@
|
||||
/obj/effect/countdown/proc/start()
|
||||
if(!started)
|
||||
fast_processing += src
|
||||
started = 1
|
||||
started = TRUE
|
||||
|
||||
/obj/effect/countdown/proc/stop()
|
||||
if(started)
|
||||
maptext = null
|
||||
fast_processing -= src
|
||||
started = 0
|
||||
started = FALSE
|
||||
|
||||
/obj/effect/countdown/proc/get_value()
|
||||
// Get the value from our atom
|
||||
@@ -56,6 +60,19 @@
|
||||
fast_processing -= src
|
||||
return ..()
|
||||
|
||||
/obj/effect/countdown/ex_act(severity) //immune to explosions
|
||||
return
|
||||
|
||||
/obj/effect/countdown/syndicatebomb
|
||||
name = "syndicate bomb countdown"
|
||||
|
||||
/obj/effect/countdown/syndicatebomb/get_value()
|
||||
var/obj/machinery/syndicatebomb/S = attached_to
|
||||
if(!istype(S))
|
||||
return
|
||||
else if(S.active)
|
||||
return S.seconds_remaining()
|
||||
|
||||
/obj/effect/countdown/clonepod
|
||||
name = "cloning pod countdown"
|
||||
text_size = 1
|
||||
|
||||
@@ -324,6 +324,30 @@
|
||||
/obj/item/stack/rods = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/chemical_payload
|
||||
name = "Chemical Payload (C4)"
|
||||
result = /obj/item/weapon/bombcore/chemical
|
||||
reqs = list(
|
||||
/obj/item/weapon/stock_parts/matter_bin = 1,
|
||||
/obj/item/weapon/grenade/plastic/c4 = 1,
|
||||
/obj/item/weapon/grenade/chem_grenade = 2
|
||||
)
|
||||
parts = list(/obj/item/weapon/stock_parts/matter_bin = 1, /obj/item/weapon/grenade/chem_grenade = 2)
|
||||
time = 30
|
||||
category = CAT_WEAPON
|
||||
|
||||
/datum/crafting_recipe/chemical_payload2
|
||||
name = "Chemical Payload (gibtonite)"
|
||||
result = /obj/item/weapon/bombcore/chemical
|
||||
reqs = list(
|
||||
/obj/item/weapon/stock_parts/matter_bin = 1,
|
||||
/obj/item/weapon/twohanded/required/gibtonite = 1,
|
||||
/obj/item/weapon/grenade/chem_grenade = 2
|
||||
)
|
||||
parts = list(/obj/item/weapon/stock_parts/matter_bin = 1, /obj/item/weapon/grenade/chem_grenade = 2)
|
||||
time = 50
|
||||
category = CAT_WEAPON
|
||||
|
||||
/datum/crafting_recipe/bonfire
|
||||
name = "Bonfire"
|
||||
time = 60
|
||||
|
||||
@@ -296,13 +296,6 @@
|
||||
flags = RESTRICTED | HIVEMIND
|
||||
|
||||
/datum/language/grey/broadcast(mob/living/speaker, message, speaker_mask)
|
||||
var/their = "their"
|
||||
if(speaker.gender == "female")
|
||||
their = "her"
|
||||
if(speaker.gender == "male")
|
||||
their = "his"
|
||||
|
||||
speaker.visible_message("<span class='notice'>[speaker] touches [their] fingers to [their] temple.</span>")
|
||||
..(speaker,message,speaker.real_name)
|
||||
|
||||
/datum/language/grey/check_can_speak(mob/living/speaker)
|
||||
@@ -316,6 +309,14 @@
|
||||
if(speaker.incapacitated(ignore_lying = 1))
|
||||
to_chat(speaker,"<span class='warning'>You can't communicate while unable to move your hands to your head!</span>")
|
||||
return FALSE
|
||||
|
||||
var/their = "their"
|
||||
if(speaker.gender == "female")
|
||||
their = "her"
|
||||
if(speaker.gender == "male")
|
||||
their = "his"
|
||||
speaker.visible_message("<span class='notice'>[speaker] touches [their] fingers to [their] temple.</span>") //If placed in grey/broadcast, it will happen regardless of the success of the action.
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/language/grey/check_special_condition(mob/living/carbon/human/other, mob/living/carbon/human/speaker)
|
||||
|
||||
@@ -654,9 +654,10 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
|
||||
"<span class='userdanger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM].</span>")
|
||||
|
||||
var/no_mask
|
||||
if(!(wear_mask && wear_mask.flags & AIRTIGHT))
|
||||
if(!(head && head.flags & AIRTIGHT))
|
||||
no_mask = 1
|
||||
if(!get_organ_slot("breathing_tube"))
|
||||
if(!(wear_mask && wear_mask.flags & AIRTIGHT))
|
||||
if(!(head && head.flags & AIRTIGHT))
|
||||
no_mask = 1
|
||||
if(no_mask)
|
||||
to_chat(usr, "<span class='warning'>[src] is not wearing a suitable mask or helmet!</span>")
|
||||
return
|
||||
@@ -667,9 +668,10 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
|
||||
update_internals_hud_icon(0)
|
||||
else
|
||||
var/no_mask2
|
||||
if(!(wear_mask && wear_mask.flags & AIRTIGHT))
|
||||
if(!(head && head.flags & AIRTIGHT))
|
||||
no_mask2 = 1
|
||||
if(!get_organ_slot("breathing_tube"))
|
||||
if(!(wear_mask && wear_mask.flags & AIRTIGHT))
|
||||
if(!(head && head.flags & AIRTIGHT))
|
||||
no_mask2 = 1
|
||||
if(no_mask2)
|
||||
to_chat(usr, "<span class='warning'>[src] is not wearing a suitable mask or helmet!</span>")
|
||||
return
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,SPECIALROLE_HUD)
|
||||
var/list/stomach_contents = list()
|
||||
var/list/internal_organs = list()
|
||||
var/list/internal_organs_slot = list() //Same as above, but stores "slot ID" - "organ" pairs for easy access.
|
||||
var/antibodies = 0
|
||||
|
||||
var/life_tick = 0 // The amount of life ticks that have processed on this mob.
|
||||
|
||||
@@ -427,7 +427,7 @@
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask)
|
||||
var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask) || get_organ_slot("breathing_tube")
|
||||
var/list/obscured = check_obscured_slots()
|
||||
|
||||
var/dat = {"<table>
|
||||
@@ -596,7 +596,7 @@
|
||||
return
|
||||
|
||||
//repurposed proc. Now it combines get_id_name() and get_face_name() to determine a mob's name variable. Made into a seperate proc as it'll be useful elsewhere
|
||||
/mob/living/carbon/human/get_visible_name()
|
||||
/mob/living/carbon/human/get_visible_name(var/id_override = FALSE)
|
||||
if(name_override)
|
||||
return name_override
|
||||
if(wear_mask && (wear_mask.flags_inv & HIDEFACE)) //Wearing a mask which hides our face, use id-name if possible
|
||||
@@ -605,7 +605,7 @@
|
||||
return get_id_name("Unknown") //Likewise for hats
|
||||
var/face_name = get_face_name()
|
||||
var/id_name = get_id_name("")
|
||||
if(id_name && (id_name != face_name))
|
||||
if(id_name && (id_name != face_name) && !id_override)
|
||||
return "[face_name] (as [id_name])"
|
||||
return face_name
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
update_hair() //rebuild hair
|
||||
update_fhair()
|
||||
update_head_accessory()
|
||||
if(internal)
|
||||
if(internal && !get_organ_slot("breathing_tube"))
|
||||
internal = null
|
||||
update_internals_hud_icon(0)
|
||||
wear_mask_update(I, toggle_off = FALSE)
|
||||
|
||||
@@ -305,9 +305,10 @@
|
||||
var/null_internals = 0 //internals are invalid, therefore turn them off
|
||||
var/skip_contents_check = 0 //rigsuit snowflake, oxygen tanks aren't stored inside the mob, so the 'contents.Find' check has to be skipped.
|
||||
|
||||
if(!(wear_mask && wear_mask.flags & AIRTIGHT)) //if NOT (wear_mask AND wear_mask.flags CONTAIN AIRTIGHT)
|
||||
if(!(head && head.flags & AIRTIGHT)) //if NOT (head AND head.flags CONTAIN AIRTIGHT)
|
||||
null_internals = 1 //not wearing a mask or suitable helmet
|
||||
if(!get_organ_slot("breathing_tube"))
|
||||
if(!(wear_mask && wear_mask.flags & AIRTIGHT)) //if NOT (wear_mask AND wear_mask.flags CONTAIN AIRTIGHT)
|
||||
if(!(head && head.flags & AIRTIGHT)) //if NOT (head AND head.flags CONTAIN AIRTIGHT)
|
||||
null_internals = 1 //not wearing a mask or suitable helmet
|
||||
|
||||
if(istype(back, /obj/item/weapon/rig)) //wearing a rigsuit
|
||||
var/obj/item/weapon/rig/rig = back //needs to be typecasted because this doesn't use get_rig() for some reason
|
||||
|
||||
@@ -49,9 +49,12 @@
|
||||
var/tank_slot_name = "suit storage"
|
||||
|
||||
switch(assigned_role)
|
||||
if("Scientist","Geneticist","Roboticist")
|
||||
if("Scientist","Roboticist")
|
||||
suit=/obj/item/clothing/suit/space/eva/plasmaman/science
|
||||
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/science
|
||||
if("Geneticist")
|
||||
suit=/obj/item/clothing/suit/space/eva/plasmaman/science/geneticist
|
||||
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/science/geneticist
|
||||
if("Research Director")
|
||||
suit=/obj/item/clothing/suit/space/eva/plasmaman/science/rd
|
||||
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/science/rd
|
||||
@@ -103,6 +106,12 @@
|
||||
if("Chief Medical Officer")
|
||||
suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/cmo
|
||||
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/cmo
|
||||
if("Coroner")
|
||||
suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/coroner
|
||||
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/coroner
|
||||
if("Virologist")
|
||||
suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/virologist
|
||||
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/virologist
|
||||
if("Bartender", "Chef")
|
||||
suit=/obj/item/clothing/suit/space/eva/plasmaman/service
|
||||
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/service
|
||||
|
||||
@@ -927,7 +927,7 @@
|
||||
"brain" = /obj/item/organ/internal/brain/mmi_holder/posibrain,
|
||||
"cell" = /obj/item/organ/internal/cell,
|
||||
"optics" = /obj/item/organ/internal/eyes/optical_sensor, //Default darksight of 2.
|
||||
"charger" = /obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord
|
||||
"charger" = /obj/item/organ/internal/cyberimp/arm/power_cord
|
||||
)
|
||||
|
||||
vision_organ = /obj/item/organ/internal/eyes/optical_sensor
|
||||
|
||||
@@ -183,9 +183,10 @@
|
||||
if(internal)
|
||||
if(internal.loc != src)
|
||||
internal = null
|
||||
if(!wear_mask || !(wear_mask.flags & AIRTIGHT)) //not wearing mask or non-breath mask
|
||||
if(!head || !(head.flags & AIRTIGHT)) //not wearing helmet or non-breath helmet
|
||||
internal = null //turn off internals
|
||||
if(!get_organ_slot("breathing_tube"))
|
||||
if(!wear_mask || !(wear_mask.flags & AIRTIGHT)) //not wearing mask or non-breath mask
|
||||
if(!head || !(head.flags & AIRTIGHT)) //not wearing helmet or non-breath helmet
|
||||
internal = null //turn off internals
|
||||
|
||||
if(internal)
|
||||
update_internals_hud_icon(1)
|
||||
|
||||
@@ -120,6 +120,7 @@
|
||||
|
||||
var/has_enabled_antagHUD = 0
|
||||
var/antagHUD = 0
|
||||
var/can_change_intents = 1 //all mobs can change intents by default.
|
||||
|
||||
//Generic list for proc holders. Only way I can see to enable certain verbs/procs. Should be modified if needed.
|
||||
var/proc_holder_list[] = list()
|
||||
|
||||
@@ -167,9 +167,11 @@
|
||||
|
||||
*/
|
||||
|
||||
var/breathing_tube = affecting.get_organ_slot("breathing_tube")
|
||||
|
||||
if(state >= GRAB_NECK)
|
||||
affecting.Stun(5) //It will hamper your voice, being choked and all.
|
||||
if(isliving(affecting))
|
||||
if(isliving(affecting) && !breathing_tube)
|
||||
var/mob/living/L = affecting
|
||||
L.adjustOxyLoss(1)
|
||||
|
||||
@@ -177,7 +179,8 @@
|
||||
//affecting.apply_effect(STUTTER, 5) //would do this, but affecting isn't declared as mob/living for some stupid reason.
|
||||
affecting.Stuttering(5) //It will hamper your voice, being choked and all.
|
||||
affecting.Weaken(5) //Should keep you down unless you get help.
|
||||
affecting.AdjustLoseBreath(2, bound_lower = 0, bound_upper = 3)
|
||||
if(!breathing_tube)
|
||||
affecting.AdjustLoseBreath(2, bound_lower = 0, bound_upper = 3)
|
||||
|
||||
adjust_position()
|
||||
|
||||
@@ -290,7 +293,8 @@
|
||||
msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]")
|
||||
|
||||
assailant.next_move = world.time + 10
|
||||
affecting.AdjustLoseBreath(1)
|
||||
if(!affecting.get_organ_slot("breathing_tube"))
|
||||
affecting.AdjustLoseBreath(1)
|
||||
affecting.setDir(WEST)
|
||||
adjust_position()
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ proc/slur(phrase, var/list/slurletters = ("'"))//use a different list as an inpu
|
||||
return sanitize(copytext(t,1,MAX_MESSAGE_LEN))
|
||||
|
||||
|
||||
proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 for p will cause letters to be replaced instead of added
|
||||
/proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 for p will cause letters to be replaced instead of added
|
||||
/* Turn text into complete gibberish! */
|
||||
var/returntext = ""
|
||||
for(var/i = 1, i <= length(t), i++)
|
||||
@@ -337,30 +337,31 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM)
|
||||
set name = "a-intent"
|
||||
set hidden = 1
|
||||
|
||||
if(ishuman(src) || isalienadult(src) || isbrain(src))
|
||||
switch(input)
|
||||
if(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM)
|
||||
a_intent = input
|
||||
if("right")
|
||||
a_intent = intent_numeric((intent_numeric(a_intent)+1) % 4)
|
||||
if("left")
|
||||
a_intent = intent_numeric((intent_numeric(a_intent)+3) % 4)
|
||||
if(hud_used && hud_used.action_intent)
|
||||
hud_used.action_intent.icon_state = "[a_intent]"
|
||||
if(can_change_intents)
|
||||
if(ishuman(src) || isalienadult(src) || isbrain(src))
|
||||
switch(input)
|
||||
if(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM)
|
||||
a_intent = input
|
||||
if("right")
|
||||
a_intent = intent_numeric((intent_numeric(a_intent)+1) % 4)
|
||||
if("left")
|
||||
a_intent = intent_numeric((intent_numeric(a_intent)+3) % 4)
|
||||
if(hud_used && hud_used.action_intent)
|
||||
hud_used.action_intent.icon_state = "[a_intent]"
|
||||
|
||||
else if(isrobot(src) || islarva(src))
|
||||
switch(input)
|
||||
if(INTENT_HELP)
|
||||
a_intent = INTENT_HELP
|
||||
if(INTENT_HARM)
|
||||
a_intent = INTENT_HARM
|
||||
if("right","left")
|
||||
a_intent = intent_numeric(intent_numeric(a_intent) - 3)
|
||||
if(hud_used && hud_used.action_intent)
|
||||
if(a_intent == INTENT_HARM)
|
||||
hud_used.action_intent.icon_state = "harm"
|
||||
else
|
||||
hud_used.action_intent.icon_state = "help"
|
||||
else if(isrobot(src) || islarva(src))
|
||||
switch(input)
|
||||
if(INTENT_HELP)
|
||||
a_intent = INTENT_HELP
|
||||
if(INTENT_HARM)
|
||||
a_intent = INTENT_HARM
|
||||
if("right","left")
|
||||
a_intent = intent_numeric(intent_numeric(a_intent) - 3)
|
||||
if(hud_used && hud_used.action_intent)
|
||||
if(a_intent == INTENT_HARM)
|
||||
hud_used.action_intent.icon_state = "harm"
|
||||
else
|
||||
hud_used.action_intent.icon_state = "help"
|
||||
|
||||
|
||||
/mob/living/verb/mob_sleep()
|
||||
|
||||
@@ -1,30 +1,20 @@
|
||||
/obj/item/weapon/gun/energy/gun/advtaser/mounted
|
||||
name = "mounted taser"
|
||||
desc = "An arm mounted dual-mode weapon that fires electrodes and disabler shots."
|
||||
icon_state = "armcannon"
|
||||
icon = 'icons/obj/items_cyborg.dmi'
|
||||
icon_state = "taser"
|
||||
item_state = "armcannonstun4"
|
||||
force = 5
|
||||
flags = NODROP
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
can_flashlight = 0
|
||||
selfcharge = 1
|
||||
can_flashlight = 0
|
||||
trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses neural signals instead
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/advtaser/mounted/dropped()//if somebody manages to drop this somehow...
|
||||
..()
|
||||
loc = null//send it to nullspace to get retrieved by the implant later on. gotta cover those edge cases.
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/mounted
|
||||
name = "mounted laser"
|
||||
desc = "An arm mounted cannon that fires lethal lasers. Doesn't come with a charge beam."
|
||||
icon_state = "armcannon"
|
||||
desc = "An arm mounted cannon that fires lethal lasers."
|
||||
icon = 'icons/obj/items_cyborg.dmi'
|
||||
icon_state = "laser"
|
||||
item_state = "armcannonlase"
|
||||
force = 5
|
||||
flags = NODROP
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
materials = null
|
||||
selfcharge = 1
|
||||
trigger_guard = TRIGGER_GUARD_ALLOW_ALL
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/mounted/dropped()
|
||||
..()
|
||||
loc = null
|
||||
trigger_guard = TRIGGER_GUARD_ALLOW_ALL
|
||||
@@ -0,0 +1,78 @@
|
||||
// Replaces chemgrenade stuff, allowing reagent explosions to be called from anywhere.
|
||||
// It should be called using a location, the range, and a list of reagents involved.
|
||||
|
||||
// Threatscale is a multiplier for the 'threat' of the grenade. If you're increasing the affected range drastically, you might want to improve this.
|
||||
// Extra heat affects the temperature of the mixture, and may cause it to react in different ways.
|
||||
|
||||
|
||||
/proc/chem_splash(turf/epicenter, affected_range = 3, list/datum/reagents/reactants = list(), extra_heat = 0, threatscale = 1, adminlog = 1)
|
||||
if(!isturf(epicenter) || !reactants.len || threatscale <= 0)
|
||||
return
|
||||
var/has_reagents
|
||||
var/total_reagents
|
||||
for(var/datum/reagents/R in reactants)
|
||||
if(R.total_volume)
|
||||
has_reagents = 1
|
||||
total_reagents += R.total_volume
|
||||
|
||||
if(!has_reagents)
|
||||
return
|
||||
|
||||
var/datum/reagents/splash_holder = new/datum/reagents(total_reagents*threatscale)
|
||||
splash_holder.my_atom = epicenter // For some reason this is setting my_atom to null, and causing runtime errors.
|
||||
var/total_temp = 0
|
||||
|
||||
for(var/datum/reagents/R in reactants)
|
||||
R.trans_to(splash_holder, R.total_volume, threatscale, 1, 1)
|
||||
total_temp += R.chem_temp
|
||||
splash_holder.chem_temp = (total_temp/reactants.len) + extra_heat // Average temperature of reagents + extra heat.
|
||||
splash_holder.handle_reactions() // React them now.
|
||||
|
||||
if(splash_holder.total_volume && affected_range >= 0) //The possible reactions didnt use up all reagents, so we spread it around.
|
||||
var/datum/effect/system/steam_spread/steam = new /datum/effect/system/steam_spread()
|
||||
steam.set_up(10, 0, epicenter)
|
||||
steam.attach(epicenter)
|
||||
steam.start()
|
||||
|
||||
var/list/viewable = view(affected_range, epicenter)
|
||||
|
||||
var/list/accessible = list(epicenter)
|
||||
for(var/i=1; i<=affected_range; i++)
|
||||
var/list/turflist = list()
|
||||
for(var/turf/T in (orange(i, epicenter) - orange(i-1, epicenter)))
|
||||
turflist |= T
|
||||
for(var/turf/T in turflist)
|
||||
if( !(get_dir(T,epicenter) in cardinal) && (abs(T.x - epicenter.x) == abs(T.y - epicenter.y) ))
|
||||
turflist.Remove(T)
|
||||
turflist.Add(T) // we move the purely diagonal turfs to the end of the list.
|
||||
for(var/turf/T in turflist)
|
||||
if(accessible[T])
|
||||
continue
|
||||
for(var/thing in T.GetAtmosAdjacentTurfs(alldir = TRUE))
|
||||
var/turf/NT = thing
|
||||
if(!(NT in accessible))
|
||||
continue
|
||||
if(!(get_dir(T,NT) in cardinal))
|
||||
continue
|
||||
accessible[T] = 1
|
||||
break
|
||||
var/list/reactable = accessible
|
||||
for(var/turf/T in accessible)
|
||||
for(var/atom/A in T.GetAllContents())
|
||||
if(!(A in viewable))
|
||||
continue
|
||||
reactable |= A
|
||||
if(extra_heat >= 300)
|
||||
T.hotspot_expose(extra_heat*2, 5)
|
||||
if(!reactable.len) //Nothing to react with. Probably means we're in nullspace.
|
||||
return
|
||||
for(var/thing in reactable)
|
||||
var/atom/A = thing
|
||||
var/distance = max(1,get_dist(A, epicenter))
|
||||
var/fraction = 0.5/(2 ** distance) //50/25/12/6... for a 200u splash, 25/12/6/3... for a 100u, 12/6/3/1 for a 50u
|
||||
splash_holder.reaction(A, TOUCH, fraction)
|
||||
|
||||
qdel(splash_holder)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ var/const/INGEST = 2
|
||||
|
||||
return the_id
|
||||
|
||||
/datum/reagents/proc/trans_to(target, amount=1, multiplier=1, preserve_data=1)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
|
||||
/datum/reagents/proc/trans_to(target, amount=1, multiplier=1, preserve_data=1, no_react = 0)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
|
||||
if(!target)
|
||||
return
|
||||
if(total_volume <= 0)
|
||||
@@ -143,13 +143,14 @@ var/const/INGEST = 2
|
||||
if(preserve_data)
|
||||
trans_data = copy_data(current_reagent)
|
||||
|
||||
R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data, chem_temp)
|
||||
R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data, chem_temp, no_react = 1)
|
||||
remove_reagent(current_reagent.id, current_reagent_transfer)
|
||||
|
||||
update_total()
|
||||
R.update_total()
|
||||
R.handle_reactions()
|
||||
handle_reactions()
|
||||
if(!no_react)
|
||||
R.handle_reactions()
|
||||
handle_reactions()
|
||||
return amount
|
||||
|
||||
/datum/reagents/proc/copy_to(obj/target, amount=1, multiplier=1, preserve_data=1, safety = 0)
|
||||
@@ -537,7 +538,7 @@ var/const/INGEST = 2
|
||||
var/amt = list_reagents[r_id]
|
||||
add_reagent(r_id, amt, data)
|
||||
|
||||
/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300)
|
||||
/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300, no_react = 0)
|
||||
if(!isnum(amount))
|
||||
return 1
|
||||
update_total()
|
||||
@@ -554,7 +555,8 @@ var/const/INGEST = 2
|
||||
update_total()
|
||||
my_atom.on_reagent_change()
|
||||
R.on_merge(data)
|
||||
handle_reactions()
|
||||
if(!no_react)
|
||||
handle_reactions()
|
||||
return 0
|
||||
|
||||
var/datum/reagent/D = chemical_reagents_list[reagent]
|
||||
@@ -570,7 +572,8 @@ var/const/INGEST = 2
|
||||
|
||||
update_total()
|
||||
my_atom.on_reagent_change()
|
||||
handle_reactions()
|
||||
if(!no_react)
|
||||
handle_reactions()
|
||||
return 0
|
||||
else
|
||||
warning("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])")
|
||||
|
||||
@@ -371,10 +371,12 @@
|
||||
description = "What is this emotion you humans call \"love?\" Oh, it's this? This is it? Huh, well okay then, thanks."
|
||||
reagent_state = LIQUID
|
||||
color = "#FF83A5"
|
||||
process_flags = ORGANIC | SYNTHETIC // That's the power of love~
|
||||
|
||||
/datum/reagent/love/on_mob_life(mob/living/M)
|
||||
if(M.a_intent == INTENT_HARM)
|
||||
M.a_intent = INTENT_HELP
|
||||
if(M.a_intent != INTENT_HELP)
|
||||
M.a_intent_change(INTENT_HELP)
|
||||
M.can_change_intents = 0 //Now you have no choice but to be helpful.
|
||||
|
||||
if(prob(8))
|
||||
var/lovely_phrase = pick("appreciated", "loved", "pretty good", "really nice", "pretty happy with yourself, even though things haven't always gone as well as they could")
|
||||
@@ -391,9 +393,14 @@
|
||||
break
|
||||
..()
|
||||
|
||||
/datum/reagent/love/on_mob_delete(mob/living/M)
|
||||
M.can_change_intents = 1
|
||||
..()
|
||||
|
||||
/datum/reagent/love/reaction_mob(mob/living/M, method=TOUCH, volume)
|
||||
to_chat(M, "<span class='notice'>You feel loved!</span>")
|
||||
|
||||
|
||||
/datum/reagent/royal_bee_jelly
|
||||
name = "royal bee jelly"
|
||||
id = "royal_bee_jelly"
|
||||
|
||||
@@ -221,6 +221,8 @@
|
||||
if(method == TOUCH)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.get_species() == "Grey")
|
||||
return
|
||||
|
||||
if(volume > 25)
|
||||
|
||||
@@ -247,6 +249,8 @@
|
||||
if(method == INGEST)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.get_species() == "Grey")
|
||||
return
|
||||
|
||||
if(volume < 10)
|
||||
to_chat(M, "<span class='danger'>The greenish acidic substance stings you, but isn't concentrated enough to harm you!</span>")
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
/obj/machinery/biogenerator,
|
||||
/obj/machinery/hydroponics,
|
||||
/obj/machinery/constructable_frame,
|
||||
/obj/machinery/icemachine)
|
||||
/obj/machinery/icemachine,
|
||||
/obj/item/weapon/bombcore/chemical)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/New()
|
||||
..()
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
/obj/structure/reagent_dispensers/proc/boom()
|
||||
visible_message("<span class='danger'>[src] ruptures!</span>")
|
||||
chem_splash(loc, 5, list(reagents))
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/reagent_dispensers/ex_act(severity)
|
||||
@@ -53,15 +54,6 @@
|
||||
desc = "A water tank."
|
||||
icon_state = "water"
|
||||
|
||||
/obj/structure/reagent_dispensers/watertank/boom()
|
||||
playsound(loc, 'sound/effects/spray2.ogg', 50, 1, -6)
|
||||
new /obj/effect/effect/water(loc)
|
||||
for(var/turf/simulated/T in view(5, loc))
|
||||
T.MakeSlippery()
|
||||
for(var/mob/living/L in T)
|
||||
L.adjust_fire_stacks(-20)
|
||||
..()
|
||||
|
||||
/obj/structure/reagent_dispensers/watertank/high
|
||||
name = "high-capacity water tank"
|
||||
desc = "A highly-pressurized water tank made to hold gargantuan amounts of water.."
|
||||
|
||||
@@ -377,7 +377,7 @@
|
||||
found = 1
|
||||
break
|
||||
if(!found)
|
||||
to_chat(usr, "\icon[src]<span class=notice>The conveyor switch did not detect any linked conveyor belts in range.</span>")
|
||||
to_chat(usr, "<span class=notice>[bicon(src)] The conveyor switch did not detect any linked conveyor belts in range.</span>")
|
||||
return
|
||||
var/obj/machinery/conveyor_switch/NC = new/obj/machinery/conveyor_switch(A, id)
|
||||
transfer_fingerprints_to(NC)
|
||||
|
||||
@@ -1129,6 +1129,15 @@
|
||||
construction_time = 200
|
||||
category = list("Misc")
|
||||
|
||||
/datum/design/ipc_charger
|
||||
name = "IPC Charger"
|
||||
id = "ipc_cahrger"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/organ/internal/cyberimp/arm/power_cord
|
||||
materials = list(MAT_METAL=2000, MAT_GLASS=1000)
|
||||
construction_time = 200
|
||||
category = list("Misc")
|
||||
|
||||
/datum/design/ipc_optics
|
||||
name = "IPC Optical Sensor"
|
||||
id = "ipc_optics"
|
||||
|
||||
@@ -260,6 +260,28 @@
|
||||
build_path = /obj/item/organ/internal/cyberimp/eyes/shield
|
||||
category = list("Misc", "Medical")
|
||||
|
||||
/datum/design/cyberimp_breather
|
||||
name = "Breathing Tube Implant"
|
||||
desc = "This simple implant adds an internals connector to your back, allowing you to use internals without a mask and protecting you from being choked."
|
||||
id = "ci-breather"
|
||||
req_tech = list("materials" = 2, "biotech" = 3)
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
construction_time = 35
|
||||
materials = list(MAT_METAL = 600, MAT_GLASS = 250)
|
||||
build_path = /obj/item/organ/internal/cyberimp/mouth/breathing_tube
|
||||
category = list("Misc", "Medical")
|
||||
|
||||
/datum/design/cyberimp_toolset
|
||||
name = "Toolset Arm Implant"
|
||||
desc = "A stripped-down version of engineering cyborg toolset, designed to be installed on subject's arm."
|
||||
id = "ci-toolset"
|
||||
req_tech = list("materials" = 3, "engineering" = 4, "biotech" = 4, "powerstorage" = 4)
|
||||
build_type = PROTOLATHE | MECHFAB
|
||||
materials = list (MAT_METAL = 2500, MAT_GLASS = 1500, MAT_SILVER = 1500)
|
||||
construction_time = 200
|
||||
build_path = /obj/item/organ/internal/cyberimp/arm/toolset
|
||||
category = list("Misc", "Medical")
|
||||
|
||||
/datum/design/cyberimp_medical_hud
|
||||
name = "Medical HUD implant"
|
||||
desc = "These cybernetic eyes will display a medical HUD over everything you see. Wiggle eyes to control."
|
||||
|
||||
@@ -80,6 +80,36 @@
|
||||
build_path = /obj/item/weapon/grenade/chem_grenade/large
|
||||
category = list("Weapons")
|
||||
|
||||
/datum/design/pyro_grenade
|
||||
name = "Pyro Grenade"
|
||||
desc = "An advanced grenade that is able to self ignite its mixture."
|
||||
id = "pyro_Grenade"
|
||||
req_tech = list("combat" = 4, "engineering" = 4)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 2000, MAT_PLASMA = 500)
|
||||
build_path = /obj/item/weapon/grenade/chem_grenade/pyro
|
||||
category = list("Weapons")
|
||||
|
||||
/datum/design/cryo_grenade
|
||||
name = "Cryo Grenade"
|
||||
desc = "An advanced grenade that rapidly cools its contents upon detonation."
|
||||
id = "cryo_Grenade"
|
||||
req_tech = list("combat" = 3, "materials" = 3)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 2000, MAT_SILVER = 500)
|
||||
build_path = /obj/item/weapon/grenade/chem_grenade/cryo
|
||||
category = list("Weapons")
|
||||
|
||||
/datum/design/adv_grenade
|
||||
name = "Advanced Release Grenade"
|
||||
desc = "An advanced grenade that can be detonated several times, best used with a repeating igniter."
|
||||
id = "adv_Grenade"
|
||||
req_tech = list("combat" = 3, "engineering" = 4)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 3000, MAT_GLASS = 500)
|
||||
build_path = /obj/item/weapon/grenade/chem_grenade/adv_release
|
||||
category = list("Weapons")
|
||||
|
||||
/datum/design/tele_shield
|
||||
name = "Telescopic Riot Shield"
|
||||
desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
|
||||
|
||||
@@ -0,0 +1,315 @@
|
||||
/obj/item/organ/internal/cyberimp/arm
|
||||
name = "arm-mounted implant"
|
||||
desc = "You shouldn't see this! Adminhelp and report this as an issue on github!"
|
||||
parent_organ = "r_arm"
|
||||
slot = "r_arm_device"
|
||||
icon_state = "implant-toolkit"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
actions_types = list(/datum/action/item_action/organ_action/toggle)
|
||||
|
||||
var/list/items_list = list()
|
||||
// Used to store a list of all items inside, for multi-item implants.
|
||||
// I would use contents, but they shuffle on every activation/deactivation leading to interface inconsistencies.
|
||||
|
||||
var/obj/item/holder = null
|
||||
// You can use this var for item path, it would be converted into an item on New()
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/New()
|
||||
..()
|
||||
if(ispath(holder))
|
||||
holder = new holder(src)
|
||||
|
||||
update_icon()
|
||||
slot = parent_organ + "_device"
|
||||
items_list = contents.Copy()
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/update_icon()
|
||||
if(parent_organ == "r_arm")
|
||||
transform = null
|
||||
else // Mirroring the icon
|
||||
transform = matrix(-1, 0, 0, 0, 1, 0)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='info'>[src] is assembled in the [parent_organ == "r_arm" ? "right" : "left"] arm configuration. You can use a screwdriver to reassemble it.</span>")
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/attackby(obj/item/weapon/W, mob/user, params)
|
||||
..()
|
||||
if(isscrewdriver(W))
|
||||
if(parent_organ == "r_arm")
|
||||
parent_organ = "l_arm"
|
||||
else
|
||||
parent_organ = "r_arm"
|
||||
slot = parent_organ + "_device"
|
||||
to_chat(user, "<span class='notice'>You modify [src] to be installed on the [parent_organ == "r_arm" ? "right" : "left"] arm.</span>")
|
||||
update_icon()
|
||||
else if(istype(W, /obj/item/weapon/card/emag))
|
||||
emag_act()
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/remove(mob/living/carbon/M, special = 0)
|
||||
Retract()
|
||||
. = ..()
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/emag_act()
|
||||
return 0
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/gun/emp_act(severity)
|
||||
if(prob(15/severity) && owner)
|
||||
to_chat(owner, "<span class='warning'>[src] is hit by EMP!</span>")
|
||||
// give the owner an idea about why his implant is glitching
|
||||
Retract()
|
||||
..()
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/proc/Retract()
|
||||
if(!holder || (holder in src))
|
||||
return
|
||||
|
||||
owner.visible_message("<span class='notice'>[owner] retracts [holder] back into \his [parent_organ == "r_arm" ? "right" : "left"] arm.</span>",
|
||||
"<span class='notice'>[holder] snaps back into your [parent_organ == "r_arm" ? "right" : "left"] arm.</span>",
|
||||
"<span class='italics'>You hear a short mechanical noise.</span>")
|
||||
|
||||
if(istype(holder, /obj/item/device/flash/armimplant))
|
||||
var/obj/item/device/flash/F = holder
|
||||
F.set_light(0)
|
||||
|
||||
owner.unEquip(holder, 1)
|
||||
holder.forceMove(src)
|
||||
holder = null
|
||||
playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/proc/Extend(var/obj/item/item)
|
||||
if(!(item in src))
|
||||
return
|
||||
|
||||
|
||||
holder = item
|
||||
|
||||
holder.flags |= NODROP
|
||||
holder.unacidable = 1
|
||||
holder.slot_flags = null
|
||||
holder.w_class = WEIGHT_CLASS_HUGE
|
||||
holder.materials = null
|
||||
|
||||
if(istype(holder, /obj/item/device/flash/armimplant))
|
||||
var/obj/item/device/flash/F = holder
|
||||
F.set_light(7)
|
||||
|
||||
var/arm_slot = (parent_organ == "r_arm" ? slot_r_hand : slot_l_hand)
|
||||
var/obj/item/arm_item = owner.get_item_by_slot(arm_slot)
|
||||
|
||||
if(arm_item)
|
||||
if(!owner.unEquip(arm_item))
|
||||
to_chat(owner, "<span class='warning'>Your [arm_item] interferes with [src]!</span>")
|
||||
return
|
||||
else
|
||||
to_chat(owner, "<span class='notice'>You drop [arm_item] to activate [src]!</span>")
|
||||
|
||||
if(parent_organ == "r_arm" ? !owner.put_in_r_hand(holder) : !owner.put_in_l_hand(holder))
|
||||
to_chat(owner, "<span class='warning'>Your [src] fails to activate!</span>")
|
||||
return
|
||||
|
||||
// Activate the hand that now holds our item.
|
||||
if(parent_organ == "r_arm" ? owner.hand : !owner.hand)
|
||||
owner.swap_hand()
|
||||
|
||||
owner.visible_message("<span class='notice'>[owner] extends [holder] from \his [parent_organ == "r_arm" ? "right" : "left"] arm.</span>",
|
||||
"<span class='notice'>You extend [holder] from your [parent_organ == "r_arm" ? "right" : "left"] arm.</span>",
|
||||
"<span class='italics'>You hear a short mechanical noise.</span>")
|
||||
playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/ui_action_click()
|
||||
if(crit_fail || (!holder && !contents.len))
|
||||
to_chat(owner, "<span class='warning'>The implant doesn't respond. It seems to be broken...</span>")
|
||||
return
|
||||
|
||||
// You can emag the arm-mounted implant by activating it while holding emag in it's hand.
|
||||
var/arm_slot = (parent_organ == "r_arm" ? slot_r_hand : slot_l_hand)
|
||||
if(istype(owner.get_item_by_slot(arm_slot), /obj/item/weapon/card/emag) && emag_act())
|
||||
return
|
||||
|
||||
if(!holder || (holder in src))
|
||||
holder = null
|
||||
if(contents.len == 1)
|
||||
Extend(contents[1])
|
||||
else // TODO: make it similar to borg's storage-like module selection
|
||||
var/obj/item/choise = input("Activate which item?", "Arm Implant", null, null) as null|anything in items_list
|
||||
if(owner && owner == usr && owner.stat != DEAD && (src in owner.internal_organs) && !holder && istype(choise) && (choise in contents))
|
||||
// This monster sanity check is a nice example of how bad input() is.
|
||||
Extend(choise)
|
||||
else
|
||||
Retract()
|
||||
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/gun/emp_act(severity)
|
||||
if(prob(30/severity) && owner && !crit_fail)
|
||||
Retract()
|
||||
owner.visible_message("<span class='danger'>A loud bang comes from [owner]\'s [parent_organ == "r_arm" ? "right" : "left"] arm!</span>")
|
||||
playsound(get_turf(owner), 'sound/weapons/flashbang.ogg', 100, 1)
|
||||
to_chat(owner, "<span class='userdanger'>You feel an explosion erupt inside your [parent_organ == "r_arm" ? "right" : "left"] arm as your implant breaks!</span>")
|
||||
owner.adjust_fire_stacks(20)
|
||||
owner.IgniteMob()
|
||||
owner.adjustFireLoss(25)
|
||||
crit_fail = 1
|
||||
else // The gun will still discharge anyway.
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/gun/laser
|
||||
name = "arm-mounted laser implant"
|
||||
desc = "A variant of the arm cannon implant that fires lethal laser beams. The cannon emerges from the subject's arm and remains inside when not in use."
|
||||
icon_state = "arm_laser"
|
||||
origin_tech = "materials=4;combat=4;biotech=4;powerstorage=4;syndicate=3"
|
||||
contents = newlist(/obj/item/weapon/gun/energy/laser/mounted)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/gun/laser/l
|
||||
parent_organ = "l_arm"
|
||||
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/gun/taser
|
||||
name = "arm-mounted taser implant"
|
||||
desc = "A variant of the arm cannon implant that fires electrodes and disabler shots. The cannon emerges from the subject's arm and remains inside when not in use."
|
||||
icon_state = "arm_taser"
|
||||
origin_tech = "materials=5;combat=5;biotech=4;powerstorage=4"
|
||||
contents = newlist(/obj/item/weapon/gun/energy/gun/advtaser/mounted)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/gun/taser/l
|
||||
parent_organ = "l_arm"
|
||||
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/toolset
|
||||
name = "integrated toolset implant"
|
||||
desc = "A stripped-down version of engineering cyborg toolset, designed to be installed on subject's arm. Contains all neccessary tools."
|
||||
origin_tech = "materials=3;engineering=4;biotech=3;powerstorage=4"
|
||||
contents = newlist(/obj/item/weapon/screwdriver/cyborg, /obj/item/weapon/wrench/cyborg, /obj/item/weapon/weldingtool/largetank/cyborg,
|
||||
/obj/item/weapon/crowbar/cyborg, /obj/item/weapon/wirecutters/cyborg, /obj/item/device/multitool/cyborg)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/toolset/l
|
||||
parent_organ = "l_arm"
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/toolset/emag_act()
|
||||
if(!(locate(/obj/item/weapon/kitchen/knife/combat/cyborg) in items_list))
|
||||
to_chat(usr, "<span class='notice'>You unlock [src]'s integrated knife!</span>")
|
||||
items_list += new /obj/item/weapon/kitchen/knife/combat/cyborg(src)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/esword
|
||||
name = "arm-mounted energy blade"
|
||||
desc = "An illegal, and highly dangerous cybernetic implant that can project a deadly blade of concentrated enregy."
|
||||
contents = newlist(/obj/item/weapon/melee/energy/blade/hardlight)
|
||||
origin_tech = "materials=4;combat=5;biotech=3;powerstorage=2;syndicate=5"
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/medibeam
|
||||
name = "integrated medical beamgun"
|
||||
desc = "A cybernetic implant that allows the user to project a healing beam from their hand."
|
||||
contents = newlist(/obj/item/weapon/gun/medbeam)
|
||||
origin_tech = "materials=5;combat=2;biotech=5;powerstorage=4;syndicate=1"
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/flash
|
||||
name = "integrated high-intensity photon projector" //Why not
|
||||
desc = "An integrated projector mounted onto a user's arm, that is able to be used as a powerful flash."
|
||||
contents = newlist(/obj/item/device/flash/armimplant)
|
||||
origin_tech = "materials=4;combat=3;biotech=4;magnets=4;powerstorage=3"
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/flash/New()
|
||||
..()
|
||||
if(locate(/obj/item/device/flash/armimplant) in items_list)
|
||||
var/obj/item/device/flash/armimplant/F = locate(/obj/item/device/flash/armimplant) in items_list
|
||||
F.I = src
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/baton
|
||||
name = "arm electrification implant"
|
||||
desc = "An illegal combat implant that allows the user to administer disabling shocks from their arm."
|
||||
contents = newlist(/obj/item/borg/stun)
|
||||
origin_tech = "materials=3;combat=5;biotech=4;powerstorage=4;syndicate=3"
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/combat
|
||||
name = "combat cybernetics implant"
|
||||
desc = "A powerful cybernetic implant that contains combat modules built into the user's arm"
|
||||
contents = newlist(/obj/item/weapon/melee/energy/blade/hardlight, /obj/item/weapon/gun/medbeam, /obj/item/borg/stun, /obj/item/device/flash/armimplant)
|
||||
origin_tech = "materials=5;combat=7;biotech=5;powerstorage=5;syndicate=6;programming=5"
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/combat/New()
|
||||
..()
|
||||
if(locate(/obj/item/device/flash/armimplant) in items_list)
|
||||
var/obj/item/device/flash/armimplant/F = locate(/obj/item/device/flash/armimplant) in items_list
|
||||
F.I = src
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/surgery
|
||||
name = "surgical toolset implant"
|
||||
desc = "A set of surgical tools hidden behind a concealed panel on the user's arm"
|
||||
contents = newlist(/obj/item/weapon/retractor, /obj/item/weapon/hemostat, /obj/item/weapon/cautery, /obj/item/weapon/surgicaldrill, /obj/item/weapon/scalpel, /obj/item/weapon/circular_saw, /obj/item/weapon/bonegel, /obj/item/weapon/FixOVein, /obj/item/weapon/bonesetter)
|
||||
origin_tech = "materials=3;engineering=3;biotech=3;programming=2;magnets=3"
|
||||
|
||||
// lets make IPCs even *more* vulnerable to EMPs!
|
||||
/obj/item/organ/internal/cyberimp/arm/power_cord
|
||||
name = "APC-compatible power adapter implant"
|
||||
desc = "An implant commonly installed inside IPCs in order to allow them to easily collect energy from their environment"
|
||||
origin_tech = "materials=3;biotech=2;powerstorage=3"
|
||||
contents = newlist(/obj/item/apc_powercord)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/power_cord/emp_act(severity)
|
||||
// To allow repair via nanopaste/screwdriver
|
||||
// also so IPCs don't also catch on fire and fall even more apart upon EMP
|
||||
damage = 1
|
||||
crit_fail = TRUE
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/power_cord/surgeryize()
|
||||
if(crit_fail && owner)
|
||||
to_chat(owner, "<span class='notice'>Your [src] feels functional again.</span>")
|
||||
crit_fail = FALSE
|
||||
|
||||
|
||||
/obj/item/apc_powercord
|
||||
name = "power cable"
|
||||
desc = "Insert into a nearby APC to draw power from it."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "wire1"
|
||||
flags = NOBLUDGEON
|
||||
|
||||
/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
if(!istype(target, /obj/machinery/power/apc) || !ishuman(user) || !proximity_flag)
|
||||
return ..()
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
var/obj/machinery/power/apc/A = target
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.get_int_organ(/obj/item/organ/internal/cell))
|
||||
if(A.emagged || A.stat & BROKEN)
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, A)
|
||||
s.start()
|
||||
to_chat(H, "<span class='warning'>The APC power currents surge erratically, damaging your chassis!</span>")
|
||||
H.adjustFireLoss(10,0)
|
||||
else if(A.cell && A.cell.charge > 0)
|
||||
if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
|
||||
to_chat(user, "<span class='warning'>You are already fully charged!</span>")
|
||||
else
|
||||
addtimer(src, "powerdraw_loop", 0, TRUE, A, H)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There is no charge to draw from that APC.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You lack a cell in which to store charge!</span>")
|
||||
|
||||
/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H)
|
||||
H.visible_message("<span class='notice'>[H] inserts a power connector into \the [A].</span>", "<span class='notice'>You begin to draw power from \the [A].</span>")
|
||||
while(do_after(H, 10, target = A))
|
||||
if(loc != H)
|
||||
to_chat(H, "<span class='warning'>You must keep your connector out while charging!</span>")
|
||||
break
|
||||
if(A.cell.charge == 0)
|
||||
to_chat(H, "<span class='warning'>\The [A] has no more charge.</span>")
|
||||
break
|
||||
A.charging = 1
|
||||
if(A.cell.charge >= 500)
|
||||
H.nutrition += 50
|
||||
A.cell.charge -= 500
|
||||
to_chat(H, "<span class='notice'>You siphon off some of the stored charge for your own use.</span>")
|
||||
else
|
||||
H.nutrition += A.cell.charge/10
|
||||
A.cell.charge = 0
|
||||
to_chat(H, "<span class='notice'>You siphon off the last of \the [A]'s charge.</span>")
|
||||
break
|
||||
if(H.nutrition > NUTRITION_LEVEL_WELL_FED)
|
||||
to_chat(H, "<span class='notice'>You are now fully charged.</span>")
|
||||
break
|
||||
H.visible_message("<span class='notice'>[H] unplugs from \the [A].</span>", "<span class='notice'>You unplug from \the [A].</span>")
|
||||
@@ -144,6 +144,24 @@
|
||||
spawn(90 / severity)
|
||||
crit_fail = 0
|
||||
|
||||
|
||||
//[[[[MOUTH]]]]
|
||||
/obj/item/organ/internal/cyberimp/mouth
|
||||
parent_organ = "mouth"
|
||||
|
||||
/obj/item/organ/internal/cyberimp/mouth/breathing_tube
|
||||
name = "breathing tube implant"
|
||||
desc = "This simple implant adds an internals connector to your back, allowing you to use internals without a mask and protecting you from being choked."
|
||||
icon_state = "implant_mask"
|
||||
slot = "breathing_tube"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
origin_tech = "materials=2;biotech=3"
|
||||
|
||||
/obj/item/organ/internal/cyberimp/mouth/breathing_tube/emp_act(severity)
|
||||
if(prob(60/severity) && owner)
|
||||
to_chat(owner, "<span class='warning'>Your breathing tube suddenly closes!</span>")
|
||||
owner.AdjustLoseBreath(2)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/brain/clown_voice
|
||||
name = "Comical implant"
|
||||
desc = "<span class='sans'>Uh oh.</span>"
|
||||
@@ -255,175 +273,6 @@
|
||||
if(H.stat == CONSCIOUS)
|
||||
to_chat(H, "<span class='notice'>You feel your heart beating again!</span>")
|
||||
|
||||
//ARM...THAT GO IN THE CHEST
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod//dummy parent item for making arm-mod implants. works best with nodrop items that are sent to nullspace upon being dropped.
|
||||
name = "Arm-mounted item implant"
|
||||
desc = "You shouldn't see this! Adminhelp and report this as an issue on github!"
|
||||
icon_state = "chest_implant"
|
||||
implant_color = "#007ACC"
|
||||
slot = "shoulders"
|
||||
origin_tech = "materials=5;biotech=4;powerstorage=4"
|
||||
actions_types = list(/datum/action/item_action/organ_action/toggle)
|
||||
var/obj/holder//is defined as the retractable item itself. ensure this is defined somewhere!
|
||||
var/out = 0//determines if the item is in the owner's hand or not
|
||||
var/overloaded = 0//is set to 1 when owner gets EMPed. if set to 1, implant doesn't work.
|
||||
var/lasthand = null
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod/ui_action_click()
|
||||
toggle_item()
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod/proc/toggle_item()
|
||||
if(overloaded)//ensure the implant isn't broken
|
||||
to_chat(owner, "<span class='warning'>The implant doesn't respond. It seems to be broken...</span>")
|
||||
return
|
||||
owner.changeNext_move(CLICK_CD_MELEE)
|
||||
if(owner.next_move < world.time)
|
||||
return // No spam
|
||||
if(out)//check if the owner has the item out already
|
||||
owner.unEquip(holder, 1)//if he does, take it away. then,
|
||||
holder.loc = null//stash it in nullspace
|
||||
out = 0//and set this to clarify the item isn't out.
|
||||
owner.visible_message("<span class='notice'>[owner] retracts [holder].</span>","<span class='notice'>You retract [holder].</span>")
|
||||
playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
|
||||
else//if he doesn't have the item out
|
||||
if(owner.put_in_hands(holder))//put it in his hands.
|
||||
lasthand = owner.get_active_hand()
|
||||
out = 1
|
||||
owner.visible_message("<span class='notice'>[owner] extends [holder]!</span>","<span class='notice'>You extend [holder]!</span>")
|
||||
playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
|
||||
else//if this fails to put the item in his hands,
|
||||
holder.loc = null//keep it in nullspace
|
||||
to_chat(owner, "<span class='warning'>You can't extend [holder] if you can't use your hands!</span>")
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod/emp_act(severity)//if the implant gets EMPed...
|
||||
if(!owner || overloaded)//ensure that it's in an owner and that it's not already EMPed, then...
|
||||
return
|
||||
if(out)//check if he has the item out...
|
||||
owner.unEquip(holder, 1)//if he does, take it away.
|
||||
holder.loc = null
|
||||
out = 0
|
||||
owner.visible_message("<span class='notice'>[holder] forcibly retracts into [owner]'s arm.</span>")
|
||||
overload() // Make sure this doesn't happen again
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod/proc/overload()
|
||||
owner.visible_message("<span class='danger'>A loud bang comes from [owner]...</span>")
|
||||
playsound(get_turf(owner), 'sound/effects/bang.ogg', 100, 1)
|
||||
to_chat(owner, "<span class='warning'>You feel an explosion erupt inside you as your chest implant breaks. Is it hot in here?</span>")
|
||||
owner.adjust_fire_stacks(20)
|
||||
owner.IgniteMob()//ignite the owner, as well as
|
||||
owner.say("AUUUUUUUUUUUUUUUUUUGH!!")
|
||||
if(prob(50))
|
||||
if(lasthand == "r_hand")
|
||||
var/obj/item/organ/external/limb = owner.get_organ("r_arm")
|
||||
limb.droplimb(0, DROPLIMB_EDGE)
|
||||
else if(lasthand == "l_hand")
|
||||
var/obj/item/organ/external/limb = owner.get_organ("l_arm")
|
||||
limb.droplimb(0, DROPLIMB_EDGE)
|
||||
owner.say("I HAVE BEEN DISARMED!!!")
|
||||
owner.adjustFireLoss(25)//severely injure him!
|
||||
overloaded = TRUE
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod/tase//mounted, self-charging taser!
|
||||
name = "Arm-cannon taser implant"
|
||||
desc = "A variant of the arm cannon implant that fires electrodes and disabler shots. The cannon emerges from the subject's arms and remains in the shoulders when not in use."
|
||||
icon_state = "armcannon_tase_implant"
|
||||
origin_tech = "materials=5;combat=5;biotech=4;powerstorage=4"
|
||||
actions_types = list(/datum/action/item_action/organ_action/toggle)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod/tase/New()//when the implant is created...
|
||||
..()
|
||||
holder = new /obj/item/weapon/gun/energy/gun/advtaser/mounted(src)//assign a brand new item to it. (in this case, a gun)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod/lase//mounted, self-charging laser!
|
||||
name = "Arm-cannon laser implant"
|
||||
desc = "A variant of the arm cannon implant that fires lethal laser beams. The cannon emerges from the subject's arms and remains in the shoulders when not in use."
|
||||
icon_state = "armcannon_lase_implant"
|
||||
origin_tech = "materials=4;combat=4;biotech=4;powerstorage=4;syndicate=3"
|
||||
actions_types = list(/datum/action/item_action/organ_action/toggle)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod/lase/New()
|
||||
..()
|
||||
holder = new /obj/item/weapon/gun/energy/laser/mounted(src)
|
||||
|
||||
// lets make IPCs even *more* vulnerable to EMPs!
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord
|
||||
name = "APC-compatible power adapter implant"
|
||||
desc = "An implant commonly installed inside IPCs in order to allow them to easily collect energy from their environment"
|
||||
origin_tech = "materials=3;biotech=2;powerstorage=3"
|
||||
slot = "shoulders2"
|
||||
actions_types = list(/datum/action/item_action/organ_action/toggle)
|
||||
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord/New()
|
||||
..()
|
||||
holder = new /obj/item/apc_powercord(src)
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord/overload()
|
||||
// To allow repair via nanopaste/screwdriver
|
||||
// also so IPCs don't also catch on fire and fall even more apart upon EMP
|
||||
damage = 1
|
||||
overloaded = TRUE
|
||||
|
||||
/obj/item/organ/internal/cyberimp/chest/arm_mod/power_cord/surgeryize()
|
||||
if(overloaded && owner)
|
||||
to_chat(owner, "<span class='notice'>Your [src] feels functional again.</span>")
|
||||
overloaded = FALSE
|
||||
|
||||
|
||||
/obj/item/apc_powercord
|
||||
name = "power cable"
|
||||
desc = "Insert into a nearby APC to draw power from it."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "wire1"
|
||||
flags = NODROP | NOBLUDGEON
|
||||
|
||||
/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
if(!istype(target, /obj/machinery/power/apc) || !ishuman(user) || !proximity_flag)
|
||||
return ..()
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
var/obj/machinery/power/apc/A = target
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.get_int_organ(/obj/item/organ/internal/cell))
|
||||
if(A.emagged || A.stat & BROKEN)
|
||||
var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
|
||||
s.set_up(3, 1, A)
|
||||
s.start()
|
||||
to_chat(H, "<span class='warning'>The APC power currents surge erratically, damaging your chassis!</span>")
|
||||
H.adjustFireLoss(10,0)
|
||||
else if(A.cell && A.cell.charge > 0)
|
||||
if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
|
||||
to_chat(user, "<span class='warning'>You are already fully charged!</span>")
|
||||
else
|
||||
addtimer(src, "powerdraw_loop", 0, TRUE, A, H)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There is no charge to draw from that APC.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You lack a cell in which to store charge!</span>")
|
||||
|
||||
/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/A, mob/living/carbon/human/H)
|
||||
H.visible_message("<span class='notice'>[H] inserts a power connector into \the [A].</span>", "<span class='notice'>You begin to draw power from \the [A].</span>")
|
||||
while(do_after(H, 10, target = A))
|
||||
if(loc != H)
|
||||
to_chat(H, "<span class='warning'>You must keep your connector out while charging!</span>")
|
||||
break
|
||||
if(A.cell.charge == 0)
|
||||
to_chat(H, "<span class='warning'>\The [A] has no more charge.</span>")
|
||||
break
|
||||
A.charging = 1
|
||||
if(A.cell.charge >= 500)
|
||||
H.nutrition += 50
|
||||
A.cell.charge -= 500
|
||||
to_chat(H, "<span class='notice'>You siphon off some of the stored charge for your own use.</span>")
|
||||
else
|
||||
H.nutrition += A.cell.charge/10
|
||||
A.cell.charge = 0
|
||||
to_chat(H, "<span class='notice'>You siphon off the last of \the [A]'s charge.</span>")
|
||||
break
|
||||
if(H.nutrition > NUTRITION_LEVEL_WELL_FED)
|
||||
to_chat(H, "<span class='notice'>You are now fully charged.</span>")
|
||||
break
|
||||
H.visible_message("<span class='notice'>[H] unplugs from \the [A].</span>", "<span class='notice'>You unplug from \the [A].</span>")
|
||||
|
||||
//BOX O' IMPLANTS
|
||||
|
||||
/obj/item/weapon/storage/box/cyber_implants
|
||||
|
||||
@@ -30,9 +30,7 @@
|
||||
return returnorg
|
||||
|
||||
/mob/living/carbon/get_organ_slot(slot)
|
||||
for(var/obj/item/organ/internal/O in internal_organs)
|
||||
if(slot == O.slot)
|
||||
return O
|
||||
return internal_organs_slot[slot]
|
||||
|
||||
/mob/living/carbon/get_int_organ_tag(tag)
|
||||
for(var/obj/item/organ/internal/O in internal_organs)
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
force = 1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
throwforce = 0
|
||||
var/zone = "chest"
|
||||
var/slot
|
||||
// DO NOT add slots with matching names to different zones - it will break internal_organs_slot list!
|
||||
vital = 0
|
||||
var/non_primary = 0
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
owner = M
|
||||
|
||||
M.internal_organs |= src
|
||||
M.internal_organs_slot[slot] = src
|
||||
var/obj/item/organ/external/parent
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
@@ -52,6 +53,8 @@
|
||||
owner = null
|
||||
if(M)
|
||||
M.internal_organs -= src
|
||||
if(M.internal_organs_slot[slot] == src)
|
||||
M.internal_organs_slot.Remove(slot)
|
||||
if(vital && !special)
|
||||
if(M.stat != DEAD)//safety check!
|
||||
M.death()
|
||||
|
||||
@@ -38,7 +38,6 @@ var/static/regex/multispin_words = regex("like a record baby")
|
||||
/obj/item/organ/internal/vocal_cords //organs that are activated through speech with the :x channel
|
||||
name = "vocal cords"
|
||||
icon_state = "appendix"
|
||||
zone = "mouth"
|
||||
slot = "vocal_cords"
|
||||
parent_organ = "mouth"
|
||||
var/spans = null
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
/datum/surgery/organ_manipulation_boneless
|
||||
name = "Organ Manipulation"
|
||||
possible_locs = list("chest","head","groin", "eyes", "mouth")
|
||||
possible_locs = list("chest","head","groin", "eyes", "mouth", "l_arm", "r_arm")
|
||||
steps = list(/datum/surgery_step/generic/cut_open,/datum/surgery_step/generic/clamp_bleeders, /datum/surgery_step/generic/retract_skin, /datum/surgery_step/internal/manipulate_organs,/datum/surgery_step/generic/cauterize)
|
||||
requires_organic_bodypart = 1
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
/datum/surgery/cybernetic_repair/internal
|
||||
name = "Internal Component Manipulation"
|
||||
steps = list(/datum/surgery_step/robotics/external/unscrew_hatch,/datum/surgery_step/robotics/external/open_hatch,/datum/surgery_step/robotics/manipulate_robotic_organs)
|
||||
possible_locs = list("eyes", "chest","head","groin")
|
||||
possible_locs = list("eyes", "chest","head","groin","l_arm","r_arm")
|
||||
requires_organic_bodypart = 0
|
||||
|
||||
/datum/surgery/cybernetic_amputation
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<div align='center'><font size='3'><b>Paradise Station</b></font></div>
|
||||
|
||||
<p><div align='center'><font size='3'><a href="http://nanotrasen.se/phpBB3/index.php">Forum</a> | <a href="http://nanotrasen.se/wiki/index.php/Main_Page">Wiki</a> | <a href="https://github.com/ParadiseSS13/Paradise">Source</a></font></div></p>
|
||||
<font size='2'><b>Visit our IRC channel:</b> #crew on neko.sneeza.me</font>
|
||||
<font size='2'><b>Visit our Discord channel:</b><a href='https://discordapp.com/invite/nuqD478<'>-Click Here-</a></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -55,6 +55,59 @@
|
||||
|
||||
-->
|
||||
<div class="commit sansserif">
|
||||
|
||||
<h2 class="date">04 July 2017</h2>
|
||||
<h3 class="author">Birdtalon updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Traitor medical chemists can now access syndicate poison bottles.</li>
|
||||
</ul>
|
||||
<h3 class="author">Citinited updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">AIs and cyborgs can now toggle liquid dispensers by ctrl-clicking them, and can make them dispense foam by alt-clicking.</li>
|
||||
</ul>
|
||||
<h3 class="author">Citinited & LightFire53 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Adds the plasmaman coroner suit, the plasmaman geneticist suit, and the plasmaman virologist suit. Spooky purple skeletons everywhere rejoice!</li>
|
||||
</ul>
|
||||
<h3 class="author">Fethas updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Adds medical gowns to medical wardrobes.</li>
|
||||
</ul>
|
||||
<h3 class="author">Fox McCloud updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Syndicate bombs now have visible timers for observers</li>
|
||||
<li class="rscadd">Syndicate bombs tick more often</li>
|
||||
<li class="rscadd">Syndnicate bombs can be deconstructed into plasteel if it is fully defused and has no bomb core</li>
|
||||
<li class="rscadd">Can make Cryo, Pyro, and time released chemical grenades at R&D</li>
|
||||
<li class="rscadd">Can make syndicate chemical bombs utilizing crafting</li>
|
||||
<li class="tweak">love just got more powerful; it now prevents a mob from being on anything other than help intent</li>
|
||||
<li class="tweak">IPCs can now process the love reagent</li>
|
||||
<li class="rscadd">Adds in radio jammers to the traitor uplink</li>
|
||||
</ul>
|
||||
<h3 class="author">Ionward updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Greys now have properly fitting sprites for most head clothing items!</li>
|
||||
</ul>
|
||||
<h3 class="author">Kyep updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Gimmick Teams are now more configurable.</li>
|
||||
</ul>
|
||||
<h3 class="author">Vivalas updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">"Tweaks" SecHUDs to only display criminal status of people if their face is uncovered or they have no ID.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">03 July 2017</h2>
|
||||
<h3 class="author">Fethas updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">fixes issue with hand teleporter not working in active hands</li>
|
||||
</ul>
|
||||
<h3 class="author">fludd12 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Greys are now PROPERLY immune to sulfuric acid.</li>
|
||||
<li class="bugfix">Greys don't pretend to touch their heads when they don't manage to anymore.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">01 July 2017</h2>
|
||||
<h3 class="author">Fox McCloud updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
|
||||
@@ -5084,3 +5084,38 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
|
||||
than before
|
||||
- rscadd: Adds in throwing stars kit to the traitor uplink
|
||||
- rscdel: bullets no longer leave shrapnel
|
||||
2017-07-03:
|
||||
Fethas:
|
||||
- bugfix: fixes issue with hand teleporter not working in active hands
|
||||
fludd12:
|
||||
- bugfix: Greys are now PROPERLY immune to sulfuric acid.
|
||||
- bugfix: Greys don't pretend to touch their heads when they don't manage to anymore.
|
||||
2017-07-04:
|
||||
Birdtalon:
|
||||
- tweak: Traitor medical chemists can now access syndicate poison bottles.
|
||||
Citinited:
|
||||
- tweak: AIs and cyborgs can now toggle liquid dispensers by ctrl-clicking them,
|
||||
and can make them dispense foam by alt-clicking.
|
||||
Citinited & LightFire53:
|
||||
- rscadd: Adds the plasmaman coroner suit, the plasmaman geneticist suit, and the
|
||||
plasmaman virologist suit. Spooky purple skeletons everywhere rejoice!
|
||||
Fethas:
|
||||
- rscadd: Adds medical gowns to medical wardrobes.
|
||||
Fox McCloud:
|
||||
- rscadd: Syndicate bombs now have visible timers for observers
|
||||
- rscadd: Syndicate bombs tick more often
|
||||
- rscadd: Syndnicate bombs can be deconstructed into plasteel if it is fully defused
|
||||
and has no bomb core
|
||||
- rscadd: Can make Cryo, Pyro, and time released chemical grenades at R&D
|
||||
- rscadd: Can make syndicate chemical bombs utilizing crafting
|
||||
- tweak: love just got more powerful; it now prevents a mob from being on anything
|
||||
other than help intent
|
||||
- tweak: IPCs can now process the love reagent
|
||||
- rscadd: Adds in radio jammers to the traitor uplink
|
||||
Ionward:
|
||||
- bugfix: Greys now have properly fitting sprites for most head clothing items!
|
||||
Kyep:
|
||||
- tweak: Gimmick Teams are now more configurable.
|
||||
Vivalas:
|
||||
- bugfix: '"Tweaks" SecHUDs to only display criminal status of people if their face
|
||||
is uncovered or they have no ID.'
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
author: "Fox McCloud"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Adds in breathing tube augment to R&D"
|
||||
- rscadd: "Adds in arm toolset augment to R&D"
|
||||
- tweak: "IPC cell charging device is now inside their right arm, as opposed to chest"
|
||||
- rscadd: "IPC cell charging device can now be produced in mech fabricators"
|
||||
@@ -26,7 +26,7 @@
|
||||
<div align='center'><font size='3'><b>Paradise Station</b></font></div>
|
||||
|
||||
<p><div align='center'><font size='3'><a href="http://nanotrasen.se/phpBB3/index.php">Forum</a> | <a href="http://nanotrasen.se/wiki/index.php/Main_Page">Wiki</a> | <a href="https://github.com/ParadiseSS13/Paradise">Source</a></font></div></p>
|
||||
<font size='2'><b>Visit our IRC channel:</b> #crew on neko.sneeza.me</font>
|
||||
<font size='2'><b>Visit our Discord channel:</b><a href='https://discordapp.com/invite/nuqD478<'>-Click Here-</a></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -54,4 +54,4 @@
|
||||
*** DO NOT FUCK WITH THIS FILE OR YOU WILL CAUSE MERGE CONFLICTS. ***
|
||||
|
||||
-->
|
||||
<div class="commit sansserif">
|
||||
<div class="commit sansserif">
|
||||
|
||||
|
Before Width: | Height: | Size: 187 KiB After Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 184 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 326 KiB After Width: | Height: | Size: 326 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 254 KiB After Width: | Height: | Size: 254 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 286 KiB After Width: | Height: | Size: 287 KiB |
|
Before Width: | Height: | Size: 348 KiB After Width: | Height: | Size: 348 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 62 KiB |
@@ -1948,6 +1948,7 @@
|
||||
#include "code\modules\projectiles\projectile\magic.dm"
|
||||
#include "code\modules\projectiles\projectile\reusable.dm"
|
||||
#include "code\modules\projectiles\projectile\special.dm"
|
||||
#include "code\modules\reagents\chem_splash.dm"
|
||||
#include "code\modules\reagents\reagent_containers.dm"
|
||||
#include "code\modules\reagents\reagent_dispenser.dm"
|
||||
#include "code\modules\reagents\chemistry\colors.dm"
|
||||
@@ -2150,6 +2151,7 @@
|
||||
#include "code\modules\surgery\slime.dm"
|
||||
#include "code\modules\surgery\surgery.dm"
|
||||
#include "code\modules\surgery\tools.dm"
|
||||
#include "code\modules\surgery\organs\augments_arms.dm"
|
||||
#include "code\modules\surgery\organs\augments_eyes.dm"
|
||||
#include "code\modules\surgery\organs\augments_internal.dm"
|
||||
#include "code\modules\surgery\organs\autoimplanter.dm"
|
||||
|
||||