Add produce command

This commit is contained in:
Anton Vakhrushev 2019-10-15 15:21:55 +03:00
parent 189f6dd96b
commit 33b8e08f8c
2 changed files with 66 additions and 0 deletions

View File

@ -37,6 +37,11 @@ module Game::TestCommand
ts: 20, ts: 20,
resource: Resource.new(Resource::Type::Crystals, 40), resource: Resource.new(Resource::Type::Crystals, 40),
input: ResourceBag.new({Resource::Type::Crystals => 5}) input: ResourceBag.new({Resource::Type::Crystals => 5})
),
production: Production.new(
ts: 20,
input: ResourceBag.new({Resource::Type::Crystals => 40}),
output: ResourceBag.new({Resource::Type::Terraformation => 20})
) )
) )
) )
@ -104,5 +109,18 @@ module Game::TestCommand
tile = world.map.get(1, 0).as(DepositTile) tile = world.map.get(1, 0).as(DepositTile)
tile.dep.cur.should eq 40 tile.dep.cur.should eq 40
end end
it "should complete produce command" do
world = World.new create_map_with_resource
world.resources.inc(Resource::Type::Crystals, 100)
command = ProduceCommand.new Point.new(0, 1), once: true
time_point = (20 + 1 * 2 + 1 * 2).to_i64
done_at = world.push command
done_at.should eq time_point
world.run time_point
# Check world resources
world.resources[Resource::Type::Crystals].should eq 60
world.resources[Resource::Type::Terraformation].should eq 20
end
end end
end end

View File

@ -154,6 +154,54 @@ module Game
end end
end end
class ProduceCommand < Command
@holded : ResourceBag? = nil
def initialize(@point : Point, *, @once = false)
end
def desc : String
if @holded
sprintf "Produce at %d,%d", @point.x, @point.y
else
sprintf "Wait for resources at %d,%d", @point.x, @point.y
end
end
def start(world : World) : TimeSpan
tile = world.map.get(@point).as(BuildingTile)
building = tile.building
production = building.production.as(Production)
if !world.resources.has(production.input)
return production.ts
end
stock_tile = nearest_stock(world)
if stock_tile
world.resources.dec production.input
@holded = production.output
production.ts + 4 * tile.point.distance(stock_tile.point)
else
production.ts
end
end
def finish(world : World)
if @holded
world.resources.inc @holded.as(ResourceBag)
end
if !@once
world.push(ProduceCommand.new(@point))
end
end
private def nearest_stock(world : World) : BuildingTile?
tile = world.map.nearest_tile @point do |t|
t.is_a?(BuildingTile) && t.building.has_role Building::Role::Storehouse
end
tile.as?(BuildingTile)
end
end
# class BuildCrystalHarvesterCommand < Command # class BuildCrystalHarvesterCommand < Command
# BUILD_TIME = 30 # BUILD_TIME = 30