mirror of
https://github.com/cyberarm/i-mic-rts.git
synced 2025-12-15 15:52:34 +00:00
Added initial tools support, minor refactor to sidebar actions
This commit is contained in:
110
lib/tools/entity_controller.rb
Normal file
110
lib/tools/entity_controller.rb
Normal file
@@ -0,0 +1,110 @@
|
||||
class IMICRTS
|
||||
# Handles entity de/selection and basic move order
|
||||
class EntityController < Tool
|
||||
def setup
|
||||
@drag_start = CyberarmEngine::Vector.new
|
||||
end
|
||||
|
||||
def draw
|
||||
Gosu.draw_rect(
|
||||
@box.min.x, @box.min.y,
|
||||
@box.width, @box.height,
|
||||
Gosu::Color.rgba(50, 50, 50, 150), ZOrder::SELECTION_BOX
|
||||
) if @box
|
||||
end
|
||||
|
||||
def update
|
||||
if @selection_start
|
||||
select_entities
|
||||
end
|
||||
end
|
||||
|
||||
def button_down(id)
|
||||
case id
|
||||
when Gosu::KB_H
|
||||
ent = @player.entities.find { |ent| ent.name == :construction_yard }
|
||||
ent ||= @player.entities.find { |ent| ent.name == :construction_worker }
|
||||
ent ||= @player.starting_position
|
||||
|
||||
@player.camera.move_to(
|
||||
@game.window.width / 2 - ent.position.x,
|
||||
@game.window.height / 2 - ent.position.y,
|
||||
@player.camera.zoom
|
||||
)
|
||||
|
||||
when Gosu::KB_S
|
||||
@director.schedule_order(Order::STOP, @player.id)
|
||||
|
||||
when Gosu::MS_LEFT
|
||||
unless @game.sidebar.hit?(@game.window.mouse_x, @game.window.mouse_y)
|
||||
@selection_start = @player.camera.transform(@game.window.mouse)
|
||||
end
|
||||
when Gosu::MS_RIGHT
|
||||
if @game.selected_entities.size > 0
|
||||
@director.schedule_order(Order::MOVE, @player.id, @player.camera.transform(@game.window.mouse))
|
||||
|
||||
@game.overlays << Game::Overlay.new(Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/cursors/move.png"), @player.camera.transform(@game.window.mouse), 0, 255)
|
||||
@game.overlays.last.position.z = ZOrder::OVERLAY
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def button_up(id)
|
||||
case id
|
||||
when Gosu::MS_RIGHT
|
||||
when Gosu::MS_LEFT
|
||||
@box = nil
|
||||
@selection_start = nil
|
||||
|
||||
diff = (@player.selected_entities - @game.selected_entities)
|
||||
|
||||
@director.schedule_order(Order::DESELECTED_UNITS, @player.id, diff) if diff.size > 0
|
||||
if @game.selected_entities.size > 0
|
||||
@director.schedule_order(Order::SELECTED_UNITS, @player.id, @game.selected_entities)
|
||||
else
|
||||
pick_entity
|
||||
if ent = @game.selected_entities.first
|
||||
return unless ent.component(:sidebar_actions)
|
||||
|
||||
@game.sidebar_actions.clear do |stack|
|
||||
ent.component(:sidebar_actions).actions.each do |action|
|
||||
stack.button action.label, tip: action.description, width: 1.0 do
|
||||
action.block.call if action.block
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pick_entity
|
||||
transform = @player.camera.transform(@game.window.mouse)
|
||||
|
||||
found = @player.entities.find do |ent|
|
||||
transform.distance(ent.position) <= ent.radius
|
||||
end
|
||||
|
||||
if found
|
||||
@game.selected_entities = [found]
|
||||
@director.schedule_order(Order::SELECTED_UNITS, @player.id, @game.selected_entities)
|
||||
end
|
||||
end
|
||||
|
||||
def select_entities
|
||||
transform = @player.camera.transform(@game.window.mouse)
|
||||
@box = CyberarmEngine::BoundingBox.new(@selection_start.xy, transform.xy)
|
||||
|
||||
selected_entities = @player.entities.select do |ent|
|
||||
@box.point?(ent.position) ||
|
||||
@box.point?(ent.position - ent.radius) || @box.point?(ent.position + ent.radius)
|
||||
end
|
||||
|
||||
if Gosu.button_down?(Gosu::KB_LEFT_SHIFT) || Gosu.button_down?(Gosu::KB_RIGHT_SHIFT)
|
||||
@game.selected_entities = @game.selected_entities.union(selected_entities)
|
||||
else
|
||||
@game.selected_entities = selected_entities
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
49
lib/tools/place_entity.rb
Normal file
49
lib/tools/place_entity.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
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)
|
||||
end
|
||||
|
||||
def draw
|
||||
# TODO: draw affected tiles
|
||||
@preview.draw
|
||||
end
|
||||
|
||||
def update
|
||||
# TODO: ensure that construction worker is alive
|
||||
cancel_tool if @construction_worker.die?
|
||||
@preview.position = @player.camera.transform(@game.window.mouse)
|
||||
@preview.position.z = ZOrder::OVERLAY
|
||||
|
||||
@preview.color.alpha = 150
|
||||
end
|
||||
|
||||
def button_down(id)
|
||||
case id
|
||||
when Gosu::MsRight
|
||||
cancel_tool
|
||||
end
|
||||
end
|
||||
|
||||
def button_up(id)
|
||||
case id
|
||||
when Gosu::MsLeft
|
||||
return if @game.sidebar.hit?(@game.window.mouse_x, @game.window.mouse_y)
|
||||
|
||||
transform = @player.camera.transform(@game.window.mouse)
|
||||
|
||||
@director.spawn_entity(
|
||||
player_id: @player.id, name: @entity,
|
||||
position: CyberarmEngine::Vector.new(transform.x, transform.y, ZOrder::BUILDING)
|
||||
)
|
||||
|
||||
cancel_tool
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
9
lib/tools/repair_entity.rb
Normal file
9
lib/tools/repair_entity.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class IMICRTS
|
||||
class SellEntity < Tool
|
||||
attr_accessor :entity
|
||||
|
||||
def setup
|
||||
@entity = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
9
lib/tools/sell_entity.rb
Normal file
9
lib/tools/sell_entity.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class IMICRTS
|
||||
class SellEntity < Tool
|
||||
attr_accessor :entity
|
||||
|
||||
def setup
|
||||
@entity = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user