mirror of
https://github.com/cyberarm/i-mic-rts.git
synced 2025-12-15 07:42:34 +00:00
125 lines
3.5 KiB
Ruby
125 lines
3.5 KiB
Ruby
class IMICRTS
|
|
class PlaceEntity < Tool
|
|
attr_reader :entity, :construction_worker
|
|
|
|
def setup
|
|
@entity = @options[:entity]
|
|
@construction_worker = @options[:construction_worker]
|
|
|
|
@preview = Entity.new(name: @entity, player: @player, id: 0, position: CyberarmEngine::Vector.new, angle: 0, director: @director, proto_entity: true)
|
|
end
|
|
|
|
def draw
|
|
each_tile(vector_to_grid(@game.window.mouse)) do |tile, _data, x, y|
|
|
if tile.entity || tile.reserved || tile.type != :ground || @director.map.ore_at(x, y) # tile unavailable
|
|
Gosu.draw_rect(
|
|
tile.position.x + 2, tile.position.y + 2,
|
|
@director.map.tile_size - 4, @director.map.tile_size - 4,
|
|
Gosu::Color.rgba(200, 50, 50, 200), ZOrder::OVERLAY
|
|
)
|
|
else # tile available
|
|
Gosu.draw_rect(
|
|
tile.position.x + 2, tile.position.y + 2,
|
|
@director.map.tile_size - 4, @director.map.tile_size - 4,
|
|
Gosu::Color.rgba(100, 100, 100, 200), ZOrder::OVERLAY
|
|
)
|
|
end
|
|
end
|
|
|
|
@preview.draw
|
|
end
|
|
|
|
def update
|
|
# TODO: ensure that construction worker is alive
|
|
cancel_tool if @construction_worker.die?
|
|
vector = vector_to_grid(@game.window.mouse)
|
|
|
|
if tile = @director.map.tile_at(vector.x, vector.y)
|
|
position = tile.position.clone
|
|
@preview.position = position + @director.map.tile_size / 2
|
|
@preview.position.z = ZOrder::OVERLAY
|
|
else
|
|
@preview.position.z = -10
|
|
end
|
|
|
|
@preview.color.alpha = 150
|
|
end
|
|
|
|
def use_tool(vector)
|
|
return if @game.sidebar.hit?(@game.window.mouse_x, @game.window.mouse_y)
|
|
|
|
tile = @director.map.tile_at(vector.x, vector.y)
|
|
return unless tile
|
|
position = tile.position + @director.map.tile_size / 2
|
|
|
|
ent = @director.spawn_entity(
|
|
player_id: @player.id, name: @entity,
|
|
position: CyberarmEngine::Vector.new(position.x, position.y, ZOrder::BUILDING)
|
|
)
|
|
|
|
each_tile(vector) do |tile, space_required|
|
|
if space_required == true
|
|
tile.entity = ent
|
|
else
|
|
tile.reserved = ent
|
|
end
|
|
end
|
|
|
|
cancel_tool
|
|
end
|
|
|
|
def can_use?(vector)
|
|
return false if @game.sidebar.hit?(@game.window.mouse_x, @game.window.mouse_y)
|
|
useable = true
|
|
done = false
|
|
|
|
if tile = @director.map.tile_at(vector.x, vector.y)
|
|
ent = Entity.get(@entity)
|
|
origin = (tile.grid_position - 2)
|
|
|
|
each_tile(vector) do |tile, _data, x, y|
|
|
if tile.entity || tile.reserved || tile.type != :ground || @director.map.ore_at(x, y)
|
|
useable = false
|
|
break
|
|
end
|
|
end
|
|
|
|
return useable
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
def each_tile(vector, &block)
|
|
if tile = @director.map.tile_at(vector.x, vector.y)
|
|
ent = Entity.get(@entity)
|
|
origin = (tile.grid_position - 2)
|
|
|
|
ent.tiles.each_with_index do |array, y|
|
|
array.each_with_index do |space_required, x|
|
|
next unless space_required
|
|
|
|
other_tile = @director.map.tile_at(origin.x + x, origin.y + y)
|
|
if other_tile
|
|
block.call(other_tile, space_required, origin.x + x, origin.y + y)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def button_down(id)
|
|
case id
|
|
when Gosu::MsRight
|
|
cancel_tool
|
|
end
|
|
end
|
|
|
|
def button_up(id)
|
|
case id
|
|
when Gosu::MsLeft
|
|
use_tool(vector_to_grid(@game.window.mouse)) if can_use?(vector_to_grid(@game.window.mouse))
|
|
end
|
|
end
|
|
end
|
|
end |