diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm
index 56e1c53b51..90c5524f92 100644
--- a/code/game/jobs/access.dm
+++ b/code/game/jobs/access.dm
@@ -510,7 +510,7 @@
jobName = src:assignment
realJobName = src:assignment_real_title
- if(realJobName in get_all_jobs())
+ if( (realJobName in get_all_jobs()) || (jobName in get_all_jobs()) )
return jobName
return "Unknown"
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index c678740235..f381a96fed 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -407,7 +407,7 @@ steam.start() -- spawns the effect
/obj/effect/effect/chem_smoke/Move()
..()
- for(var/atom/A in view(1, src))
+ for(var/atom/A in view(2, src))
if(reagents.has_reagent("radium")||reagents.has_reagent("uranium")||reagents.has_reagent("carbon")||reagents.has_reagent("thermite"))//Prevents unholy radium spam by reducing the number of 'greenglows' down to something reasonable -Sieve
if(prob(5))
reagents.reaction(A)
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index ce4e4f2ce6..f053e0f4f4 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -1,148 +1,269 @@
/obj/item/weapon/grenade/chem_grenade
name = "Grenade Casing"
icon_state = "chemg"
+ icon = 'chemical.dmi'
item_state = "flashbang"
- desc = "A hand made chemical grenade."
w_class = 2.0
force = 2.0
- var/stage = 0
+ var/list/beakers = list()
+ var/obj/item/device/assembly/attached_device
+ var/exploding = 0
var/state = 0
var/path = 0
- var/obj/item/device/assembly_holder/detonator = null
- var/list/beakers = new/list()
- var/list/allowed_containers = list(/obj/item/weapon/reagent_containers/glass/beaker, /obj/item/weapon/reagent_containers/glass/bottle)
+ var/motion = 0
+ var/direct = "SOUTH"
+ var/obj/item/weapon/circuitboard/circuit = null
+ var/list/allowed_containers = list("/obj/item/weapon/reagent_containers/glass/beaker", "/obj/item/weapon/reagent_containers/glass/dispenser", "/obj/item/weapon/reagent_containers/glass/bottle")
var/affected_area = 3
+ var/mob/attacher = "Unknown"
+ throw_speed = 4
+ throw_range = 20
+ flags = FPRINT | TABLEPASS | CONDUCT | USEDELAY
+ slot_flags = SLOT_BELT
- New()
- var/datum/reagents/R = new/datum/reagents(1000)
- reagents = R
- R.my_atom = src
+ attackby(var/obj/item/weapon/W, var/mob/user)
+ if(path || !active)
+ switch(active)
+ if(0)
+ if(istype(W, /obj/item/device/assembly/igniter))
+ active = 1
+ icon_state = initial(icon_state) +"_ass"
+ name = "unsecured grenade"
+ path = 1
+ del(W)
+ if(1)
+ if(istype(W, /obj/item/weapon/reagent_containers/glass))
+ if(beakers.len == 2)
+ user << "\red There are already two beakers inside, remove one first!"
+ return
- attack_self(mob/user as mob)
- if(!stage || stage==1)
- if(detonator)
-// detonator.loc=src.loc
- detonator.detached()
- usr.put_in_hands(detonator)
- detonator=null
- stage=0
- icon_state = initial(icon_state)
- else if(beakers.len)
- for(var/obj/B in beakers)
- if(istype(B))
- beakers -= B
- user.put_in_hands(B)
- name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
- if(stage > 1 && !active && clown_check(user))
- user << "You prime \the [name]!"
+ beakers |= W
+ user.drop_item()
+ W.loc = src
+ user << "\blue You insert the beaker into the casing."
- log_attack("[user.name] ([user.ckey]) primed \a [src].")
- log_admin("ATTACK: [user] ([user.ckey]) primed \a [src].")
- message_admins("ATTACK: [user] ([user.ckey]) primed \a [src].")
+ else if(istype(W, /obj/item/device/assembly/signaler) || istype(W, /obj/item/device/assembly/timer) || istype(W, /obj/item/device/assembly/infra) || istype(W, /obj/item/device/assembly/prox_sensor))
+ if(attached_device)
+ user << "\red There is already an device attached to the controls, remove it first!"
+ return
- activate()
- add_fingerprint(user)
- if(iscarbon(user))
- var/mob/living/carbon/C = user
- C.throw_mode_on()
+ attached_device = W
+ user.drop_item()
+ W.loc = src
+ user << "\blue You attach the [W] to the grenade controls!"
+ W.master = src
+ bombers += "[key_name(user)] attached a [W] to a grenade casing."
+ message_admins("[key_name_admin(user)] attached a [W] to a grenade casing.")
+ log_game("[key_name_admin(user)] attached a [W] to a grenade casing.")
+ attacher = key_name(user)
- attackby(obj/item/weapon/W as obj, mob/user as mob)
+ else if(istype(W, /obj/item/weapon/screwdriver))
+ if(beakers.len == 2 && attached_device)
+ user << "\blue You lock the assembly."
+ playsound(src.loc, 'Screwdriver.ogg', 25, -3)
+ name = "grenade"
+ icon_state = initial(icon_state) + "_locked"
+ active = 2
+ path = 1
+ else
+ user << "\red You need to add all components before locking the assembly."
+ if(2)
+ if(istype(W, /obj/item/weapon/screwdriver))
+ user << "\blue You disarm the [src]!"
+ playsound(src.loc, 'Screwdriver.ogg', 25, -3)
+ name = "grenade casing"
+ icon_state = initial(icon_state) +"_ass"
+ active = 1
+ path = 1
- if(istype(W,/obj/item/device/assembly_holder) && (!stage || stage==1) && path != 2)
- var/obj/item/device/assembly_holder/det = W
- if(istype(det.a_left,det.a_right.type) || (!isigniter(det.a_left) && !isigniter(det.a_right)))
- user << "\red Assembly must contain one igniter."
- return
- if(!det.secured)
- user << "\red Assembly must be secured with screwdriver."
- return
- path = 1
- user << "\blue You add [W] to the metal casing."
- playsound(src.loc, 'sound/items/Screwdriver2.ogg', 25, -3)
- user.remove_from_mob(det)
- det.loc = src
- detonator = det
- icon_state = initial(icon_state) +"_ass"
- name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
- stage = 1
- else if(istype(W,/obj/item/weapon/screwdriver) && path != 2)
- if(stage == 1)
- path = 1
- if(beakers.len)
- user << "\blue You lock the assembly."
- name = "grenade"
- else
-// user << "\red You need to add at least one beaker before locking the assembly."
- user << "\blue You lock the empty assembly."
- name = "fake grenade"
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 25, -3)
- icon_state = initial(icon_state) +"_locked"
- stage = 2
- else if(stage == 2)
- if(active && prob(95))
- user << "\red You trigger the assembly!"
- prime()
- return
- else
- user << "\blue You unlock the assembly."
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 25, -3)
- name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
- icon_state = initial(icon_state) + (detonator?"_ass":"")
- stage = 1
- active = 0
- else if(is_type_in_list(W, allowed_containers) && (!stage || stage==1) && path != 2)
- path = 1
- if(beakers.len == 2)
- user << "\red The grenade can not hold more containers."
- return
+ if(path != 1)
+ if(!istype(src.loc,/turf))
+ user << "\red You need to put the canister on the ground to do that!"
else
- if(W.reagents.total_volume)
- user << "\blue You add \the [W] to the assembly."
- user.drop_item()
- W.loc = src
- beakers += W
- stage = 1
- name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
- else
- user << "\red \the [W] is empty."
-
- examine()
- set src in usr
- usr << desc
- if(detonator)
- usr << "With attached [detonator.name]"
-
- activate(mob/user as mob)
- if(active) return
-
- if(detonator)
- if(!isigniter(detonator.a_left))
- detonator.a_left.activate()
- active = 1
- if(!isigniter(detonator.a_right))
- detonator.a_right.activate()
- active = 1
- if(active)
- icon_state = initial(icon_state) + "_active"
-
- if(user)
- log_attack("[user.name] ([user.ckey]) primed \a [src]")
- log_admin("ATTACK: [user] ([user.ckey]) primed \a [src]")
- message_admins("ATTACK: [user] ([user.ckey]) primed \a [src]")
-
+ switch(state)
+ if(0)
+ if(istype(W, /obj/item/weapon/wrench))
+ playsound(src.loc, 'Ratchet.ogg', 50, 1)
+ if(do_after(user, 20))
+ user << "\blue You wrench the canister in place."
+ src.name = "Camera Assembly"
+ src.anchored = 1
+ src.state = 1
+ path = 2
+ if(1)
+ if(istype(W, /obj/item/weapon/wrench))
+ playsound(src.loc, 'Ratchet.ogg', 50, 1)
+ if(do_after(user, 20))
+ user << "\blue You unfasten the canister."
+ src.name = "Grenade Casing"
+ src.anchored = 0
+ src.state = 0
+ path = 0
+ if(istype(W, /obj/item/device/multitool))
+ playsound(src.loc, 'Deconstruct.ogg', 50, 1)
+ user << "\blue You place the electronics inside the canister."
+ src.circuit = W
+ user.drop_item()
+ W.loc = src
+ if(istype(W, /obj/item/weapon/screwdriver) && circuit)
+ playsound(src.loc, 'Screwdriver.ogg', 50, 1)
+ user << "\blue You screw the circuitry into place."
+ src.state = 2
+ if(istype(W, /obj/item/weapon/crowbar) && circuit)
+ playsound(src.loc, 'Crowbar.ogg', 50, 1)
+ user << "\blue You remove the circuitry."
+ src.state = 1
+ circuit.loc = src.loc
+ src.circuit = null
+ if(2)
+ if(istype(W, /obj/item/weapon/screwdriver) && circuit)
+ playsound(src.loc, 'Screwdriver.ogg', 50, 1)
+ user << "\blue You unfasten the circuitry."
+ src.state = 1
+ if(istype(W, /obj/item/weapon/cable_coil))
+ if(W:amount >= 1)
+ playsound(src.loc, 'Deconstruct.ogg', 50, 1)
+ if(do_after(user, 20))
+ W:amount -= 1
+ if(!W:amount) del(W)
+ user << "\blue You add cabling to the canister."
+ src.state = 3
+ if(3)
+ if(istype(W, /obj/item/weapon/wirecutters))
+ playsound(src.loc, 'wirecutter.ogg', 50, 1)
+ user << "\blue You remove the cabling."
+ src.state = 2
+ var/obj/item/weapon/cable_coil/A = new /obj/item/weapon/cable_coil( src.loc )
+ A.amount = 1
+ if(issignaler(W))
+ playsound(src.loc, 'Deconstruct.ogg', 50, 1)
+ user << "\blue You attach the wireless signaller unit to the circutry."
+ user.drop_item()
+ W.loc = src
+ src.state = 4
+ if(4)
+ if(istype(W, /obj/item/weapon/crowbar) && !motion)
+ playsound(src.loc, 'Crowbar.ogg', 50, 1)
+ user << "\blue You remove the remote signalling device."
+ src.state = 3
+ var/obj/item/device/assembly/signaler/S = locate() in src
+ if(S)
+ S.loc = src.loc
+ else
+ new /obj/item/device/assembly/signaler( src.loc, 1 )
+ if(isprox(W) && motion == 0)
+// if(W:amount >= 1)
+ playsound(src.loc, 'Deconstruct.ogg', 50, 1)
+// W:use(1)
+ user << "\blue You attach the proximity sensor."
+ user.drop_item()
+ W.loc = src
+ motion = 1
+ if(istype(W, /obj/item/weapon/crowbar) && motion)
+ playsound(src.loc, 'Crowbar.ogg', 50, 1)
+ user << "\blue You remove the proximity sensor."
+ var/obj/item/device/assembly/prox_sensor/S = locate() in src
+ if(S)
+ S.loc = src.loc
+ else
+ new /obj/item/device/assembly/prox_sensor( src.loc, 1 )
+ motion = 0
+ if(istype(W, /obj/item/stack/sheet/glass))
+ if(W:amount >= 1)
+ playsound(src.loc, 'Deconstruct.ogg', 50, 1)
+ if(do_after(user, 20))
+ if(W)
+ W:use(1)
+ user << "\blue You put in the glass lens."
+ src.state = 5
+ if(5)
+ if(istype(W, /obj/item/weapon/crowbar))
+ playsound(src.loc, 'Crowbar.ogg', 50, 1)
+ user << "\blue You remove the glass lens."
+ src.state = 4
+ new /obj/item/stack/sheet/glass( src.loc, 2 )
+ if(istype(W, /obj/item/weapon/screwdriver))
+ playsound(src.loc, 'Screwdriver.ogg', 50, 1)
+ user << "\blue You connect the lense."
+ var/B
+ if(motion == 1)
+ B = new /obj/machinery/camera/motion( src.loc )
+ else
+ B = new /obj/machinery/camera( src.loc )
+ B:network = "SS13"
+ B:network = input(usr, "Which network would you like to connect this camera to?", "Set Network", "SS13")
+ direct = input(user, "Direction?", "Assembling Camera", null) in list( "NORTH", "EAST", "SOUTH", "WEST" )
+ B:dir = text2dir(direct)
+ del(src)
return
- proc/primed(var/primed = 1)
- if(active)
- icon_state = initial(icon_state) + (primed?"_primed":"_active")
- prime()
- if(!stage || stage<2) return
+ attack_self(mob/user as mob)
+ if(active == 2)
+ attached_device.attack_self(user)
+ return
+ user.machine = src
+ var/dat = {" Grenade properties:
+
Beaker one: [beakers[1]] [beakers[1] ? "Remove" : ""]
+
Beaker two: [beakers[2]] [beakers[2] ? "Remove" : ""]
+
Control attachment: [attached_device ? "[attached_device]" : "None"] [attached_device ? "Remove" : ""]"}
+
+ user << browse(dat, "window=trans_valve;size=600x300")
+ onclose(user, "trans_valve")
+ return
+
+
+ Topic(href, href_list)
+ ..()
+ if (usr.stat || usr.restrained())
+ return
+ if (src.loc == usr)
+ if(href_list["beakerone"])
+ if(beakers.len < 1)
+ return
+ var/obj/b1 = beakers[1]
+ b1.loc = get_turf(src)
+ beakers.Remove(b1)
+ if(href_list["beakertwo"])
+ if(beakers.len < 2)
+ return
+ var/obj/b2 = beakers[2]
+ b2.loc = get_turf(src)
+ beakers.Remove(b2)
+ if(href_list["rem_device"])
+ attached_device.loc = get_turf(src)
+ attached_device = null
+ if(href_list["device"])
+ attached_device.attack_self(usr)
+ src.attack_self(usr)
+ src.add_fingerprint(usr)
+ return
+
+ receive_signal(signal)
+ if(!(active == 2))
+ return //cant go off before it gets primed
+ explode()
+
+
+ HasProximity(atom/movable/AM as mob|obj)
+ if(istype(attached_device, /obj/item/device/assembly/prox_sensor))
+ var/obj/item/device/assembly/prox_sensor/D = attached_device
+ if (istype(AM, /obj/effect/beam))
+ return
+ if (AM.move_speed < 12)
+ D.sense()
+
+
+ proc/explode()
+ if(exploding) return
+ exploding = 1
//if(prob(reliability))
var/has_reagents = 0
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
- if(G.reagents.total_volume) has_reagents = 1
+ if(G.reagents.total_volume)
+ has_reagents = 1
+ break
active = 0
if(!has_reagents)
@@ -150,11 +271,18 @@
playsound(src.loc, 'sound/items/Screwdriver2.ogg', 50, 1)
return
+ var/datum/reagents/R = new/datum/reagents(1000)
+ reagents = R
+ R.my_atom = src
+
playsound(src.loc, 'sound/effects/bamf.ogg', 50, 1)
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
G.reagents.trans_to(src, G.reagents.total_volume)
+ var/obj/item/weapon/reagent_containers/glass/G = locate() in beakers
+ reagents.trans_to(G, reagents.total_volume/2)
+
if(src.reagents.total_volume) //The possible reactions didnt use up all reagents.
var/datum/effect/effect/system/steam_spread/steam = new /datum/effect/effect/system/steam_spread()
steam.set_up(10, 0, get_turf(src))
@@ -165,6 +293,10 @@
if( A == src ) continue
src.reagents.reaction(A, 1, 10)
+ for(var/atom/A in view(affected_area, src.loc))
+ if( A == src ) continue
+ G.reagents.reaction(A, 1, 10)
+
invisibility = INVISIBILITY_MAXIMUM //Why am i doing this?
spawn(50) //To make sure all reagents can work
@@ -175,12 +307,19 @@
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
G.loc = get_turf(src.loc)*/
+ proc/c_state(var/i = 0)
+ if(i)
+ icon_state = initial(icon_state) + "_armed"
+ else
+ icon_state = initial(icon_state) + "_locked"
+ return
+
/obj/item/weapon/grenade/chem_grenade/large
name = "Large Chem Grenade"
desc = "An oversized grenade that affects a larger area."
icon_state = "large_grenade"
- allowed_containers = list(/obj/item/weapon/reagent_containers/glass)
+ allowed_containers = list("/obj/item/weapon/reagent_containers/glass")
origin_tech = "combat=3;materials=3"
affected_area = 4
@@ -188,10 +327,13 @@
name = "Metal-Foam Grenade"
desc = "Used for emergency sealing of air breaches."
path = 1
- stage = 2
+ active = 2
New()
..()
+ attached_device = new /obj/item/device/assembly/timer(src)
+ attached_device.master = src
+ attached_device.toggle_secure()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
@@ -199,41 +341,41 @@
B2.reagents.add_reagent("foaming_agent", 10)
B2.reagents.add_reagent("pacid", 10)
- detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
-
- beakers += B1
- beakers += B2
- icon_state = initial(icon_state) +"_locked"
+ beakers.Add(B1, B2)
+ icon_state = "chemg_locked"
/obj/item/weapon/grenade/chem_grenade/incendiary
name = "Incendiary Grenade"
desc = "Used for clearing rooms of living things."
path = 1
- stage = 2
+ active = 2
New()
..()
+ attached_device = new /obj/item/device/assembly/timer(src)
+ attached_device.master = src
+ attached_device.toggle_secure()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
B1.reagents.add_reagent("aluminum", 25)
B2.reagents.add_reagent("plasma", 25)
- B2.reagents.add_reagent("sacid", 25)
+ B2.reagents.add_reagent("acid", 25)
- detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
-
- beakers += B1
- beakers += B2
- icon_state = initial(icon_state) +"_locked"
+ beakers.Add(B1, B2)
+ icon_state = "chemg_locked"
/obj/item/weapon/grenade/chem_grenade/cleaner
name = "Cleaner Grenade"
desc = "BLAM!-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas."
- stage = 2
+ active = 2
path = 1
New()
..()
+ attached_device = new /obj/item/device/assembly/timer(src)
+ attached_device.master = src
+ attached_device.toggle_secure()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
@@ -241,8 +383,5 @@
B2.reagents.add_reagent("water", 40)
B2.reagents.add_reagent("cleaner", 10)
- detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
-
- beakers += B1
- beakers += B2
- icon_state = initial(icon_state) +"_locked"
+ beakers.Add(B1, B2)
+ icon_state = "chemg_locked"
\ No newline at end of file
diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm
index 61773960fb..68789879a1 100644
--- a/code/modules/assembly/assembly.dm
+++ b/code/modules/assembly/assembly.dm
@@ -71,6 +71,8 @@
holder.process_activation(src, 1, 0)
if(holder && (wires & WIRE_PULSE_SPECIAL))
holder.process_activation(src, 0, 1)
+ if(master && (wires & WIRE_PULSE))
+ master.receive_signal("activate")
// if(radio && (wires & WIRE_RADIO_PULSE))
//Not sure what goes here quite yet send signal?
return 1
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index b8fd910719..710e9564c3 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -231,9 +231,6 @@
if ( !(usr.stat || usr.restrained()) )
var/obj/item/device/assembly_holder/holder
- if(istype(src,/obj/item/weapon/grenade/chem_grenade))
- var/obj/item/weapon/grenade/chem_grenade/gren = src
- holder=gren.detonator
var/obj/item/device/assembly/timer/tmr = holder.a_left
if(!istype(tmr,/obj/item/device/assembly/timer))
tmr = holder.a_right
diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm
index c54afdc0c6..7d35d6f70f 100644
--- a/code/modules/assembly/proximity.dm
+++ b/code/modules/assembly/proximity.dm
@@ -104,7 +104,7 @@
holder.update_icon()
if(holder && istype(holder.loc,/obj/item/weapon/grenade/chem_grenade))
var/obj/item/weapon/grenade/chem_grenade/grenade = holder.loc
- grenade.primed(scanning)
+ grenade.c_state(scanning)
return
diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm
index 979c97d5b7..5d140703ac 100644
--- a/code/modules/reagents/Chemistry-Reagents.dm
+++ b/code/modules/reagents/Chemistry-Reagents.dm
@@ -749,7 +749,7 @@ datum
return
if(H.head)
- if(prob(15) && !H.head.unacidable)
+ if(!H.head.unacidable)
del(H.head)
H.update_inv_head()
H << "\red Your helmet melts away but protects you from the acid"
diff --git a/html/changelog.html b/html/changelog.html
index f9a279c798..5d168f5e28 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -56,6 +56,16 @@ Stuff which is in development and not yet visible to players or just code relate
should be listed in the changelog upon commit though. Thanks. -->
+