78 lines
2.2 KiB
Plaintext
78 lines
2.2 KiB
Plaintext
|
-- it is up to user to ensure that total breached volume is lower
|
||
|
-- than the total volume
|
||
|
class Fluid
|
||
|
new: (opts={}) =>
|
||
|
@volume = opts.volume or 1
|
||
|
@pressure = opts.pressure or 1
|
||
|
@contents = opts.contents or {}
|
||
|
-- breaches stored on high pressure side of Fluids
|
||
|
@breaches = {}
|
||
|
|
||
|
update: (dt) =>
|
||
|
leak = 0 -- total leak rate (pressure)
|
||
|
for breach in *@breaches
|
||
|
-- difference in pressure * relative size of hole
|
||
|
rate = (@pressure - breach.pressure) * (breach.size / @volume) * dt
|
||
|
leak += rate
|
||
|
breach.pressure += rate * (@volume / breach.volume)
|
||
|
breach.pressure = 0 if breach.pressure < 0
|
||
|
amount = breach.pressure * breach.volume
|
||
|
|
||
|
modifier = 1 - @volume * rate / amount
|
||
|
for item, percentage in pairs breach.contents
|
||
|
breach.contents[item] = percentage * modifier
|
||
|
|
||
|
for item, percentage in pairs @contents
|
||
|
percentage = (@volume * rate * percentage) / amount
|
||
|
if breach.contents[item]
|
||
|
breach.contents[item] += percentage
|
||
|
else
|
||
|
breach.contents[item] = percentage
|
||
|
|
||
|
@pressure -= leak
|
||
|
|
||
|
for i = 1, #@breaches
|
||
|
if @breaches[i].pressure > @pressure
|
||
|
other = table.remove @breaches, i
|
||
|
other\breach(@, other.size)
|
||
|
i -= 1
|
||
|
|
||
|
amount: (key) =>
|
||
|
if key
|
||
|
if @contents[key]
|
||
|
return @volume * @pressure * @contents[key]
|
||
|
else
|
||
|
return 0
|
||
|
else
|
||
|
return @volume * @pressure
|
||
|
|
||
|
remove: (key, amount=1) =>
|
||
|
total = @amount key
|
||
|
if total >= amount
|
||
|
percentage = amount / total
|
||
|
@contents[key] -= @contents[key] * percentage
|
||
|
percentage = amount / @amount!
|
||
|
@pressure -= @pressure * percentage
|
||
|
for item, p in pairs @contents
|
||
|
@contents[item] += p * percentage
|
||
|
return true
|
||
|
else
|
||
|
return false
|
||
|
|
||
|
breach: (other, size) =>
|
||
|
if other.pressure > @pressure
|
||
|
other\breach(@, size)
|
||
|
else
|
||
|
other.size = size or 1
|
||
|
table.insert @breaches, other
|
||
|
|
||
|
print: =>
|
||
|
print "Volume", @volume, "Pressure", @pressure, "#", @amount!
|
||
|
percentage, amount = 0, 0
|
||
|
for k,v in pairs @contents
|
||
|
x = @amount k
|
||
|
print k, v, x
|
||
|
percentage += v
|
||
|
amount += x
|
||
|
print "", "Total:", percentage, amount
|