diff --git a/code/ZAS/FEA_gas_mixture.dm b/code/ZAS/FEA_gas_mixture.dm
index cea0efc3ab7..3eccad7e913 100644
--- a/code/ZAS/FEA_gas_mixture.dm
+++ b/code/ZAS/FEA_gas_mixture.dm
@@ -965,6 +965,7 @@ What are the archived variables for?
//Outputs: 1 if can rebuild, 0 if not.
if(!sample) return 0
+
if((abs(oxygen-sample.oxygen) > MINIMUM_AIR_TO_SUSPEND) && \
((oxygen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen)))
return 0
@@ -972,52 +973,61 @@ What are the archived variables for?
((nitrogen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen) || (nitrogen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen)))
return 0
if((abs(carbon_dioxide-sample.carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && \
- ((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide)))
+ ((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (carbon_dioxide > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide)))
return 0
if((abs(toxins-sample.toxins) > MINIMUM_AIR_TO_SUSPEND) && \
((toxins < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins) || (toxins > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins)))
return 0
+
if(total_moles() > MINIMUM_AIR_TO_SUSPEND)
if((abs(temperature-sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \
((temperature < (1-MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature) || (temperature > (1+MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature)))
//world << "temp fail [temperature] & [sample.temperature]"
return 0
-
+ var/check_moles
if(sample.trace_gases.len)
for(var/datum/gas/trace_gas in sample.trace_gases)
- if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND)
- var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
- if(corresponding)
- if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \
- ((corresponding.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (corresponding.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles)))
- return 0
- else
- return 0
+ var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
+ if(corresponding)
+ check_moles = corresponding.moles
+ else
+ check_moles = 0
+
+ if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \
+ ((check_moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (check_moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles)))
+ return 0
if(trace_gases.len)
for(var/datum/gas/trace_gas in trace_gases)
- if(trace_gas.moles > MINIMUM_AIR_TO_SUSPEND)
- var/datum/gas/corresponding = locate(trace_gas.type) in sample.trace_gases
- if(corresponding)
- if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \
- ((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles)))
- return 0
- else
- return 0
+ var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
+ if(corresponding)
+ check_moles = corresponding.moles
+ else
+ check_moles = 0
+
+ if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \
+ ((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles)))
+ return 0
+
return 1
-/datum/gas_mixture/proc/compare_unsim(turf/list/samples)
- //Purpose: Compares a list of unsimulated tiles to self to see if within acceptable ranges that group processing may be enabled
- //Called by: ZAS sleeping detection.
- //Inputs: List of unsimulated turfs to compare to
- //Outputs: 1 if within an acceptable range to sleep, 0 otherwise.
- var/datum/gas_mixture/after_share = new
- after_share.copy_from(src)
+/datum/gas_mixture/proc/add(datum/gas_mixture/right_side)
+ oxygen += right_side.oxygen
+ carbon_dioxide += right_side.carbon_dioxide
+ nitrogen += right_side.nitrogen
+ toxins += right_side.toxins
- ShareSpace(after_share, samples)
+ if(trace_gases.len || right_side.trace_gases.len)
+ for(var/datum/gas/trace_gas in right_side.trace_gases)
+ var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
+ if(!corresponding)
+ corresponding = new trace_gas.type()
+ trace_gases += corresponding
+ corresponding.moles += trace_gas.moles
- return src.compare(after_share)
+ update_values()
+ return 1
/datum/gas_mixture/proc/subtract(datum/gas_mixture/right_side)
//Purpose: Subtracts right_side from air_mixture. Used to help turfs mingle
@@ -1025,18 +1035,42 @@ What are the archived variables for?
//Inputs: Gas mix to remove
//Outputs: 1
- oxygen -= right_side.oxygen
- carbon_dioxide -= right_side.carbon_dioxide
- nitrogen -= right_side.nitrogen
- toxins -= right_side.toxins
+ oxygen = max(oxygen - right_side.oxygen)
+ carbon_dioxide = max(carbon_dioxide - right_side.carbon_dioxide)
+ nitrogen = max(nitrogen - right_side.nitrogen)
+ toxins = max(toxins - right_side.toxins)
- if((trace_gases.len > 0)||(right_side.trace_gases.len > 0))
+ if(trace_gases.len || right_side.trace_gases.len)
for(var/datum/gas/trace_gas in right_side.trace_gases)
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
- if(!corresponding)
- corresponding = new trace_gas.type()
- trace_gases += corresponding
+ if(corresponding)
+ corresponding.moles = max(0, corresponding.moles - trace_gas.moles)
- corresponding.moles -= trace_gas.moles
update_values()
- return 1
\ No newline at end of file
+ return 1
+
+/datum/gas_mixture/proc/multiply(factor)
+ oxygen *= factor
+ carbon_dioxide *= factor
+ nitrogen *= factor
+ toxins *= factor
+
+ if(trace_gases && trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ trace_gas.moles *= factor
+
+ update_values()
+ return 1
+
+/datum/gas_mixture/proc/divide(factor)
+ oxygen /= factor
+ carbon_dioxide /= factor
+ nitrogen /= factor
+ toxins /= factor
+
+ if(trace_gases && trace_gases.len)
+ for(var/datum/gas/trace_gas in trace_gases)
+ trace_gas.moles /= factor
+
+ update_values()
+ return 1
diff --git a/code/ZAS/ZAS_Zones.dm b/code/ZAS/ZAS_Zones.dm
index b58cdd1903a..2a5c5818a49 100644
--- a/code/ZAS/ZAS_Zones.dm
+++ b/code/ZAS/ZAS_Zones.dm
@@ -10,6 +10,9 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
var/list/contents //All the tiles that are contained in this zone.
var/list/unsimulated_tiles // Any space tiles in this list will cause air to flow out.
+ var/datum/gas_mixture/air_unsim //Overall average of the air in connected unsimualted tiles.
+ var/unsim_air_needs_update = 0 //Set to 1 on geometry changes, marks air_unsim as needing update.
+
var/list/connections //connection objects which refer to connections with other zones, e.g. through a door.
var/list/direct_connections //connections which directly connect two zones.
@@ -126,6 +129,8 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
unsimulated_tiles += T
contents -= T
+ unsim_air_needs_update = 1
+
/zone/proc/RemoveTurf(turf/T)
//Same, but in reverse.
if(istype(T, /turf/simulated))
@@ -146,6 +151,45 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
if(!unsimulated_tiles.len)
unsimulated_tiles = null
+ unsim_air_needs_update = 1
+
+//Updates the air_unsim var
+/zone/proc/UpdateUnsimAvg()
+ if(!unsim_air_needs_update)
+ return
+
+ unsim_air_needs_update = 0
+
+ if(!air_unsim)
+ air_unsim = new /datum/gas_mixture
+
+ air_unsim.oxygen = 0
+ air_unsim.nitrogen = 0
+ air_unsim.carbon_dioxide = 0
+ air_unsim.toxins = 0
+ air_unsim.temperature = 0
+
+ var/correction_ratio = max(1, max(max(1, air.group_multiplier) + 3, 1) + unsimulated_tiles.len) / unsimulated_tiles.len
+
+ for(var/turf/T in unsimulated_tiles)
+ if(!istype(T, /turf/simulated))
+ air_unsim.oxygen += T.oxygen
+ air_unsim.carbon_dioxide += T.carbon_dioxide
+ air_unsim.nitrogen += T.nitrogen
+ air_unsim.toxins += T.toxins
+ air_unsim.temperature += T.temperature/unsimulated_tiles.len
+
+ //These values require adjustment in order to properly represent a room of the specified size.
+ air_unsim.oxygen *= correction_ratio
+ air_unsim.carbon_dioxide *= correction_ratio
+ air_unsim.nitrogen *= correction_ratio
+ air_unsim.toxins *= correction_ratio
+
+ air_unsim.group_multiplier = unsimulated_tiles.len
+
+ air_unsim.update_values()
+ return
+
//////////////
//PROCESSING//
//////////////
@@ -180,20 +224,23 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
progress = "problem with: ShareSpace()"
+ if(unsim_air_needs_update)
+ unsim_air_needs_update = 0
+ UpdateUnsimAvg()
+
if(unsimulated_tiles)
if(locate(/turf/simulated) in unsimulated_tiles)
for(var/turf/simulated/T in unsimulated_tiles)
unsimulated_tiles -= T
if(unsimulated_tiles.len)
- var/old_pressure = air.return_pressure()
- var/moved_air = ShareSpace(air,unsimulated_tiles)
+ var/moved_air = ShareSpace(air, air_unsim)
+
+ if(!air.compare(air_unsim))
+ interactions_with_unsim++
if(moved_air > vsc.airflow_lightest_pressure)
AirflowSpace(src)
-
- if(old_pressure && (moved_air / old_pressure) > MINIMUM_AIR_RATIO_TO_SUSPEND) //Check if we've moved enough air to be considered awake.
- interactions_with_unsim++
else
unsimulated_tiles = null
@@ -310,11 +357,11 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
Z.interactions_with_neighbors++
interactions_with_neighbors++
- if(!interactions_with_neighbors && !interactions_with_unsim)
- SetStatus(ZONE_SLEEPING)
+ if(!interactions_with_neighbors && !interactions_with_unsim)
+ SetStatus(ZONE_SLEEPING)
- interactions_with_neighbors = 0
- interactions_with_unsim = 0
+ interactions_with_neighbors = 0
+ interactions_with_unsim = 0
progress = "all components completed successfully, the problem is not here"
@@ -327,6 +374,11 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
else if(status == ZONE_ACTIVE && new_status == ZONE_SLEEPING)
air_master.active_zones.Remove(src)
status = ZONE_SLEEPING
+
+ if(unsimulated_tiles && unsimulated_tiles.len)
+ UpdateUnsimAvg()
+ air.copy_from(air_unsim)
+
if(!archived_air)
archived_air = new
archived_air.copy_from(air)
@@ -342,12 +394,13 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
var/difference = 0
if(unsimulated_tiles && unsimulated_tiles.len)
- if(air.compare_unsim(unsimulated_tiles))
+ UpdateUnsimAvg()
+ if(!air.compare(air_unsim))
difference = 1
if(!difference)
for(var/zone/Z in connected_zones) //Check adjacent zones for air difference.
- if(air.compare(Z.air))
+ if(!air.compare(Z.air))
difference = 1
break
@@ -362,11 +415,20 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
return air.merge(giver)
else
+ if(unsimulated_tiles && unsimulated_tiles.len)
+ UpdateUnsimAvg()
+ var/datum/gas_mixture/compare_air = new
+ compare_air.copy_from(giver)
+ compare_air.add(air_unsim)
+ compare_air.divide(air.group_multiplier)
+
+ if(air_unsim.compare(compare_air))
+ return 0
+
var/result = air.merge(giver)
if(!archived_air.compare(air))
SetStatus(ZONE_ACTIVE)
-
return result
@@ -443,6 +505,7 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
if(H)
var/G_avg = (G.moles*size + H.moles*share_size) / (size+share_size)
G.moles = (G.moles - G_avg) * (1-ratio) + G_avg
+
H.moles = (H.moles - G_avg) * (1-ratio) + G_avg
else
H = new G.type
@@ -451,6 +514,15 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
G.moles = (G.moles - G_avg) * (1-ratio) + G_avg
H.moles = (H.moles - G_avg) * (1-ratio) + G_avg
+ for(var/datum/gas/G in B.trace_gases)
+ var/datum/gas/H = locate(G.type) in A.trace_gases
+ if(H)
+ H = new G.type
+ A.trace_gases += H
+ var/G_avg = (G.moles*size) / (size+share_size)
+ G.moles = (G.moles - G_avg) * (1-ratio) + G_avg
+ H.moles = (H.moles - G_avg) * (1-ratio) + G_avg
+
A.update_values()
B.update_values()
@@ -459,7 +531,7 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
//A modified version of ShareRatio for spacing gas at the same rate as if it were going into a large airless room.
- if(!unsimulated_tiles || !unsimulated_tiles.len)
+ if(!unsimulated_tiles)
return 0
var
@@ -472,6 +544,22 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
size = max(1,A.group_multiplier)
+ var/tileslen
+ var/share_size
+
+ if(istype(unsimulated_tiles, /datum/gas_mixture))
+ var/datum/gas_mixture/avg_unsim = unsimulated_tiles
+ unsim_oxygen = avg_unsim.oxygen
+ unsim_co2 = avg_unsim.carbon_dioxide
+ unsim_nitrogen = avg_unsim.nitrogen
+ unsim_plasma = avg_unsim.toxins
+ unsim_temperature = avg_unsim.temperature
+ share_size = max(1, max(size + 3, 1) + avg_unsim.group_multiplier)
+ tileslen = avg_unsim.group_multiplier
+
+ else if(istype(unsimulated_tiles, /list))
+ if(!unsimulated_tiles.len)
+ return 0
// We use the same size for the potentially single space tile
// as we use for the entire room. Why is this?
// Short answer: We do not want larger rooms to depressurize more
@@ -479,20 +567,25 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
// oh-shit effect when large rooms get breached, but still having small
// rooms remain pressurized for long enough to make escape possible.
share_size = max(1, max(size + 3, 1) + unsimulated_tiles.len)
- correction_ratio = share_size / unsimulated_tiles.len
+ var/correction_ratio = share_size / unsimulated_tiles.len
- for(var/turf/T in unsimulated_tiles)
- unsim_oxygen += T.oxygen
- unsim_co2 += T.carbon_dioxide
- unsim_nitrogen += T.nitrogen
- unsim_plasma += T.toxins
- unsim_temperature += T.temperature/unsimulated_tiles.len
+ for(var/turf/T in unsimulated_tiles)
+ unsim_oxygen += T.oxygen
+ unsim_co2 += T.carbon_dioxide
+ unsim_nitrogen += T.nitrogen
+ unsim_plasma += T.toxins
+ unsim_temperature += T.temperature/unsimulated_tiles.len
+
+ //These values require adjustment in order to properly represent a room of the specified size.
+ unsim_oxygen *= correction_ratio
+ unsim_co2 *= correction_ratio
+ unsim_nitrogen *= correction_ratio
+ unsim_plasma *= correction_ratio
+ tileslen = unsimulated_tiles.len
+
+ else //invalid input type
+ return 0
- //These values require adjustment in order to properly represent a room of the specified size.
- unsim_oxygen *= correction_ratio
- unsim_co2 *= correction_ratio
- unsim_nitrogen *= correction_ratio
- unsim_plasma *= correction_ratio
unsim_heat_capacity = HEAT_CAPACITY_CALCULATION(unsim_oxygen, unsim_co2, unsim_nitrogen, unsim_plasma)
var
@@ -517,8 +610,8 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
if((full_heat_capacity + unsim_heat_capacity) > 0)
temp_avg = (A.temperature * full_heat_capacity + unsim_temperature * unsim_heat_capacity) / (full_heat_capacity + unsim_heat_capacity)
- if(sharing_lookup_table.len >= unsimulated_tiles.len) //6 or more interconnecting tiles will max at 42% of air moved per tick.
- ratio = sharing_lookup_table[unsimulated_tiles.len]
+ if(sharing_lookup_table.len >= tileslen) //6 or more interconnecting tiles will max at 42% of air moved per tick.
+ ratio = sharing_lookup_table[tileslen]
A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg )
A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg )
diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm
index 0f1fd97b36f..e98d128559f 100644
--- a/code/game/gamemodes/heist/heist.dm
+++ b/code/game/gamemodes/heist/heist.dm
@@ -99,6 +99,7 @@ var/global/vox_kills = 0 //Used to check the Inviolate.
vox.real_name = capitalize(newname)
vox.name = vox.real_name
+ raider.name = vox.name
vox.age = rand(12,20)
vox.dna.mutantrace = "vox"
vox.set_species("Vox")
@@ -253,6 +254,34 @@ var/global/vox_kills = 0 //Used to check the Inviolate.
..()
+datum/game_mode/proc/auto_declare_completion_heist()
+ if(raiders.len)
+ var/check_return = 0
+ if(ticker && istype(ticker.mode,/datum/game_mode/heist))
+ check_return = 1
+ var/text = "The vox raiders were:"
+
+ for(var/datum/mind/vox in raiders)
+ text += "
[vox.key] was [vox.name] ("
+ if(check_return)
+ var/obj/stack = raiders[vox]
+ if(get_area(stack) != locate(/area/shuttle/vox/station))
+ text += "left behind)"
+ continue
+ if(vox.current)
+ if(vox.current.stat == DEAD)
+ text += "died"
+ else
+ text += "survived"
+ if(vox.current.real_name != vox.name)
+ text += " as [vox.current.real_name]"
+ else
+ text += "body destroyed"
+ text += ")"
+
+ world << text
+ return 1
+
/datum/game_mode/heist/check_finished()
if (!(is_raider_crew_alive()) || (vox_shuttle_location && (vox_shuttle_location == "start")))
return 1
diff --git a/code/game/objects/effects/decals/contraband.dm b/code/game/objects/effects/decals/contraband.dm
index d7ac2baa6fc..077780119bb 100644
--- a/code/game/objects/effects/decals/contraband.dm
+++ b/code/game/objects/effects/decals/contraband.dm
@@ -149,11 +149,11 @@ obj/structure/sign/poster/attackby(obj/item/weapon/W as obj, mob/user as mob)
if("No")
return
-/obj/structure/sign/poster/proc/roll_and_drop(turf/loc)
+/obj/structure/sign/poster/proc/roll_and_drop(turf/newloc)
var/obj/item/weapon/contraband/poster/P = new(src, serial_number)
P.resulting_poster = src
- P.loc = loc
- loc = P
+ P.loc = newloc
+ src.loc = P
//seperated to reduce code duplication. Moved here for ease of reference and to unclutter r_wall/attackby()
diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm
index 120a6ffa702..a47b091da93 100644
--- a/code/game/objects/items/stacks/sheets/mineral.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -126,7 +126,7 @@ var/global/list/datum/stack_recipe/plasma_recipes = list ( \
perunit = 2000
var/global/list/datum/stack_recipe/plastic_recipes = list ( \
- new/datum/stack_recipe("plastic crate", /obj/structure/closet/pcrate, 10, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("plastic crate", /obj/structure/closet/crate/plastic, 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("plastic ashtray", /obj/item/ashtray/plastic, 2, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("plastic fork", /obj/item/weapon/kitchen/utensil/pfork, 1, on_floor = 1), \
new/datum/stack_recipe("plastic spoon", /obj/item/weapon/kitchen/utensil/pspoon, 1, on_floor = 1), \
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index 61b1750a82f..ccace6a8f0e 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -5,392 +5,62 @@
desc = "A rectangular steel crate."
icon = 'icons/obj/storage.dmi'
icon_state = "crate"
- density = 1
icon_opened = "crateopen"
icon_closed = "crate"
- req_access = null
- opened = 0
- flags = FPRINT
// mouse_drag_pointer = MOUSE_ACTIVE_POINTER //???
var/rigged = 0
-/obj/structure/closet/pcrate
- name = "plastic crate"
- desc = "A rectangular plastic crate."
- icon = 'icons/obj/storage.dmi'
- icon_state = "plasticcrate"
- density = 1
- icon_opened = "plasticcrateopen"
- icon_closed = "plasticcrate"
- req_access = null
- opened = 0
- flags = FPRINT
-// mouse_drag_pointer = MOUSE_ACTIVE_POINTER //???
- var/rigged = 0
+/obj/structure/closet/crate/can_open()
+ return 1
-/obj/structure/closet/crate/internals
- desc = "A internals crate."
- name = "Internals crate"
- icon = 'icons/obj/storage.dmi'
- icon_state = "o2crate"
- density = 1
- icon_opened = "o2crateopen"
- icon_closed = "o2crate"
-
-/obj/structure/closet/crate/trashcart
- desc = "A heavy, metal trashcart with wheels."
- name = "Trash Cart"
- icon = 'icons/obj/storage.dmi'
- icon_state = "trashcart"
- density = 1
- icon_opened = "trashcartopen"
- icon_closed = "trashcart"
-
-/*these aren't needed anymore
-/obj/structure/closet/crate/hat
- desc = "A crate filled with Valuable Collector's Hats!."
- name = "Hat Crate"
- icon = 'icons/obj/storage.dmi'
- icon_state = "crate"
- density = 1
- icon_opened = "crateopen"
- icon_closed = "crate"
-
-/obj/structure/closet/crate/contraband
- name = "Poster crate"
- desc = "A random assortment of posters manufactured by providers NOT listed under Nanotrasen's whitelist."
- icon = 'icons/obj/storage.dmi'
- icon_state = "crate"
- density = 1
- icon_opened = "crateopen"
- icon_closed = "crate"
-*/
-
-/obj/structure/closet/crate/medical
- desc = "A medical crate."
- name = "Medical crate"
- icon = 'icons/obj/storage.dmi'
- icon_state = "medicalcrate"
- density = 1
- icon_opened = "medicalcrateopen"
- icon_closed = "medicalcrate"
-
-/obj/structure/closet/crate/rcd
- desc = "A crate for the storage of the RCD."
- name = "RCD crate"
- icon = 'icons/obj/storage.dmi'
- icon_state = "crate"
- density = 1
- icon_opened = "crateopen"
- icon_closed = "crate"
-
-/obj/structure/closet/crate/freezer
- desc = "A freezer."
- name = "Freezer"
- icon = 'icons/obj/storage.dmi'
- icon_state = "freezer"
- density = 1
- icon_opened = "freezeropen"
- icon_closed = "freezer"
- var/target_temp = T0C - 40
- var/cooling_power = 40
-
- return_air()
- var/datum/gas_mixture/gas = (..())
- if(!gas) return null
- var/datum/gas_mixture/newgas = new/datum/gas_mixture()
- newgas.oxygen = gas.oxygen
- newgas.carbon_dioxide = gas.carbon_dioxide
- newgas.nitrogen = gas.nitrogen
- newgas.toxins = gas.toxins
- newgas.volume = gas.volume
- newgas.temperature = gas.temperature
- if(newgas.temperature <= target_temp) return
-
- if((newgas.temperature - cooling_power) > target_temp)
- newgas.temperature -= cooling_power
- else
- newgas.temperature = target_temp
- return newgas
-
-
-/obj/structure/closet/crate/bin
- desc = "A large bin."
- name = "Large bin"
- icon = 'icons/obj/storage.dmi'
- icon_state = "largebin"
- density = 1
- icon_opened = "largebinopen"
- icon_closed = "largebin"
-
-/obj/structure/closet/crate/radiation
- desc = "A crate with a radiation sign on it."
- name = "Radioactive gear crate"
- icon = 'icons/obj/storage.dmi'
- icon_state = "radiation"
- density = 1
- icon_opened = "radiationopen"
- icon_closed = "radiation"
-
-/obj/structure/closet/crate/secure/weapon
- desc = "A secure weapons crate."
- name = "Weapons crate"
- icon = 'icons/obj/storage.dmi'
- icon_state = "weaponcrate"
- density = 1
- icon_opened = "weaponcrateopen"
- icon_closed = "weaponcrate"
-
-/obj/structure/closet/crate/secure/plasma
- desc = "A secure plasma crate."
- name = "Plasma crate"
- icon = 'icons/obj/storage.dmi'
- icon_state = "plasmacrate"
- density = 1
- icon_opened = "plasmacrateopen"
- icon_closed = "plasmacrate"
-
-/obj/structure/closet/crate/secure/gear
- desc = "A secure gear crate."
- name = "Gear crate"
- icon = 'icons/obj/storage.dmi'
- icon_state = "secgearcrate"
- density = 1
- icon_opened = "secgearcrateopen"
- icon_closed = "secgearcrate"
-
-/obj/structure/closet/crate/secure/hydrosec
- desc = "A crate with a lock on it, painted in the scheme of the station's botanists."
- name = "secure hydroponics crate"
- icon = 'icons/obj/storage.dmi'
- icon_state = "hydrosecurecrate"
- density = 1
- icon_opened = "hydrosecurecrateopen"
- icon_closed = "hydrosecurecrate"
-
-/obj/structure/closet/crate/secure/bin
- desc = "A secure bin."
- name = "Secure bin"
- icon_state = "largebins"
- icon_opened = "largebinsopen"
- icon_closed = "largebins"
- redlight = "largebinr"
- greenlight = "largebing"
- sparks = "largebinsparks"
- emag = "largebinemag"
-
-/obj/structure/closet/crate/secure/large
- name = "large crate"
- desc = "A hefty metal crate with an electronic locking system."
- icon = 'icons/obj/storage.dmi'
- icon_state = "largemetal"
- icon_opened = "largemetalopen"
- icon_closed = "largemetal"
- redlight = "largemetalr"
- greenlight = "largemetalg"
-
-/obj/structure/closet/crate/secure/large/close()
- //we can hold up to one large item
- var/found = 0
- for(var/obj/structure/S in src.loc)
- if(S == src)
- continue
- if(!S.anchored)
- found = 1
- S.loc = src
- break
- if(!found)
- for(var/obj/machinery/M in src.loc)
- if(!M.anchored)
- M.loc = src
- break
- ..()
-
-//fluff variant
-/obj/structure/closet/crate/secure/large/reinforced
- desc = "A hefty, reinforced metal crate with an electronic locking system."
- icon_state = "largermetal"
- icon_opened = "largermetalopen"
- icon_closed = "largermetal"
-
-/obj/structure/closet/crate/secure
- desc = "A secure crate."
- name = "Secure crate"
- icon_state = "securecrate"
- icon_opened = "securecrateopen"
- icon_closed = "securecrate"
- var/redlight = "securecrater"
- var/greenlight = "securecrateg"
- var/sparks = "securecratesparks"
- var/emag = "securecrateemag"
- var/broken = 0
- var/locked = 1
-
-/obj/structure/closet/crate/large
- name = "large crate"
- desc = "A hefty metal crate."
- icon = 'icons/obj/storage.dmi'
- icon_state = "largemetal"
- icon_opened = "largemetalopen"
- icon_closed = "largemetal"
-
-/obj/structure/closet/crate/large/close()
- //we can hold up to one large item
- var/found = 0
- for(var/obj/structure/S in src.loc)
- if(S == src)
- continue
- if(!S.anchored)
- found = 1
- S.loc = src
- break
- if(!found)
- for(var/obj/machinery/M in src.loc)
- if(!M.anchored)
- M.loc = src
- break
- ..()
-
-/obj/structure/closet/crate/hydroponics
- name = "Hydroponics crate"
- desc = "All you need to destroy those pesky weeds and pests."
- icon = 'icons/obj/storage.dmi'
- icon_state = "hydrocrate"
- icon_opened = "hydrocrateopen"
- icon_closed = "hydrocrate"
- density = 1
-
-/obj/structure/closet/crate/hydroponics/prespawned
- //This exists so the prespawned hydro crates spawn with their contents.
-/* name = "Hydroponics crate"
- desc = "All you need to destroy those pesky weeds and pests."
- icon = 'icons/obj/storage.dmi'
- icon_state = "hydrocrate"
- icon_opened = "hydrocrateopen"
- icon_closed = "hydrocrate"
- density = 1*/
- New()
- ..()
- new /obj/item/weapon/reagent_containers/spray/plantbgone(src)
- new /obj/item/weapon/reagent_containers/spray/plantbgone(src)
- new /obj/item/weapon/minihoe(src)
-// new /obj/item/weapon/weedspray(src)
-// new /obj/item/weapon/weedspray(src)
-// new /obj/item/weapon/pestspray(src)
-// new /obj/item/weapon/pestspray(src)
-// new /obj/item/weapon/pestspray(src)
-
-
-/obj/structure/closet/crate/secure/New()
- ..()
- if(locked)
- overlays.Cut()
- overlays += redlight
- else
- overlays.Cut()
- overlays += greenlight
-
-/obj/structure/closet/crate/rcd/New()
- ..()
- new /obj/item/weapon/rcd_ammo(src)
- new /obj/item/weapon/rcd_ammo(src)
- new /obj/item/weapon/rcd_ammo(src)
- new /obj/item/weapon/rcd(src)
-
-/obj/structure/closet/crate/radiation/New()
- ..()
- new /obj/item/clothing/suit/radiation(src)
- new /obj/item/clothing/head/radiation(src)
- new /obj/item/clothing/suit/radiation(src)
- new /obj/item/clothing/head/radiation(src)
- new /obj/item/clothing/suit/radiation(src)
- new /obj/item/clothing/head/radiation(src)
- new /obj/item/clothing/suit/radiation(src)
- new /obj/item/clothing/head/radiation(src)
+/obj/structure/closet/crate/can_close()
+ return 1
/obj/structure/closet/crate/open()
- playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
+ if(src.opened)
+ return 0
+ if(!src.can_open())
+ return 0
+ if(rigged && locate(/obj/item/device/radio/electropack) in src)
+ if(isliving(usr))
+ var/mob/living/L = usr
+ if(L.electrocute_act(17, src))
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(5, 1, src)
+ s.start()
+ return 2
+
+ playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
for(var/obj/O in src)
O.loc = get_turf(src)
-
icon_state = icon_opened
src.opened = 1
+ return 1
/obj/structure/closet/crate/close()
+ if(!src.opened)
+ return 0
+ if(!src.can_close())
+ return 0
+
playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
-
var/itemcount = 0
-
for(var/obj/O in get_turf(src))
if(itemcount >= storage_capacity)
break
-
if(O.density || O.anchored || istype(O,/obj/structure/closet))
continue
-
if(istype(O, /obj/structure/stool/bed)) //This is only necessary because of rollerbeds and swivel chairs.
var/obj/structure/stool/bed/B = O
if(B.buckled_mob)
continue
-
O.loc = src
itemcount++
icon_state = icon_closed
src.opened = 0
-
-/obj/structure/closet/crate/attack_hand(mob/user as mob)
- if(opened)
- close()
- else
- if(rigged && locate(/obj/item/device/radio/electropack) in src)
- if(isliving(user))
- var/mob/living/L = user
- if(L.electrocute_act(17, src))
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, src)
- s.start()
- return
- open()
- return
-
-/obj/structure/closet/crate/secure/attack_hand(mob/user as mob)
- if(locked && !broken)
- if (allowed(user))
- user << "You unlock [src]."
- src.locked = 0
- overlays.Cut()
- overlays += greenlight
- return
- else
- user << "[src] is locked."
- return
- else
- ..()
-
-/obj/structure/closet/crate/secure/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(istype(W, /obj/item/weapon/card) && src.allowed(user) && !locked && !opened && !broken)
- user << "You lock \the [src]."
- src.locked = 1
- overlays.Cut()
- overlays += redlight
- return
- else if ( (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && locked &&!broken)
- overlays.Cut()
- overlays += emag
- overlays += sparks
- spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface*
- playsound(src.loc, "sparks", 60, 1)
- src.locked = 0
- src.broken = 1
- user << "You unlock \the [src]."
- return
-
- return ..()
-
-/obj/structure/closet/crate/attack_paw(mob/user as mob)
- return attack_hand(user)
+ return 1
/obj/structure/closet/crate/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(opened)
@@ -424,6 +94,107 @@
return
else return attack_hand(user)
+/obj/structure/closet/crate/ex_act(severity)
+ switch(severity)
+ if(1.0)
+ for(var/obj/O in src.contents)
+ del(O)
+ del(src)
+ return
+ if(2.0)
+ for(var/obj/O in src.contents)
+ if(prob(50))
+ del(O)
+ del(src)
+ return
+ if(3.0)
+ if (prob(50))
+ del(src)
+ return
+ else
+ return
+
+/obj/structure/closet/crate/secure
+ desc = "A secure crate."
+ name = "Secure crate"
+ icon_state = "securecrate"
+ icon_opened = "securecrateopen"
+ icon_closed = "securecrate"
+ var/redlight = "securecrater"
+ var/greenlight = "securecrateg"
+ var/sparks = "securecratesparks"
+ var/emag = "securecrateemag"
+ var/broken = 0
+ var/locked = 1
+
+/obj/structure/closet/crate/secure/New()
+ ..()
+ if(locked)
+ overlays.Cut()
+ overlays += redlight
+ else
+ overlays.Cut()
+ overlays += greenlight
+
+/obj/structure/closet/crate/secure/can_open()
+ return !locked
+
+/obj/structure/closet/crate/secure/proc/togglelock(mob/user as mob)
+ if(src.opened)
+ user << "Close the crate first."
+ return
+ if(src.broken)
+ user << "The crate appears to be broken."
+ return
+ if(src.allowed(user))
+ src.locked = !src.locked
+ for(var/mob/O in viewers(user, 3))
+ if((O.client && !( O.blinded )))
+ O << "The crate has been [locked ? null : "un"]locked by [user]."
+ overlays.Cut()
+ overlays += locked ? redlight : greenlight
+ else
+ user << "Access Denied"
+
+/obj/structure/closet/crate/secure/verb/verb_togglelock()
+ set src in oview(1) // One square distance
+ set category = "Object"
+ set name = "Toggle Lock"
+
+ if(!usr.canmove || usr.stat || usr.restrained()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain
+ return
+
+ if(ishuman(usr))
+ src.add_fingerprint(usr)
+ src.togglelock(usr)
+ else
+ usr << "This mob type can't use this verb."
+
+/obj/structure/closet/crate/secure/attack_hand(mob/user as mob)
+ src.add_fingerprint(user)
+ if(locked)
+ src.togglelock(user)
+ else
+ src.toggle(user)
+
+/obj/structure/closet/crate/secure/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(is_type_in_list(W, list(/obj/item/weapon/packageWrap, /obj/item/weapon/cable_coil, /obj/item/device/radio/electropack, /obj/item/weapon/wirecutters)))
+ return ..()
+ if(locked && (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)))
+ overlays.Cut()
+ overlays += emag
+ overlays += sparks
+ spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface*
+ playsound(src.loc, "sparks", 60, 1)
+ src.locked = 0
+ src.broken = 1
+ user << "You unlock \the [src]."
+ return
+ if(!opened)
+ src.togglelock(user)
+ return
+ return ..()
+
/obj/structure/closet/crate/secure/emp_act(severity)
for(var/obj/O in src)
O.emp_act(severity)
@@ -447,23 +218,234 @@
src.req_access += pick(get_all_accesses())
..()
+/obj/structure/closet/crate/plastic
+ name = "plastic crate"
+ desc = "A rectangular plastic crate."
+ icon_state = "plasticcrate"
+ icon_opened = "plasticcrateopen"
+ icon_closed = "plasticcrate"
-/obj/structure/closet/crate/ex_act(severity)
- switch(severity)
- if(1.0)
- for(var/obj/O in src.contents)
- del(O)
- del(src)
- return
- if(2.0)
- for(var/obj/O in src.contents)
- if(prob(50))
- del(O)
- del(src)
- return
- if(3.0)
- if (prob(50))
- del(src)
- return
+/obj/structure/closet/crate/internals
+ desc = "A internals crate."
+ name = "Internals crate"
+ icon_state = "o2crate"
+ icon_opened = "o2crateopen"
+ icon_closed = "o2crate"
+
+/obj/structure/closet/crate/trashcart
+ desc = "A heavy, metal trashcart with wheels."
+ name = "Trash Cart"
+ icon_state = "trashcart"
+ icon_opened = "trashcartopen"
+ icon_closed = "trashcart"
+
+/*these aren't needed anymore
+/obj/structure/closet/crate/hat
+ desc = "A crate filled with Valuable Collector's Hats!."
+ name = "Hat Crate"
+ icon_state = "crate"
+ icon_opened = "crateopen"
+ icon_closed = "crate"
+
+/obj/structure/closet/crate/contraband
+ name = "Poster crate"
+ desc = "A random assortment of posters manufactured by providers NOT listed under Nanotrasen's whitelist."
+ icon_state = "crate"
+ icon_opened = "crateopen"
+ icon_closed = "crate"
+*/
+
+/obj/structure/closet/crate/medical
+ desc = "A medical crate."
+ name = "Medical crate"
+ icon_state = "medicalcrate"
+ icon_opened = "medicalcrateopen"
+ icon_closed = "medicalcrate"
+
+/obj/structure/closet/crate/rcd
+ desc = "A crate for the storage of the RCD."
+ name = "RCD crate"
+ icon_state = "crate"
+ icon_opened = "crateopen"
+ icon_closed = "crate"
+
+/obj/structure/closet/crate/rcd/New()
+ ..()
+ new /obj/item/weapon/rcd_ammo(src)
+ new /obj/item/weapon/rcd_ammo(src)
+ new /obj/item/weapon/rcd_ammo(src)
+ new /obj/item/weapon/rcd(src)
+
+/obj/structure/closet/crate/freezer
+ desc = "A freezer."
+ name = "Freezer"
+ icon_state = "freezer"
+ icon_opened = "freezeropen"
+ icon_closed = "freezer"
+ var/target_temp = T0C - 40
+ var/cooling_power = 40
+
+ return_air()
+ var/datum/gas_mixture/gas = (..())
+ if(!gas) return null
+ var/datum/gas_mixture/newgas = new/datum/gas_mixture()
+ newgas.oxygen = gas.oxygen
+ newgas.carbon_dioxide = gas.carbon_dioxide
+ newgas.nitrogen = gas.nitrogen
+ newgas.toxins = gas.toxins
+ newgas.volume = gas.volume
+ newgas.temperature = gas.temperature
+ if(newgas.temperature <= target_temp) return
+
+ if((newgas.temperature - cooling_power) > target_temp)
+ newgas.temperature -= cooling_power
else
+ newgas.temperature = target_temp
+ return newgas
+
+
+/obj/structure/closet/crate/bin
+ desc = "A large bin."
+ name = "Large bin"
+ icon_state = "largebin"
+ icon_opened = "largebinopen"
+ icon_closed = "largebin"
+
+/obj/structure/closet/crate/radiation
+ desc = "A crate with a radiation sign on it."
+ name = "Radioactive gear crate"
+ icon_state = "radiation"
+ icon_opened = "radiationopen"
+ icon_closed = "radiation"
+
+/obj/structure/closet/crate/radiation/New()
+ ..()
+ new /obj/item/clothing/suit/radiation(src)
+ new /obj/item/clothing/head/radiation(src)
+ new /obj/item/clothing/suit/radiation(src)
+ new /obj/item/clothing/head/radiation(src)
+ new /obj/item/clothing/suit/radiation(src)
+ new /obj/item/clothing/head/radiation(src)
+ new /obj/item/clothing/suit/radiation(src)
+ new /obj/item/clothing/head/radiation(src)
+
+/obj/structure/closet/crate/secure/weapon
+ desc = "A secure weapons crate."
+ name = "Weapons crate"
+ icon_state = "weaponcrate"
+ icon_opened = "weaponcrateopen"
+ icon_closed = "weaponcrate"
+
+/obj/structure/closet/crate/secure/plasma
+ desc = "A secure plasma crate."
+ name = "Plasma crate"
+ icon_state = "plasmacrate"
+ icon_opened = "plasmacrateopen"
+ icon_closed = "plasmacrate"
+
+/obj/structure/closet/crate/secure/gear
+ desc = "A secure gear crate."
+ name = "Gear crate"
+ icon_state = "secgearcrate"
+ icon_opened = "secgearcrateopen"
+ icon_closed = "secgearcrate"
+
+/obj/structure/closet/crate/secure/hydrosec
+ desc = "A crate with a lock on it, painted in the scheme of the station's botanists."
+ name = "secure hydroponics crate"
+ icon_state = "hydrosecurecrate"
+ icon_opened = "hydrosecurecrateopen"
+ icon_closed = "hydrosecurecrate"
+
+/obj/structure/closet/crate/secure/bin
+ desc = "A secure bin."
+ name = "Secure bin"
+ icon_state = "largebins"
+ icon_opened = "largebinsopen"
+ icon_closed = "largebins"
+ redlight = "largebinr"
+ greenlight = "largebing"
+ sparks = "largebinsparks"
+ emag = "largebinemag"
+
+/obj/structure/closet/crate/large
+ name = "large crate"
+ desc = "A hefty metal crate."
+ icon = 'icons/obj/storage.dmi'
+ icon_state = "largemetal"
+ icon_opened = "largemetalopen"
+ icon_closed = "largemetal"
+
+/obj/structure/closet/crate/large/close()
+ . = ..()
+ if (.)//we can hold up to one large item
+ var/found = 0
+ for(var/obj/structure/S in src.loc)
+ if(S == src)
+ continue
+ if(!S.anchored)
+ found = 1
+ S.loc = src
+ break
+ if(!found)
+ for(var/obj/machinery/M in src.loc)
+ if(!M.anchored)
+ M.loc = src
+ break
return
+
+/obj/structure/closet/crate/secure/large
+ name = "large crate"
+ desc = "A hefty metal crate with an electronic locking system."
+ icon = 'icons/obj/storage.dmi'
+ icon_state = "largemetal"
+ icon_opened = "largemetalopen"
+ icon_closed = "largemetal"
+ redlight = "largemetalr"
+ greenlight = "largemetalg"
+
+/obj/structure/closet/crate/secure/large/close()
+ . = ..()
+ if (.)//we can hold up to one large item
+ var/found = 0
+ for(var/obj/structure/S in src.loc)
+ if(S == src)
+ continue
+ if(!S.anchored)
+ found = 1
+ S.loc = src
+ break
+ if(!found)
+ for(var/obj/machinery/M in src.loc)
+ if(!M.anchored)
+ M.loc = src
+ break
+ return
+
+//fluff variant
+/obj/structure/closet/crate/secure/large/reinforced
+ desc = "A hefty, reinforced metal crate with an electronic locking system."
+ icon_state = "largermetal"
+ icon_opened = "largermetalopen"
+ icon_closed = "largermetal"
+
+/obj/structure/closet/crate/hydroponics
+ name = "Hydroponics crate"
+ desc = "All you need to destroy those pesky weeds and pests."
+ icon_state = "hydrocrate"
+ icon_opened = "hydrocrateopen"
+ icon_closed = "hydrocrate"
+
+/obj/structure/closet/crate/hydroponics/prespawned
+ //This exists so the prespawned hydro crates spawn with their contents.
+
+ New()
+ ..()
+ new /obj/item/weapon/reagent_containers/spray/plantbgone(src)
+ new /obj/item/weapon/reagent_containers/spray/plantbgone(src)
+ new /obj/item/weapon/minihoe(src)
+// new /obj/item/weapon/weedspray(src)
+// new /obj/item/weapon/weedspray(src)
+// new /obj/item/weapon/pestspray(src)
+// new /obj/item/weapon/pestspray(src)
+// new /obj/item/weapon/pestspray(src)
\ No newline at end of file
diff --git a/code/modules/admin/verbs/vox_raiders.dm b/code/modules/admin/verbs/vox_raiders.dm
index 1e3a8defe74..5548aab001f 100644
--- a/code/modules/admin/verbs/vox_raiders.dm
+++ b/code/modules/admin/verbs/vox_raiders.dm
@@ -60,9 +60,10 @@ var/global/vox_tick = 1
var/obj/item/weapon/card/id/syndicate/W = new(src)
W.name = "[real_name]'s Legitimate Human ID Card"
W.icon_state = "id"
- W.access = list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage, access_syndicate)
+ W.access = list(access_syndicate)
W.assignment = "Trader"
W.registered_name = real_name
+ W.registered_user = src
equip_to_slot_or_del(W, slot_wear_id)
var/obj/item/weapon/implant/cortical/I = new(src)
@@ -75,6 +76,7 @@ var/global/vox_tick = 1
if(ticker.mode && ( istype( ticker.mode,/datum/game_mode/heist ) ) )
var/datum/game_mode/heist/M = ticker.mode
M.cortical_stacks += I
+ M.raiders[mind] = I
vox_tick++
if (vox_tick > 4) vox_tick = 1
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index aed3517d03a..be7a028f2aa 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -35,7 +35,6 @@
icon_state = "night"
item_state = "glasses"
origin_tech = "magnets=2"
- vision_flags = SEE_TURFS
darkness_view = 3
/obj/item/clothing/glasses/eyepatch
diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm
index 8fd158fdf3f..07602471f49 100644
--- a/code/modules/clothing/shoes/magboots.dm
+++ b/code/modules/clothing/shoes/magboots.dm
@@ -2,6 +2,7 @@
desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle."
name = "magboots"
icon_state = "magboots0"
+ species_restricted = null
var/magpulse = 0
// flags = NOSLIP //disabled by default
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index cc0db4e9322..6599bf0bfd6 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1267,12 +1267,6 @@ mob/living/carbon/human/yank_out_object()
species = all_species[new_species]
- see_in_dark = species.darksight
- if(see_in_dark > 2)
- see_invisible = SEE_INVISIBLE_LEVEL_ONE
- else
- see_invisible = SEE_INVISIBLE_LIVING
-
spawn(0)
update_icons()
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 0f0cf418e3b..aec9fe44c60 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -1173,6 +1173,8 @@
if(healths) healths.icon_state = "health7" //DEAD healthmeter
else
sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
+ see_in_dark = species.darksight
+ see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING
if(dna)
switch(dna.mutantrace)
if("slime")
@@ -1217,40 +1219,27 @@
if(!druggy) see_invisible = SEE_INVISIBLE_LIVING
if(glasses)
- if(istype(glasses, /obj/item/clothing/glasses/meson))
- sight |= SEE_TURFS
- if(!druggy)
- see_invisible = SEE_INVISIBLE_MINIMUM
- else if(istype(glasses, /obj/item/clothing/glasses/night))
- see_in_dark = 5
- if(!druggy)
- see_invisible = SEE_INVISIBLE_MINIMUM
- else if(istype(glasses, /obj/item/clothing/glasses/thermal))
- sight |= SEE_MOBS
- if(!druggy)
- see_invisible = SEE_INVISIBLE_MINIMUM
- else if(istype(glasses, /obj/item/clothing/glasses/material))
- sight |= SEE_OBJS
- if(!druggy)
- see_invisible = SEE_INVISIBLE_MINIMUM
+ var/obj/item/clothing/glasses/G = glasses
+ if(istype(G))
+ see_in_dark += G.darkness_view
+ if(G.vision_flags)
+ sight |= G.vision_flags
+ if(!druggy)
+ see_invisible = SEE_INVISIBLE_MINIMUM
/* HUD shit goes here, as long as it doesn't modify sight flags */
// The purpose of this is to stop xray and w/e from preventing you from using huds -- Love, Doohl
- else if(istype(glasses, /obj/item/clothing/glasses/sunglasses))
- see_in_dark = 1
- if(istype(glasses, /obj/item/clothing/glasses/sunglasses/sechud))
- var/obj/item/clothing/glasses/sunglasses/sechud/O = glasses
- if(O.hud) O.hud.process_hud(src)
- if(!druggy) see_invisible = SEE_INVISIBLE_LIVING
-
+ if(istype(glasses, /obj/item/clothing/glasses/sunglasses/sechud))
+ var/obj/item/clothing/glasses/sunglasses/sechud/O = glasses
+ if(O.hud) O.hud.process_hud(src)
+ if(!druggy) see_invisible = SEE_INVISIBLE_LIVING
else if(istype(glasses, /obj/item/clothing/glasses/hud))
var/obj/item/clothing/glasses/hud/O = glasses
O.process_hud(src)
if(!druggy)
see_invisible = SEE_INVISIBLE_LIVING
- else
- see_invisible = SEE_INVISIBLE_LIVING
+
else if(!seer)
see_invisible = SEE_INVISIBLE_LIVING
diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm
index 55e37a4a4f6..caa104a98a5 100644
--- a/code/modules/mob/new_player/sprite_accessories.dm
+++ b/code/modules/mob/new_player/sprite_accessories.dm
@@ -521,7 +521,6 @@
name = "Short Vox Quills"
icon_state = "vox_shortquills"
species_allowed = list("Vox")
- do_colouration = 0
/datum/sprite_accessory/facial_hair
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index ca2d1cd0538..a708562e7ab 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -63,6 +63,15 @@ obj/item/weapon/gun/energy/staff
update_icon()
return
+
+
+ click_empty(mob/user = null)
+ if (user)
+ user.visible_message("*fizzle*", "\red *fizzle*")
+ else
+ src.visible_message("*fizzle*")
+ playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 1)
+
/obj/item/weapon/gun/energy/staff/animate
name = "staff of animation"
desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines."
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index c12f900bc02..9dbcabc47d9 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -112,27 +112,25 @@
M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a [src]"
msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a [src] (JMP)") //BS12 EDIT ALG
- spawn(0)
-
- if(A)
- if (!forcedodge)
- forcedodge = A.bullet_act(src, def_zone) // searches for return value
- if(forcedodge == -1) // the bullet passes through a dense object!
- bumped = 0 // reset bumped variable!
- if(istype(A, /turf))
- loc = A
- else
- loc = A.loc
- permutated.Add(A)
- return 0
- if(istype(A,/turf))
- for(var/obj/O in A)
- O.bullet_act(src)
- for(var/mob/M in A)
- M.bullet_act(src, def_zone)
- density = 0
- invisibility = 101
- del(src)
+ if(A)
+ if (!forcedodge)
+ forcedodge = A.bullet_act(src, def_zone) // searches for return value
+ if(forcedodge == -1) // the bullet passes through a dense object!
+ bumped = 0 // reset bumped variable!
+ if(istype(A, /turf))
+ loc = A
+ else
+ loc = A.loc
+ permutated.Add(A)
+ return 0
+ if(istype(A,/turf))
+ for(var/obj/O in A)
+ O.bullet_act(src)
+ for(var/mob/M in A)
+ M.bullet_act(src, def_zone)
+ density = 0
+ invisibility = 101
+ del(src)
return 1
diff --git a/code/modules/projectiles/projectile/animate.dm b/code/modules/projectiles/projectile/animate.dm
index 5950ac59556..490227d2330 100644
--- a/code/modules/projectiles/projectile/animate.dm
+++ b/code/modules/projectiles/projectile/animate.dm
@@ -7,7 +7,7 @@
flag = "energy"
/obj/item/projectile/animate/Bump(var/atom/change)
- . = ..()
- if(istype(change, /obj/item) || istype(change, /obj/structure) && !is_type_in_list(change, protected_objects))
+ if((istype(change, /obj/item) || istype(change, /obj/structure)) && !is_type_in_list(change, protected_objects))
var/obj/O = change
new /mob/living/simple_animal/hostile/mimic/copy(O.loc, O, firer)
+ ..()
diff --git a/code/modules/reagents/dartgun.dm b/code/modules/reagents/dartgun.dm
index 33e29dc809f..a79a181e729 100644
--- a/code/modules/reagents/dartgun.dm
+++ b/code/modules/reagents/dartgun.dm
@@ -29,7 +29,7 @@
var/obj/item/weapon/dart_cartridge/cartridge = null //Container of darts.
var/max_beakers = 3
var/dart_reagent_amount = 15
- var/container_type = /obj/item/weapon/reagent_containers/glass/beaker/vial
+ var/container_type = /obj/item/weapon/reagent_containers/glass/beaker
var/list/starting_chems = null
/obj/item/weapon/gun/dartgun/update_icon()
@@ -51,7 +51,7 @@
..()
if(starting_chems)
for(var/chem in starting_chems)
- var/obj/item/weapon/reagent_containers/glass/beaker/vial/B = new(src)
+ var/obj/B = new container_type(src)
B.reagents.add_reagent(chem, 50)
beakers += B
cartridge = new /obj/item/weapon/dart_cartridge(src)
@@ -97,7 +97,7 @@
user << "\blue [I] doesn't seem to fit into [src]."
return
if(beakers.len >= max_beakers)
- user << "\blue [src] already has [max_beakers] vials in it - another one isn't going to fit!"
+ user << "\blue [src] already has [max_beakers] beakers in it - another one isn't going to fit!"
return
var/obj/item/weapon/reagent_containers/glass/beaker/B = I
user.drop_item()
diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm
index 0945f60b72c..a55adeb4f9e 100644
--- a/code/modules/virus2/effect.dm
+++ b/code/modules/virus2/effect.dm
@@ -138,6 +138,7 @@
if (!(E.status & ORGAN_DEAD))
E.status |= ORGAN_DEAD
H << "You can't feel your [E.display_name] anymore..."
+ H.update_body(1)
mob.adjustToxLoss(15*multiplier)
deactivate(var/mob/living/carbon/mob,var/multiplier)
@@ -145,6 +146,7 @@
var/mob/living/carbon/human/H = mob
for (var/datum/organ/external/E in H.organs)
E.status &= ~ORGAN_DEAD
+ H.update_body(1)
/datum/disease2/effect/immortal
name = "Longevity Syndrome"
diff --git a/icons/mob/dam_mask.dmi b/icons/mob/dam_mask.dmi
index 286d742f4b9..a50d1358187 100644
Binary files a/icons/mob/dam_mask.dmi and b/icons/mob/dam_mask.dmi differ
diff --git a/maps/tgstation2.dmm b/maps/tgstation2.dmm
index b79db7287c1..bf615760b6f 100644
--- a/maps/tgstation2.dmm
+++ b/maps/tgstation2.dmm
@@ -7819,7 +7819,7 @@
"cUs" = (/obj/structure/rack,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/turf/simulated/shuttle/floor4,/area/shuttle/vox/station)
"cUt" = (/obj/structure/rack,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/turf/simulated/shuttle/floor4,/area/shuttle/vox/station)
"cUu" = (/obj/structure/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/carapace,/obj/item/clothing/head/helmet/space/vox/carapace,/obj/item/clothing/mask/breath/vox,/turf/simulated/shuttle/floor4,/area/shuttle/vox/station)
-"cUv" = (/obj/structure/rack,/obj/item/weapon/gun/dartgun/vox/raider,/obj/item/weapon/gun/dartgun/vox/medical,/turf/simulated/shuttle/floor4,/area/shuttle/vox/station)
+"cUv" = (/obj/structure/rack,/obj/item/weapon/gun/dartgun/vox/raider,/obj/item/weapon/gun/dartgun/vox/medical,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/turf/simulated/shuttle/floor4,/area/shuttle/vox/station)
"cUw" = (/obj/machinery/sleeper,/turf/simulated/shuttle/floor4,/area/shuttle/vox/station)
"cUx" = (/obj/machinery/sleep_console,/turf/simulated/shuttle/floor4,/area/shuttle/vox/station)
"cUy" = (/obj/machinery/bodyscanner,/turf/simulated/shuttle/floor4,/area/shuttle/vox/station)
@@ -10172,7 +10172,7 @@
"dNF" = (/obj/machinery/mineral/stacking_machine,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production)
"dNG" = (/obj/machinery/conveyor{icon_state = "conveyor0"; dir = 10; id = "mining_internal"},/obj/machinery/mineral/input,/turf/simulated/floor{dir = 8; icon_state = "loadingarea"},/area/mine/production)
"dNH" = (/turf/space,/area/vox_station/mining)
-
+
(1,1,1) = {"
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -11720,3 +11720,4 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
"}
+