Core/src/components/game/resources.cr

118 lines
2.7 KiB
Crystal

@[Context(Game)]
class TETU::Resources < Entitas::Component
BLUEPRINTS = Blueprint.all("resources", filter: /\.yaml$/)
Log.debug { {"resources bp": BLUEPRINTS} }
DESCRIPTIONS = BLUEPRINTS.map { |b| YAML.parse(File.open(b)).as_h }.reduce { |l, r| l.merge(r) }
LIST = DESCRIPTIONS.keys.map(&.as_s)
# LIST = %i[food food2 mineral mineral2 alloy alloy2 chemical weapon logistic pollution research]
# LIST_S_TO_SYM = LIST.to_h { |k| Tuple.new(k.to_s, k) }
alias Name = String
class Store
property amount, max
def initialize(@amount : Float64, @max : Float64)
end
def self.empty
new(amount: 0.0, max: 0.0)
end
def humanize
"#{@amount}/#{@max}"
end
end
class Stores < Hash(Name, Store)
def humanize(sep = "\n")
map { |k, store| "#{k}: #{store.humanize}" }.join(sep)
end
def amount_hash
transform_values { |store| store.amount }
end
end
# alias Prod = Tuple(Name, Float64)
alias Moving = Hash(Name, Float64)
class Prods < Moving
end
class Manpower
property min : Float64 = 0.0
property optimal : Float64 = 0.0
property max : Float64 = 0.0
end
class Infra
property id : String
property tier : Int32
property prods : Prods
property consumes : Prods
property wastes : Prods
property manpower : Manpower
# this allow to manipulate the planet (local) store
# or make a special infrastructure specific store not shared if we want
getter stores : Stores
def initialize(@id, @stores, @tier = 0)
@prods = Prods.new
@consumes = Prods.new
@wastes = Prods.new
@manpower = Manpower.new
end
def humanize(sep = "\n")
all_res = (consumes.keys + stores.keys + prods.keys).uniq.sort
all_res.map do |res|
store = (stores[res]? || Store.empty)
consume = consumes[res]? || 0.0
prod = prods[res]? || 0.0
"#{res}: #{store.humanize} +#{prod} -#{consume}"
end.join(sep)
end
end
class Infras < Hash(Name, Infra)
# getter @stores : Stores
# def initialize(@stores)
# end
def humanize(sep = ", ")
map { |id, infra| "#{id} (#{infra.tier})" }.join(sep)
end
end
prop :stores, Stores
prop :infras, Infras
def can_produce?
stores? && infras?
end
def humanize(sep = "\n")
infras.humanize(sep)
end
def self.default
stores = Stores.new
stores["pollution"] = Store.new(amount: 0.0, max: 1.0.millions)
infras = Infras.new
Resources.new(stores: stores, infras: infras)
end
def self.default_populated
r = default()
r.stores["pollution"].amount = 100.0 # habitable planet are already polluted a little
r
end
def humanize
"Resources:#{infras.humanize}"
end
end