diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 61dfe3d915e..acbb6ff54cc 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -1,9 +1,14 @@
+#define CAT_NORMAL 0
+#define CAT_HIDDEN 1
+#define CAT_COIN 2
+
/datum/data/vending_product
var/product_name = "generic"
var/product_path = null
var/amount = 0
var/price = 0
var/display_color = "blue"
+ var/category = CAT_NORMAL
@@ -119,10 +124,13 @@
R.display_color = pick("red","blue","green")
if(hidden)
+ R.category=CAT_HIDDEN
hidden_records += R
else if(req_coin)
+ R.category=CAT_COIN
coin_records += R
else
+ R.category=CAT_NORMAL
product_records += R
if(delay_product_spawn)
@@ -259,6 +267,31 @@
/obj/machinery/vending/attack_ai(mob/user as mob)
return attack_hand(user)
+/obj/machinery/vending/proc/GetProductIndex(var/datum/data/vending_product/P)
+ var/list/plist
+ switch(P.category)
+ if(CAT_NORMAL)
+ plist=product_records
+ if(CAT_HIDDEN)
+ plist=hidden_records
+ if(CAT_COIN)
+ plist=coin_records
+ else
+ warning("UNKNOWN CATEGORY [P.category] IN TYPE [P.product_path] INSIDE [type]!")
+ return plist.Find(P)
+
+/obj/machinery/vending/proc/GetProductByID(var/pid, var/category)
+ switch(category)
+ if(CAT_NORMAL)
+ return product_records[pid]
+ if(CAT_HIDDEN)
+ return hidden_records[pid]
+ if(CAT_COIN)
+ return coin_records[pid]
+ else
+ warning("UNKNOWN PRODUCT: PID: [pid], CAT: [category] INSIDE [type]!")
+ return null
+
/obj/machinery/vending/attack_hand(mob/user as mob)
if(stat & (BROKEN|NOPOWER))
return
@@ -291,12 +324,11 @@
dat += "No product loaded!"
else
var/list/display_records = src.product_records
+
if(src.extended_inventory)
- display_records = src.product_records + src.hidden_records
+ display_records += src.hidden_records
if(src.coin)
- display_records = src.product_records + src.coin_records
- if(src.coin && src.extended_inventory)
- display_records = src.product_records + src.hidden_records + src.coin_records
+ display_records += src.coin_records
for (var/datum/data/vending_product/R in display_records)
dat += "[R.product_name]:"
@@ -304,7 +336,8 @@
if(R.price)
dat += " (Price: [R.price])"
if (R.amount > 0)
- dat += " (Vend)"
+ var/idx=GetProductIndex(R)
+ dat += " (Vend)"
else
dat += " SOLD OUT"
dat += "
"
@@ -388,7 +421,10 @@
flick(src.icon_deny,src)
return
- var/datum/data/vending_product/R = locate(href_list["vend"])
+ var/idx=text2num(href_list["vend"])
+ var/cat=text2num(href_list["cat"])
+
+ var/datum/data/vending_product/R = GetProductByID(idx,cat)
if (!R || !istype(R) || !R.product_path || R.amount <= 0)
return
diff --git a/code/game/sound.dm b/code/game/sound.dm
index 25e693a91c2..b5a4006e345 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -31,17 +31,7 @@ var/list/page_sound = list('sound/effects/pageturn1.ogg', 'sound/effects/pagetur
var/turf/T = get_turf(M)
if(T && T.z == turf_source.z)
- //check that the air can transmit sound
- var/datum/gas_mixture/environment = T.return_air()
- if (!environment || environment.return_pressure() < SOUND_MINIMUM_PRESSURE)
- if (distance > 1)
- continue
-
- var/new_frequency = 32000 + (frequency - 32000)*0.125 //lower the frequency. very rudimentary
- var/new_volume = vol*0.15 //muffle the sound, like we're hearing through contact
- M.playsound_local(turf_source, soundin, new_volume, vary, new_frequency, falloff, is_global)
- else
- M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global)
+ M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global)
var/const/FALLOFF_SOUNDS = 0.5
@@ -63,12 +53,34 @@ var/const/FALLOFF_SOUNDS = 0.5
if(isturf(turf_source))
// 3D sounds, the technology is here!
var/turf/T = get_turf(src)
- S.volume -= get_dist(T, turf_source) * 2 //multiplicative falloff to add on top of natural audio falloff.
- var/datum/gas_mixture/environment = T.return_air()
- if(get_dist(T, turf_source) > 2)
- S.volume -= environment.return_pressure()/100 + 1
- if (S.volume < 0)
- S.volume = 0
+
+ //sound volume falloff with distance
+ var/distance = get_dist(T, turf_source)
+
+ S.volume -= max(distance - world.view, 0) * 2 //multiplicative falloff to add on top of natural audio falloff.
+
+ //sound volume falloff with pressure
+ var/pressure_factor = 1.0
+
+ var/datum/gas_mixture/hearer_env = T.return_air()
+ var/datum/gas_mixture/source_env = turf_source.return_air()
+
+ if (hearer_env && source_env)
+ var/pressure = min(hearer_env.return_pressure(), source_env.return_pressure())
+
+ if (pressure < ONE_ATMOSPHERE)
+ pressure_factor = max((pressure - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 0)
+ else //in space
+ pressure_factor = 0
+
+ if (distance <= 1)
+ pressure_factor = max(pressure_factor, 0.15) //hearing through contact
+
+ S.volume *= pressure_factor
+
+ if (S.volume <= 0)
+ return //no volume means no sound
+
var/dx = turf_source.x - T.x // Hearing from the right/left
S.x = dx
var/dz = turf_source.y - T.y // Hearing from infront/behind