expansion/src/command.cr

143 lines
3.0 KiB
Crystal

require "./tile"
abstract class Command
abstract def start(world : World) : Int32
abstract def finish(world : World)
end
class BuildCrystalHarvesterCommand < Command
BUILD_TIME = 30
def initialize(@point : Point)
end
def start(world : World) : Int32
BUILD_TIME
end
def finish(world : World)
world.map.set(CrystalHarvesterTile.new(@point))
world.push(HarvestCrystalCommand.new(@point))
end
end
class HarvestCrystalCommand < Command
HARVEST_VALUE = 80
HARVEST_TIME = 10
REST_TIME = 5
def initialize(@point : Point)
@value = 0
end
def start(world : World) : Int32
deposit_tile = nearest_deposit(world)
stock_tile = nearest_stock(world)
if deposit_tile && stock_tile
wood_dist = @point.distance(deposit_tile.point)
stock_dist = @point.distance(stock_tile.point)
@value = deposit_tile.withdraw(HARVEST_VALUE)
HARVEST_TIME + 2 * wood_dist + 2 * stock_dist
else
REST_TIME
end
end
def finish(world : World)
world.resources.inc(ResourceType::Crystal, @value)
world.push(HarvestCrystalCommand.new(@point))
end
private def nearest_deposit(world : World)
world.map.nearest_tile @point do |tile|
tile.has_role(TileRole::CrystalDeposits) && tile.cur > 0
end
end
private def nearest_stock(world : World)
world.map.nearest_tile @point do |tile|
tile.has_role(TileRole::Warehouse)
end
end
end
class BuildCrystalRestorerCommand < Command
BUILD_TIME = 50
def initialize(@point : Point)
end
def start(world : World) : Int32
BUILD_TIME
end
def finish(world : World)
world.map.set(CrystalRestorerTile.new(@point))
world.push(RestoreCrystalCommand.new(@point))
end
end
class RestoreCrystalCommand < Command
RESTORE_TIME = 15
RESTORE_VALUE = 30
REST_TIME = 5
@target_tile : Tile | Nil = nil
def initialize(@point : Point)
end
def start(world : World) : Int32
@target_tile = nearest_deposit(world)
if @target_tile
dist = @point.distance(@target_tile.as(Tile).point)
RESTORE_TIME + 2 * dist
else
REST_TIME
end
end
def finish(world : World)
if @target_tile
@target_tile.as(Tile).charge(RESTORE_VALUE)
end
world.push(RestoreCrystalCommand.new(@point))
end
private def nearest_deposit(world : World)
world.map.nearest_tile @point do |tile|
tile.has_role(TileRole::CrystalDeposits) && tile.cur < tile.cap
end
end
end
class BuildTerraformerCommand < Command
BUILD_TIME = 120
def initialize(@point : Point)
end
def start(world : World) : Int32
BUILD_TIME
end
def finish(world : World)
world.map.set(TerraformerTile.new(@point))
world.push(TerraformCommand.new(@point))
end
end
class TerraformCommand < Command
def initialize(@point : Point)
end
def start(world : World) : Int32
10
end
def finish(world : World)
world.resources.inc(ResourceType::Terraformation, 5)
world.push(TerraformCommand.new(@point))
end
end