FluidContainers/Fluid.moon

78 lines
2.2 KiB
Plaintext
Raw Normal View History

2018-10-01 16:12:32 +00:00
-- 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